ucos-II 任务间同步源码分析(一)

 

ucos-II 任务间的同步主要有三个部分,信号量、互斥性信号量和事件标志组,前两者都基于事件机制完成(见ucos-II 事件控制块)。本文主要记录信号量和互斥信号量的分析。

1. 信号量SEM的主要接口函数

  • 建立一个信号量:OS_EVENT *OSSemCreate(INT16U cnt);创建一个OS_EVENT_TYPE_SEM类型的事件块,将cnt赋值给OSEventCnt,可表示共享资源的数量;
  • 删除一个信号量:OSSemDel();在删除一个信号量时需要考虑当前是否有任务因为该信号量而挂起,此时有两种删除方式,一种是OS_DEL_NO_PEND,它要求删除该信号量时没有任务因为该信号量被挂起,否则会返回错误;另外一种是OS_DEL_ALWAYS,这个时候信号量一定被删除,但删除前所有的等待任务都会被加入就绪队列,如下:

 

        case OS_DEL_ALWAYS: /* Always delete the semaphore              */
             while (pevent->OSEventGrp != 0u) {  /* Ready ALL tasks waiting for semaphore    */
                 (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_OK);
             }
  • 等待一个信号量:OSSemPend():首先判断当前的信号量是否存在(if(pevent -> OSEventCnt > 0)),如果存在则减去一个资源量返回;否则调用该函数的任务将置状态为OS_STAT_SEM,调用OS_EventTaskWait和OS_Sched后进入等待状态。
  •  发出一个信号量:OSSemPost();通过EVENT机制,选择等待该信号量的优先级最高的任务进入就绪队列并调度;信号量增加 pevent -> OSEventCnt ++;

 

2.  互斥信号量(Mutex)的主要接口函数

mutex的目的在于解决共享资源的独占处理,为了解决该共享过程中的优先级翻转问题。mutex是所有任务间同步、通信手段中唯一不采用改变任务状态(挂起),而是通过调整任务优先级的形式触发调度。

  • 建立一个mutex OS_EVENT *OSMutexCreate(INT8U prio, INT8U *err);  mutex在创建时需要赋给一个优先级,函数处理如下:删除一个mutex,OSMutexDel(),该函数的机制与OSSemDel几乎一模一样,此处不做赘述;
    • 确认该mutex的优先级是唯一的,不存在任务已经占用该优先级;否则返回错误;
    • 更新OSTCBPrioTbl相应位,表示该优先级已被占用;
    • 建立一个OS_EVNET_TYPE_MUTEX的事件;并在OSEventCnt中保存这个优先级(高8位保存优先级,低8位保存mutex有效标志);
    pevent->OSEventType    = OS_EVENT_TYPE_MUTEX;
    pevent->OSEventCnt     = (INT16U)((INT16U)prio << 8u) | OS_MUTEX_AVAILABLE; /* Resource is avail.  */
    pevent->OSEventPtr     = (void *)0;   
  • 等待一个mutex挂起:OSMutexPend(), 函数处理如下:
    • 如果当前mutex有效,即未被占用,则 1.置该mutex为无效;2.在OSEventCnt中保存当前任务的优先级;3.在mutex的OSEventPtr中保存当前任务的TCB地址;否则
    • 获取mutex的优先级,如果当前任务的优先级小与占用该mutex任务的优先级,则该任务的优先级被设置为mutex的优先级并挂起;
  • 释放一个互斥信号量 OSMutexPost(),函数处理如下:
    • 如果当前任务的优先级等于mutex的优先级(即在上次OSMutexPend时被提升了优先级),则恢复该任务原本优先级;
    • 若当前存在等待该mutex的任务则调用OS_EventTaskRdy和OS_Sched唤醒;

 例子:优先级反转的情况,低优先级占用mutex后,被中优先级抢断挂起,高优先级需要mutex则必须等待中优先级任务结束。在ucos-II 中 高优先级需要mutex时,即调用OSMutexPend时,原本占用mutex的低优先级任务会调整优先级至mutex的优先级。然后再OSMutexPost时再把优先级调整回原来的优先级。

 

       

        

posted @   Fredric_2013  阅读(2574)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示