针对GD32F527在添加以太网功能后,仿真器烧录可启动但手动上电卡死的问题,结合系统卡在object->type = type | RT_Object_Class_Static;且SysTick中断仅触发一次的现象,以下是详细分析和解决方案:
时钟初始化时序问题
以太网PHY复位不充分
中断冲突或优先级配置错误
内存访问异常
在 rt_hw_board_init() 中增加外部晶振稳定延时:
// 在 system_clock_config() 后添加
void rt_hw_board_init()
{
// ... 其他初始化
system_clock_config(); // 配置系统时钟
/* 增加HXTAL稳定延时 */
volatile uint32_t delay = 1000000;
while (delay--); // 简单延时循环
/* 初始化以太网 */
rt_hw_eth_init();
// ...
}在PHY复位代码中增加硬件复位和状态检测:
void rt_hw_eth_init()
{
/* 硬件复位PHY (假设RST引脚连接PE2) */
rt_pin_mode(GET_PIN(E, 2), PIN_MODE_OUTPUT);
rt_pin_write(GET_PIN(E, 2), PIN_LOW);
rt_thread_mdelay(100); // 保持复位100ms
rt_pin_write(GET_PIN(E, 2), PIN_HIGH);
rt_thread_mdelay(200); // 等待PHY启动完成
/* 检测PHY ID确保通信正常 */
uint32_t phy_id = 0;
for (int retry = 0; retry < 10; retry++) {
phy_id = eth_device_phy_read(ETH_PHY_ADDR, PHY_ID1_REG);
if (phy_id != 0xFFFF && phy_id != 0) break;
rt_thread_mdelay(10);
}
if (phy_id == 0xFFFF || phy_id == 0) {
rt_kprintf("ETH: PHY init failed!n");
return;
}
// ... 后续初始化
}在 drv_eth.c 中配置以太网中断优先级低于SysTick:
void gd32_eth_init(void)
{
// ... 以太网外设初始化
/* 设置ETH中断优先级 (低于SysTick) */
nvic_irq_enable(ETH_IRQn, 1, 0); // 优先级1 (数值越大优先级越低)
/* 确保SysTick优先级最低 */
NVIC_SetPriority(SysTick_IRQn, 0xF);
}增大堆栈大小
在 rtconfig.h 中调整:
#define RT_MAIN_THREAD_STACK_SIZE 4096 // 原值若为2048则增大
#define RT_THREAD_STACK_SIZE 1024 // 默认线程栈
#define ETH_RXBUFNB 4 // 减少接收缓冲区数量以节省内存确认DMA描述符地址对齐
确保描述符位于非缓存区且64字节对齐:
__attribute__((section(".noncache"), aligned(64))) ETH_DMADescTypeDef DMARxDscrTab[ETH_RXBUFNB];调试日志定位
在卡死代码前添加详细日志:
rt_kprintf("Init eth, step1n");
object->type = type | RT_Object_Class_Static; // 卡死行
rt_kprintf("Init eth, step2n"); // 此句不会执行检查复位状态寄存器
在启动时读取复位标志,确定复位原因:
uint32_t reset_flags = RCU_RSTSCK;
rt_kprintf("Reset flags: 0x%08Xn", reset_flags);完成上述修改后:
PHY ID: 0xXXXX 表示PHY初始化成功。ping 192.168.1.100 # 根据实际网络配置
提示:若仍卡死,使用JTAG在手动上电后立刻暂停CPU,检查
PC指针位置和堆栈内容,定位异常指令。
通过以上步骤,可解决手动上电卡死问题,确保以太网功能稳定运行。
举报
更多回帖