从零开始学硬件<10>demo源码OceanOS-CM0-B8解读

📅 2026/8/3 6:51:39 👁️ 阅读次数 📝 编程学习
从零开始学硬件<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 每次:

  1. pend(500) → 挂起,最多等 500 tick(约 500ms)
  2. 超时返回错误 → 打印失败
  3. 立刻再 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?

看代码:task1task2先执行os_semaphore_post(&g_sem)post唤醒了正在等的main_taskOK往往紧挨在对应的exit前面,是优先级抢占造成的。