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

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

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

chSysLock();

а также

chSysUnlock();

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

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

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

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

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

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

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

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

1 ответ

Решение

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

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

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

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

Заметка

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

[...]

Функциональный класс:

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

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

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

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

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

Другие вопросы по тегам