Tool/software:
Hello,
I have inherited a legacy TMS320F28035 project I'm trying to debug. There is some kind of problem in Canbus functionality. The application is a custom design OS-style program, with prioritized tasks. One task is the Canbus message handler. When Canbus interrupt is received, it sets a flag and requests scheduling the Canbus message handler.
Lets say, we have normally this message cycle (happening during only a couple of milliseconds):
MSG_ROUND_TO_ME XX YY
MSG_STATE AA BB CC DD EE FF GG HH
MSG_MEAS II JJ KK LL MM NN OO PP
MSG_ROUND_TO_NEXT XX YY
So, upon receiving MSG_ROUND_TO_ME , the unit sends its state information and measurements via Canbus and finally sends the MSG_ROUND token to next unit.
All good. But sometimes, there is a spurious message to the mix like in the following (can be valid, invalid, or out-of-turn). Observe:
MSG_ROUND_TO_ME XX YY
??? QQ RR SS TT
MSG_STATE AA BB CC DD EE FF GG HH
MSG_STATE AA BB KK LL MM NN OO PP
MSG_ROUND_TO_NEXT XX YY
So, what happens is that
- MSG_STATE is send succesfully as earlier
- Next message (should be MSG_MEAS) contains actually MSG_STATE bytes AA BB as first 2 bytes, but then contains the proper MSG_MEAS data bytes KK LL MM NN OO PP
So in other words, when trying to send MSG_MEAS, we get remnant bytes from the message we previously send.
What might be going wrong here?
The interrupt handler:
interrupt void isrCAN0(void)
{
u8TaskStatus |= CAN_TASK;
bCanInt=TRUE;
vOS_Scheduler();
return;
}
Here is part of the Canbus handler task:
if(!bCanInt)
{
vOS_Wait(Timeout);
}
if(bCanInt)
{
bCanInt = FALSE;
while(ECanaRegs.CANRMP.all != 0)
{
// another frame received
vProcessMBOX(ECanaRegs.CANGIF0.bit.MIV0));
}
PieCtrlRegs.PIEACK.bit.ACK9 = 1;
}
Paraphrased vProcessMBOX(X):
void vProcessMBOX(X)
{
vSendCan(MSG_STATE);
vOS_Wait(1 TICK);
vSendCan(MSG_MEAS);
vOS_Wait(1 TICK);
vSendCan(MSG_ROUND_TO_NEXT);
vOS_Wait(1 TICK);
// Clear message flag of the corresponding MBOX, X=6,7 or 8
ECanaRegs.CANRMP.bit.RMPX = 1;
}
Paraphrased vSendCan(MSG):
void vSendCan(MSG):
{
bool bRet = FALSE;
ECanaShadow.CANTA.all = ECanaRegs.CANTA.all;
ECanaShadow.CANTA.bit.TA0 = TRUE;// transmission acknowledge
ECanaRegs.CANTA.all = ECanaShadow.CANTA.all;
ECanaShadow.CANME.all = ECanaRegs.CANME.all;
ECanaShadow.CANME.bit.ME0 = FALSE;
ECanaRegs.CANME.all = ECanaShadow.CANME.all;
// disable mailbox
ECanaShadow.CANME.all = ECanaRegs.CANME.all;
ECanaShadow.CANME.bit.ME0 = FALSE;
ECanaRegs.CANME.all = ECanaShadow.CANME.all;
ECanaMboxes.MBOX0.MSGID.bit.STDMSGID = MSG->Id;// id
// enable mailbox
ECanaShadow.CANME.all = ECanaRegs.CANME.all;
ECanaShadow.CANME.bit.ME0 = TRUE;
ECanaRegs.CANME.all = ECanaShadow.CANME.all;
ECanaMboxes.MBOX0.MDL.byte.BYTE0 = MSG->Data.Byte.Byte0;// data bytes
ECanaMboxes.MBOX0.MDL.byte.BYTE1 = MSG->Data.Byte.Byte1;
ECanaMboxes.MBOX0.MDL.byte.BYTE2 = MSG->Data.Byte.Byte2;
ECanaMboxes.MBOX0.MDL.byte.BYTE3 = MSG->Data.Byte.Byte3;
ECanaMboxes.MBOX0.MDH.byte.BYTE4 = MSG->Data.Byte.Byte4;
ECanaMboxes.MBOX0.MDH.byte.BYTE5 = MSG->Data.Byte.Byte5;
ECanaMboxes.MBOX0.MDH.byte.BYTE6 = MSG->Data.Byte.Byte6;
ECanaMboxes.MBOX0.MDH.byte.BYTE7 = MSG->Data.Byte.Byte7;
ECanaMboxes.MBOX0.MSGCTRL.bit.DLC = msg->Length;// length
ECanaShadow.CANTRS.all = ECanaRegs.CANTRS.all;
ECanaShadow.CANTRS.bit.TRS0 = TRUE; // send message
ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all;
vRefreshWatchdog();
vOS_Delay(2000);
if (!ECanaRegs.CANTA.bit.TA0 && ECanaRegs.CANTRS.bit.TRS0)
{
// transmit failed
bRet = TRUE;
}
return bRet;
}
I see some things are sub-optimal and different from example codes, but are there obvious critical flaws which would make the message sending copy bytes from ealier sent message?