从零开始学硬件<10>demo源码OceanOS-CM0-B8解读
B8课程:信号量
上一课B7 用互斥锁保护“同一时刻只能一人用”的资源;
B8 用计数信号量管理“可同时被 N 个任务占用”的资源。信号量用一个计数值count管理“有多少份可用资源”;pend取走一份,post归还一份。
(图一)
阶段1:一口气进场100次(count: 100 → 0)
每次 pend 时 count > 0,内核直接 count-- 返回成功,不阻塞:
Enter parking OK. ← count 100→99
Enter parking OK. ← 99→98
...
Enter parking OK. ← 1→0
(图二)
阶段2:前3秒——车位空了,超时失败
count == 0,且 task1/2 还在 delay(3000),没有人 post。
main_task 每次:
- pend(500) → 挂起,最多等 500 tick(约 500ms)
- 超时返回错误 → 打印失败
- 立刻再 pend(500)……
阶段3:约t=3s——第一次离场唤醒(关键)
task1、task2 同时从 delay 醒来。此时 main_task 多半正挂在 pend 上。
以 task1 先跑为例(同优先级,顺序可能对调):
(1)task1: os_semaphore_post()
等待队列里有main_task
不把count++,而是直接唤醒main_task
触发调度
(2)main_task(优先级更高)立刻抢跑
pend成功返回
打印Enter parking OK.
再pend → count仍为0 →再次挂起
(3)回到task1
打印task1:exit.
delay(1000)
(4)task2: post →再次唤醒main → OK →再挂起
打印task2:exit.
delay(1000)
(图三)
对log可能有个疑问的,exit后为什么接着有ok?
看代码:task1和task2先执行os_semaphore_post(&g_sem),post唤醒了正在等的main_task;OK往往紧挨在对应的exit前面,是优先级抢占造成的。