freeRTOS Kernel Control-vTaskSuspendAll-xTaskResumeAll


freeRTOS Kernel Control-vTaskSuspendAll-xTaskResumeAll_第1张图片

=======================================================================

freeRTOS Kernel Control-vTaskSuspendAll-xTaskResumeAll_第2张图片

上面这句话什么意思?说得是“这里不用加上critical section。想知道原因?那么到论坛里看Richard Barry的回复”

然后我一输入网址打不开。critical section是什么意思呢?在百度百科的简介里面是这么说得“不论是硬件临界资源,还是软件临界资源,多个线程必须互斥地对它进行访问。每个线程中访问临界资源的那段代码称为临界区(Critical Section)。”

找了找freertos代码,感觉作者说得可能是这两句:

#define portENTER_CRITICAL()vPortEnterCritical()
       #define portEXIT_CRITICAL() vPortExitCritical()

在非操作系统时,也遇到这个知识点,并且印象极其深刻。这是所谓的“原子”操作。关键是这个变量“uxSchedulerSuspended”的数据类型与处理器的处理位数的关系。比如说STM32F407是32位处理器那么如果uxSchedulerSuspended的数据类型若大于32位,则要小心了!因为这个变量就无法被一条汇编语句处理,如果在两条汇编语句之间进入了中断服务程序,而中断服务程序里面恰好有对这个变量uxSchedulerSuspended的处理,那么以前的汇编语句可能就读取错误。当然这个错误发生概率极低了。有两种方法处理这个问题,一个是指向含有uxSchedulerSuspended的语句之前禁止中断,执行完后使能中断。还有一种方式是弄个临时变量比较一下。如果两次的值相同的话就是正确的值。

=================================================================

void vTaskSwitchContext( void )
{
if( uxSchedulerSuspended != ( UBaseType_t ) pdFALSE )
{
/* The scheduler is currently suspended - do not allow a context switch. */
xYieldPending = pdTRUE;
}
else
{
                //DO SOMETHING !!!
}
}

freeRTOS Kernel Control-vTaskSuspendAll-xTaskResumeAll_第3张图片

freeRTOS Kernel Control-vTaskSuspendAll-xTaskResumeAll_第4张图片



freeRTOS Kernel Control-vTaskSuspendAll-xTaskResumeAll_第5张图片

、====================================

简单总结一下:

(0)挂起是令调度器阻止上下文切换,但是却能继续使能中断。

那么为什么要挂起呢?因为vTaskSuspendAll和xTaskResumeAll之间的代码执行时间有点长。

(1)vTaskSuspendAll和xTaskResumeAll必须成双入对。

(2)可以嵌套,如下:

vTaskSuspendAll();

//DOsomething!!

vTaskSuspendAll();

//DOsomething!!

xTaskResumeAll();

//DOsomething!!

xTaskResumeAll();



你可能感兴趣的:(rtos/os,vTaskSuspendAll,xTaskResumeAll,freeRtos,suspend,resume)