Skip to main content
Just Matt
Associate III
January 28, 2014
Question

Receiving Can Messages. 70% of network traffic missing

  • January 28, 2014
  • 11 replies
  • 2654 views
Posted on January 28, 2014 at 20:18

Hi,

I'm using a STM32F407VGT mcu. Also with the latest DSP lib pack from ST. The network has 2 nodes, and I'm attempting to capture the traffic between the nodes. 500kbps 75% SP. 30% bus load. One node queries the other for some data, the responding node sends 145 CAN Messages over the network. (I am using a 3rd party tool to capture the traffic) My following code only picks up 31 of those messages, and its sporadic. It does always catch the first Message correctly. (Then it endlessly loops) Here is my code, I call this code right after a query is made to a node. Is this the right way to approach this situation? All feedback welcome :)

CanRxMsg rxMessage;
CanRxMsg rxMessageArray[144];
int
loopCount = 0;
int
receiveCount = 144;
while
(loopCount < receiveCount)
{
if
(CAN_MessagePending(CANx, CAN_FIFO0) > 0)
{ 
//Receive the Message
CAN_Receive(CANx, CAN_FIFO0, &rxMessage);
rxMessageArray[loopCount] = rxMessage;
loopCount++;
}
}

#can #can
This topic has been closed for replies.

11 replies

jpeacock2399
Associate III
February 5, 2014
Posted on February 05, 2014 at 16:19

Check the CAN_RFxR registers, FOVR flag to determine if your FIFO is being overrun.  If it's set that explains why you are losing messages.  Messages are arriving faster than they can be processed.

In my CANopen application the CAN RX interrupts drain the incoming message FIFOs into one in-memory queue that's large enough to handle a burst of TPDO messages from several nodes after a SYNC (somewhat similar to what you are doing).  A completion task is unblocked as soon as messages are posted to the queue.  The completion task extracts each message in time sequence from the queue and processes the data. 

This separates data collection from processing time.  All the messages in a burst are captured in a FIFO type buffer and can be processed at leisure during the time between data collection points when the CAN bus is mostly idle.

I also use filters to direct incoming messages into both RX FIFOs.  This doubles the hardware buffering and reduces interrupt overhead on the controller.  During an RX interrupt I collect up to three messages from the hardware FIFO at one time instead of an interrupt per message...one third the overhead.

An added benefit from split RX FIFOs is that higher priority messages (such as the CANopen SYNC or NMT-EC heartbeat) can be directed to one FIFO, which in turn inserts the messages at thehead of the message queue so they are processed at high priority.  This is especially important if you're messages contain safety related data (such as CANopen SRDO or GFC messages) that must be processed as soon as possible.

I do the same thing for outgoing messages.  The TX interrupt drains a queue of pending messages so that the application can post large numbers of messages (such as the TPDO burst after a SYNC) without any delays waiting for an empty TX mailbox.

DMA isn't really useful with CAN messages because data is often processed out of sequence, that's why the dual RX FIFO structure is used instead of a DMA channel.

   Jack Peacock