任务挂起的主要工作包括:

将任务从状态列表中移除并挂接到挂起列表中

更新任务唤醒时间

如果挂起当前任务,需要请求切换

/* 挂起任务 */
void vTaskSuspend(TaskHandle_t xTaskToSuspend)
{TCB_t *pxTCB;/* 进入临界区 */taskENTER_CRITICAL();{/* 通过任务句柄获取任务TCB */pxTCB = prvGetTCBFromHandle(xTaskToSuspend);traceTASK_SUSPEND(pxTCB);/* 将任务从状态列表中移除,状态列表中没有任何任务 */if(uxListRemove(&(pxTCB->xStateListItem)) == (UBaseType_t)0){/* 检查该优先级就绪列表中是否有任务,如果没有将该优先级从当前任务优先级记录中清除 */taskRESET_READY_PRIORITY(pxTCB->uxPriority);}else{mtCOVERAGE_TEST_MARKER();}/* 任务被挂接在事件列表中 */if(listLIST_ITEM_CONTAINER(&(pxTCB->xEventListItem)) != NULL){/* 将任务从事件列表中移除 */(void)uxListRemove(&(pxTCB->xEventListItem));}else{mtCOVERAGE_TEST_MARKER();}/* 将任务挂接到挂起列表中 */vListInsertEnd(&xSuspendedTaskList, &(pxTCB->xStateListItem));#if (configUSE_TASK_NOTIFICATIONS == 1){if(pxTCB->ucNotifyState == taskWAITING_NOTIFICATION){pxTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION;}}#endif}/* 退出临界区 */taskEXIT_CRITICAL();/* 当前调度器正在运行 */if(xSchedulerRunning != pdFALSE){/* 进入临界区 */taskENTER_CRITICAL();{/* 更新下一个要解除阻塞的时间,防止该任务就是最近需要唤醒的任务 */prvResetNextTaskUnblockTime();}/* 退出临界区 */taskEXIT_CRITICAL();}else{mtCOVERAGE_TEST_MARKER();}/* 该任务为当前任务 */if(pxTCB == pxCurrentTCB){/* 调度器正在运行 */if(xSchedulerRunning != pdFALSE){configASSERT(uxSchedulerSuspended == 0);/* 请求切换任务 */portYIELD_WITHIN_API();}/* 调度器没有正在运行 */else{/* 所有任务都被挂起 */if(listCURRENT_LIST_LENGTH(&xSuspendedTaskList) == uxCurrentNumberOfTasks){/* 没有当前任务可以运行了 */pxCurrentTCB = NULL;}/* 有部分任务没有被挂起 */else{/* 任务切换上下文 */vTaskSwitchContext();}}}else{mtCOVERAGE_TEST_MARKER();}
}

解除任务挂起主要工作包括:

将任务从挂起列表重新加入就绪列表

任务优先级高于当前任务优先级,请求切换

/* 解除任务挂起 */
void vTaskResume(TaskHandle_t xTaskToResume)
{TCB_t *const pxTCB = xTaskToResume;configASSERT(xTaskToResume);/* 当前任务不能被解除挂起,因为当前任务肯定正在运行 */if((pxTCB != pxCurrentTCB) && (pxTCB != NULL)){/* 进入临界区 */taskENTER_CRITICAL();{/* 任务确实被挂起 */if(prvTaskIsTaskSuspended(pxTCB) != pdFALSE){traceTASK_RESUME(pxTCB);/* 将任务从挂起列表中移除 */(void)uxListRemove(&(pxTCB->xStateListItem));/* 将任务重新加入就绪列表 */prvAddTaskToReadyList(pxTCB);/* 任务优先级大于当前任务优先级 */if(pxTCB->uxPriority >= pxCurrentTCB->uxPriority){/* 请求切换 */taskYIELD_IF_USING_PREEMPTION();}else{mtCOVERAGE_TEST_MARKER();}}else{mtCOVERAGE_TEST_MARKER();}}taskEXIT_CRITICAL();}else{mtCOVERAGE_TEST_MARKER();}
}

带中断的任务挂起解除和不带中断的任务挂起解除之间的差别,在于任务优先级高于当前任务优先级的情况下也不可以立即请求切换任务,而是要等到下一节拍才能切换。

/* 在中断中解除任务挂起 */
BaseType_t xTaskResumeFromISR(TaskHandle_t xTaskToResume)
{BaseType_t xYieldRequired = pdFALSE;TCB_t * const pxTCB = xTaskToResume;UBaseType_t uxSavedInterruptStatus;configASSERT(xTaskToResume);portASSERT_IF_INTERRUPT_PRIORITY_INVALID();/* 进入临界区(意味着不能进入SysTick中断) */uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();{/* 任务确实被挂起 */if(prvTaskIsTaskSuspended(pxTCB) != pdFALSE){traceTASK_RESUME_FROM_ISR(pxTCB);/* 调度器没有被挂起 */if(uxSchedulerSuspended == (UBaseType_t)pdFALSE){/* 该任务优先级高于当前任务优先级 */if(pxTCB->uxPriority >= pxCurrentTCB->uxPriority){/* 在下一个节拍时进行任务切换 */xYieldRequired = pdTRUE;}else{mtCOVERAGE_TEST_MARKER();}/* 将任务从挂起列表中移除 */(void)uxListRemove(&(pxTCB->xStateListItem));/* 将任务重新加入就绪列表 */prvAddTaskToReadyList(pxTCB);}/* 调度器被挂起 */else{/* 将任务加入挂起时就绪列表 */vListInsertEnd(&(xPendingReadyList), &(pxTCB->xEventListItem));}}else{mtCOVERAGE_TEST_MARKER();}}/* 退出临界区 */portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);return xYieldRequired;
}

