Tool/software:
Hello everyone,
I'm currently working with the CAN module of the TM4C microcontroller, and I've encountered a strange issue during communication between multiple devices.
There are 16 devices on the CAN bus. Each device monitors CAN messages from other devices and determines which devices are online based on the IDs of the received messages. For example, if devices 1, 2, 3, and 4 are online, each device counts the number of active nodes by checking which device IDs it receives messages from.
Here's the problem:
If I disconnect device 3 while keeping devices 1, 2, and 4 connected, device 1 continues to believe that device 3 is still online, even for an extended period. To rule out the possibility that device 1 might be mistakenly interpreting messages from device 2 or 4 as coming from device 3, I also disconnected devices 2 and 4, leaving only device 1 connected.
Surprisingly, even when only device 1 is on the CAN bus, it still keeps receiving messages with the CAN ID of device 3.
There is no physical CAN message from device 3 on the bus (confirmed with a CAN analyzer/sniffer), yet the interrupt handler in device 1 continues to receive a message with message_ID corresponding to device 3.
I suspect that this might be due to the CAN FIFO or message object buffer not being cleared correctly, and old/stale messages are still being triggered in the interrupt handler.
Below is the CAN initialization configuration I'm using:
CAN Init Code CANInit(CAN0_BASE); // Initialize the CAN controller CANBitRateSet(CAN0_BASE, g_ui32SysClock, ui32BitRate); // Set up the bit rate for the CAN bus. CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); // Enable interrupts on the CAN peripheral. IntEnable(INT_CAN0); // Enable the CAN interrupt on the processor (NVIC). CANEnable(CAN0_BASE); // Enable the CAN for operation. //接收初始化 sCANMessage.ui32MsgID = 0; sCANMessage.ui32MsgIDMask = 0; sCANMessage.ui32Flags = (MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER|MSG_OBJ_FIFO); sCANMessage.ui32MsgLen = 8; // MsgBox1-20 is Rx, MsgBox21-30 is TX for(i=1;i<=(CANMaxRXObject-1);i++) { CANMessageSet(CAN0_BASE, i, &sCANMessage, MSG_OBJ_TYPE_RX); } sCANMessage.ui32Flags = (MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER); CANMessageSet(CAN0_BASE, CANMaxRXObject, &sCANMessage, MSG_OBJ_TYPE_RX);
Below is the CAN Interrupt code:
void CAN0IntHandler(void) { uint32_t status; uint8_t i = 0; uint8_t dataBuffer[8] = {0}; tCANMsgObject receivedMsg; // Get the interrupt status status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); // Handle controller status interrupt if (status == CAN_INT_INTID_STATUS) { status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL); } // Check if the interrupt is from a receive message object if (status <= MAX_RX_OBJECT) { for (i = 1; i <= MAX_RX_OBJECT; i++) { if (status == i) { CANIntClear(CAN0_BASE, i); g_rxFlag = 1; receivedMsg.pui8MsgData = dataBuffer; CANMessageGet(CAN0_BASE, i, &receivedMsg, true); ProcessCANMessage(receivedMsg); // User-defined message processing } } } else { // Clear interrupts for other message objects (e.g., transmit objects) for (i = 9; i <= 32; i++) { if (status == i) { CANIntClear(CAN0_BASE, i); } } } }
In my CAN initialization, I'm using FIFO mode by linking multiple message objects together using the MSG_OBJ_USE_FIFO
flag. For example, message objects 1 through 4 are set up as a receive FIFO chain.
In my interrupt handler, when I detect a message has been received, I call:CANMessageGet(CAN0_BASE, objID, &receivedMsg, true);
My question is: Is it incorrect to call CANMessageGet()
with bClrPendingInt = true
inside a receive FIFO interrupt?
From my observation, sometimes the FIFO seems to behave abnormally — such as the same message appearing to be received multiple times, or stale message IDs remaining in the buffer even when no new data is on the bus.
I suspect this may be caused by the way I’m using CANMessageGet()
with FIFO. Perhaps clearing the interrupt this way doesn't properly advance the FIFO pointer?
Has anyone experienced a similar issue, or do you have suggestions on how to ensure the CAN receive buffer or FIFO is properly cleared to avoid this kind of "ghost" message behavior?
Any help would be appreciated!
Thanks in advance!