FreeRTOS任务调用阻塞函数时的上下文切换机制及执行连续性问询
FreeRTOS任务调用阻塞函数时的上下文切换机制及执行连续性问询
嘿,先给你的初始理解点个赞——你对高优先级任务就绪时的上下文切换逻辑是完全正确的:调度器会立刻保存当前任务的完整上下文(包括程序计数器、寄存器状态、栈内的局部变量以及像你代码里的i这类任务状态变量),然后切换到高优先级任务执行;等那个高优先级任务进入阻塞状态后,调度器又会恢复之前任务的上下文,让它从暂停的位置继续跑。
回到你的核心问题:当任务调用vTaskDelay()这类阻塞函数时,上下文切换的逻辑本质上和你说的抢占场景是一致的,绝对不会让任务从头开始执行。
具体到你给出的代码例子:
int i = 0; while( c != EOF ){ printf("%c",c); if( i == 10 ){ vTaskDelay(100/portTICK_PERIOD_MS); } i++; }
当循环执行到i == 10时触发vTaskDelay(),此时FreeRTOS会做这些操作:
- 保存当前任务的所有执行状态:程序计数器会指向
vTaskDelay()执行完成后的下一行代码(也就是i++;),i的当前值(10)、c的当前值、循环的迭代进度都会被完整保留 - 把这个任务移到阻塞队列,暂时让出CPU
- 调度器会从就绪队列里挑选下一个合适的任务来运行
等100ms的延迟时间到了,这个任务会被重新移回就绪队列。当调度器再次选中它时,会把之前保存的所有上下文完整恢复,任务会从i++;这一行继续执行:i会变成11,然后进入下一次循环迭代,完全不会回到i=0的起点重新跑。
简单总结一下:不管是被动被高优先级任务抢占,还是主动调用阻塞函数放弃CPU,FreeRTOS的上下文切换都会完整保留任务的执行状态,确保任务能从暂停的精确位置继续执行,不会丢失之前的运行进度。
备注:内容来源于stack exchange,提问作者mafia2g2001
相关产品推荐
相关产品推荐

