什么是RTOS内核锁定以及何时需要使用它?

时间:2018-04-01 08:26:13

标签: kernel locking rtos unlock chibios

我正在使用ChibiOS RTOS,我有一些看似基本的问题,但有点让我感到懊恼。

ChibiOS有一个名为:

的功能
chSysLock();

chSysUnlock();

我的理解是这两个函数将分别锁定和解锁内核。

所以我的问题是:

  1. 锁定内核有什么作用?
  2. 你为什么要锁定内核?
  3. 最后,让我们使用这个例子:

    static void sem_cb(void) {
        chSysLock();
        chBSemSignalI(&sem_1);
        chSysUnlock();
    }
    

    此函数仅用信号通知线程正在等待它的信号量。

    所以我的最后一个问题是:

    1. 锁定内核只是为了发出信号量的信号是什么意思?如果我不这样做,那么ChibiOS会抱怨并且在没有系统锁定的情况下不会编译。

1 个答案:

答案 0 :(得分:1)

通常在RTOS内核锁定中,调度程序不会运行,因此不会发生上下文切换。通常也会禁用部分或全部中断。锁定用于关键部分 - 必须在不中断或抢占的情况下运行的代码段。

我不是ChibiOS的专家,但在这方面似乎有点过于复杂,并没有非常全面的记录。内核状态描述为here。它有两种锁定模式,chSysLock()调用S-Locked状态,其中

  

禁用内核锁定和常规中断源。启用快速中断源。在此状态下可以调用S-Class和I-Class API。

从文档中不清楚这是否意味着可以使用 I / S-Class API,或者只能在锁定时调用I/S-mode API。整个国家及其目的没有明确定义IMO。然而,在某些RTOS中,通常会有不调用调度程序的特殊版本的函数,这样可以节省常规API函数,从而不必检查内核状态或中断上下文,这是一个小的优化(以安全为代价)我的看法)。 chBSemSignalI的文档证实了这一点:

  

注意

     

此功能不会重新安排。

     

<强> [...]

     

功能类:

     

这是一个I-Class API,   可以通过两者在系统锁定区域内调用此函数   线程和中断处理程序。

在您的示例中,正在发生的是信号量,但调度程序将不会运行,因此任何等待的线程都不会立即就绪。目前尚不清楚chSysUnlock()是否导致调度程序运行 - 文档说“特殊功能,此功能有特殊要求请参阅注释。”,但不清楚这些注释可能在何处被发现。

我希望调度程序能够运行,从表面上看,函数sem_cb()似乎没什么用处;但是我也希望chSysLock()/chSysUnlock()可以嵌套,在这种情况下,函数的目的更有意义。它允许使用单个信号量给定函数(sem_cb()),而不管内核状态如何。也就是说,在正常和S状态下调用是安全的,但增加了单独的S状态/正常状态API旨在避免的开销。就个人而言,我总是寻求安全(尽管不一定以这种方式实施)至少直到可以证明开销是不可接受的。它本质上说“_give信号量,如果内核没有锁定重新安排,否则推迟重新安排直到内核解锁 - 即在最后一次嵌套解锁之后”。

但是不允许从中断上下文中调用sem_cb(),因为这需要chSysLockFromISR()

以上内容从文档和“预期的”RTOS行为中做出了很多假设。如果我碰巧在面对如此缺乏的文档时使用ChibOS,我会检查源代码以确定确切的行为。