本文主要记录了【沁恒蓝牙MESH】CH582单板无法正常启动的原因,
由于开发疏忽,注释了中断服务函数的代码,是入门嵌入式开发经常忽视的错误,用以记录,共勉!!
友情提示: 千万不要随便注释工程中你认为没有用的代码!!!!!!!!!!!!!!!!
【沁恒蓝牙MESH】CH582串口中断内存溢出导致MCU频繁重启
目录
- 1. 问题二:串口1的接收中断,线路状态错误导致单板无法正常启动
- 1.1 问题描述:
- 1.2 错误的代码如下:
- 1.3 问题复现与定位
- 1.4 打破砂锅问到底
- 1.4.1 UART1_GetLinSTA 这行代码是什么意思?
- 1.4.2 读取线路状态寄存器的值,定位问题####
- 💖 作者简介:大家好,我是喜欢记录零碎知识点的小菜鸟。😎
- 📝 个人主页:欢迎访问我的 Ethernet_Comm 博客主页🔥
- 🎉 支持我:点赞👍+收藏⭐️+留言📝
- 📣 系列专栏:沁恒蓝牙mesh二次开发🍁
- 💬格言:写文档啊不是写文章,重要的还是直白!🔥
1. 问题二:串口1的接收中断,线路状态错误导致单板无法正常启动
1.1 问题描述:
之前自己开发的基于CH58x的固件在自己的手头的测试板中功能都正常,但是当大批量烧写100块卡发板时却遇到了问题,
问题表现为 有的单板上电无法正常启动,经过排查,发现代码中开启了串口1的接收中断和线路状态错误中断,但是在中断服务函数中却没有清除线路状态错误中断,导致单板无法启动。
1.2 错误的代码如下:
注意 UART1_INTCfg(ENABLE, RB_IER_RECV_RDY | RB_IER_LINE_STAT);
这行代码,开启线路中断和接收中断
但是我在中断服务函数中却没有清除线路状态错误中断,UART1_GetLinSTA();
这行代码官方库中是有的,但是我因为开发过程中,编译总是报警告,所以我注释了这行代码,导致拍查浪费了几天的时间。
void ch58x_Uart_init()
{/*串口1 PA9 TX1 PA8--RX1*/GPIOA_SetBits(bTXD1 ); //;GPIO_Pin_9);GPIOA_ModeCfg(bTXD1, GPIO_ModeOut_PP_5mA); // PA9 TXGPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU); // PA8 RXD-配置上拉输入UART1_DefInit();UART1_ByteTrigCfg(UART_7BYTE_TRIG);UART1_INTCfg(ENABLE, RB_IER_RECV_RDY | RB_IER_LINE_STAT);//开启线路中断和接收中断PFIC_EnableIRQ(UART1_IRQn);
}//中断服务函数
__INTERRUPT
__HIGH_CODE
void UART1_IRQHandler(void)
{volatile uint8_t i;switch(UART1_GetITFlag()){case UART_II_LINE_STAT: // 线路状态错误{//UART1_GetLinSTA(); // 我注释了这行代码break;}}
}
1.3 问题复现与定位
找了几块每次上电都无法正常启动的板子,修改代码如下,发现单板确实是因为进入了中断但是没有清中断导致无法正常启动。
1.4 打破砂锅问到底
1.4.1 UART1_GetLinSTA 这行代码是什么意思?
// 官方解释:refer to LINE error and status define
#define UART1_GetLinSTA() (R8_UART1_LSR)
#define R8_UART1_LSR (*((PUINT8V)0x40003405)) // RO, UART1 line status
这行代码的意思就是读了一下 R8_UART1_LSR
这个寄存器的值,由于代码中没有赋值,所以编译的时候报 warning
信息,如果改为
uint8_t regVlaue = R8_UART1_LSR
这种赋值的形式编译就不报错了?
继续看手册, 读取寄存器的值可以直接清中断,那么UART1_GetLinSTA()
这行代码的作用就是 清除线路状态错误中断
1.4.2 读取线路状态寄存器的值,定位问题####
为了测试,在中断服务函数中打印出寄存器的值(在中断中不要使用 printf ,这里仅仅是为了测试)
上电数次后发现,正常启动的单板读取的线路状态寄存器(R8_UART1_LSR
)的值都是复位值 0x60 ,但是有问题的单板的读取的复位值是 248 = 0xf8
那么问题就很清楚了,单板上电检测到线路状态错误,进入了中断,但是又没有清中断,所以卡在中断里就无法正常启动了