Перейти к содержанию

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 семафоров может выставить флаг и вызвать прерывание. Это позволяет не опрашивать семафор в цикле, а ждать в режиме сна.

Источники

  1. 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
  2. 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

Нашли ошибку?