标题:
关于指针的使用
[打印本页]
作者:
jinandawei
时间:
2011-6-16 09:37
标题:
关于指针的使用
我们的项目使用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就完全跑飞了,从而造成不可预知的各种灾难性的后果。
总结:指针啊指针,逻辑啊逻辑,要谨慎!
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0