SoFunction
Updated on 2025-04-14

Analysis of kernel control examples for FreeRTOS real-time operating system

Preface

Some functions of kernel control need to be provided by the porting layer. To facilitate porting, these API functions are implemented using macros, such as context switching, entry and exit critical sections, and prohibiting and enabling maskable interrupts. The kernel control function also includes a start and stop scheduler, a suspend and restore scheduler, and a tuning system beat function for low power modes.

1. Force context switch macro

taskYIELD: Macro used to force context switching. The equivalent version in the interrupt service program is portYIELD_FROM_ISR, which is also a macro, and its implementation depends on the porting layer.

The actual code for context switching is provided by the porting layer. For Cortex-M3 hardware, this macro causes PendSV interrupts.

2. Enter the critical area macro

taskENTER_CRITICAL: A macro used to enter the critical zone. No context switching occurs in the critical section.

The actual code entering the critical area is provided by the porting layer. For Cortex-M3 hardware, all RTOS maskable interrupts are prohibited first, which can be achieved by writing configMAX_SYSCALL_INTERRUPT_PRIORITY to the basepri register.

After the basepri register is set to a certain value, all interrupts with priority numbers greater than or equal to this value are disabled, but if set to 0, no interrupts are turned off, 0 is the default value. Then increase the critical area nesting counter by 1.

3. Exit the critical zone macro

taskEXIT_CRITICAL: Macro used to exit critical zone.

The actual code to exit the critical zone is provided by the porting layer. For Cortex-M3 hardware, the critical zone nested counter is first reduced by 1. If the critical zone counter is zero, all RTOS can be enabled to mask interrupts, which can be achieved by writing 0 to the basepri register.

4. Disable blocking interrupted macros

taskDISABLE_INTERRUPTS: Disable all RTOS blockable interrupts.

When the macro taskENTER_CRITICAL is called into the critical section, the macro will also be indirectly called to prohibit all RTOS from blocking interrupts.

5. Enable blockable interrupt macro

taskENABLE_INTERRUPTS: Enable all RTOS maskable interrupts.

When the macro taskEXIT_CRITICAL is called out of the critical area, the macro is also called indirectly to enable all RTOS masking interrupts.

6. Start the scheduler

6.1 Function description

void vTaskStartScheduler( void );

Start the RTOS scheduler, and then the RTOS kernel controls which task is executed and when.

When vTaskStartScheduler() is called, the idle task is automatically created.

If configUSE_TIMERS is set to 1, the timer background task will also be created.

If vTaskStartScheduler() is executed successfully, the function will not return until a task calls vTaskEndScheduler().

If the idle task cannot be created due to insufficient RAM, the function may also fail and will be returned to the call immediately.

7. Stop the scheduler

7.1 Function description

void vTaskEndScheduler( void );

Only used in x86 hardware architecture.

Stop the beat clock of the RTOS kernel system. All created tasks are automatically deleted and multitasking stops.

8. Stop the scheduler

8.1 Function description

void vTaskSuspendAll( void );

Suspend the scheduler, but interrupts are not prohibited. When the scheduler is suspended, no context switching is performed. After the scheduler is suspended, the executing task will continue to be executed and the kernel will no longer schedule (meaning that the current task will not be switched out) until the task calls the xTaskResumeAll () function.

During kernel scheduler hangs, those API functions that can cause context switching (such as vTaskDelayUntil(), xQueueSend(), etc.) must not be used.

9. Recover the suspended scheduler

9.1 Function Description

BaseType_t xTaskResumeAll( void );

Recover the real-time kernel scheduler suspended by calling the vTaskSuspendAll() function.

xTaskResumeAll() only restores the scheduler, it will not restore tasks suspended by the vTaskSuspend() function.

9.2 Return value

Returning pdTRUE means that the recovery scheduler caused a context switch, otherwise, return pdFALSE.

9.3 Examples of usage

 voidvTask1( void * pvParameters )
 {
     for( ;; )
     {
         /* Task code is written here */
         /* ... */
         /* Sometimes, a task hopes to run for a long time, but at this time, the taskENTER_CRITICAL ()/taskEXIT_CRITICAL () method cannot be used, as this will block out interrupts and cause interrupt loss, including the system beat clock.  You can use vTaskSuspendAll () to stop RTOS kernel scheduling: */
         xTaskSuspendAll ();
         /* The execution operation code is placed here.  This way, you can perform it for a long time without entering the critical area.  During this period, interrupts will still be responded, and the beat clock of the RTOS kernel system will continue to operate */
         /* ... */
         /* The operation ends, restart the RTOS kernel.  We want to force a context switch, but if the context switch has been performed when the scheduler is restored, it is meaningless to execute it again, so we will make a judgment.  */
         if( !xTaskResumeAll () )
         {
              taskYIELD ();
         }
     }
 }

10. Adjust the system beat

