CAN Blocking/Non-blocking modes and code generation from MBDT in Simulink

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

CAN Blocking/Non-blocking modes and code generation from MBDT in Simulink

1,302 Views
JQiggle
Contributor II

Dear community,

first I want to share a remark about the blocking mode of CAN on the MPC5744P devkit. I was wondering what is actually the difference between the blocking and non-blocking mode. It was an extreme pain to get to know that but an examination of generated code revealed that the generated function for blocking mode contains a default, hardcoded 50ms interval for which the function is waiting for a message. That means each CAN Rx/Tx function in blocking mode is waiting for 50ms no matter the message comes or not. The point - it is not suitable for any serious CAN application.

Now comes my question. When I hook up my program in a non-blocking manner, an error pops up during code generation:

"Error: Obsolete TLC function LibExecuteFcnCall. This function generates incorrect code when subsystem <<xxx>> is one of the subsystems called by a branched function call. Please update the TLC file of the S-function that calls this block, use LibBlockExecuteFcnCall instead."

Please, would anyone be able to provide such an updated TLC file? System target file: mbd_mpc574x.tlc.

Put the other way around, I simply want to receive multiple can messages and parse them based on their id in non-blocking mode and extract their data. Any tips on that?

Many thanks in advance for your feedback.

Regards

JQiggle

0 Kudos
4 Replies

1,249 Views
paulvlase
NXP Employee
NXP Employee

Hi @JQiggle ,

We are sorry for not explaining clearly the difference between Blocking and Non-blocking modes in our help. We'll update that part in the next release.

As you found out already, the blocking CAN Rx and Tx operations will wait for the specified timeout duration to receive or send a CAN message. But the timeout value is not hardcoded, it is configurable from the CAN Receive or Send block. In the case of non-blocking mode, it will not wait for the operation to complete. Instead, an Rx or Tx interrupt is triggered on the completion, which is handled through the CAN ISR block.

In the case of Rx the blocking mode maybe is not so useful, but for Tx it can help you reuse the same message buffer and simplify your model because you don't need to add any extra blocks.

 

Can you try to apply the following patch:

1. Download and unzip the attached fcan_mpc_isr.zip archive.

2. Run in Matlab winopen(fullfile(mbd_find_mpc_root, 'mbdtbx_mpc', 'blocks', 'fcan'))

3. Copy fcan_mpc_isr.tlc file in the newly opened explorer win.

4. Build your model.

 

There are multiple approaches for what you want to accomplish:

1. If the number of used IDs does not exceed the maximum number of message buffers, you can call CAN Receive for each message ID, each call using a different message buffer (MB).

2. If you want to reuse message buffers, you will need to specify an ID mask that accepts multiple IDs.

The IDs and ID masks are used to filter incoming IDs. There is bit-to-bit correspondence between received ID, mask, and programmed MB ID (the one configured in the CAN Receive or Send block). The mask says if the corresponding incoming ID bit is compared with the programmed ID bit.

If the mask bit is cleared or 0 the incoming ID bit is not compared, it is don’t care. If the mask bit is set or 1, then there must be an exact match between the incoming ID bit and the programmed ID bit. To receive a message into a MB/RXFIFO all relevant bits with mask bit set must be equal to programmed one.

For example:

1. You have ID 0x3FE, ID mask 0xFFFFFFFF, message buffer (MB) 1.

Because the ID mask has all bits set to 1, which means that all bits from ID will be compared and there should be an exact match between the programmed ID, 0x3FE, and the incoming ID,  in MB 1 will be received messages with ID 0x3FE only.

2. You want to receive the following IDs, 0x3FE and 0x3FF in message buffer (MB) 2.

0x3FE is in binary 0b1111111110

0x3FF is in binary 0b1111111111

Looking at the binary representation only the 1st bit changes, which means that the 1st bit of the ID mask should be 0 or don't care to allow 0 or 1 as values. All the other bits will be set to 1. So the ID mask will be 0b11111111111111111111111111111110 or 0xFFFFFFFE.

 

The CAN ISR block returns the ID and Data of the received message. Inside the subsystem that is triggered by the CAN ISR block, you can use a SwitchCase block that will take the ID as input to execute different Switch Case Action subsystem based on the received ID. An example of this implementation can be found in flexcan_echo_mpc574x.mdl example from our toolbox.

Regards,

Paul

0 Kudos

1,175 Views
JQiggle
Contributor II

Dear @paulvlase,

thank you for your post. The replacement of the fcan_mpc_isr.tlc file helped, the error ceased to exist. Thank you!

Concerning the message reception, I want to use a unique message buffer for each message. Thus, hopefully, I don't have to care about the masks. You advised me to use a switch case block. However, that way I would only receive one message each program cycle, right? I want my program to run at 100 Hz and each cycle I want to receive all messages that came. Is the only solution to use a CAN ISR block for every single message?

Thanks for your answer in advance. Wish you a nice day.

Regards

JQiggle

 

0 Kudos

1,276 Views
mariuslucianand
NXP Employee
NXP Employee

Hello @JQiggle,

Thank you very much for your post. I've opened an internal ticket and we will handle your request as soon as possible. 

Can you please tell me which MATLAB version are you using?

Keep you updated,

Marius

0 Kudos

1,264 Views
JQiggle
Contributor II

Dear @mariuslucianand,

thanks for reaching me back and for the ticket opening.

I use MATLAB 2020a.

Regards

JQiggle

0 Kudos