搜索
bottom↓
回复: 10

疑似CRC校验引起的HardFault,请求帮助看看原因

[复制链接]

出0入0汤圆

发表于 2018-10-23 15:25:34 | 显示全部楼层 |阅读模式
本帖最后由 qaya 于 2018-10-24 09:29 编辑

系统采用485通讯,主机发起询问,子机回复。主机收到子机的回复后调用CRC校验程序检验子机的回复是否正确。主机连接了一块迪文串口屏。
错误现象是快速点击主机的屏幕引发频繁的主从机通讯,就会引起主机死机。DEBUG发现死机时进入了 HardFault_Handler() 的while(1)里。
然后在此while(1)循环设置断点,程序停在此处时在“Call Stack + Locals”对话框右键Show Caller Code,看到进入HardFault_Handler() 调用的是CRC校验程序。看了看校验程序,似乎也没什么问题,很疑惑。
以下是校验程序:
#define POLY        0x1021  
unsigned int CRC16(unsigned char *addr, int num, unsigned int crc)  
{  
    int i=0;  
    for (; num > 0; num--)              /* Step through bytes in memory */  
    {  
        crc = crc ^ (*addr++ << 8);     /* Fetch byte from memory, XOR into CRC top byte*/  
        for (i = 0; i < 8; i++)             /* Prepare to rotate 8 bits */  
        {  
            if (crc & 0x8000)            /* b15 is set... */  
                crc = (crc << 1) ^ POLY;    /* rotate and XOR with polynomic */  
            else                          /* b15 is clear... */  
                crc <<= 1;                  /* just rotate */  
        }                             /* Loop for 8 bits */  
        crc &= 0xFFFF;                  /* Ensure CRC remains 16-bit value */  
    }                               /* Loop until num=0 */  
    return(crc);                    /* Return updated CRC */  
}


/*************************************以下增加程序相关主要部分*********************************************************************/
unsigned char MasterToSlaveReceiveBuff[400];
void SysTick_Handler(void)
{
  ...
        if(SysTick_50ms_1Second==0)//系统嘀嗒设置为50ms一次
        {
          SysTick_50ms_1Second=20;
                SysTick_SecondFlag=1;        
         }

}
void USART1_IRQHandler(void)
{
   if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){
      ...
      if(接收到完整的子机回复){
      ...
      MasterToSlaveReceive_VirtualLength=(MasterToSlaveReceiveBuff[2]<<8)+MasterToSlaveReceiveBuff[3];
      MasterToSlaveReceive_ReceiveStatus=MasterToSlaveReceive_ReceiveStatus_Complete;
      ...
      }
   ...
   }
   
}
void HandShakeAllSlaveScan(void)
{
unsigned int VVre,VVcrc;
  switch(HandShakeAllSlaveScanStatus){
     case HandShakeAllSlaveScanStatus_Star:
     ...  //主机发起发送
    break;
    case HandShakeAllSlaveScanStatus_WaitReceive:
       //等待从机回应,从机回应则计算校验是否正确
       ...
      VVcrc=CRC16(MasterToSlaveReceiveBuff,MasterToSlaveReceive_VirtualLength+2,0xffff);
      VVre=(MasterToSlaveReceiveBuff[MasterToSlaveReceive_VirtualLength+2]<<8)+MasterToSlaveReceiveBuff[MasterToSlaveReceive_VirtualLength+3];
      if(VVcrc==VVre) {
                 //校验正确
            ...
        }else{
                 //校验错误
            ...
        }
      
    break;
    ...
  }
}
void NVIC_Configuration(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;
        /* Configure the NVIC Preemption Priority Bits */  
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//抢占优先级0~1,响应优先级0~7

        /* Enable the UART5 Interrupt */
        NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;         
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);       


        /* Enable the USART4 Interrupt */
        NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;       
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;//响应优先级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);       

        /* Enable the USART3 Interrupt */
        NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;         
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;//抢占优先级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 6;//响应优先级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
       
        /* Enable the USART2 Interrupt */
        NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;         
       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
       
       
        /* Enable the USART1 Interrupt */
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;         
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);       
       
        /* Enable the TIM2 Interrupt */
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;                            
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}
int main(void)
{
...
NVIC_Configuration();
...

while (1)
{
   ...
    if(HandShakeAllSlaveScanStatus!=HandShakeAllSlaveScanStatus_Free){
              HandShakeAllSlaveScan();
              }
   ...
    if(SysTick_SecondFlag)//1秒间隔
   {
   ...
        //发起一次对所有子机的询问
        if(HandShakeAllSlaveScanStatus==HandShakeAllSlaveScanStatus_Free){
                                          MasterToSlave_CurrentComSlaveID=1;
                                          HandShakeAllSlaveScanStatus=HandShakeAllSlaveScanStatus_Star;
                                          MasterToSlave_ComCounter=0;
                                }
   ...
   }

}

}

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2018-10-23 16:11:21 | 显示全部楼层
看看是不是传进去的NUM太大,数组越界导致。

出0入42汤圆

发表于 2018-10-23 16:36:06 | 显示全部楼层
是不是CRC16多次重入。

出0入0汤圆

发表于 2018-10-23 16:43:34 | 显示全部楼层
发个相对完整的工程看看

出0入0汤圆

发表于 2018-10-23 16:51:27 | 显示全部楼层
num 过大, 或者 传入 addr 有问题

出0入0汤圆

 楼主| 发表于 2018-10-24 08:59:40 | 显示全部楼层
zhuozz 发表于 2018-10-23 16:11
看看是不是传进去的NUM太大,数组越界导致。

NUM不超过400,应该不是这个原因

出0入0汤圆

 楼主| 发表于 2018-10-24 09:00:55 | 显示全部楼层
cocom 发表于 2018-10-23 16:36
是不是CRC16多次重入。

CRC16仅在主循环中调用函数的时候调用到,应该不会重入

出0入4汤圆

发表于 2018-10-24 09:28:40 | 显示全部楼层
keil 里面出现HardFault 可以看callback那边,上次执行的函数什么的

出0入0汤圆

 楼主| 发表于 2018-10-24 09:30:43 | 显示全部楼层
prince2010 发表于 2018-10-23 16:43
发个相对完整的工程看看

感谢关注,主楼我重新编辑,增加了主要相关部分

出0入0汤圆

 楼主| 发表于 2018-10-24 09:31:09 | 显示全部楼层
qiufengshijian 发表于 2018-10-24 09:28
keil 里面出现HardFault 可以看callback那边,上次执行的函数什么的

上一次执行的就是CRC16这个函数

出0入0汤圆

发表于 2018-11-2 15:49:11 | 显示全部楼层
qaya 发表于 2018-10-24 08:59
NUM不超过400,应该不是这个原因

可以在调用CRC16前对num做一次最大值判断,保护一下试试。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 03:07

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表