cancel
Showing results for 
Search instead for 
Did you mean: 

Receiving Can Messages. 70% of network traffic missing

Just Matt
Associate III
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
11 REPLIES 11
muhammaduzairafzal45
Associate III
Posted on January 29, 2014 at 07:17

Use CAN interrupt to capture packets. Polling is not a sufficient method if you do not want to miss data.

jpeacock2399
Associate II
Posted on January 29, 2014 at 15:59

How are your receive filters set up?  Are all messages directed to FIFO0?  You might try splitting message traffic between FIFO0 and FIFO1 when you set up the receive filters.

Are those 145 messages in a burst or do you have inhibit times to spread out the arrival? You may be flooding FIFO0, check for FIFO overflows.  Either you have to wait in the polling loop and do nothing else or switch to interrupt driven CAN.

  Jack Peacock
Just Matt
Associate III
Posted on January 29, 2014 at 18:17

Jack and Afzal,

Thanks for your replies! I should have noted in my last post i'm new the STM platform (Hobbyist) The traffic originates from one node, on a single ArbId. I have a single filter setup directing everything to FIFO0. I'm not sure what you mean by splitting the traffic. Do you have an example or a reference I could look at? The 145 messages are sent in a burst (I cannot control the speed at which they are sent) I have switched to a interrupt driven setup. However, I'm still loosing messages :\ It may be in the way i'm storing the messages. I tried std::vector first then switched to plain ole array. Looking at the data, it seems that the first two messages are correct, then it skips like 30 of them. (See new code below)

extern 
''C''
void CAN
1
_RX
0
_IRQHandler(void)
{
CanRxMsg rxMessage;
CAN_Receive(CAN
1
, CAN_FIFO
0
, &rxMessage);
CanDriver::StuffCanMsg(rxMessage);
CAN_ClearITPendingBit(CAN
1
, CAN_IT_TME);
}
//std::vector<CanRxMsg> RxMessageArray;
CanRxMsg RxMessageArray [
145
];
int ArrayCounter = 
0
;
void CanDriver::StuffCanMsg(CanRxMsg RxMessage)
{ 
RxMessageArray[ArrayCounter++] = RxMessage;
if (ArrayCounter == 
50
) // So I can inspect what's in the array
{
DeconstructHandler(); // This just disables the handler. 
asm(
''nop''
);
}
}

Posted on January 29, 2014 at 19:52

I'm really not sure than spinning in a hard polling loop is any less effective than interrupts.

Splitting the traffic, I assume, means making it less bursty and increasing the inter-packet delays.

Thoughts, perhaps you can assign multiple FIFO mailboxes to the same filtering criterion, and thus handle back-to-back transfers. Figure you'd want at least TWO, to allow you the process the one in hand, and the one hot behind it on the wire.

Is there a DMA option for CAN that would allow you evacuate the FIFO sufficiently quickly so it wouldn't overflow?
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Just Matt
Associate III
Posted on January 30, 2014 at 02:26

Hi clive1, 

Thanks for the reply.

I cannot find any examples for DMA related to CAN. Nor can I find what channel or stream for the CAN DMA request mapping. (Pages 304 and 305 of the Reference Manual). Am I overlooking?

I'll give the multiple FIFO thing a try. (I'm not quiet sure how to implement it though)

Thanks!

-Matt
Just Matt
Associate III
Posted on February 03, 2014 at 17:27

I still can't figure out this issue.

Does anyone else have any other debugging ideas? I have attached a logic analyzer to PD0 and PD1 of my MCU, I can verify that all the messages are at least making it that far.

If it helps, I'm offering a $100 bounty to whomever figures this out.

Cheers,

-Matt
frankmeyer9
Associate II
Posted on February 03, 2014 at 17:33

Does anyone else have any other debugging ideas? 

 

How about reducing your CAN network bitrate to a minimum,  and check how much of the traffic you still miss ?

If the picture changes, you seem to have a performance problem.

Just Matt
Associate III
Posted on February 03, 2014 at 17:39

Unfortunately I cannot slow down the speed of the 3rd party module. 

I can probably build another module to send traffic. I'll give that a go and see.

-Matt

frankmeyer9
Associate II
Posted on February 04, 2014 at 09:10

Judging by some code you posted earlier, I suspect your concept, as implemented, is not workable. As I understood it, you disable the handler while parsing one message.

DeconstructHandler(); // This just disables the handler. 

I think you can't handle this CAN message in such a rigid synchronous manner. You lose CAN messages while you parse former messages.

My suggestion: add some GPIO toggle code to your CAN handler and parser, then take a scope to visualize you CAN traffic against the time spent in your handler code and parsing code.