通常,在 RTOS 内核锁定中,调度程序不会运行,因此不会发生上下文切换。通常也禁用一些或所有中断。锁定用于关键部分 - 必须在没有中断或抢占的情况下运行的代码部分。
我不是 ChibiOS 方面的专家,但它在这方面似乎有些过于复杂,并且没有非常全面的文档记录。这里描述了内核状态。它有两种锁定模式,并chSysLock()
调用 S-Locked 状态,其中
"内核锁定并禁用常规中断源。启用快速中断源。在此状态下可调用 S-Class 和 I-Class API。 "
从文档中不清楚这是否意味着只能使用I/S 类 API,或者I/S-mode
只能在锁定时调用 API。整个状态及其目的没有明确定义 IMO。然而,在某些 RTOS 中,具有不调用调度程序的特殊版本的函数是很常见的,这使常规 API 函数免于检查内核状态或中断上下文的开销,并且是一个小的优化(以牺牲安全性为代价)我的意见)。chBSemSignalI的文档证实了这一点:
笔记
此功能不会重新安排。
[...]
功能类:
这是一个 I-Class API,线程和中断处理程序都可以从系统锁定区域内调用此函数。
在您的示例中,发生的情况是给出了信号量,但调度程序不会运行,因此任何等待线程都不会立即准备就绪。目前尚不清楚是否chSysUnlock()
会导致调度程序运行 - 文档说“特殊功能,此功能有特殊要求,请参阅注释。 ”,但没有提供有关这些注释在哪里可以找到的线索。
我希望调度程序能够运行,从表面上看,该功能sem_cb()
似乎没有什么用处;但是我也希望chSysLock()/chSysUnlock()
是可嵌套的,在这种情况下,函数的目的更有意义。sem_cb()
无论内核状态如何,它都允许使用单个信号量函数 ( )。也就是说,在 normal 和 S-State 中调用都是安全的,但会增加单独的 S-State/Normal state API 旨在避免的开销。就我个人而言,至少在可以证明开销是不可接受的之前,我总是会寻求安全(尽管不一定以这种方式实现它)。它本质上说“_give 信号量,如果内核没有被锁定重新调度,否则推迟重新调度直到内核被解锁 - 即在最后一次嵌套解锁之后”。
但是它不允许sem_cb()
从中断上下文中调用,因为这需要chSysLockFromISR()
.
以上从文档和“预期的”RTOS 行为中做出了很多假设。如果我碰巧在面对如此少的文档时使用 ChibOS,我会检查源代码以确定确切的行为。