本文主要记录了【沁恒蓝牙MESH】CH582单板无法正常启动的原因,
由于开发疏忽,注释了中断服务函数的代码,是入门嵌入式开发经常忽视的错误,用以记录,共勉!!
友情提示: 千万不要随便注释工程中你认为没有用的代码!!!!!!!!!!!!!!!!
【沁恒蓝牙MESH】CH582串口中断内存溢出导致MCU频繁重启
- 作者简介:大家好,我是喜欢记录零碎知识点的小菜鸟。
- 个人主页:欢迎访问我的 Ethernet_Comm 博客主页
- 支持我:点赞+收藏⭐️+留言
- 系列专栏:沁恒蓝牙mesh二次开发
- 格言:写文档啊不是写文章,重要的还是直白!
之前自己开发的基于CH58x的固件在自己的手头的测试板中功能都正常,但是当大批量烧写100块卡发板时却遇到了问题,
问题表现为 有的单板上电无法正常启动,经过排查,发现代码中开启了串口1的接收中断和线路状态错误中断,但是在中断服务函数中却没有清除线路状态错误中断,导致单板无法启动。
注意 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 TX
GPIOA_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;
}
}
}
找了几块每次上电都无法正常启动的板子,修改代码如下,发现单板确实是因为进入了中断但是没有清中断导致无法正常启动。
// 官方解释: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()
这行代码的作用就是 清除线路状态错误中断
为了测试,在中断服务函数中打印出寄存器的值(在中断中不要使用 printf ,这里仅仅是为了测试)
上电数次后发现,正常启动的单板读取的线路状态寄存器(R8_UART1_LSR
)的值都是复位值 0x60 ,但是有问题的单板的读取的复位值是 248 = 0xf8
那么问题就很清楚了,单板上电检测到线路状态错误,进入了中断,但是又没有清中断,所以卡在中断里就无法正常启动了