Hi everyone,
I am using S32K344 board for a CAN related project for a while. Recently, When I was doing stress tests, I found out that S32K344 had issue to receive/process/send CAN messages. Please point out anything wrong with my Program.
1. Project goal and structure
The project is basically to receive a CAN message from a CAN channel and send the same CAN message to another or multiple CAN channels, it's a "CAN forwarding gateway". Here's my program blocks:
CAN Rx -> process block
Process block, inside it's some simple program to find out which CAN channel(s) should the CAN messages go to. After that, the program will call Simulink functions for sending.
Simulink functions for sending
Inside of Simulink sending function, each channel has its own send function to call.
The current issues:
1. I am not seeing right amount of CAN messages. In this case, CAN1->CAN1, CAN2->CAN2 etc.
Even at every low loading, a message per 5ms, I saw CAN 1 & 2 had less CAN data, while CAN 3 & 4 had more data.
2. The above issue happened to S32K344 especially when CAN messages are received from multiple CAN channels. I similar tests to CAN 1 only, it seems ok.
My questions:
1. Are there potential issues where there is only one receive block to handle 6 CAN channels? Is there a way to separate them into each channel?
2. Since all CAN messages go to receive block, there is bigger risk of CAN message collision, where two CAN messages received at the same time. How to avoid this?
3. Should a queue be added into process block? Any recommendations on what queue should I use?
4. Any improvement suggestions on sending side for my project?
Thank you in advance
Hello and thank for you interest in using MBDT,
Having your Simulink model attached to this post would allow us to better understand the issue but still, there are a few general things to consider when using the CAN communication in projects.
For the receiving part:
Make sure that you have multiple CanHardwareObjects configured in your configuration project. If available resources allow it, there could be one for each Can ID in the network, for better performance.
A CanHardwareObject can be configured to accept only certain Can IDs by setting the CanHwFilters in your configuration project (EB Tresos or S32 COnfiguration Tools)
For the sending part:
Quite often it happens that the same transmitting CanHardwareObject, with the same PDU ID (message buffer) is used for sending CAN messages multiple times in the same call of the step function, or in notifications that happen almost simultaneously.
For this scenario it is recommended apply one of these solutions:
1) Introduce different values for the Pdu ID input of the Can_Write blocks (e.g. 0, 1, 2) , as this will specify different CAN transmit message buffers for each place where the Can_Write block is used.
2) Use different CanHardwareObjects from the existing ones in the configuration project or create new ones as necessary. Then select different Hardware Object wherever the Can_Write block is used.
For more details and a comprehensive tutorial on MBDT using the CAN communication please check this article:
Communicating over the CAN Bus
Quick update, I have tried to assign PDU ID for each message.
For example, for CAN0, I use 0 to 19 in a loop to be assigned to each message that was sent out.
However, the results are the same. I did not see improvements on losing data.
@Adrian_Gherca Thank you for your reply. Here is my project.
I have simplified my project so all it does was like an echo. For each channel, I sent whatever I received.
0. Back to my issue
If you see screen shots from PCAN View from first post, number of sending is not equal to number of receiving.
For my project, especially, whenever I had CAN load above 10-20% for CAN channel 2 and 3 (channel index start with 0), I saw the sending side started sending less data than receive side.
1. Regarding the hardware filter
My application does not allow me to filter because the customer will pick the CAN ID to forward to different can channel(s). Sometimes, they can pick over 100 CAN IDs, I don't think is very efficient to add hardware filter.
2. Sending part
a. I will try PDU ID.
b. Adding another CanHardwareObjects is possible, but I can see my program became harder to manage. Once I add more objects, I will have multiple write function to call for the same channel.
Here is the project file with config.
Hello,
It looks that in the model you provided, blocks from another toolbox, Vehicle Network Toolbox, are used for the receiving part of the CAN communication. I am referring here to CAN Receive and CAN Configuration blocks from your model:
Not sure exactly how these work, NXP_MBDToolbox_S32K3xx also provides means for receiving CAN messages with you MRCANHUBK344 board (please check the s32k3xx_can_receive_s32ct example). Here are a few things to consider if you want a faster transfer of CAN messages:
1) With some exceptions, everything that is placed on the Simulink canvas is executed at the time intervals of the Step function, which in your case is 100 ms:
This might be a problem since the cycle time of the Transmit messages in the PCAN-View tool is 5 ms.
This remark's relevance depends on how the CAN Receive block from the Vehicle Network Toolbox works, which you have to figure out.
2) If you just want to send CAN messages faster, the Hardware Interrupt Callback set for the CanIf_TxConfirmation can be used. When A transmission finished notification callback is executed, another transmission can be immediately triggered.
Because Hardware Interrupt Callback is one of the exceptions from point 1), the transmission pace will not be the Step interval but the actual time it takes to send a message on CAN.
Here's how you could implement this:
3) If you want an even snappier response on CAN to various messages, the Hardware Interrupt Callback set for the CanIf_RxIndication can be used. Whenever a CAN message is received, the notification callback will be instantly executed (not waiting for the step timer).
Inside this callback, another transmission can be immediately triggered.
Please check the s32k344_can_echo_interrupt_ebt example from the NXP_MBDToolbox_S32K3xx toolbox for more details.
You can also combine points 1), 2) and 3) to achieve the goals of your application.
Hi @Adrian_Gherca ,
Thank you for your reply.
1. It's variant subsystem, I included it but did not use it for this project. I modified my project to avoid same kind of confusion.
2. We had similar thoughts, however, after we did more tests, we found that receive side is the root cause. Currently, we are more focused on how to fix receive side. I did some tests, and they showed that controllerID and hardwareID did not match for some receive messages.
CAN0 CAN1 seems to run ok alone.
whenever CAN2, CAN3, CAN4 or CAN5 joined in, the whole CAN system became unstable.
My colleague had similar results:
Inconsistent Controller ID and Hardware Object ID - NXP Community
3. We already used Rx interruption to trigger subsystem. It's related to the first point, my apologies to cause confusion.