HSEM (аппаратный семафор)
Обычный семафор в RTOS — это переменная и атомарные инструкции. В STM32H7 есть ещё и аппаратный блок семафоров HSEM: захват и освобождение выполняет сама шина, а владельца семафор помнит по номеру мастера и процесса.
Обновлено Редакция GAW
HSEM (hardware semaphore) — периферийный блок STM32H7 из 32 аппаратных семафоров. По RM0433 он служит для синхронизации процессов и обеспечивает неблокирующий атомарный захват: захват выполняет сам блок, поэтому гонки между процессами или ядрами не возникает. При захвате в один шаг проверка и захват укладываются в одно чтение по шине, при захвате в два шага — запись и проверочное чтение. Это аппаратный вариант семафора, а по смыслу — мьютекса: у захваченного семафора есть владелец.
Как устроен (RM0433, разд. 10)
- Владелец. Семафор хранит 4-битный MASTERID (номер мастера шины, например ядра) и 8-битный PROCID (номер процесса).
- Захват в два шага. Записать MASTERID и PROCID в регистр HSEM_Rx и прочитать его, чтобы убедиться, что захват удался.
- Захват в один шаг. Прочитать HSEM_RLRx: если семафор был свободен, чтение его захватывает.
- Освобождение. Только с совпадающими MASTERID и PROCID — чужой процесс семафор не сбросит. Есть общий сброс всех семафоров одного мастера.
- Прерывание при освобождении: у каждого семафора свой флаг, общая линия прерывания, регистры HSEM_IER, HSEM_ISR, HSEM_ICR.
Чем отличается от программного семафора
Программный семафор строят на атомарных операциях ядра над переменной в памяти. HSEM — отдельный блок на шине, и владельца он различает по номеру мастера, поэтому в двухъядерных STM32H745 и H747 (у них в CMSIS описаны оба ядра, Cortex-M7 и Cortex-M4) им согласуют доступ ядер к общей памяти и периферии. В одноядерном STM32H743 HSEM пригоден для синхронизации процессов на одном ядре, а прерывание по освобождению избавляет от опроса в цикле.
Типичная ошибка без такой синхронизации — состояние гонки при одновременной записи в общий буфер. Обзор семейства — на странице STM32H7.
Частые вопросы
Зачем аппаратный семафор, если семафор можно сделать программно?
Программный семафор — переменная в памяти и атомарные инструкции ядра. HSEM — отдельный блок на шине, общий для всех её мастеров: в двухъядерных STM32H745 и H747 через него согласуют работу Cortex-M7 и Cortex-M4. Кроме того, он сам выдаёт прерывание при освобождении семафора и не даёт освободить его чужому процессу.
Чем захват в один шаг отличается от захвата в два шага?
В два шага процесс записывает в регистр семафора свои MASTERID и PROCID и затем читает его, чтобы проверить, что захватил именно он. В один шаг достаточно прочитать регистр RLR: если семафор был свободен, чтение его захватывает и возвращает MASTERID. PROCID при этом равен 0, поэтому RM0433 запрещает захват в один шаг, если семафором пользуются несколько процессов одного мастера: все они увидят семафор захваченным собой.
Как узнать, что семафор освободился?
Включить прерывание этого семафора в HSEM_IER: при освобождении каждый из 32 семафоров может выставить флаг и вызвать прерывание. Это позволяет не опрашивать семафор в цикле, а ждать в режиме сна.
Источники
- STMicroelectronics. RM0433: STM32H742, STM32H743/753 and STM32H750 Value line advanced Arm-based 32-bit MCUs. Reference manual, Rev 9 — разд. 10.1: блок аппаратных семафоров — 32 регистровых 32-битных семафора для синхронизации процессов на ядре; неблокирующий атомарный захват; захват в два шага — запись MASTERID и PROCID с последующей проверкой чтением; в один шаг — чтение MASTERID из семафора; прерывание при освобождении, у каждого семафора своё; семафор освобождается, только если совпадают MASTERID и PROCID; общий сброс по MASTERID; захватить можно только свободный семафор; при захвате чтением PROCID = 0, поэтому захват в один шаг нельзя применять, если семафором пользуются несколько процессов одного мастера; разд. 10.2: 32 семафора, 8-битный PROCID, 4-битный MASTERID, одна линия прерывания, индикация захвата; разд. 10.3.1: подблоки — семафор, интерфейс доступа через HSEM_Rx и HSEM_RLRx, интерфейс прерываний HSEM_ISR, HSEM_IER, HSEM_MISR, HSEM_ICR
- STMicroelectronics. CMSIS device header stm32h743xx.h, cmsis-device-h7 v1.10.7 (GitHub, Apache-2.0) — HSEM, HSEM_R_LOCK — бит захвата, поля HSEM_R_PROCID и HSEM_R_MASTERID; заголовок stm32h745xx.h того же пакета описывает конфигурацию двух ядер, Cortex-M4 и Cortex-M7
Нашли ошибку?
Смотрите также
- Семафор (двоичный и счётный)Объект RTOS для сигнала о событиях и учёта свободных ресурсов
- Мьютекс (mutex)Объект RTOS для взаимного исключения задач при доступе к общему ресурсу
- Атомарная операцияОперация, которую прерывание не застанет наполовину
- Состояние гонкиОшибка, зависящая от момента срабатывания прерывания
- STM32H7Cortex-M7 от 280 до 600 МГц, двухъядерные H745/H747 — линейки, память, загрузка и распиновки
- Критическая секцияУчасток кода под запретом прерываний