打印
[N32G03x]

关于串口通信意外卡死的严重问题,有哪位兄台遇到过不?!

[复制链接]
2775|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
goodlife9999|  楼主 | 2023-8-4 17:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
当前使用 N32G031C8L7,基于串口1都进行了测试(200ms 收一帧 20字节的数据,收到后判断后回复),几百帧或2000帧左右,程序出现意外卡死(设置了独立看门狗,看门狗复位)的严重问题!
修改了一下程序,在 N32G032C8L7 下进行再验证 (证明不是N32G031  RAM不足引起的意外溢出 ),意外卡死问题仍旧!!(变量清零,溢出的可能性极小)
问一下,有那位兄台或大侠,遇到过这问题不?!

程序的基本情况:
1、初始化 SysTick 中断 每2ms 中断一次 (用于系统计时)
2、串口1   115200,NONE,8,1
当前KEIL 编译后 RAM 占   4.91kB(N32G032C8L7下,有16K RAM  64K 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[Usart1.rec_len++] =         (unsigned char)(USART1->DAT & (uint16_t)0x01FF);
                        Usart1.rec_buf[Usart1.rec_len++] =         (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.tran_pos]));
       
                        USART1->DAT = Usart1.tran_buf[Usart1.tran_pos];
                        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);       
                }
    }
}

使用特权

评论回复
沙发
goodlife9999|  楼主 | 2023-8-4 17:29 | 只看该作者
个人感觉就是有某个地方的初始化没弄好,或是串口某个地方的标志位什么的 没处理到 而引起程序飞了!

使用特权

评论回复
板凳
ZG11211| | 2023-8-5 10:00 | 只看该作者
肯定严重,你的接收数组溢出时,没有读取接收寄存器,是个逻辑漏洞,跟芯片无关。

使用特权

评论回复
地板
LcwSwust| | 2023-8-5 10:45 | 只看该作者
没看到Usart1.rec_buf 的定义,无法确定这个数组是否够大.
没看到Usart1.rec_len的初始化,如果是随机值,那数组可能越界.

使用特权

评论回复
5
goodlife9999|  楼主 | 2023-8-5 14:17 | 只看该作者
ZG11211 发表于 2023-8-5 10:00
肯定严重,你的接收数组溢出时,没有读取接收寄存器,是个逻辑漏洞,跟芯片无关。 ...

溢出后继续不断的读 接收寄存器 ? 当前已经接收长度清零 < Usart1.rec_len = 0;>  继续有数据的话,会回到上方的 if

使用特权

评论回复
6
goodlife9999|  楼主 | 2023-8-5 14:18 | 只看该作者
LcwSwust 发表于 2023-8-5 10:45
没看到Usart1.rec_buf 的定义,无法确定这个数组是否够大.
没看到Usart1.rec_len的初始化,如果是随机值,那数 ...

初始化就是清零   这个有操作的  接收数据长度 50   因为是对应蓝牙使用的 蓝牙一帧就是 20字节

使用特权

评论回复
7
goodlife9999|  楼主 | 2023-8-5 14:29 | 只看该作者
还有使用芯片调试时,这个函数  USART_ClrIntPendingBit   还是 USART_ClrFlag  这个函数,一调这个函数就卡死 !
所以,我真的觉得就是某个标志的问题  盲猜!当前解决不了!

使用特权

评论回复
8
coody| | 2023-8-5 15:17 | 只看该作者
搞了几十年单片机,串口通信这种简单的收发,基本不会出现卡死的说法。

使用特权

评论回复
9
mapeoire| | 2023-8-5 16:08 | 只看该作者
可以看一下是不是栈溢出了 局部变量的占空间远远小于全局变量占空间 如果数组占用空间太大就会溢出

使用特权

评论回复
10
goodlife9999|  楼主 | 2023-8-5 16:22 | 只看该作者
coody 发表于 2023-8-5 15:17
搞了几十年单片机,串口通信这种简单的收发,基本不会出现卡死的说法。

能不能说   我也是十几年来第一回  (手动狗头)

使用特权

评论回复
11
goodlife9999|  楼主 | 2023-8-5 16:24 | 只看该作者
mapeoire 发表于 2023-8-5 16:08
可以看一下是不是栈溢出了 局部变量的占空间远远小于全局变量占空间 如果数组占用空间太大就会溢出 ...

