I have a task that periodically that does some calculations and finally sends data from the calculation onto CAN. The task uses vTaskDelayUntil to be called with a fixed frequency. The problem is, that the task has different execution times: Every for example 10 times the calculation takes significantly more time (still not as long as the fixed frequency the task is called). The task is therefore correctly executed with a fixed frequency but the sending onto CAN in the end of an execution cycle is always delayed, when the calculcation takes longer. My goal is that the sending is periodically. I could resolve this problem easily when placing the vTaskDelay between the calculation and the sending onto CAN. However, this would mean that I send the data much later than it is available. So basically I would have to separate the measurement of the execution time and the call of the vTaskDelayUntil. Is there a simple possibility with FreeRTOS-API-Calls to solve this problem or do I have to measure the execution time myself and call vTaskDelay myself?
I’m not sure I understand. If you are using vTaskDelayUntil() as per the API documentation then the task will execute with an exact period (assuming it is the highest priority task that is able to run when the vTaskDelayUntil() function returns). If the time between vTaskDelayUntil() returning and the CAN message actually being output onto the bus varies because the calculation performed after vTaskDelayUntil() returned varies then that would seem to be a characteristic of your system – rather than an RTOS specific thing. I would think you need to decide what is most important to the stable running of your system – the time the calculation starts (in which case the way you have the code now will give the best result) – or the time the result of the calculation goes onto the bus (in which case you can wake from vTaskDelayUntil() earlier, perform the calculation, then wait whatever time remains before the data is output onto the bus).
Thanks for the fast reply. And yes, I am using vTaskDelayUntil() as per the API documentation and the task executes (means: starts to calculate) with an exact period, I verified this also with Tracealyzer. Important to the stable running of my system would be, that the CAN message is sent exactly periodically, but immediately after the calculation is done, no matter how long the calculation takes (which is always shorter than the frequency the task is called). I guess there is no clean way to do this with vTaskDelayUntil() or other RTOS API functions (like manipulating the laskWakeTime variable that is passed by reference to vTaskDelayUntil())? I tried now to measure the time the calculations take myself and used vTaskDelay() with varying ticks to wait: Whenever a “short” calculation will be followed by a “long” calculation, the ticks are reduced by the time, the “long” calculation takes so that the task executes with a fixed frequency regarding the point the CAN message is sent. By now it seems to work.
If you know (or can estimate) how long the NEXT calculation will occur, then you can modify the parameter in the call to vTaskDelayUntil by subrtracting the estimated time of the next calculation and adding the extimated time of the previous calculation. Then your sends will be uniform to the precision of you estimate of the calculation. This would be basically the same as keeping a moving time stamp of when you wan to send your next message, subtract the estimated time of computation, and subtract the current timestamp, and then increment the moving time stamp by one period.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.