FreeRTOS任务挂起与解除相关推荐

  1. FreeRTOS调度器挂起与解除

    通过分析任务切换,我们知道任务切换的两种方法:系统节拍器中断.调用portYIELD产生PendSV中断. 在系统节拍器中断中,如果调度器被挂起,仅仅将调度器挂起时间加一(在解除挂起后需要补偿这些节拍 ...

  2. 任务延时、任务挂起、解除任务挂起、任务优先级获取和设置

    FreeRTOS任务控制API函数主要实现任务延时.任务挂起.解除任务挂起.任务优先级获取和设置等功能. 1.相对延时 1.1函数描述 void vTaskDelay( portTickTypexTi ...

  3. 【STM32】FreeRTOS任务挂起和恢复API

    00. 目录 文章目录 00. 目录 01. 概述 02. vTaskSuspend函数 03. vTaskResume函数 04. xTaskResumeFromISR函数 05. 预留 06. 附 ...

  4. 【STM32】FreeRTOS任务挂起和恢复示例

    00. 目录 文章目录 00. 目录 01. 概述 02. 功能描述 03. 任务设计 04. 程序设计 05. 执行结果 06. 附录 07. 参考 01. 概述 任务挂起和恢复,当某个任务要停止运 ...

  5. FreeRTOS任务挂起和恢复

    任务挂起:暂停某个任务的执行 任务恢复:让暂停的任务继续执行 通过任务挂起和恢复,可以达到让任务停止一段时间后重新运行. 相关API函数: vTaskSuspend void vTaskSuspend ...

  6. FreeRTOS源码分析与应用开发02:任务管理

    目录 1. 任务概述 1.1 任务表示 1.2 任务状态 1.2.1 运行态 1.2.2 就绪态 1.2.3 阻塞态 1.2.4 挂起态 1.3 任务优先级 1.3.1 FreeRTOS优先级配置 1 ...

  7. FreeRTOS消息队列

    全文字数9920,预计阅读时长12分钟 问题解答 曾经有人问我,FreeRTOS那么多API,到底怎么记住呢? 我想说,其实API不难记,就是有点难找,因为FreeRTOS的API很多都是带参宏,所以 ...

  8. 正点原子FreeRTOS(上)

    更多干货推荐可以去牛客网看看,他们现在的IT题库内容很丰富,属于国内做的很好的了,而且是课程+刷题+面经+求职+讨论区分享,一站式求职学习网站,最最最重要的里面的资源全部免费!!!点击进入------ ...

  9. 继续学习FreeRTOS~

    写在前面:杰杰这个月很忙~所以并没有时间更新,现在健身房闭馆装修,晚上有空就更新一下!其实在公众号没更新的这段日子,每天都有兄弟在来关注我的公众号,这让我受宠若惊,在这里谢谢大家的支持啦!!谢谢^ 在 ...

最新文章

  1. 电机控制应用中的电磁兼容性设计与测试标准
  2. python 写入网络视频文件很慢_用Python将数据写入LMDB非常慢
  3. HTMLCSS设计与构建网站 笔记HTML
  4. Python学习:numpy点乘,按元素相乘,以及转置的处理
  5. 计算机视觉CV算法分类,计算机视觉(CV)的算法有哪些,具体都有哪些特点?...
  6. Java开发中快速提升编码能力的方法有哪些?
  7. 蓝桥杯单片机DS18B20代码注释及部分时序图
  8. gets()gets_s()puts()函数的使用
  9. SAP固定资产业务配置及操作手册
  10. Spring 揭秘 12.1
  11. 幼儿园学校网站JAVA_基于jsp的幼儿园网站-JavaEE实现幼儿园网站 - java项目源码
  12. echarts官网demo
  13. ASO优化技巧:利用好App下载周期变化,aso优化技巧介绍
  14. photoshop切片的使用
  15. 徐静蕾代言“英纳格”的十大不合理
  16. 如何利用git将本地项目上传到码市、github等远程仓库
  17. funcode 音乐播放、提示及提示消失、时间显示等(c++版)
  18. mysql sql dateadd函数_SQL DATEADD函数 (sqlserver 只更新表中年份,不改其他时间)...
  19. 阿衰小冲用计算机,猫小乐:阿衰错把充电电池当成废旧电池扔进回收箱,惹怒小冲了...
  20. uedit如何连接本机linux虚拟机,实现文件交互

热门文章

  1. Linux工作笔记-解决spawn: not found与expect: not found问题(安装expect)
  2. Qt文档阅读笔记-QHeaderView::sectionResized官方解析与实例
  3. c++ public 函数名相同_C++虚函数、重载、覆盖
  4. ajax加载对应的json,jQuery:多个AJAX/JSON请求对应单个回调并行加载
  5. 11年潜心研究产品 全屋智能品牌Aqara终于要开发布会了
  6. 元气骑士如何获得机器人成就皮肤_元气骑士:9大英雄特典皮肤2技能特效优化,“颜控”玩家有福了...
  7. 红黑树的删除_红黑树
  8. vue引用electron_如何搞定跨平台桌面开发?Electron助你快速起步
  9. 计组之数据运算:11、浮点数的运算
  10. 数据结构之串:基本概念