- UID
- 846221
|
我们的项目使用CAN接口进行数据的传输,通过中断接收CAN消息。主函数中完成接收CAN消息后的处理。前两天在我们的项目中出现问题:
主函数不能正常运行,通过仿真器看到好像程序大多的时间都在CAN收中断中忙活。
于是乎,就开始找中断的问题,本来以为是中断函数中添加了太多的处理所致。下面是我的代码:-
- //滤除接受CAN消息中的杂波
- //入口参数:PCAN_MSG pcan_msg_dst CAN消息结构体数组的首地址,PCAN_MSG pcan_msg_src 接收到的CAN消息地址
- void FiltReceivdCanMsg(PCAN_MSG pcan_msg_dst,PCAN_MSG pcan_msg_src)
- {
- byte i=0;
- if((pcan_msg_dst[0].data[0]^pcan_msg_src->data[0])||(pcan_msg_dst[0].data[1]^pcan_msg_src->data[1])||
- (pcan_msg_dst[0].data[2]^pcan_msg_src->data[2])||(pcan_msg_dst[0].data[3]^pcan_msg_src->data[3])||
- (pcan_msg_dst[0].data[4]^pcan_msg_src->data[4])||(pcan_msg_dst[0].data[5]^pcan_msg_src->data[5])||
- (pcan_msg_dst[0].data[6]^pcan_msg_src->data[6])||(pcan_msg_dst[0].data[7]^pcan_msg_src->data[7])) //不相等
- {
- for(i=0;i<CAN_LENTH;i++)
- {
- pcan_msg_dst[0].data=pcan_msg_src->data;
- }
- }else
- {
- for(i=0;i<CAN_LENTH;i++)
- {
- pcan_msg_dst[1].data=pcan_msg_src->data;
- }
- }
- }
- //复制数据到相应的CAN消息缓存区
- void CopyDataToRAM(PCAN_MSG pcan_msg)
- {
- dword id;
- PCAN_MSG pcan_msg_dst;
- if (IS_BIT_SET(pcan_msg->id.b[1],4)&&IS_BIT_SET(pcan_msg->id.b[1],3)&&IS_BIT_CLR(pcan_msg->id.b[3],0))//ID满足扩展数据帧的条件
- {
- id=GetPureID(pcan_msg);
- if((id==BCM1_STATUS1_ID)||(id==BCM1_STATUS2_ID)||(id==BCM1_STATUS3_ID)||(id==BCM1_DIAG1_ID)||
- (id==BCM1_INFO1_ID)||(id==DashBoard_INFO_ID))
- {
- if(id==BCM1_STATUS1_ID)
- {
- CANMSG_BCM1_STATUS1[1].id.dw=id;
- pcan_msg_dst=CANMSG_BCM1_STATUS1;//复制驾驶室输入状态信息1的CAN消息
- }else if(id==BCM1_STATUS2_ID)
- {
- CANMSG_BCM1_STATUS2[1].id.dw=id;
- pcan_msg_dst=CANMSG_BCM1_STATUS2;//复制驾驶室输入状态信息2的CAN消息
- }else if(id==BCM1_STATUS3_ID)
- {
- CANMSG_BCM1_STATUS3[1].id.dw=id;
- pcan_msg_dst=CANMSG_BCM1_STATUS3;//复制驾驶室输入状态信息3的CAN消息
- }else if(id==BCM1_DIAG1_ID)
- {
- CANMSG_BCM1_DIAG1[1].id.dw=id;
- pcan_msg_dst=CANMSG_BCM1_DIAG1;//驾驶室诊断信息1
- }else if(id==BCM1_INFO1_ID)
- {
- CANMSG_BCM1_INFO1[1].id.dw=id;
- pcan_msg_dst=CANMSG_BCM1_INFO1;//驾驶室模块信息(输出信息)
- }else if(id==DashBoard_INFO_ID)
- {
- CANMSG_DashBoard_INFO[1].id.dw=id;
- pcan_msg_dst=CANMSG_DashBoard_INFO;//仪表模块信息(仪表模块状态信息)
- }
- FiltReceivdCanMsg(pcan_msg_dst,pcan_msg);
- }
- }
- }
- //中断函数
- void interrupt 28 MSCAN_RX(void)
- {
- unsigned char j;
- unsigned char arry[13];
-
- for(j = 0; j < 12; j++)
- {
- arry[j] = *(&CANRIDR0 + j);
- }
- arry[12] = (*(&CANRIDR0 + 12) & 0x0f);
-
- CopyDataToRAM((PCAN_MSG)arry);
- CANRFLG |= 0X01;
- }
复制代码 其实发现,中断并非太臃肿,原来还使用了库函数“memcpy,memcmp”,于是以为是不是库函数不合适在这里,可是去掉库函数还是不能解决问题。
最后发现一个很大的BUG,就是在函数CopyDataToRAM中,原来是这样的(未修改前):-
- //复制数据到相应的CAN消息缓存区
- void CopyDataToRAM(PCAN_MSG pcan_msg)
- {
- dword id;
- PCAN_MSG pcan_msg_dst;
- if (IS_BIT_SET(pcan_msg->id.b[1],4)&&IS_BIT_SET(pcan_msg->id.b[1],3)&&IS_BIT_CLR(pcan_msg->id.b[3],0))//ID满足扩展数据帧的条件
- {
- id=GetPureID(pcan_msg);
- if(id==BCM1_STATUS1_ID)
- {
- CANMSG_BCM1_STATUS1[1].id.dw=id;
- pcan_msg_dst=CANMSG_BCM1_STATUS1;//复制驾驶室输入状态信息1的CAN消息
- }else if(id==BCM1_STATUS2_ID)
- {
- CANMSG_BCM1_STATUS2[1].id.dw=id;
- pcan_msg_dst=CANMSG_BCM1_STATUS2;//复制驾驶室输入状态信息2的CAN消息
- }else if(id==BCM1_STATUS3_ID)
- {
- CANMSG_BCM1_STATUS3[1].id.dw=id;
- pcan_msg_dst=CANMSG_BCM1_STATUS3;//复制驾驶室输入状态信息3的CAN消息
- }else if(id==BCM1_DIAG1_ID)
- {
- CANMSG_BCM1_DIAG1[1].id.dw=id;
- pcan_msg_dst=CANMSG_BCM1_DIAG1;//驾驶室诊断信息1
- }else if(id==BCM1_INFO1_ID)
- {
- CANMSG_BCM1_INFO1[1].id.dw=id;
- pcan_msg_dst=CANMSG_BCM1_INFO1;//驾驶室模块信息(输出信息)
- }else if(id==DashBoard_INFO_ID)
- {
- CANMSG_DashBoard_INFO[1].id.dw=id;
- pcan_msg_dst=CANMSG_DashBoard_INFO;//仪表模块信息(仪表模块状态信息)
- }
- FiltReceivdCanMsg(pcan_msg_dst,pcan_msg);
- }
- }
复制代码 这样造成只要是ID满足扩展帧的条件,FiltReceivdCanMsg(pcan_msg_dst,pcan_msg);就会被执行。这样不仅造成额外的CPU占用(本来是想着如果ID不满足那几个特定ID的话就不做处理了),更重要的是如果ID不是特定的几个ID的话FiltReceivdCanMsg函数中的指针pcan_msg_dst,pcan_msg就完全跑飞了,从而造成不可预知的各种灾难性的后果。
总结:指针啊指针,逻辑啊逻辑,要谨慎! |
|