Some of the kernel-controlled functions need to be provided by the porting layer, which are implemented with macros for portability, such as context switching, entering and exiting critical sections, and blocking and enabling masking interrupts. The kernel control functions also include a start and stop scheduler, a suspend and resume scheduler, and an adjustment system beat function for low power modes.
1. Forcing context Switch macros
Taskyield: A 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 used for context switching is provided by the migration layer. For CORTEX-M3 hardware, this macro causes PENDSV interrupts.
2. Enter the critical section macro
Taskenter_critical: macro used to enter a critical section. The context switch does not occur in the critical section.
The actual code that enters the critical section is provided by the migration layer, and for cortex-m3 hardware, all RTOS can be blocked first, which can be Basepri Register write configmax_syscall_interrupt_priority to implement. When the BASEPRI register is set to a value, all interrupts with a priority number greater than or equal to this value are disabled, but if set to 0, no interrupts are turned off, and 0 is the default value. Then the critical section nesting counter increases by 1.
3. Exit the critical section macro
Taskexit_critical: the macro used to exit the critical section.
The actual code exiting the critical section is provided by the porting layer, and for cortex-m3 Hardware, the critical section nesting counter is reduced by 1, and if the critical section counter is zero, all RTOS the interrupt can be masked, which can be achieved by writing to the Basepri register.
4. Disable masking interrupt macros
Taskdisable_interrupts: Disable all RTOs to block interrupts. When the macro taskenter_critical is called into the critical section, the macro is also called indirectly to prohibit all rtos from masking interrupts.
5. Enable to mask interrupt macros
Taskenable_interrupts: Enable all RTOs to mask interrupts. When the macro taskexit_critical exits the critical section, the macro is also invoked indirectly to enable all RTOs to mask interrupts.
6. Start the Scheduler6.1 Function Description
void Vtaskstartscheduler (void);
Starts the RTOs Scheduler, after which the RTOs kernel controls which tasks are executed and when.
when calling Vtaskstartscheduler () , the idle task is created automatically. If configuse_timers is set to 1, the timer background task will also be created.
if vtaskstartscheduler () executes successfully, the function does not return until a task is called Vtaskendscheduler () . If The idle task cannot be created because of insufficient RAM, the function may fail and will return to the call immediately.
7. Stop the Scheduler7.1 Function Description
void Vtaskendscheduler (void);
Used only in x86 hardware architectures.
Stop the RTOs kernel system beat clock. All created tasks automatically delete and stop the multitasking schedule.
8. Suspending the scheduler8.1 Function Description
void Vtasksuspendall (void);
Suspends the scheduler, but does not prohibit interrupts. When the scheduler is suspended, no context switching occurs. After the scheduler is suspended, the executing task continues, and the kernel is no longer dispatched (meaning that the current task is not switched out) until the task calls the Xtaskresumeall () function.
The API functions that can cause context switching (such as Vtaskdelayuntil (), Xqueuesend (), and so on) must never be used during the kernel scheduler suspension.
9. Recovering a suspended scheduler9.1 Function Description
basetype_t xtaskresumeall (void);
Restores the real-time kernel scheduler that was suspended because of the call to the Vtasksuspendall () function. Xtaskresumeall () recovers only the scheduler, which does not restore tasks that are suspended by the Vtasksuspend () function.
9.2 return value
Returning pdtrue indicates that the recovery scheduler caused a context switch, otherwise, returns PDFALSE.
9.3 Usage Examples
VoidvTask1 (void * pvparameters) {for (;;) { /* The task code is written here * ///////////////////////* Some times, a task would like to be able to run for a long time, but you cannot use taskenter_critical ()/taskexit_critical This will block out interrupts and cause loss of interrupts, including the system beat clock. The RTOs kernel Scheduler can be stopped using Vtasksuspendall (): */ Xtasksuspendall (); /* Execute the operation code here. This can be performed for a long time without entering the critical section. During this time, the interrupt will still be responsive, and the RTOs kernel system beat clock will continue to operate */*////////////////to restart the RTOs kernel. We want to force a context switch, but if a context switch has been performed when the scheduler is resumed, it makes no sense to do it again, so a single decision is made. */ if (!xtaskresumeall ()) { Taskyield (); }}}
10. Adjust the system beats10.1 Function Description
void Vtasksteptick (Ticktype_txtickstojump);
If the RTOS enables tickless idle functionality, the system beat clock interrupt will stop when only idle tasks are executed, and the microcontroller enters low power mode. When the microcontroller exits the low power, the system beat counter must be adjusted to enter a low-power time offset.
If the macro portsuppress_ticks_and_sleep () entity is defined in the FreeRTOS migration file, the function Vtasksteptick is used in this macro portsuppress_ticks_and_sleep () The system beat counter is adjusted inside the entity. The function Vtasksteptick is a global function, so you can also override the function in the macro portsuppress_ticks_and_sleep () entity.
In file FreeRTOSConfig.h, the macro configuse_tickless_idle must be set to 1 for this function to be valid.
10.2 Parameter Description
- Xticktojump: The time value, which is the system tick cycle, indicates that the microprocessor enters a low-power time, and the function adjusts the value of the system tick counter based on this value.
10.3 Usage Examples
/* First define the Macro Portsuppress_ticks_and_sleep (). The macro parameter specifies the time to enter low power (sleep) in the system cycle. */#defineportSUPPRESS_TICKS_AND_SLEEP (xidletime) vapplicationsleep (xidletime)/* defined by Macro Portsuppress_ticks_and_sleep () called function */void vapplicationsleep (ticktype_t xexpectedidletime) {unsigned long ullowpowertimebeforesleep, Ullowpowertimeaftersleep; /* Gets the current time from the clock source, and when the microcontroller enters low power, the clock source must be running */Ullowpowertimebeforesleep =ulgetexternaltime (); /* Stop the system beat clock interrupt. */Prvstoptickinterrupttimer (); /* Configure an interrupt to wake the processor from low power when the specified sleep time has been reached. This interrupt source must also work when the microcontroller enters low power. */Vsetwaketimeinterrupt (xexpectedidletime); /* Enter low power */prvsleep (); /* Determine the true time that the microcontroller continues to enter the low-power mode. Because other interrupts can also cause the microprocessor to exit the low-power mode. Note: Before calling macro Portsuppress_ticks_and_sleep (), the scheduler should be suspended, Portsuppress_ticks_and_sleep () returned, and the scheduler resumed. Therefore, no other tasks are performed until this function is completed. */Ullowpowertimeaftersleep =ulgetexternaltime (); /* Adjust the kernel system beat counter. */Vtasksteptick (ullowpowertimeaftersleep–ullowpowertimebeforesleep); /* Restart the system beat clock interrupt. */Prvstarttickinterrupttimer ();}
FreeRTOS Series 13th---freertos core control