free rtos 任务切换的理解
Posted Eliot_shao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了free rtos 任务切换的理解相关的知识,希望对你有一定的参考价值。
rtos 系统运行的几个要素:本质上,系统的运行依靠sys tick/PendSV 中断 驱动 任务管理程序完成任务切换执行不同任务程序。除sys tick/PendSV 中断 以外的中断程序执行。以及任务任务运行过程引发的任务阻塞,挂起,恢复。
所以占有cpu的优先级:高优先级中断>sys tick/PendSV 中断>高优先级的任务>低优先级任务,cpu在各个代码跳来跳去。
如图:
引起任务阻塞的api:
Tasks can enter the Blocked state to wait for two different types of event:
1. Temporal (time-related) events—the event being either a delay period expiring, or an
absolute time being reached. For example, a task may enter the Blocked state to wait
for 10 milliseconds to pass.
2. Synchronization events—where the events originate from another task or interrupt. For
example, a task may enter the Blocked state to wait for data to arrive on a queue.
Synchronization events cover a broad range of event types.
FreeRTOS queues, binary semaphores, counting semaphores, mutexes, recursive mutexes,
event groups and direct to task notifications can all be used to create synchronization events.
All these features are covered in future chapters of this book.
引起任务挂起的api
vTaskSuspend()/vTaskSuspendall()
任务的让出(ruunnig-->block)
1.vTaskDelay()/vTaskDelayUntil()-->prvAddCurrentTaskToDelayedList
2.等待某事件,将tcb放到EventList
xQueueReceive->vTaskPlaceOnEventList
xQueueSemaphoreTake->vTaskPlaceOnEventList
3.(ruunnig-->suspend)vTaskSuspend()
任务的唤醒(block-->ready)
1.xTaskIncrementTick -> prvAddTaskToReadyList( pxTCB );
2.xQueueGenericSend->xTaskRemoveFromEventList
3.(suspend-->ready)vTaskResume()
------------------------------------------------------------------------------------------
#define taskENTER_CRITICAL() portENTER_CRITICAL()
--->
#define portENTER_CRITICAL() vPortEnterCritical()
--->
void vPortEnterCritical( void )
{
portDISABLE_INTERRUPTS();-->msr basepri, configMAX_SYSCALL_INTERRUPT_PRIORITY //设置中断屏蔽寄存器 屏蔽优先级小于configMAX_SYSCALL_INTERRUPT_PRIORITY 的中断,此时os无法完成调度
uxCriticalNesting++;
/* This is not the interrupt safe version of the enter critical function so
assert() if it is being called from an interrupt context. Only API
functions that end in "FromISR" can be used in an interrupt. Only assert if
the critical nesting count is 1 to protect against recursive calls if the
assert function also uses a critical section. */
if( uxCriticalNesting == 1 )
{
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
}
}
taskEXIT_CRITICAL
退出临界段,调用taskEXIT_CRITICAL portEXIT_CRITICAL vPortExitCritical 本质都是调用 __set_BASEPRI( 0 )清除中断屏蔽。和...ENTER_CRITICAL成对嵌套使用。
------------------------------------------------------------------------------------------
void vTaskSuspendAll( void )
--->
void vTaskSuspendAll( void )
{
/* A critical section is not required as the variable is of type
BaseType_t. Please read Richard Barry's reply in the following link to a
post in the FreeRTOS support forum before reporting this as a bug! -
http://goo.gl/wu4acr */
++uxSchedulerSuspended;
}
将uxSchedulerSuspended标志位加一,禁止上下文切换;但是SysTick继续运行,当前任务和中断还可以继续运行。
BaseType_t xTaskResumeAll( void )
会将所有挂起状态的列表中的任务加入到就绪的列表 list 当中。
------------------------------------------------------------------------------------------
以上是关于free rtos 任务切换的理解的主要内容,如果未能解决你的问题,请参考以下文章