Scheduling the transmision of CAN frames in an RTOS

ccanrtosstm32

I'm planning to use my STM32 board to send CAN frames. I implemented a simple scheduler that contains 10 tasks; one task will be responsible for sending frames. To do the job I declared a structure for the CAN frame:

typedef struct
{
    unsigned int id;
    unsigned char data[];
    unsigned char dlc;
    unsigned int timeOfSend  //This is the time in ms in which a frame should be sent
} tFrame;

And then I declared a table of the frames to be sent:

aubFrames[MAX_FRAMES] = {
    {0x12, 0xAABBCC, 4, 100},
    {0x12, 0xAABBCC, 4, 1000},
    {0x12, 0xAABBCC, 4, 2000},
    {0x12, 0xAABBCC, 4, 2010}
};

This tells the board to send the first frame after 100 ms, the second after 1000 ms, etc.

What I actually do:

I added a new task in the scheduler with a period of 10 ms. This task will check the aubFrames table, and if it's time to send a frame, it sends the concerned frame. Else nothing is to be done. The probem with this solution is that there is a big loss of time. For example, to send the first frame, the scheduler accesses this task nine times, but with nothing to do.

Is there another solution so that the scheduling will be more effective?

I thought to use a timer interrupt, but I don't think that's the good solution since there are only four timers on the board and the number of frames is more than four, so in my opinion configuring the timers to generate interrupts for different periods of time won't work.

Best Answer

  • Use a single timer.

  • Setup the timer for 10 ms.

  • Define elapsed time as static and initialize to 0

  • Define albtable selector as static and initialize to 0

  • At each interrupt:

    • Increment elapsed time by 10

    • Check albtable[albtable selector] to see if time field matches elapsed time

    • If times match,
    • then
      • Send frame using albtable[albtable selector]
      • Increment albtable selector
    • Endif

    • If albtable selector >= number of entries in albtable[]:

      • Turn off timer
    • Return from interrupt