STM32的CAN收发数据死在硬件错误中断

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_24880087/article/details/90081617

STM32的CAN收发数据死在硬件错误中断

使用uCosIII的消息队列,当CAN接收到数据,使用消息队列给CAN数据处理任务发送一个消息
CAN数据处理任务使用请求消息函数收到一个消息,进行下一步操作。
程序编译无错误。
运行程序时,上位机每隔一秒通过CAN分析仪向STM32发送数据,程序死在硬中断

void HardFault_Handler(void)
{
    /* Go to infinite loop when Hard Fault exception occurs */
    while (1)
    {
    }
}

在 while(1) 打断点,重新运行后程序停在断点处
在这里插入图片描述

打开Call Stack+Locals, 点击HardFault_Handler 右键选择第一个Show Caller Code
程序跳转到中断之前的程序处

*p_err                   = OS_ERR_INT_Q_FULL;

说明 p_err 有问题
打开Call Stack+Locals查看 p_err的值是0xAAAA…

看看p_err的地址去memory查一下,不是RAM运行的空间。。。

打开Call Stack+Locals 向下追踪点击USB_LP_CAN1_RX0_IRQHandler()函数程序右键Show Caller Code
查看传递的p_err参数是不是进行非法操作

#if CAN_RX0_INT_ENABLE	//使能RX0中断
/****************************************************
函数名:CAN_RX_IRQHandler()
形参:
返回值:
函数功能://中断服务函数
****************************************************/
void CAN_RX_IRQHandler(void)
{
    OSIntEnter();   //中断嵌套
    OS_ERR err;
    static CanRxMsg RxMessage;
    CAN_Receive(CANx,CAN_FIFO0,&RxMessage);
    //只接收数据帧
    if(((RxMessage.StdId == 0x02)||(RxMessage.StdId == 0x0FF)) && (RxMessage.DLC == 0x08))   //软件再次筛选  ID为0x020 、0x0FF 并且数据位为8位
    {
        memcpy(CAN_Receive_Queue.data_buff,&RxMessage.Data,8);  //将消息邮件内容取出
        //判断上位机是否回应连接
        if((CAN_Receive_Queue.data_buff[0] == 0x02)&&(CAN_Receive_Queue.data_buff[1] == 0xFC))  //收到回应
        {
            LinkState = 1; //设置连接标志  TIM4不再向上位机发送
        }

        //发送消息队列到任务
        if(LinkState == 1) //连接成功  才会发送指令 否则 不会发送
        {
            OSQPost((OS_Q *)&CanServer_DATA_Q,
                    (void *)CAN_Receive_Queue.data_buff,
                    (OS_MSG_SIZE )sizeof(CAN_Receive_Queue.data_buff),
                    (OS_OPT )OS_OPT_POST_FIFO,/*OS_OPT_POST_NO_SCHED*/
                    (OS_ERR *)&err);//取地址啊啊啊啊啊啊啊啊啊 啊啊啊啊啊!!!!!
        }
    }
    CAN_FIFORelease(CANx,CAN_FIFO0);    //释放消息
    OSIntExit();
}
#endif

查看程序发现 (OS_ERR *)&err); 这一行没有添加&取地址符号。。
晒得代码里加了已经免得别人看见犯同样错误。。

因为数据类型支持强制转换,所以编译器信任可以这样编写,而往往这些强制转换处理稍不注意就可能出现异常的情况。

猜你喜欢

转载自blog.csdn.net/sinat_24880087/article/details/90081617