基于rt-thread 5.2.1 bsp/at/at32f437-start进行开发,记录详细过程,包括中间遇到的各种坑。

at32f437-start原理图

自己设计的电路板主要换了一块小封装的同系列芯片, 目标是移植opENer。

1. 开发环境

env长时间不用,有点忘了。这次新下载了个2.0新版本。

软件包列表更新,现在新加入的包很多,会出现和服务器不同步的情况。本次开发想用的opENer在iot里找不到,就需要更新。

软件包更新和下载

pkgs --upgrade 命令更新软件包列表

项目menuconfig选中相应的包后,需要下载。

pkgs --update 命令会自动更新/下载/删除相关软件包

2.项目配置

启动ENV,进入bsp目录,这儿选择/bsp/at32/at32f437-start。menuconfig配置,项目硬件有uart,emac,pin,内部falsh,软件包选了opENer。

从rt-thread 5.2.0起,硬件sdk包和以前版本稍有不同,需要通过on packages/peripheral libraries and drivers/HAL & SDK Drivers/AT32HAL & SDK Drivers中选择对应的单片机型号。

保存配置,scons --update, 下载软件包。scons --target==mdk5 生成项目文件。编译项目,有几个错误,提示找不到 fal_cfg.h文件。

因为选择了fal,还需定义内部flash分区表,文件fal_cfg.h内容如下:

