Skip to content

Comments

New API xTaskPeriodicDelay (#1349)#1368

Open
ntd wants to merge 1 commit intoFreeRTOS:mainfrom
ntd:xTaskPeriodicDelay
Open

New API xTaskPeriodicDelay (#1349)#1368
ntd wants to merge 1 commit intoFreeRTOS:mainfrom
ntd:xTaskPeriodicDelay

Conversation

@ntd
Copy link

@ntd ntd commented Feb 17, 2026

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 ([BUG] xTaskDelayUntil updates pxPreviousWakeTime incorrectly in case of deadline miss #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)

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:

static void loop(void *data)
{
        TickType_t rv;
        TickType_t last = xTaskGetTickCount();
        for (int i = 0; i < 10; ++i) {
                rv = xTaskPeriodicDelay(&last, 5);
                printf("Iteration %d: last=%lu, tick=%lu, rv=%lu\n",
                       i, last, xTaskGetTickCount(), rv);
        }
        vTaskDelete(NULL);
}

void app_main(void)
{
        TaskHandle_t handle;
        xTaskCreate(loop, "LOOP", 2048, NULL, 1, &handle);
        vTaskSuspend(handle);
        vTaskResume(handle);
        vTaskDelay(3);
        vTaskSuspend(handle);
        vTaskResume(handle);
        vTaskDelay(6);
        vTaskSuspend(handle);
        vTaskDelay(12);
        vTaskResume(handle);
}

#if 0

/* This is an approximation of what ESP-IDF is doing behind the scene */
static void main_task(void *data)
{
        printf("main_task: Calling app_main()\n");
        app_main();
        printf("main_task: Returned from app_main()\n");
        vTaskDelete(NULL);
}

void main(void)
{
        TaskHandle_t handle;
        xTaskCreate(main_task, "MAIN", 2048, NULL, 1, &handle);
        vTaskStartScheduler();
}
#endif

and here are the results:

I (301) main_task: Calling app_main()
Iteration 0: last=1, tick=1, rv=0
Iteration 1: last=1, tick=4, rv=0
Iteration 2: last=1, tick=6, rv=0
I (406) main_task: Returned from app_main()
Iteration 3: last=6, tick=22, rv=1
Iteration 4: last=21, tick=26, rv=3
Iteration 5: last=26, tick=31, rv=1
Iteration 6: last=31, tick=36, rv=1
Iteration 7: last=36, tick=41, rv=1
Iteration 8: last=41, tick=46, rv=1
Iteration 9: last=46, tick=51, rv=1

Checklist:

  • I have tested my changes. No regression in existing tests.
  • I have modified and/or added unit-tests to cover the code changes in this Pull Request.

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.

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>
@ntd ntd force-pushed the xTaskPeriodicDelay branch from 25ed0e3 to e1eb15a Compare February 18, 2026 07:51
@sonarqubecloud
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant