FreeRTos 笔记(4e):解除任务挂起 vTaskResume 与 xTaskResumeFromISR 的源码。ARM内核里的寄存器 BASEPRI、PRIMASK、FAULTMASK

发布时间:2026/11/4 23:02:17
FreeRTos 笔记(4e):解除任务挂起 vTaskResume 与 xTaskResumeFromISR 的源码。ARM内核里的寄存器 BASEPRI、PRIMASK、FAULTMASK 42解除任务挂起 vTaskResume 源码voidvTaskResume(TaskHandle_t xTaskToResume)// tasks.c 1868 形参不能为 NULL 或 pxCurrentTCB{TCB_t*constpxTCBxTaskToResume;configASSERT(xTaskToResume);// 确认断言if((pxTCB!pxCurrentTCB)(pxTCB!NULL))// 形参不能为 NULL 或 pxCurrentTCB{taskENTER_CRITICAL();// 进入临界区{if(prvTaskIsTaskSuspended(pxTCB)!pdFALSE)// 要求形参任务在挂起链表中{traceTASK_RESUME(pxTCB);// 统计(void)uxListRemove((pxTCB-xStateListItem));// 其实就是在 xSuspendedTaskList 链表里prvAddTaskToReadyList(pxTCB);// 宏函数注释过了插入对应的就绪链表并更新对应的 bit 位// 本函数不是 vTaskResumeFromISR故可直接操作临界区不用插入到 xPendingReadyList待就绪任务链表if(pxTCB-uxPrioritypxCurrentTCB-uxPriority)// 形参任务比当前任务的优先级要高{taskYIELD_IF_USING_PREEMPTION();// 宏函数//宏taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API() 宏 portYIELD()}elsemtCOVERAGE_TEST_MARKER();}elsemtCOVERAGE_TEST_MARKER();}taskEXIT_CRITICAL();// 结束临界区}elsemtCOVERAGE_TEST_MARKER();}// vTaskResume43vTaskResume 调用了下面的函数 prvTaskIsTaskSuspendedstaticBaseType_tprvTaskIsTaskSuspended(constTaskHandle_t xTask)// tasks.c 1658{BaseType_t xReturnpdFALSE;constTCB_t*constpxTCBxTask;configASSERT(xTask);// xPendingReadyList 解除挂起的待就绪任务//判断形参任务是否是真的被挂起的任务//宏listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( pxListItem -pxContainer pxList ) ? pdTRUE : pdFALSEif(listIS_CONTAINED_WITHIN(xSuspendedTaskList,(pxTCB-xStateListItem))!pdFALSE){// 形参任务不能是已解除挂起等待恢复就绪态的任务if(listIS_CONTAINED_WITHIN(xPendingReadyList,(pxTCB-xEventListItem))pdFALSE){// 要求本任务的 pxTCB-xEventListItem-pxContainer NULL 才可以不能在等待事件或无限期阻塞/* Is it in the suspended list because it is in the Suspended state, or because is is blocked with no timeout? */if(listIS_CONTAINED_WITHIN(NULL,(pxTCB-xEventListItem))!pdFALSE)xReturnpdTRUE;elsemtCOVERAGE_TEST_MARKER();}elsemtCOVERAGE_TEST_MARKER();}elsemtCOVERAGE_TEST_MARKER();returnxReturn;}44从中断中恢复挂起任务 xTaskResumeFromISR源码BaseType_txTaskResumeFromISR(TaskHandle_t xTaskToResume)// tasks.c 1758{BaseType_t xYieldRequiredpdFALSE;// 本函数的返回值TCB_t*constpxTCBxTaskToResume;UBaseType_t uxSavedInterruptStatus;// 寄存器 BASEPRI 的值configASSERT(xTaskToResume);//处于 5 - 15 中断优先级之间的中断函数才可以调用这些 xxFromISR函数portASSERT_IF_INTERRUPT_PRIORITY_INVALID();// 空的宏// #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()// #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x )uxSavedInterruptStatusportSET_INTERRUPT_MASK_FROM_ISR();//设置 寄存器 BASEPRI{if(prvTaskIsTaskSuspended(pxTCB)!pdFALSE)// 这个函数在上面出现过记录过了{traceTASK_RESUME_FROM_ISR(pxTCB);if(uxSchedulerSuspended(UBaseType_t)pdFALSE)// 查看调度器是否被挂起{/* Ready lists can be accessed so move the task from the suspended list to the ready list directly. */if(pxTCB-uxPrioritypxCurrentTCB-uxPriority)// 形参优先级太高{xYieldRequiredpdTRUE;// 这是本函数的局部变量作为本函数的返回值xYieldPendingpdTRUE;// 软中断标志}elsemtCOVERAGE_TEST_MARKER();// 这里虽然也是操作了临界区资源但这是在中断函数里对于单核的 M3 CPU是不会出现数据竞争的(void)uxListRemove((pxTCB-xStateListItem));prvAddTaskToReadyList(pxTCB);// 直接插入就绪链表}else// 注意下面操作的是 pxTCB-xEventListItem 链表不再是上面的 pxTCB-xStateListItem 链表vListInsertEnd((xPendingReadyList),(pxTCB-xEventListItem));}elsemtCOVERAGE_TEST_MARKER();}portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);//宏portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x )returnxYieldRequired;}补充 pxTCB-xEventListItem 和 pxTCB-xStateListItem 这俩节点的区别上面的 函数 使用了俩操作 寄存器 BASEPRI 的宏函数调整中断屏蔽阈值。如下staticportFORCE_INLINEuint32_tulPortRaiseBASEPRI(void){//#define configMAX_SYSCALL_INTERRUPT_PRIORITY \// ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY (8 - configPRIO_BITS) )uint32_tulReturn,ulNewBASEPRIconfigMAX_SYSCALL_INTERRUPT_PRIORITY;//应该只是为了挪到高位 bit__asm{/* Set BASEPRI to the max syscall priority to effect a critical section. *//* *INDENT-OFF* */// 如此中断优先级 5 以上的全部被屏蔽了mrs ulReturn,basepri msr basepri,ulNewBASEPRI dsb isb/* *INDENT-ON* */}returnulReturn;}staticportFORCE_INLINEvoidvPortSetBASEPRI(uint32_tulBASEPRI){__asm{/* Barrier instructions are not used as this function is only used to * lower the BASEPRI value. */// 恢复原来的屏蔽优先级/* *INDENT-OFF* */msr basepri,ulBASEPRI/* *INDENT-ON* */}}45ARM 内核里的寄存器 BASEPRI、PRIMASK、FAULTMASK46谢谢

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询