赞
踩
使用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); 这一行没有添加&取地址符号。。
晒得代码里加了已经免得别人看见犯同样错误。。
因为数据类型支持强制转换,所以编译器信任可以这样编写,而往往这些强制转换处理稍不注意就可能出现异常的情况。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。