New API xTaskPeriodicDelay (#1349)#1368
Conversation
25ed0e3 to
e1eb15a
Compare
|
|
Is this not solved by the timer task? |
Not sure what to answer here. This PR just implements |
|
@archigup this could be implemented with a signalling mechanism + a software timer task however that is more setup than simply calling this function. For that reason and because it avoids the runaway problem of |
| * \defgroup xTaskPeriodicDelay xTaskPeriodicDelay | ||
| * \ingroup TaskCtrl | ||
| */ | ||
| TickType_t xTaskPeriodicDelay( TickType_t * const pxPreviousWakeTime, |
There was a problem hiding this comment.
| TickType_t xTaskPeriodicDelay( TickType_t * const pxPreviousWakeTime, | |
| UBaseType_t xTaskPeriodicDelay( TickType_t * const pxPreviousWakeTime, |
Let's use the unsigned based type since this is a simple count
There was a problem hiding this comment.
My problem is this code:
/* This plays well with overflow */
const TickType_t xTicksElapsed = xTickCount - *pxPreviousWakeTime;
needs everything to be of the same type to work properly, so xTicksElapsed must be TickType_t. Then xIncrements (that is, what xTaskPeriodicDelay returns) is calculated as:
xIncrements = xTicksElapsed / xTimeIncrement;
and if I declare it as UBaseType_t I get the following error on my host:
error: conversion from ‘TickType_t’ {aka ‘long unsigned int’} to ‘UBaseType_t’ {aka ‘unsigned char’} may change value [[-Werror=conversion](https://gcc.gnu.org/onlinedocs/gcc-16.1.0/gcc/Warning-Options.html#index-Wconversion)]
I can cast it to remove the error, but in that case I think the result can easily overflow if I suspend a task for too much time.
| * not enough ticks have elapsed, 1 in the common case or | ||
| * more than 1 if the task has not been resumed in time */ | ||
| xIncrements = xTicksElapsed / xTimeIncrement; | ||
| xTicksIncrements = xIncrements * xTimeIncrement; |
There was a problem hiding this comment.
Probably need a check for overflow here. Don't want xIncrements * xTimeIncrement to be exactly one more than the xTicksIncrements maximum possible value.
There was a problem hiding this comment.
xTicksIncrements cannot overflow. If you substitute xIncrements you get:
xTicksIncrements = xTicksElapsed / xTimeIncrement * xTimeIncrement;
so xTicksIncrements would never exceed xTicksElapsed.
e1eb15a to
5e7424f
Compare
|
I'm not particularly worried about the failing UTs as those will need to be added. |
New function to be used for periodic tasks to ensure a constant execution frequency. It is intended to supersede xTaskDelayUntil to overcome its shortcomings, that is: - avoid run away of pxPreviousWakeTime (FreeRTOS#1339) - catch up any skipped period immediately (and update pxPreviousWakeTime accordingly), notify the caller of the number of periods skipped (by returning them) and wait until the next period (it could be less than xTimeIncrement if we are close to the next period) - notify the caller when not enough ticks have been elapsed (by returning 0) and handle the situation gracefully (by properly waiting until the next wake time) Signed-off-by: Nicola Fontana <ntd@entidi.it>
|
|
@kstribrnAmzn Many thanks for the review. I force-pushed before realizing you rebased, so I force-pushed again... sorry for the mess. Some issues you raised are still open though. In the specific, I don't know how to solve the |



New function to be used for periodic tasks to ensure a constant execution frequency. It is intended to supersede xTaskDelayUntil to overcome its shortcomings, that is:
Description
Test Steps
I tested that function on my ESP-IDF setup, directly running the resulting binary on an ESP32-S3 evaluation board. I would be more than happy to provide a unit test but I simply don't know how to do it.
This is the code I used:
and here are the results:
Checklist:
Related Issue
#1349
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.