Системы реального времени
RTOS: архитектура
1997 год. Mars Pathfinder успешно приземлился на Марс. Через несколько дней - серия загадочных перезагрузок в моменты пиковой активности. Инженеры JPL диагностируют с Земли (задержка сигнала 10 минут) и находят классический priority inversion: задача метеорологии заблокирована задачей логирования через mutex шины данных. Исправление отправлено на Марс через uplink: включить priority inheritance в VxWorks RTOS одной командой. Перезагрузки прекратились. Патчинг работающей системы на другой планете - это RTOS в production.
- **Boeing 777** управляющий компьютер: VxWorks RTOS с DO-178B сертификацией - hard deadline для flight control < 10мс, 99.9999% reliability
- **Tesla FSD** (Full Self-Driving chip): QNX RTOS для sensor fusion и decision making - automotive-grade ASIL-D safety
- **NASA Mars Rovers** (Curiosity, Perseverance): VxWorks RTOS на RAD750 radiation-hardened processor - работает с 2004 без перезагрузки
QNX и рождение commercial RTOS
QNX был создан в 1980 году для microcomputer-based real-time систем. Революционная идея: microkernel архитектура - ядро минимального размера, все сервисы как отдельные процессы. Отказ любого сервиса не роняет систему. FreeRTOS появился в 2003 как open-source альтернатива, разработан Richard Barry. К 2023 FreeRTOS используется на 40+ миллионах устройств ежегодно (AWS FreeRTOS). VxWorks (Wind River) стал стандартом для aerospace и defense - на каждой NASA миссии с 1988. POSIX-совместимые RTOS (VxWorks, QNX) позволяют переносить код между RTOS и Linux с минимальными изменениями.
RTOS Kernel
**RTOS (Real-Time Operating System)** - операционная система с детерминированными временными гарантиями. Ключевое отличие от Linux/Windows: не 'быстро' а 'предсказуемо'. RTOS гарантирует что задача высокого приоритета получит CPU в течение строго ограниченного времени (Worst-Case Execution Time, WCET). Hard real-time: нарушение deadline = отказ системы. Soft real-time: нарушение нежелательно, но терпимо.
| Характеристика | Linux | FreeRTOS / RTOS |
|---|---|---|
| Латентность прерывания | 10-100мкс (может быть выше) | < 1-10мкс, гарантированно |
| Планировщик | CFS (справедливость, throughput) | Priority preemptive (determinism) |
| Context switch | ~2-10мкс, variabel | < 1мкс, детерминированный |
| Memory allocation | malloc() может занять неизвестно сколько | Фиксированные пулы, O(1) |
| Kernel overhead | Монолитное ядро 10+ МБ | Минималистичный kernel 5-50 КБ |
| Применение | Серверы, desktop, embedded Linux | Авиация, automotive, медтехника, IoT |
**Tickless mode**: FreeRTOS может останавливать системный tick timer когда нет готовых задач - экономия энергии на IoT устройствах. Критично для battery-powered сенсоров: разница между 100мкА и 10нА тока потребления.
Система управления ABS (антиблокировочная система) должна реагировать на проскальзывание колеса за < 5мс. Какая ОС подходит?
Real-Time Scheduling
**Priority preemptive scheduling** - основной алгоритм RTOS. Задача с наивысшим приоритетом среди Ready задач всегда выполняется первой. При появлении более приоритетной задачи текущая немедленно вытесняется (preempted). Rate Monotonic Scheduling (RMS) - теоретически оптимальный алгоритм для periodic tasks: чем чаще задача - тем выше приоритет.
**Priority Inversion**: задача высокого приоритета заблокирована задачей низкого приоритета, держащей mutex. Mars Pathfinder 1997: именно priority inversion вызывало periodic reset системы. Решение: Priority Inheritance - при блокировке mutex временно повышается приоритет держателя. FreeRTOS mutex (не xSemaphore!) реализует priority inheritance.
Mars Pathfinder Priority Inversion (1997)
Low-priority задача захватила mutex шины данных. High-priority метеорологическая задача заблокирована на этом mutex. Medium-priority задача обработки изображений (без зависимости от mutex) продолжает работать и не даёт low-priority задаче отпустить mutex. Watchdog timer не видит признаков жизни от high-priority задачи → системный reset. Инженеры JPL диагностировали и исправили через uplink-команду включения priority inheritance на Марсе.
Задача H (high, prio=10) ждёт mutex, захваченный задачей L (low, prio=1). Задача M (medium, prio=5) активно работает. Без priority inheritance что произойдёт?
IPC: очереди, семафоры, мьютексы
**IPC (Inter-Process Communication)** в RTOS - механизмы безопасного обмена данными между задачами без race conditions. Три основных примитива: Queue (передача данных), Semaphore (сигнализация и счёт), Mutex (взаимное исключение с ownership). Выбор примитива зависит от семантики: что нужно передать и кто кому сигнализирует.
| Примитив | Семантика | Использовать когда |
|---|---|---|
| Queue | Передача данных, FIFO буфер | Задача → задача, ISR → задача (данные) |
| Binary Semaphore | Событие без ownership | ISR сигнализирует задаче о событии |
| Counting Semaphore | Счётчик ресурсов (0..N) | N слотов буфера, N единиц ресурса |
| Mutex | Взаимное исключение с ownership + PI | Защита shared ресурса (SPI, UART, файл) |
| Task Notification | Прямое уведомление задаче | Быстрая альтернатива semaphore (45% быстрее) |
ISR получает данные от UART и нужно передать их задаче обработки. Какой IPC примитив выбрать?
Memory Protection и MPU
**MPU (Memory Protection Unit)** - аппаратный механизм ARM Cortex-M для ограничения доступа задач к памяти. Без MPU: ошибка в одной задаче может перезаписать стек другой задачи или kernel данные - hard fault без диагностики. С MPU: неавторизованный доступ → немедленное исключение с информацией о нарушителе.
**Stack overflow detection**: FreeRTOS может заполнить стек задачи known pattern (0xA5A5A5A5) при создании и проверять при context switch (configCHECK_FOR_STACK_OVERFLOW=2). При переполнении вызывается hook vApplicationStackOverflowHook() вместо молчаливой порчи памяти. Без MPU в критических системах (IEC 61508, DO-178C) - обязателен этот механизм.
RTOS нужен только для очень быстрых систем с жёсткими deadline < 1мс
RTOS нужен для детерминизма, не только для скорости. Система с deadline 100мс но требованием 99.9999% выполнения в срок - тоже требует RTOS
Linux scheduler оптимизирован для throughput и fairness, не для worst-case latency. В Linux даже с PREEMPT_RT patch jitter может достигать 1-5мс. Для soft real-time (audio, video) Linux достаточен. Для hard real-time (automotive, medical, industrial control) - RTOS или PREEMPT_RT + careful tuning.
Задача с ошибкой записывает данные по неверному адресу в стек другой задачи. Без MPU и без stack overflow detection что произойдёт?
Ключевые идеи
- **RTOS vs Linux**: не быстрее, а детерминированнее. WCET гарантирован, jitter минимален. Kernel < 50KB, context switch < 1мкс
- **Priority preemptive scheduling**: наивысший приоритет Ready задачи всегда получает CPU. Priority Inversion решается через Priority Inheritance Mutex
- **IPC**: Queue для передачи данных, Binary Semaphore для событий из ISR, Mutex для защиты shared ресурса с PI
- **MPU**: аппаратная изоляция памяти задач. Без MPU - memory corruption без диагностики. Обязателен для safety-critical (IEC 61508)
Вопросы для размышления
- Система управления промышленным роботом: задача motion control (1мс период, критическая), задача safety monitoring (10мс, watchdog), задача UI (100мс, отображение статуса). Спроектируй приоритеты и IPC между задачами. Как предотвратить priority inversion если motion и UI используют общий SPI дисплей?