| Hook API Function | Description |
|---|---|
| vApplicationIdleHook() | Runs user-defined background or low-power code during Idle task execution |
| vApplicationTickHook() | Runs from the RTOS tick interrupt |
| vApplicationMallocFailedHook() | Called when pvPortMalloc() cannot allocate memory |
| vApplicationStackOverflowHook() | Called when a task stack overflow is detected |
| vApplicationDaemonTaskStartupHook() | Runs once when the Timer Service/Daemon task starts |
| configUSE_TICKLESS_IDLE | Enables tickless idle mode, allowing FreeRTOS to suppress unnecessary tick interrupts and reduce power consumption while the system is idle |
The idle task hook is a user-defined callback function that FreeRTOS executes repeatedly whenever no other task is ready to run. It is implemented as vApplicationIdleHook() and enabled by setting configUSE_IDLE_HOOK to 1 in FreeRTOSConfig.h. The hook can be used for low-priority background operations, such as entering a low-power mode, collecting system statistics, or performing simple maintenance tasks. It must never block, call functions that may block, or perform lengthy processing, because doing so prevents the idle task from running normally and may delay the cleanup of deleted tasks.
void vApplicationIdleHook(void)
// ---------------------- Example ----------------------
#define configUSE_TICKLESS_IDLE 0
#define configUSE_IDLE_HOOK 1
#define configIDLE_SHOULD_YIELD 1
void BeforeEnterSleep(void)
{
__HAL_RCC_GPIOB_CLK_SLEEP_DISABLE();
__HAL_RCC_GPIOC_CLK_SLEEP_DISABLE();
__HAL_RCC_GPIOD_CLK_SLEEP_DISABLE();
__HAL_RCC_GPIOE_CLK_SLEEP_DISABLE();
__HAL_RCC_GPIOF_CLK_SLEEP_DISABLE();
__HAL_RCC_GPIOG_CLK_SLEEP_DISABLE();
__HAL_RCC_GPIOH_CLK_SLEEP_DISABLE();
}
void AfterExitSleep(void)
{
__HAL_RCC_GPIOB_CLK_SLEEP_ENABLE();
__HAL_RCC_GPIOC_CLK_SLEEP_ENABLE();
__HAL_RCC_GPIOD_CLK_SLEEP_ENABLE();
__HAL_RCC_GPIOE_CLK_SLEEP_ENABLE();
__HAL_RCC_GPIOF_CLK_SLEEP_ENABLE();
__HAL_RCC_GPIOG_CLK_SLEEP_ENABLE();
__HAL_RCC_GPIOH_CLK_SLEEP_ENABLE();
}
void vApplicationIdleHook(void)
{
BeforeEnterSleep();
__DSB();
__WFI();
__ISB();
AfterExitSleep();
}vApplicationTickHook() is a user-defined FreeRTOS hook function that is called from the RTOS tick interrupt each time the system tick occurs. To enable it, set configUSE_TICK_HOOK to 1 in FreeRTOSConfig.h. It is typically used for short, periodic operations such as incrementing counters, updating software timing variables, or triggering lightweight monitoring functions. Because it executes in interrupt context, the hook must run quickly, must not block, and may only call FreeRTOS API functions that are safe to use from an ISR.
void vApplicationTickHook(void)
// ---------------------- Example ----------------------
#define configUSE_TICK_HOOK 1
volatile uint32_t ulTickHookCounter = 0;
volatile BaseType_t xOneSecondElapsed = pdFALSE;
void vApplicationTickHook(void) {
ulTickHookCounter++;
// Set a flag approximately once every second
if (ulTickHookCounter >= configTICK_RATE_HZ)
{
ulTickHookCounter = 0;
xOneSecondElapsed = pdTRUE;
}
}vApplicationMallocFailedHook() is a user-defined FreeRTOS hook function that is called whenever a dynamic memory allocation request fails, such as when pvPortMalloc(), xTaskCreate(), or another kernel object creation function cannot obtain enough heap memory. To enable it, set configUSE_MALLOC_FAILED_HOOK to 1 in FreeRTOSConfig.h. The hook is commonly used to record diagnostic information, trigger an assertion, illuminate an error indicator, or halt execution for debugging. Because the system may have very little memory remaining, the hook should avoid performing additional dynamic memory allocations.
void vApplicationMallocFailedHook(void)
// ---------------------- Example ----------------------
#define configUSE_MALLOC_FAILED_HOOK 1
void vApplicationMallocFailedHook(void)
{
taskDISABLE_INTERRUPTS();
for (;;) {}
}vApplicationStackOverflowHook() is a user-defined FreeRTOS hook function that is called when the kernel detects that a task has exceeded its allocated stack space. To enable stack-overflow checking, set configCHECK_FOR_STACK_OVERFLOW to 1 or 2 in FreeRTOSConfig.h, with 2 providing more thorough checking. The hook receives the handle and name of the affected task, allowing the application to record diagnostic information, trigger an assertion, illuminate an error LED, or halt execution for debugging. Because stack corruption may already have occurred, the hook should avoid complex operations and should normally stop the system so the cause can be investigated.
void vApplicationStackOverflowHook(TaskHandle_t xTask,
char *pcTaskName)
// ---------------------- Example ----------------------
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define configCHECK_FOR_STACK_OVERFLOW 2
volatile const char *g_overflow_task_name = NULL;
volatile TaskHandle_t g_overflow_task_handle = NULL;
void vApplicationStackOverflowHook(TaskHandle_t xTask,
char *pcTaskName)
{
g_overflow_task_handle = xTask;
g_overflow_task_name = pcTaskName; // points to the task name string
taskDISABLE_INTERRUPTS();
for (;;) {
__NOP(); // set breakpoint here and inspect g_overflow_task_name
// LED may also be turned on or toggled here
}
}
TaskHandle_t taskHandler;
UBaseType_t uxRemainingWords;
uxRemainingWords = uxTaskGetStackHighWaterMark(taskHandler);
printf("Unused stack: %lu words (%lu bytes)\r\n",
(unsigned long)uxRemainingWords,
(unsigned long)uxRemainingWords * sizeof(StackType_t));vApplicationDaemonTaskStartupHook() is a user-defined FreeRTOS hook function that is called once when the daemon task, also known as the timer service task, begins running after the scheduler starts. To enable it, set configUSE_DAEMON_TASK_STARTUP_HOOK to 1 in FreeRTOSConfig.h. It is typically used to perform application initialization that must occur after the scheduler is active, such as creating synchronization objects, starting software timers, or initializing components that depend on FreeRTOS services. Because the hook executes in the context of the daemon task, lengthy or blocking operations should be avoided so that software timers and deferred callback processing are not delayed.
void vApplicationDaemonTaskStartupHook(void)
// ---------------------- Example ----------------------
#define configUSE_DAEMON_TASK_STARTUP_HOOK 1
#define configUSE_TIMERS 1
TimerHandle_t OneShotTimer_Handle;
OneShotTimer_Handle =
xTimerCreate((const char* ) "OneShotTimer",
(TickType_t ) 3000,
(UBaseType_t ) pdFALSE,
(void* ) 1,
(TimerCallbackFunction_t) OneShotTimerCallback);
void vApplicationDaemonTaskStartupHook(void) {
BaseType_t xResult;
xResult = xTimerStart(OneShotTimer_Handle, 0);
configASSERT(xResult == pdPASS);
}
void OneShotTimerCallback(TimerHandle_t xTimer) {
static TickType_t xTimeNow;
xTimeNow = xTaskGetTickCount();
printf("One-shot timer callback executing: %d\r\n", (int)xTimeNow);
}configUSE_TICKLESS_IDLE enables FreeRTOS tickless idle mode, which reduces power consumption when no application task is ready to run. Normally, the periodic RTOS tick interrupt continues waking the processor even while the Idle task is running. When tickless idle is enabled, FreeRTOS temporarily stops the tick interrupt, places the processor into a low-power state, and sleeps until an interrupt occurs or a blocked task is due to wake. After waking, the kernel adjusts its tick count to account for the elapsed time. Set it to 0 to disable tickless idle, 1 to use the port’s built-in implementation when supported, or 2 to provide a custom portSUPPRESS_TICKS_AND_SLEEP() implementation.
#define configUSE_TICKLESS_IDLE 1
// FreeRTOSConfig.h
extern void PreSleepProcessing(uint32_t ulExpectedIdleTime);
extern void PostSleepProcessing(uint32_t ulExpectedIdleTime);
#define configPRE_SLEEP_PROCESSING PreSleepProcessing
#define configPOST_SLEEP_PROCESSING PostSleepProcessing
// main.c
void PreSleepProcessing(uint32_t ulExpectedIdleTime)
{
(void)ulExpectedIdleTime;
// Disable GPIO clocks that are not needed during sleep
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();
__HAL_RCC_GPIOD_CLK_DISABLE();
__HAL_RCC_GPIOE_CLK_DISABLE();
__HAL_RCC_GPIOF_CLK_DISABLE();
__HAL_RCC_GPIOG_CLK_DISABLE();
__HAL_RCC_GPIOH_CLK_DISABLE();
}
void PostSleepProcessing(uint32_t ulExpectedIdleTime)
{
(void)ulExpectedIdleTime;
// Re-enable GPIO clocks after waking up
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
}Back to top of the page