Change period of TX CAN message in flexcan_fd_master_s32K14x example

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

Change period of TX CAN message in flexcan_fd_master_s32K14x example

Jump to solution
1,041 Views
erik_ziel
Contributor II

Hello all,

I am using the S32K142 Demoboard with the Model Based Design Toolbox.

Everything works well, but try to change the period of the TX CAN message in the example flexcan_fd_master_s32K14x.

Model.PNG

The model sends the message every 100ms 

CANTraffic.PNG

Where can I change the time for example to 500ms? 

Thanks for a hint.

Erik

Labels (1)
0 Kudos
1 Solution
865 Views
constantinrazva
NXP Employee
NXP Employee

Hello erik.ziel@autoliv.com‌,

So for changing the period you have 3 approaches:

- changing the main loop period

- using a hardware timer

- using a software timer

Let me go into some details for all 3 of them:

[Changing the main loop period]

I'll start by explaining how the code is generated from our toolbox. Code generation is comprised of:

  • Initialization code (let's call it Init)
  • Loop code (let's call it Loop)

The generated code for the initialization is called only once, at the start, while the loop code is called continuously - not in a while(1) loop, but in a time-controlled manner (more on that in the next part).

Furthermore, depending on where they are placed, blocks can generate code in:

  • The main loop
  • Various interrupt service routines

Most, if not all of the configuration blocks (like, in your case, CAN Config block), generate code in the Init function. Other blocks - so called action blocks (like, in your case, CAN Send block) - generate code in the Loop function. Some blocks can generate code both in Init and Loop (like the profiler block). 

The code in the main loop is triggered by a low power timer, and the period of this timer is controlled by the discrete fixed step. You can change this from Model Configuration Parameters -> Solver -> Fixed step-size. 

pastedImage_2.png

So an easy way to change the period of the CAN messages is to change this value, as CAN Send block is in the main loop, thus it's calling frequency is dependent to this step size. If you change it to 0.5, you'll get a CAN message every 500ms.

To continue the explanation, ISRs (interrupt service routines), blocks like CAN Tx Complete ISR in your example, are used to trigger a subsystem outside the main loop. In this example, an interrupt is generated for every Send event, so you'll end up with the same calling frequency of the subsystem triggered by CAN Tx Complete ISR; but if it were an Rx ISR, that is totally non-dependent of the main loop period. The code generated from the blocks inside the subsystem triggered by that ISR would be called only when an Rx event would be issued.

[Using a hardware timer]

If you want dedicated timing (and not using the main loop step size), you can use a LPIT block. You can set it's period (in ms) and use this block to trigger a subsystem at that given period. This way you can schedule multiple tasks with different frequencies. But keep in mind that you have a limited number of (hardware) timers. You could use multiple timers and with a bit of extra software, you could achieve multiple timing values, but with this hardware-software timer combination. The limitation here would be that if you want more than the number of hardware channels available, with all the software changes you can make, you'll only be able to get to periods that are a linear combination of the individual periods given to each channel (e.g.: you have the following periods:

ch0 - 1s

ch1 - 100ms

ch2 - 25 ms

With these values you can get (i0*1s) + (i1*0.1s) + (i2*0.25) period, where i0, i1, i2 are unsigned integers.)

[Using a software timer]

gramirezv‌ wrote a good article for such an approach. You can read it here.

Hope this helps!

Razvan.

View solution in original post

0 Kudos
2 Replies
866 Views
constantinrazva
NXP Employee
NXP Employee

Hello erik.ziel@autoliv.com‌,

So for changing the period you have 3 approaches:

- changing the main loop period

- using a hardware timer

- using a software timer

Let me go into some details for all 3 of them:

[Changing the main loop period]

I'll start by explaining how the code is generated from our toolbox. Code generation is comprised of:

  • Initialization code (let's call it Init)
  • Loop code (let's call it Loop)

The generated code for the initialization is called only once, at the start, while the loop code is called continuously - not in a while(1) loop, but in a time-controlled manner (more on that in the next part).

Furthermore, depending on where they are placed, blocks can generate code in:

  • The main loop
  • Various interrupt service routines

Most, if not all of the configuration blocks (like, in your case, CAN Config block), generate code in the Init function. Other blocks - so called action blocks (like, in your case, CAN Send block) - generate code in the Loop function. Some blocks can generate code both in Init and Loop (like the profiler block). 

The code in the main loop is triggered by a low power timer, and the period of this timer is controlled by the discrete fixed step. You can change this from Model Configuration Parameters -> Solver -> Fixed step-size. 

pastedImage_2.png

So an easy way to change the period of the CAN messages is to change this value, as CAN Send block is in the main loop, thus it's calling frequency is dependent to this step size. If you change it to 0.5, you'll get a CAN message every 500ms.

To continue the explanation, ISRs (interrupt service routines), blocks like CAN Tx Complete ISR in your example, are used to trigger a subsystem outside the main loop. In this example, an interrupt is generated for every Send event, so you'll end up with the same calling frequency of the subsystem triggered by CAN Tx Complete ISR; but if it were an Rx ISR, that is totally non-dependent of the main loop period. The code generated from the blocks inside the subsystem triggered by that ISR would be called only when an Rx event would be issued.

[Using a hardware timer]

If you want dedicated timing (and not using the main loop step size), you can use a LPIT block. You can set it's period (in ms) and use this block to trigger a subsystem at that given period. This way you can schedule multiple tasks with different frequencies. But keep in mind that you have a limited number of (hardware) timers. You could use multiple timers and with a bit of extra software, you could achieve multiple timing values, but with this hardware-software timer combination. The limitation here would be that if you want more than the number of hardware channels available, with all the software changes you can make, you'll only be able to get to periods that are a linear combination of the individual periods given to each channel (e.g.: you have the following periods:

ch0 - 1s

ch1 - 100ms

ch2 - 25 ms

With these values you can get (i0*1s) + (i1*0.1s) + (i2*0.25) period, where i0, i1, i2 are unsigned integers.)

[Using a software timer]

gramirezv‌ wrote a good article for such an approach. You can read it here.

Hope this helps!

Razvan.

0 Kudos
865 Views
erik_ziel
Contributor II

Hello Razvan,

works very well thanks to the explanation, this is exactly the starting point I needed.

BR

Erik

0 Kudos