ucos源码阅读3——信号量,互斥信号量(未完待续)

ucos源码阅读3——信号量,互斥信号量

  • 事件控制块ECB
    • InitEventList()
    • EventWaitListInit()
    • EventTaskRdy()
    • EventTaskRdy()
  • 信号量
    • OSSemCreate()
    • OSSemDel()
    • OSSemPend()
    • OSSemPost()
    • OSSemAccept()
    • OSSemQuery()
  • 互斥信号量
    • OSMutexCreate()
    • OSMutexDel()
    • OSMutexDel()
  • 总结

事件控制块ECB

ucos源码阅读3——信号量,互斥信号量(未完待续)_第1张图片

InitEventList()

ucos源码阅读3——信号量,互斥信号量(未完待续)_第2张图片

EventWaitListInit()

等待值和表置零,条件编译代替if循环,还有被除信号量集之外的创建函数调用。
ucos源码阅读3——信号量,互斥信号量(未完待续)_第3张图片

EventTaskRdy()

取得最高优先级然后清除就绪值和表,OSTCBDly置零,为了防止时钟中断把该任务变成就绪态(时钟只是判断挂没挂起来)指向事件控制块的指针OSTCBEventPtr清零,任务控制块里还有这个,OSTCBMsg,然后TCB里状态清相应的位,如果是就绪态就修改对应就绪值和表。
ucos源码阅读3——信号量,互斥信号量(未完待续)_第4张图片

EventTaskRdy()

第一个函数:TCB关联ECB,清就绪,置等待
第二个函数:超时以后时钟把任务置为就绪,需要有个函数善后,包括清等待,更改状态位为等待,取关ECB。一个超时了之后其他的事件也没法等待了。
ucos源码阅读3——信号量,互斥信号量(未完待续)_第5张图片

信号量

OSSemCreate()

初始化计数值,指向消息或者消息队列的指针为空,置类型,调上面的基础函数。
ucos源码阅读3——信号量,互斥信号量(未完待续)_第6张图片

OSSemDel()

只有确实有等待任务的才发生任务调度
每个TCB就只能挂一个事件控制块???清了这个状态还有挂起状态所以不能进入就绪队列?
这个中断延时与等待任务数量有关
ucos源码阅读3——信号量,互斥信号量(未完待续)_第7张图片
ucos源码阅读3——信号量,互斥信号量(未完待续)_第8张图片

OSSemPend()

阻塞态IO之类的
有资源的时候不用TCB挂上ECB,如果没资源,设置状态和延迟时间,清就绪,置等待然后调度。再返回的话要看是延迟返回还是获得信号量返回,如果延迟返回,清等待状态,TCB的状态和其指向ECB的指针,否则只清指针。根据返回值判断情况。
ucos源码阅读3——信号量,互斥信号量(未完待续)_第9张图片

OSSemPost()

直接让优先级最高的任务就绪然后任务调度,如果没有就绪任务就继续往下执行
ucos源码阅读3——信号量,互斥信号量(未完待续)_第10张图片

OSSemAccept()

返回值为零,可以表示计数为零以及出错,返回值大于零就是可用资源数。
ucos源码阅读3——信号量,互斥信号量(未完待续)_第11张图片

OSSemQuery()

就定义了个新的数据结构,复制ECB的三个成员变量。
ucos源码阅读3——信号量,互斥信号量(未完待续)_第12张图片
ucos源码阅读3——信号量,互斥信号量(未完待续)_第13张图片

互斥信号量

OSMutexCreate()

需要找一个没被占用的优先级做优先级继承优先级,高八位为优先级继承优先级,低八位做正在占有任务的优先级或者空闲0xFF
ucos源码阅读3——信号量,互斥信号量(未完待续)_第14张图片

OSMutexDel()

让非挂起的等待任务恢复就绪态,如果有等待任务,就调度,之前的那个延时置零有什么用。。。这么一调用他是在关中断里面。
ucos源码阅读3——信号量,互斥信号量(未完待续)_第15张图片
ucos源码阅读3——信号量,互斥信号量(未完待续)_第16张图片

OSMutexDel()

总结

TCB的状态和ECB的类型变量每种都占一位,用或运算表示,多个类型或状态。
事件块操作和时钟中断函数息息相关
使用条件编译而不是循环语句
任务主动挂起避免高优先级一直使用
互斥量有一个优先级反转。。。
明天看完邮箱消息,邮箱消息队列,内存管理,先略掉互斥信号量和信号量组去看LwIP。。。

你可能感兴趣的:(ucos源码阅读3——信号量,互斥信号量(未完待续))