关于串口通信意外卡死的严重问题,有哪位兄台遇到过不?!
当前使用 N32G031C8L7,基于串口1都进行了测试(200ms 收一帧 20字节的数据,收到后判断后回复),几百帧或2000帧左右,程序出现意外卡死(设置了独立看门狗,看门狗复位)的严重问题!修改了一下程序,在 N32G032C8L7 下进行再验证 (证明不是N32G031RAM不足引起的意外溢出 ),意外卡死问题仍旧!!(变量清零,溢出的可能性极小)
问一下,有那位兄台或大侠,遇到过这问题不?!
程序的基本情况:
1、初始化 SysTick 中断 每2ms 中断一次 (用于系统计时)
2、串口1 115200,NONE,8,1
当前KEIL 编译后 RAM 占 4.91kB(N32G032C8L7下,有16K RAM64K FLASH),FLASH约占 40KB
//系统tick 初始化
void SysTick_Configuration(void)
{
if(SysTick_Config(SystemCoreClock/SYSTICK_2MS)) // SYSTICK_2MS = 500
{
/* Capture error */
while (1) ;
}
NVIC_SetPriority(SysTick_IRQn, 0); // NVIC_InitType
}
//N32G032 串口1 中断
void USART1_2_IRQHandler(void)
{
if (USART_GetIntStatus(USART1, USART_INT_RXDNE) != RESET)//USART_FLAG_RXDNE
{
assert_param(IS_USART_ALL_PERIPH(USART1));
if(Usart1.rec_len < Usart1_MAX_REC)//
{ // USARTx->DAT = (Data & (uint16_t)0x01FF);
//Usart1.rec_buf = (unsigned char)(USART1->DAT & (uint16_t)0x01FF);
Usart1.rec_buf = (unsigned char)(USART1->DAT & 0x01FF);
Usart1.rec_existflag = 1;
Usart1.rec_dltime = Uart1_Max_Rec_DLTime;
}
else
{
Usart1.rec_len = 0;
Usart1.rec_existflag = 0; //
}
}
//SET
//if (USART_GetIntStatus(USART1, USART_INT_TXC) != RESET)
if (USART_GetIntStatus(USART1, USART_INT_TXDE) != RESET)
{
if(Usart1.tran_pos < Usart1.tran_len)
{
assert_param(IS_USART_ALL_PERIPH(USART1));
assert_param(IS_USART_DATA(Usart1.tran_buf));
USART1->DAT = Usart1.tran_buf;
Usart1.tran_pos++;
}
else
{
Usart1.tran_pos = 0;
Usart1.tran_len = 0;
Usart1.tran_enable = 1;
//USART_ConfigInt(USART1, USART_INT_TXC, DISABLE);
USART_ConfigInt(USART1, USART_INT_TXDE, DISABLE);
}
}
}
个人感觉就是有某个地方的初始化没弄好,或是串口某个地方的标志位什么的 没处理到 而引起程序飞了!
肯定严重,你的接收数组溢出时,没有读取接收寄存器,是个逻辑漏洞,跟芯片无关。 没看到Usart1.rec_buf 的定义,无法确定这个数组是否够大.
没看到Usart1.rec_len的初始化,如果是随机值,那数组可能越界.
ZG11211 发表于 2023-8-5 10:00
肯定严重,你的接收数组溢出时,没有读取接收寄存器,是个逻辑漏洞,跟芯片无关。 ...
溢出后继续不断的读 接收寄存器 ? 当前已经接收长度清零 < Usart1.rec_len = 0;>继续有数据的话,会回到上方的 if LcwSwust 发表于 2023-8-5 10:45
没看到Usart1.rec_buf 的定义,无法确定这个数组是否够大.
没看到Usart1.rec_len的初始化,如果是随机值,那数 ...
初始化就是清零 这个有操作的接收数据长度 50 因为是对应蓝牙使用的 蓝牙一帧就是 20字节 还有使用芯片调试时,这个函数USART_ClrIntPendingBit 还是 USART_ClrFlag这个函数,一调这个函数就卡死 !
所以,我真的觉得就是某个标志的问题盲猜!当前解决不了!
搞了几十年单片机,串口通信这种简单的收发,基本不会出现卡死的说法。 可以看一下是不是栈溢出了 局部变量的占空间远远小于全局变量占空间 如果数组占用空间太大就会溢出 coody 发表于 2023-8-5 15:17
搞了几十年单片机,串口通信这种简单的收发,基本不会出现卡死的说法。
能不能说 我也是十几年来第一回(手动狗头) mapeoire 发表于 2023-8-5 16:08
可以看一下是不是栈溢出了 局部变量的占空间远远小于全局变量占空间 如果数组占用空间太大就会溢出 ...
修改过程序的 堆栈区,增大了一倍 结果一样 N32G032 的RAM ,也较 N32G031的 RAM大一倍没什么改变
if(Usart1.rec_len < Usart1_MAX_REC)//
{ // USARTx->DAT = (Data & (uint16_t)0x01FF);
//Usart1.rec_buf = (unsigned char)(USART1->DAT & (uint16_t)0x01FF);
Usart1.rec_buf = (unsigned char)(USART1->DAT & 0x01FF);
Usart1.rec_existflag = 1;
Usart1.rec_dltime = Uart1_Max_Rec_DLTime;
}
else
{
temp = ( unsigned char)(USART1->DAT & 0x01FF);
Usart1.rec_len = 0;
Usart1.rec_existflag = 0; //
}
这边没读一直卡死在中断了 是不是内存溢出,看下你的程序。 chenjun89 发表于 2023-8-5 16:54
是不是内存溢出,看下你的程序。
没有的 KEIL 编译后 RAM 占 4.91kB(N32G032C8L7下,有16K RAM) 本帖最后由 zlf1208 于 2023-8-5 17:49 编辑
我没研究你的程序,只是告诉你我以前的一个经历:
我们的产品用了很多年,串口通讯一直是正常的,有一次,客户修改上位机的app,结果串口死机了,单片机其它部分工作正常,原因是通讯负荷太大,但是奇怪的是单片机检测到串口死机后,用软件复位指令无法使串口恢复正常,必须对串口重新初始化才行,单片机是台湾产的arm芯片,我严重怀疑芯片有bug,但是供应商不承认。后来客户限制了通讯负荷,故障就没再出现。 zlf1208 发表于 2023-8-5 17:47
我没研究你的程序,只是告诉你我以前的一个经历:
我们的产品用了很多年,串口通讯一直是正常的,有一次, ...
您好,谢谢你的分享,当前的也可能存在这个问题!
只是,因为这边测试是每200ms才一帧数据(含收发),每帧数据20字节,115200的速率。正常来说,芯片应该是完全处理得过来!
另外一种情况,当前帖子没有说明,在没有高速通信时(每5秒会收到一帧数据,约40字节),也会出现卡死看门狗复位(机率较小)。
不管是那一种,意外复位要处理的现场场境都太多了! 马踏匈奴 发表于 2023-8-5 16:48
if(Usart1.rec_len < Usart1_MAX_REC)//
{ ...
您好此点与中断主函数无关的正常来说,因为标志位已清,缓冲区的数据读不读,与其他都无关了
基于您的提醒,缓冲区长度溢出后,也读数据缓冲区对此点进行了再验证,经测试,意外卡断复位的事没有改变。 本帖最后由 goodlife9999 于 2023-8-7 19:59 编辑
情况汇报:
1、原程序,在官方技术李蒙蒙工程师的大力支持下,经多次不同时段测试,最后在官方的N32G032C8L7的开发板上跑近一小时,20Bytes/1帧/200ms(含收发)。除出现部分丢包现象外,没出现卡断现象。
2、开发板的芯片运行电压是3.3V ,我这边的芯片运行工作电压是 5V 。此可能是最大的区别。
3、因此,需要对芯片在 3.3V的实际工作条件下继续进行验证。有结果的话,会再向大伙汇报,谢谢大伙了哈!
情况汇报:
重画了pcb板,让N32G032C8L7 在3.3V下工作,经测试,卡断现象还是存在!
程序与在仿真板上的连续测试,除了串口收发端口(IO口管脚)不一致外(映射使用的IO不一样),其他的好像没有什么不同了!
搞不懂了!! RAM不足引起的?
页:
[1]
2