#ifndef _FAL_CFG_H_
#define _FAL_CFG_H_#include <rtthread.h>
#include <board.h>#include "drv_flash.h"
#include "fal.h"#ifdef __cplusplus
extern "C" {
#endifextern const struct fal_flash_dev at32_onchip_flash;
extern struct fal_flash_dev nor_flash0;/* flash device table */
#define FAL_FLASH_DEV_TABLE                                          \
{                                                                    \&at32_onchip_flash,                                              \
}/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG/* partition table */
#define FAL_PART_TABLE                                                                       \
{                                                                                            \{FAL_PART_MAGIC_WROD,        "app",   "onchip_flash",       0,           1000 * 1024, 0}, \{FAL_PART_MAGIC_WROD,        "param", "onchip_flash",       1000 * 1024,    6 * 1024, 0}, \
}#endif /* FAL_PART_HAS_TABLE_CFG */#ifdef __cplusplus
extern "C" {
#endif#endif /* _FAL_CFG_H_ */

AT32F435RG有1M flash, 把最后boot rom/user option前面的6K作为参数存储区。

把fal_cfg.h文件存在bsp包中board/inc目录下。重新编译,完美通过!

执行 scons --dist 将配置好的项目生成独立分发版本,只要把dist目录复制出来就可以独立开发了。需要注意的是,每次运行scons --dist命令,会把dist目录里的内容清空,如有修改要做好备份!!!

完整命令为:scons --dist [--target=xxx] [--project-name="xxx"] [--project-path="xxx"]

3.修改硬件配置

由于项目用到了emac和uart1,uart3,管脚配置和at32f437-start的配置不一样,有几个地方还需要修改。

emac 采用RMII,节省资源。用到的引脚有PA1、PA2、PA7、PC1、PC4、PC5、PB11、PB12、PB13。phy芯片yt8512复位脚为PB1。

uart1使用PA9、PA10,uart3使用PC10、PC11。

除yt8512复位脚外,其它都在at32_msp.c文件中。

at32_msp.c中的修改部分。

#ifdef BSP_USING_UART3if(usart_x == USART3){crm_periph_clock_enable(CRM_USART3_PERIPH_CLOCK, TRUE);crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);gpio_init_struct.gpio_mode = GPIO_MODE_MUX;gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;gpio_init_struct.gpio_pull = GPIO_PULL_NONE;gpio_init_struct.gpio_pins = GPIO_PINS_10 | GPIO_PINS_11;gpio_init(GPIOC, &gpio_init_struct);gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE10, GPIO_MUX_7);gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE11, GPIO_MUX_7);}
#endif#ifdef BSP_USING_EMAC
void at32_msp_emac_init(void *instance)
{gpio_init_type gpio_init_struct;crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);//lggpio_default_para_init(&gpio_init_struct);gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;gpio_init_struct.gpio_mode = GPIO_MODE_MUX;gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;gpio_init_struct.gpio_pull = GPIO_PULL_NONE;gpio_init_struct.gpio_pins = GPIO_PINS_1 | GPIO_PINS_2;gpio_init(GPIOA, &gpio_init_struct);gpio_init_struct.gpio_pins = GPIO_PINS_1;gpio_init(GPIOC, &gpio_init_struct);gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE7, GPIO_MUX_11);gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE4, GPIO_MUX_11);gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE5, GPIO_MUX_11);gpio_init_struct.gpio_pins = GPIO_PINS_7;gpio_init(GPIOA, &gpio_init_struct);gpio_init_struct.gpio_pins = GPIO_PINS_4 | GPIO_PINS_5;gpio_init(GPIOC, &gpio_init_struct);gpio_init_struct.gpio_pins = GPIO_PINS_11 | GPIO_PINS_12 | GPIO_PINS_13;//lggpio_init(GPIOB, &gpio_init_struct);gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE1, GPIO_MUX_11);gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE2, GPIO_MUX_11);gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE1, GPIO_MUX_11);gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE11, GPIO_MUX_11);//lggpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE12, GPIO_MUX_11);gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE13, GPIO_MUX_11);
}
#endif /* BSP_USING_EMAC */

phy芯片复位却PB1,需要在drv_emac.c中phy_reset()函数中修改:

static void phy_reset(void)
{gpio_init_type gpio_init_struct;#if defined (SOC_SERIES_AT32F437) || defined (SOC_SERIES_AT32F457)crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);gpio_default_para_init(&gpio_init_struct);gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;gpio_init_struct.gpio_pull = GPIO_PULL_NONE;gpio_init_struct.gpio_pins = GPIO_PINS_1;gpio_init(GPIOB, &gpio_init_struct);gpio_bits_reset(GPIOB, GPIO_PINS_1);rt_thread_mdelay(2);gpio_bits_set(GPIOB, GPIO_PINS_1);
#endif
#if defined (SOC_SERIES_AT32F407)crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);gpio_default_para_init(&gpio_init_struct);gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;gpio_init_struct.gpio_pull = GPIO_PULL_NONE;gpio_init_struct.gpio_pins = GPIO_PINS_8;gpio_init(GPIOC, &gpio_init_struct);gpio_bits_reset(GPIOC, GPIO_PINS_8);rt_thread_mdelay(2);gpio_bits_set(GPIOC, GPIO_PINS_8);
#endifrt_thread_mdelay(2000);
}

最后还要在项目属性页(Device和C/C++)中把单片机型号改成AT32F437RG.

4. 遇到的问题

程序跑起来后,发现网络有问题。phy_linkchange函数没被调用,导致网络不能用。经分析,是phy_monitor_thread_entry函数中的rt_thread_mdelay()导致线程挂起后,时间到了也没被唤醒,后续代码就没有执行到。

static void phy_monitor_thread_entry(void *parameter)
{uint8_t detected_count = 0;while(phy_addr == 0xFF){/* phy search */rt_uint32_t i, temp;for (i = 0; i <= 0x1F; i++){emac_phy_register_read(i, PHY_BASIC_STATUS_REG, (uint16_t *)&temp);if (temp != 0xFFFF && temp != 0x00){phy_addr = i;break;}}detected_count++;//rt_thread_mdelay(1000);if (detected_count > 10){LOG_E("No PHY device was detected, please check hardware!");}}LOG_D("Found a phy, address:0x%02X", phy_addr);/* reset phy */LOG_D("RESET PHY!");emac_phy_register_write(phy_addr, PHY_BASIC_CONTROL_REG, PHY_RESET_MASK);//rt_thread_mdelay(2000);emac_phy_register_write(phy_addr, PHY_BASIC_CONTROL_REG, PHY_AUTO_NEGOTIATION_MASK);phy_linkchange();
#ifdef PHY_USING_INTERRUPT_MODE/* configuration intterrupt pin */rt_pin_mode(PHY_INT_PIN, PIN_MODE_INPUT_PULLUP);rt_pin_attach_irq(PHY_INT_PIN, PIN_IRQ_MODE_FALLING, emac_phy_isr, (void *)"callbackargs");rt_pin_irq_enable(PHY_INT_PIN, PIN_IRQ_ENABLE);/* enable phy interrupt */emac_phy_register_write(phy_addr, PHY_INTERRUPT_MASK_REG, PHY_INT_MASK);
#if defined(PHY_INTERRUPT_CTRL_REG)emac_phy_register_write(phy_addr, PHY_INTERRUPT_CTRL_REG, PHY_INTERRUPT_EN);
#endif
#else /* PHY_USING_INTERRUPT_MODE */at32_emac_device.poll_link_timer = rt_timer_create("phylnk", (void (*)(void*))phy_linkchange,NULL, RT_TICK_PER_SECOND, RT_TIMER_FLAG_PERIODIC);if (!at32_emac_device.poll_link_timer || rt_timer_start(at32_emac_device.poll_link_timer) != RT_EOK){LOG_E("Start link change detection timer failed");}
#endif /* PHY_USING_INTERRUPT_MODE */
}

把两个rt_thread_mdelay调用注释掉,正常。延时估计是为兼容不同的Phy芯片,对于YT8512不延时没有问题。

至于为什么delay会让线程没法唤醒,还没有仔细分析!!!可能细节还在其它地方。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/90659.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/90659.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/90659.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

EMCCD相机与电可调变焦透镜的同步控制系统设计与实现

EMCCD相机与电可调变焦透镜的同步控制系统设计与实现 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff0c;觉得好请收藏。点击跳转到网站。 摘要 本文详细介绍了基于Python的EMCCD相机&#xff0…

前缀和-560.和为k的子数组-力扣(LeetCode)

一、题目解析1.子数组是数组中元素的连续非空序列2.nums[i]范围为[-1000,1000]&#xff0c;存在负数3.由于2的题目条件&#xff0c;该题不能用双指针算法&#xff0c;不具备单调性 二、算法原理解法1&#xff1a;暴力解法->枚举 O(N^2)固定一个值&#xff0c;向后枚举数组和…

解决企业微信收集表没有图片、文件组件,不能收集图片的问题

问题&#xff1a; 企业微信里面的收集表功能&#xff0c;有一个图片收集的收集表&#xff0c;但是插入的组件没有收集图片的组件&#xff1f; 原因&#xff1a; 大概率是微盘未启用 解决方法&#xff1a; 1、登陆企业微信管理后台 企业微信 2、访问微盘页面&#xff0c;…

认识单片机

《认识单片机》课程内容 一、课程导入 在我们的日常生活中&#xff0c;有很多看似普通却充满智慧的小物件。比如家里的智能电饭煲&#xff0c;它能精准地控制煮饭的时间和温度&#xff0c;让米饭煮得香喷喷的&#xff1b;还有楼道里的声控灯&#xff0c;当有人走过发出声音时&a…

数据结构(2)顺序表算法题

一、移除元素1、题目描述2、算法分析 思路1&#xff1a;查找val值对应的下标pos&#xff0c;执行删除pos位置数据的操作。该方法时间复杂度为O&#xff08;n^2&#xff09;&#xff0c;因此不建议使用。思路2&#xff1a;创建新数组&#xff08;空间大小与原数组一致&#xff0…

汽车电子架构

本文试图从Analog Devices官网中的汽车解决方案视角带读者构建起汽车电子的总体架构图&#xff0c;为国内热爱和从事汽车电子行业的伙伴们贡献一份力量。 一 、汽车电子架构总览 整个汽车电子包括四个部分&#xff1a;车身电子&#xff08;Body Electronics&#xff09;、座舱与…

pycharm 2025 专业版下载安装教程【附安装包】

安装之前&#xff0c;请确保已经关闭所有安全软件&#xff08;如杀毒软件、防火墙等&#xff09;安装包 &#x1f447;链接&#xff1a;https://pan.xunlei.com/s/VOU-5_L1KOH5j3zDaaCh-Z28A1# 提取码&#xff1a;6bjy下载 PyCharm2025专业版 安装包 并 进行解压运行 pycharm-2…

在 Java 世界里让对象“旅行”:序列化与反序列化

Java 生态里关于 JSON 的序列化与反序列化&#xff08;以下简称“序列化”&#xff09;是一个久经考验的话题&#xff0c;却常因框架繁多、配置琐碎而让初学者望而却步。本文将围绕一段极简的 JsonUtils 工具类展开&#xff0c;以 FastJSON 与 Jackson 两大主流实现为例&#x…

High Speed SelectIO Wizard ip使用记录

本次实验的目的是通过VU9P开发板的6个TG接口&#xff0c;采用固定连接的方式&#xff0c;即X和X-维度互联&#xff0c;其框图如下所示&#xff1a;IP参数配置通过调用High Speed SelectIO Wizard来实现数据通路&#xff0c;High Speed SelectIO Wizard ip有24对数据通道&#x…

Execel文档批量替换标签实现方案

问题背景需求&#xff1a;俺现网班级作为维度&#xff0c;批量导出每个班级学员的数据&#xff0c;excel的个数在1k左右&#xff0c;每一张表的人数在90左右。导出总耗时在10小时左右。代码编写完成并导出现网数据后&#xff0c;发现导出的标题错了。解决方案1.通过修改代码&am…

SpringBoot配置多数据源多数据库

Springboot支持配置多数据源。默认情况&#xff0c;在yml文件中只会配置一个数据库。如果涉及到操作多个数据库的情况&#xff0c;在同实例中&#xff08;即同一个ip地址下的不同数据库&#xff09;&#xff0c;可以采用数据库名点数据库表的方式&#xff0c;实现跨库表的操作。…

Rocky9.4部署Zabbix7

一、配置安装源 rpm -Uvh https://repo.zabbix.com/zabbix/7.0/rocky/9/x86_64/zabbix-release-7.0-5.el9.noarch.rpm ​ yum clean all 二、安装Zabbix server&#xff0c;Web前端&#xff0c;agent yum install zabbix-server-mysql zabbix-web-mysql zabbix-nginx-conf z…

【Java】对象类型转换(ClassCastException)异常:从底层原理到架构级防御,老司机的实战经验

在开发中&#xff0c;ClassCastException&#xff08;类转换异常&#xff09;就像一颗隐藏的定时炸弹&#xff0c;常常在代码运行到类型转换逻辑时突然爆发。线上排查问题时&#xff0c;这类异常往往因为类型关系复杂而难以定位。多数开发者习惯于在转换前加个instanceof判断就…

探路者:用 AI 面试加速人才集结,为户外爱好者带来更专业的服务

作为深耕户外用品领域的知名品牌&#xff0c;探路者已构建起覆盖全国的销售服务网络&#xff0c;上千品种的产品矩阵更是为品牌在市场中站稳脚跟提供了有力支撑。对探路者来说&#xff0c;要持续为户外爱好者带来专业且贴心的体验&#xff0c;专业人才是核心支撑。然而&#xf…

LeetCode——面试题 05.01 插入

通过万岁&#xff01;&#xff01;&#xff01; 题目&#xff1a;一共会给四个数&#xff0c;分别是N、M、i、j&#xff0c;然后希望我们把N和M抓怒换为2进制以后&#xff0c;将M的二进制放在i到j之间的区域&#xff0c;如果M的二进制长度小于i-j1&#xff0c;则前面补0即可。最…

前端设计中如何在鼠标悬浮时同步修改块内样式

虽然只是一个小问题&#xff0c;但这个解决问题的过程也深化了自己对盒子模型的理解问题缘起正在写一个登录注册的小窗口&#xff0c;想要在鼠标悬浮阶段让按钮和文字都变色&#xff0c;但是发现实操的时候按钮和文字没办法同时变色鼠标悬停前鼠标悬停后问题分析仔细分析了下该…

航空发动机高速旋转件的非接触式信号传输系统

航空发动机是飞机动力系统的核心&#xff0c;各种关键部件如涡轮、压气机等&#xff0c;经常处于极端高温、高速旋转的工作环境中。航空发动机内的传感器数据&#xff0c;如何能够稳定可靠的通过无线的方式传输到检测太&#xff0c;一直是业内的一个难点和痛点。在这个领域&…

【postgresql按照逗号分割字段,并统计数量和求和】

postgresql按照逗号分割字段&#xff0c;并统计数量和求和postgresql按照逗号分割字段&#xff0c;并统计数量和求和postgresql按照逗号分割字段&#xff0c;并统计数量和求和 SELECT ucd, p ,tm, step, unitcd, tm_end from resource_calc_scene_rain_bound_value_plus whe…

「iOS」————继承链与对象的结构

iOS学习前言对象的底层结构isa的类型isa_tobjc_class & objc_object类信息的静态与动态存储&#xff08;ro、rw、rwe机制&#xff09;cachebits继承链isKindOfClass和isMemberOfClassisKindOfClass:isMemberofClass前言 对 对象底层结构的相关信息有点遗忘&#xff0c;简略…

代码随想录day46dp13

647. 回文子串 题目链接 文章讲解 回溯法 class Solution { public:int count 0;// 检查字符串是否是回文bool isPalindrome(string& s, int start, int end) {while (start < end) {if (s[start] ! s[end]) return false;start;end--;}return true;}// 回溯法&#…