Что такое блокировка ядра RTOS и когда вам нужно ее использовать?

Я использую ChibiOS RTOS, и у меня есть несколько вопросов, которые могут показаться простыми, но немного ускользают от меня.

ChibiOS имеет функцию под названием:

chSysLock();

и

chSysUnlock();

Насколько я понимаю, эти две функции будут соответственно блокировать и разблокировать ядро.

Итак, мои вопросы:

  1. Что делает блокировка ядра?
  2. Почему вы хотите заблокировать ядро?

И, наконец, давайте использовать этот пример:

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

Эта функция просто сигнализирует семафору о том, какой поток его ожидает.

Итак, мой последний вопрос:

  1. Какой смысл блокировать ядро ​​только для того, чтобы сигнализировать семафору? Если я этого не сделаю, ChibiOS будет жаловаться и не будет компилироваться без системной блокировки.

person cDreamer    schedule 01.04.2018    source источник
comment
Если я этого не сделаю, ChibiOS будет жаловаться и не будет компилироваться. : Если бы он не скомпилировался, то ChibiOS не могла бы жаловаться - жаловался бы компилятор: что сообщил компилятор? Компилятор не поддерживает RTOS, поэтому не может жаловаться на семантику вызовов RTOS - утверждение не имеет смысла.   -  person Clifford    schedule 01.04.2018


Ответы (1)


Как правило, при блокировке ядра RTOS просто планировщик не будет работать, поэтому переключения контекста не произойдет. Часто некоторые или все прерывания также отключены. Блокировка используется для критических разделов — разделов кода, которые должны выполняться без прерывания или вытеснения.

Я не эксперт в ChibiOS, но в этом отношении она кажется несколько чрезмерно сложной и не очень подробно документирована. Состояния ядра описаны здесь. Он имеет два режима блокировки, и chSysLock() вызывает состояние S-Locked, где

"Ядро заблокировано, а обычные источники прерываний отключены. Включены быстрые источники прерываний. В этом состоянии можно вызывать API S-класса и I-класса."

Из документации неясно, означает ли это, что можно использовать только API I/S-класса или что I/S-mode API можно вызывать только в заблокированном состоянии. Все состояние и его цель не определены ИМО. Однако в некоторых RTOS обычно используются специальные версии функций, которые не вызывают планировщик, это избавляет обычные функции API от накладных расходов, связанных с необходимостью проверки состояния ядра или контекста прерывания, и является незначительной оптимизацией (за счет безопасности в мое мнение). Это подтверждается документацией для chBSemSignalI:

Примечание

Эта функция не перепланируется.

[...]

Класс функции:

Это API I-класса, эта функция может быть вызвана из зоны блокировки системы как потоками, так и обработчиками прерываний.

В вашем примере происходит то, что семафор задан, но планировщик не будет запущен, поэтому любой ожидающий поток не будет немедленно готов. Неясно, вызывает ли chSysUnlock() запуск планировщика — в документации сказано: «Специальная функция, к этой функции предъявляются особые требования, см. примечания.», но не указано, где эти примечания можно найти.

Я ожидаю, что планировщик запустится, и, на первый взгляд, функция sem_cb() не имеет большого смысла; однако я также ожидаю, что chSysLock()/chSysUnlock() будет вложенным, и в этом случае цель функции имеет больше смысла. Это позволяет использовать одну функцию передачи семафора (sem_cb()) независимо от состояния ядра. То есть безопасно вызывать как в обычном, так и в S-состоянии, но добавляет накладные расходы, которых призваны избежать отдельные API-интерфейсы S-состояния/нормального состояния. Лично я всегда стремился к безопасности (хотя и не обязательно реализовывал ее таким образом), по крайней мере, до тех пор, пока не было показано, что накладные расходы неприемлемы. По сути, он говорит: «_дайте семафор, и если ядро ​​​​не заблокировано, перепланируйте, в противном случае отложите перепланирование до тех пор, пока ядро ​​не будет разблокировано, то есть после последней вложенной разблокировки».

Однако он не позволяет вызывать sem_cb() из контекста прерывания, поскольку для этого потребуется chSysLockFromISR().

Вышеизложенное делает много предположений из документации и «ожидаемого» поведения RTOS. Если бы мне довелось использовать ChibOS перед лицом такой скудной документации, я бы проверил исходный код, чтобы определить точное поведение.

person Clifford    schedule 01.04.2018