修改过程序的 堆栈区,增大了一倍 结果一样    N32G032 的RAM ,也较 N32G031的 RAM大一倍  没什么改变  

使用特权

评论回复
12
马踏匈奴| | 2023-8-5 16:48 | 只看该作者
if(Usart1.rec_len < Usart1_MAX_REC)  //
                {                                                                                // USARTx->DAT = (Data & (uint16_t)0x01FF);
                        //Usart1.rec_buf[Usart1.rec_len++] =         (unsigned char)(USART1->DAT & (uint16_t)0x01FF);
                        Usart1.rec_buf[Usart1.rec_len++] =         (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;                  //      
                }


这边没读一直卡死在中断了

使用特权

评论回复
13
chenjun89| | 2023-8-5 16:54 | 只看该作者
是不是内存溢出,看下你的程序。

使用特权

评论回复
14
goodlife9999|  楼主 | 2023-8-5 17:11 | 只看该作者
chenjun89 发表于 2023-8-5 16:54
是不是内存溢出,看下你的程序。

没有的      KEIL 编译后 RAM 占   4.91kB(N32G032C8L7下,有16K RAM)

使用特权

评论回复
15
zlf1208| | 2023-8-5 17:47 | 只看该作者
本帖最后由 zlf1208 于 2023-8-5 17:49 编辑

我没研究你的程序,只是告诉你我以前的一个经历:

我们的产品用了很多年,串口通讯一直是正常的,有一次,客户修改上位机的app,结果串口死机了,单片机其它部分工作正常,原因是通讯负荷太大,但是奇怪的是单片机检测到串口死机后,用软件复位指令无法使串口恢复正常,必须对串口重新初始化才行,单片机是台湾产的arm芯片,我严重怀疑芯片有bug,但是供应商不承认。后来客户限制了通讯负荷,故障就没再出现。

使用特权

评论回复
16
goodlife9999|  楼主 | 2023-8-6 07:42 | 只看该作者
zlf1208 发表于 2023-8-5 17:47
我没研究你的程序,只是告诉你我以前的一个经历:

我们的产品用了很多年,串口通讯一直是正常的,有一次, ...

您好,谢谢你的分享,当前的也可能存在这个问题!
只是,因为这边测试是每200ms才一帧数据(含收发),每帧数据20字节,115200的速率。正常来说,芯片应该是完全处理得过来!
另外一种情况,当前帖子没有说明,在没有高速通信时(每5秒会收到一帧数据,约40字节),也会出现卡死看门狗复位(机率较小)。
不管是那一种,意外复位要处理的现场场境都太多了!

使用特权

评论回复
17
goodlife9999|  楼主 | 2023-8-6 08:19 | 只看该作者
马踏匈奴 发表于 2023-8-5 16:48
if(Usart1.rec_len < Usart1_MAX_REC)  //
                {                                            ...

您好  此点与中断主函数无关的  正常来说,因为标志位已清,缓冲区的数据读不读,与其他都无关了

基于您的提醒,缓冲区长度溢出后,也读数据缓冲区  对此点进行了再验证,经测试,意外卡断复位的事没有改变。

使用特权

评论回复
18
goodlife9999|  楼主 | 2023-8-7 19:58 | 只看该作者
本帖最后由 goodlife9999 于 2023-8-7 19:59 编辑

情况汇报:
1、原程序,在官方技术李蒙蒙工程师的大力支持下,经多次不同时段测试,最后在官方的N32G032C8L7的开发板上跑近一小时,20Bytes/1帧/200ms(含收发)。除出现部分丢包现象外,没出现卡断现象。
2、开发板的芯片运行电压是3.3V ,我这边的芯片运行工作电压是 5V 。此可能是最大的区别。
3、因此,需要对芯片在 3.3V的实际工作条件下继续进行验证。有结果的话,会再向大伙汇报,谢谢大伙了哈!

使用特权

评论回复
19
goodlife9999|  楼主 | 2023-8-15 15:58 | 只看该作者
情况汇报:
重画了pcb板,让N32G032C8L7 在3.3V下工作,经测试,卡断现象还是存在!
程序与在仿真板上的连续测试,除了串口收发端口(IO口管脚)不一致外(映射使用的IO不一样),其他的好像没有什么不同了!
搞不懂了!!

使用特权

评论回复
20
zhenykun| | 2023-8-15 20:33 | 只看该作者
RAM不足引起的?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

12

帖子

0

粉丝