When reading the CANRML register in the receive interrupt, the receive information is often lost.
What is the reason?
--
Thanks & Regards
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
When reading the CANRML register in the receive interrupt, the receive information is often lost.
What is the reason?
--
Thanks & Regards
Sorry, I don’t understand your question. Are you asking why messages are frequently lost? If so, you need to either read the received messages faster or open up more mailboxes with the same MSGID (and set the OPC bit, so that messages are not overwritten before being read). If you are saying you don’t see any bits set in the CANRML register when you read that register in the ISR, it could be that you are not using 32-bit reads.
Yes, when I read CANRML register, it find the messages are frequently lost, finally the CAN received ISR will be lost after long time running. Now in the end of interrupt function, I add code as ECanaRegs.CANRMP.all = 0xFFFFFFFF, there are few lost messages.
The following is my code in the received ISR:
void canRx_ISR(void)
{
uint8_t len;
uint8_t mailbox;
uint32_t bitMask;
CANFRAME canBuff;
struct ECAN_REGS ECanaShadow;
ECanaShadow.CANGIF1.all = ECanaRegs.CANGIF1.all;
mailbox = ECanaShadow.CANGIF1.bit.MIV1;
if(ECanaShadow.CANGIF1.bit.GMIF1 == 1)
{
bitMask = ((uint32_t)1 << mailbox);
ECanaShadow.CANRMP.all = ECanaRegs.CANRMP.all;
// CAN receive ISR
if(ECanaShadow.CANRMP.all & bitMask)
{
ECanaRegs.CANRMP.all = bitMask;
if(mailbox == CAN_MBRX_MONITOR)
{
postCanToMonitor(mailbox);
}
else if(mailbox == CAN_MBRX_RXP)
{
len = pCANRxReceiveHAL(&canBuff, mailbox);
postCanToRxp(RXP_OVER_CAN, &(canBuff.CanData[0]), len);
}
else if((mailbox >= CAN_MBRX_PARA_BEGIN) && (mailbox <= CAN_MBRX_PARA_END))
{
postCanToParallel(mailbox);
}
else
{
// TBD
}
ECanaShadow.CANRML.all = ECanaRegs.CANRML.all;
if( ECanaShadow.CANRML.all & ((uint32_t)1 << mailbox))
{
#if CAN_PROTOCOL_DIAGNOSE_ENABLED ==1
canOverWriteCount++;
#endif
}
#if CAN_PROTOCOL_DIAGNOSE_ENABLED ==1
canReceiveCount++;
#endif
}
}
ECanaRegs.CANRMP.all = 0xFFFFFFFF;
// Enable future CAN (PIE Group 1) interrupts
PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
}
Alan,
If you are losing messages, it means you are not reading messages fast enough. It is likely that your application is “busy” doing “other” things and is not servicing the CAN receive interrupts fast enough, leading to messages being overwritten thereby setting the RML bit. There are a few ways to handle this:
Thanks Hareesh for your guide!
Now I open more mailboxs with 20 to 30 for CAN receiving, and set OPC bit for mailbox 21 to 30, while mailbox 20 keep OPC with zero, is it right application?
The new code are as following, could you please help to check whether it's right?
Thanks!
void canRx_ISR(void) { uint8_t len; uint8_t mailbox; uint32_t bitMask; CANFRAME canBuff; struct ECAN_REGS ECanaShadow; ECanaShadow.CANGIF1.all = ECanaRegs.CANGIF1.all; mailbox = ECanaShadow.CANGIF1.bit.MIV1; bitMask = ((uint32_t)1 << mailbox); if(ECanaShadow.CANGIF1.bit.GMIF1 == 1) { // CAN receive ISR if(ECanaRegs.CANRMP.all & bitMask) { if( ECanaRegs.CANRML.all & bitMask) { #if CAN_PROTOCOL_DIAGNOSE_ENABLED ==1 canOverWriteCount++; #endif } ECanaRegs.CANRMP.all = bitMask; if(mailbox == CAN_MBRX_MONITOR) { postCanToMonitor(mailbox); } else if(mailbox == CAN_MBRX_RXP) { len = pCANRxReceiveHAL(&canBuff, mailbox); postCanToRxp(RXP_OVER_CAN, &(canBuff.CanData[0]), len); } else if((mailbox >= CAN_MBRX_PARA_BEGIN) && (mailbox <= CAN_MBRX_PARA_END)) { postCanToParallel(mailbox); } else { // TBD } if( ECanaRegs.CANRMP.all & bitMask) { #if CAN_PROTOCOL_DIAGNOSE_ENABLED ==1 canOverWriteCount++; #endif } #if CAN_PROTOCOL_DIAGNOSE_ENABLED ==1 canReceiveCount++; #endif } } ECanaRegs.CANRMP.all = bitMask; // Enable future CAN (PIE Group 1) interrupts PieCtrlRegs.PIEACK.all = PIEACK_GROUP9; }
Per TRM:
When a message is received, the message controller starts looking for a matching identifier at the mailbox with the highest mailbox number. Mailbox 31 has the highest receive priority. RMP[n] (RMP.31-0) has to be reset by the CPU after reading the data. If a second message has been received for this mailbox and the receive-message-pending bit is already set, the corresponding message-lost bit (RML[n] (RML.31-0)) is set. In this case, the stored message is overwritten with the new data if the overwrite-protection bit OPC[n] (OPC.31-0) is cleared; otherwise, the next mailboxes are checked.
In your case, the received messages will be stored starting in Mailbox30. Since you are setting the OPC for all mailboxes (except 20), those mailboxes will not be overwritten. Since OPC=0 for MBX20, that MBX can possibly overwritten. As long as your application services receive interrupts promptly, this should not happen. Debugging your code (or code review) is not something we can support on e2e.