【问题标题】:What is RTOS Kernel Locking and When Do You Need to Use It?什么是 RTOS 内核锁定以及何时需要使用它?
【发布时间】:2018-04-01 08:26:12
【问题描述】:

我正在使用 ChibiOS RTOS,我有一些问题可能看起来很基本,但有点逃避我。

ChibiOS 有一个函数叫做:

chSysLock();

chSysUnlock();

据我了解,这两个函数将分别锁定和解锁内核。

所以我的问题是:

  1. 锁定内核有什么作用?
  2. 为什么要锁定内核?

最后,让我们用这个例子:

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

这个函数只是为正在等待它的线程发出一个信号量。

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

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

【问题讨论】:

  • “如果我不这样做,那么 ChibiOS 会抱怨并且不会编译”。 :如果它没有编译,那么ChibiOS不可能有“抱怨”——编译器会抱怨:编译器报告了什么?编译器不支持 RTOS,因此不可能抱怨 RTOS 调用的语义——这句话毫无意义。

标签: kernel locking rtos unlock chibios


【解决方案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())。也就是说,在 normal 和 S-State 中调用都是安全的,但会增加单独的 S-State/Normal state API 旨在避免的开销。就我个人而言,至少在可以证明开销是不可接受的之前,我总是会追求安全(尽管不一定以这种方式实现它)。它本质上是说“_give 信号量,如果内核未锁定则重新调度,否则推迟重新调度直到内核解锁 - 即在最后一个嵌套 unlock 之后”。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-13
    • 2014-06-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-04
    • 2018-05-16
    • 2016-10-26
    • 1970-01-01
    相关资源
    最近更新 更多