So the standard method for preventing CAN message overwrite with the TMS320F28335 is the set the CANOPC (overwrite protection) bit for that given mailbox. The problem with this option is that if there is no other mailbox configured to receive the incoming message the message is lost in the great bit bucket. How can one go about protecting from overwrite while preventing messages from being lost.
The desired solution would be to prevent CAN bus acknowledgment until I have processed the message and cleared the RMP flag.
void CANInterruptHandler(void)
{
extern RingBuffer CANInputQueue;
extern const Semaphore_Handle CANTransferCompleteSem;
extern const Semaphore_Handle CANDataReadySem;
uint16_t count;
char data[8];
int x;
uint32_t mb = ECanbRegs.CANGIF0.bit.MIV0;
switch(mb)
{
case 0: // receive
// ideal option would be to put some kind of lock on the can bus here
data[0] = ECanbMboxes.MBOX0.MDL.byte.BYTE0;
data[1] = ECanbMboxes.MBOX0.MDL.byte.BYTE1;
data[2] = ECanbMboxes.MBOX0.MDL.byte.BYTE2;
data[3] = ECanbMboxes.MBOX0.MDL.byte.BYTE3;
data[4] = ECanbMboxes.MBOX0.MDH.byte.BYTE4;
data[5] = ECanbMboxes.MBOX0.MDH.byte.BYTE5;
data[6] = ECanbMboxes.MBOX0.MDH.byte.BYTE6;
data[7] = ECanbMboxes.MBOX0.MDH.byte.BYTE7;
if(ECanbRegs.CANRML.all != 0)
{
canOverflows++;
}
// and release it here.
count = ECanbMboxes.MBOX0.MSGCTRL.bit.DLC;
ECanbRegs.CANRMP.all = ~0; // register
for(x = 0; x < count; ++x)
{
RingBuffer_put(CANInputQueue, &data[x]);
}
break;
case 1: // send
Semaphore_post(CANTransferCompleteSem);
ECanbRegs.CANTA.all = ~0;
break;
default:
break;
}
canWatchDogReset();
}