10.1 Function description

void vTaskStepTick( TickType_txTicksToJump );

If RTOS enables the tickless idle function, the system beat clock interrupt will stop whenever only the idle task is executed and the microcontroller enters low power mode.

When the microcontroller exits the low power consumption, the system beat counter must be adjusted to make up for the time entering the low power consumption.

If the macro portSUPPRESS_TICKS_AND_SLEEP() entity is defined in the FreeRTOS port file, the function vTaskStepTick is used to adjust the system beat counter inside the macro portSUPPRESS_TICKS_AND_SLEEP() entity.

The function vTaskStepTick is a global function, so it can also be overridden in the macro portSUPPRESS_TICKS_AND_SLEEP() entity.

In the file, the macro configUSE_TICKLESS_IDLE must be set to 1 for this function to be valid.

10.2 Parameter Description

xTickToJump: The time value, unit is the system beat cycle, indicating the time when the microprocessor enters low power consumption. The function adjusts the value of the system beat counter based on this value.

10.3 Examples of usage

/* First define the macro portSUPPRESS_TICKS_AND_SLEEP().  The macro parameter specifies the time to enter low power consumption (sleep), which is the system beat cycle.  */#defineportSUPPRESS_TICKS_AND_SLEEP( xIdleTime ) vApplicationSleep( xIdleTime ) /* Define the function called by the macro portSUPPRESS_TICKS_AND_SLEEP() */void vApplicationSleep(TickType_t xExpectedIdleTime ){ unsigned long ulLowPowerTimeBeforeSleep,ulLowPowerTimeAfterSleep; /* Get the current time from the clock source. When the microcontroller enters low power consumption, this clock source must be running */ ulLowPowerTimeBeforeSleep =ulGetExternalTime(); /*Stop the system beat clock interrupt.  */ prvStopTickInterruptTimer(); /* Configure an interrupt that wakes the processor from low power consumption when the specified sleep time is reached.  This interrupt source must also work when the microcontroller enters low power consumption.  */ vSetWakeTimeInterrupt( xExpectedIdleTime ); /*Enter low power consumption */ prvSleep(); /* Determines the true time the microcontroller will last to enter low power mode.  Because other interrupts may also cause the microprocessor to exit low power mode.  Note: The scheduler should be suspended before calling the macro portSUPPRESS_TICKS_AND_SLEEP(). After portSUPPRESS_TICKS_AND_SLEEP() returns, the scheduler will be restored.  Therefore, no other tasks will be performed until this function is completed.  */ ulLowPowerTimeAfterSleep =ulGetExternalTime(); /* Adjust the kernel system beat counter.  */ vTaskStepTick( ulLowPowerTimeAfterSleep –ulLowPowerTimeBeforeSleep ); /*Restart the system beat clock interrupt.  */ prvStartTickInterruptTimer();}/* First define the macro portSUPPRESS_TICKS_AND_SLEEP().  The macro parameter specifies the time to enter low power consumption (sleep), which is the system beat cycle.  */
#defineportSUPPRESS_TICKS_AND_SLEEP( xIdleTime ) vApplicationSleep( xIdleTime )
 /* Define the function called by the macro portSUPPRESS_TICKS_AND_SLEEP() */
void vApplicationSleep(TickType_t xExpectedIdleTime )
{
    unsigned long ulLowPowerTimeBeforeSleep,ulLowPowerTimeAfterSleep;
     /* Get the current time from the clock source. When the microcontroller enters low power consumption, this clock source must be running */
    ulLowPowerTimeBeforeSleep =ulGetExternalTime();
     /*Stop the system beat clock interrupt.  */
    prvStopTickInterruptTimer();
     /* Configure an interrupt that wakes the processor from low power consumption when the specified sleep time is reached.  This interrupt source must also work when the microcontroller enters low power consumption.  */
    vSetWakeTimeInterrupt( xExpectedIdleTime );
     /*Enter low power consumption */
    prvSleep();
     /* Determines the true time the microcontroller will last to enter low power mode.  Because other interrupts may also cause the microprocessor to exit low power mode.  Note: The scheduler should be suspended before calling the macro portSUPPRESS_TICKS_AND_SLEEP(). After portSUPPRESS_TICKS_AND_SLEEP() returns, the scheduler will be restored.  Therefore, no other tasks will be performed until this function is completed.  */
    ulLowPowerTimeAfterSleep =ulGetExternalTime();
            /* Adjust the kernel system beat counter.  */
    vTaskStepTick( ulLowPowerTimeAfterSleep –ulLowPowerTimeBeforeSleep );
    /*Restart the system beat clock interrupt.  */
    prvStartTickInterruptTimer();
}

The above is the detailed analysis of the kernel control example of FreeRTOS real-time operating system. For more information about the kernel control of FreeRTOS real-time operating system, please pay attention to my other related articles!