Semihosting
Иногда программе на плате нужно напечатать строку или прочитать файл, а UART ещё не настроен. Semihosting позволяет одолжить для этого возможности компьютера: программа останавливается на специальной инструкции, отладчик выполняет запрос на хосте и возвращает результат.
Обновлено Редакция GAW
Semihosting — механизм Arm, через который программа на микроконтроллере пользуется вводом-выводом компьютера: печатает в его консоль, читает и пишет файлы, узнаёт время. Спецификация Arm описывает его как набор программных инструкций, вызывающих исключение; это исключение обрабатывает агент отладки — отладчик или эмулятор, — и он же выполняет запрос на хосте.
Как выглядит вызов
| Что | На Cortex-M |
|---|---|
| Инструкция-ловушка | BKPT #0xAB (код 0xBEAB) |
| Номер операции | регистр R0 |
| Параметр | регистр R1, обычно адрес блока параметров |
| Результат | регистр R0 |
Примеры операций: SYS_WRITEC (0x03) — вывести символ, SYS_WRITE0 (0x04) — вывести строку, оканчивающуюся нулём, SYS_WRITE (0x05) и SYS_READ (0x06) — запись и чтение файла. На ядрах A- и R-профиля вместо BKPT используются SVC или HLT. Чаще всего эти вызовы делает не прикладной код, а библиотека: printf уходит в функцию записи, которая и выполняет BKPT.
Почему без отладчика — HardFault
Инструкция BKPT — это точка останова. Когда отладчик подключён, ядро останавливается, отладчик читает R0 и R1, выполняет запрос и продолжает программу. Без отладчика справочник ARMv7-M (разд. C1.5) предписывает перевести событие точки останова в HardFault, а руководство Cortex-M0 прямо называет «BKPT без подключённого отладчика» среди причин этого отказа. Прошивка, которая работала на столе, замирает при автономном запуске. Поэтому semihosting включают только в отладочной сборке.
Плюсы и минусы
- Плюсы: не нужен ни UART, ни вывод SWO; доступны файлы компьютера — удобно для модульных тестов на плате и записи логов.
- Минусы: каждый вызов останавливает ядро целиком, вместе с прерываниями; без отладчика — HardFault.
SEGGER позиционирует RTT как сочетание достоинств SWO и semihosting без остановки ядра, а ITM с SWO выводит текст тоже без остановки. Как устроена подмена функций вывода библиотеки, рассказано в статье о ретаргетинге, сравнение всех каналов — в статье о логировании и трассировке.
Частые вопросы
Почему программа с semihosting падает в HardFault без отладчика?
Потому что на Cortex-M запрос semihosting — это инструкция BKPT #0xAB. Когда отладчик подключён, он ловит остановку, выполняет запрос и продолжает программу. Без отладчика, как сказано в справочнике ARMv7-M (разд. C1.5) и руководстве Cortex-M0 (разд. 2.4), BKPT превращается в HardFault. Поэтому в релизной сборке semihosting отключают.
Почему вывод через semihosting такой медленный?
Каждый вызов останавливает ядро: отладчик замечает остановку, читает регистры и память, выполняет операцию на компьютере и запускает ядро снова. На время запроса программа полностью стоит, включая прерывания, а длительность вызова зависит от отладчика и связи с компьютером — это несопоставимо медленнее записи в буфер, как у RTT.
Какие операции доступны через semihosting?
Спецификация Arm задаёт набор операций с номерами: вывод символа SYS_WRITEC (0x03) и строки SYS_WRITE0 (0x04), открытие, чтение и запись файлов SYS_OPEN (0x01), SYS_READ (0x06), SYS_WRITE (0x05), а также запросы времени и другие. Номера 0x100–0x1FF оставлены для приложений пользователя.
Источники
- Arm. Semihosting for AArch32 and AArch64, release 2025Q4 (23 January 2026), github.com/ARM-software/abi-aa — semihosting позволяет коду на целевой системе Arm или в эмуляторе пользоваться вводом-выводом компьютера, на котором работает эмулятор или отладчик; реализован набором программных инструкций, вызывающих исключение, которое обрабатывает агент отладки; часто вызывается из библиотечных функций; инструкция-ловушка — SVC, HLT или BKPT; для M-профиля (T32) — BKPT #0xAB, код 0xBEAB; номер операции — в R0, параметр (обычно адрес блока параметров) — в R1, результат — в R0; операции SYS_WRITEC (0x03), SYS_WRITE0 (0x04), SYS_WRITE (0x05), SYS_READ (0x06)
- Arm. ARMv7-M Architecture Reference Manual, DDI 0403E.e, 2021 — разд. C1.5: если и отладка с остановкой, и монитор отладки выключены, событие точки останова (в том числе от инструкции BKPT) переводится в HardFault; BKPT в обработчике NMI или HardFault при выключенной отладке приводит к блокировке ядра (lockup)
- Arm. Cortex-M0 Devices Generic User Guide, DUI 0497A — разд. 2.4: к отказам, вызывающим HardFault, относится выполнение инструкции BKPT без подключённого отладчика
Нашли ошибку?
Смотрите также
- Логирование и трассировкаprintf через UART, ITM и SWO, SEGGER RTT, уровни журнала, метки времени
- Точка остановаАдрес, на котором отладчик останавливает выполнение программы
- HardFaultИсключение Cortex-M при необработанной ошибке
- SEGGER RTTОбмен с отладчиком через кольцевые буферы в ОЗУ, без отдельных выводов
- ITMБлок Cortex-M, который превращает записи программы в пакеты трассировки
- РетаргетингПодмена системных функций библиотеки C для вывода в UART, ITM или RTT