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

Запуск RTOS поверх более приоритетного кода

Добрый день!

Делаю ответственные высоконадежные проекты на МК, и всяких многоядерных SoC, для  задач, где требуется реакция на события порядка наносекунд, и с различными процессами периодичностью мегагерцы, килогерцы и т.д.

 

Всегда пишу такие вещи baremetal, никаких ОС и стороннего софта. Только мой четко детерминирваннных код, который непосредственно и очень тесно связан с периферией. Предпочитаю практически не пользоваться никакими библиотеками, а все писать с регистрами и даташитом на конкретный камень)))) 

 

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

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

 

Есть еще один нюанс - проектов будет не один а целая серия, и в ней применяются очень разные по ресурсам вещи от МК TI TMS570 / RM47 (одноядерные МК на Cortex-R4/R5 до 200 МГц клока) и до всяких страшных многоядерных штук с ПЛИС. Но круг задач у этих проектов и подход к их созданию очень похожий, отличие по сути в объеме систем и количеству процессов. Поэтому я хочу выработать так сказать общую концепцию  и подход к софту.


Можно ее назвать хоть собственной ОС, хоть просто так сказать "крупнокусковые" кодовые стандарты. Это без разницы.

Я хочу разделить весь код грубо говоря на 3 категории.

 

1 категория. Работает с высоконадежными скоростными реал-тайм задачами, и пишется близко к периферии вместе с ассемблером. Грубо говоря допустим нужно что бы какая то часть кода выполнялась каждые 10 мкс - значит каждые 10 мкс, все остальные идут лесом, и по глобальному прерыванию этот код работает, тут уже моя задача(о не какого-нибудь планировщика), что бы это код выполнился за разумное время. К примеру он выполнился за 4 мкс. У нас осталось 6 мкс свободного времени для всех остальных процессов.

 

2 категория. Второй слой - это четко детерминированные процессы с шагом, который допускает 1 категория (по round-robin в четкое время по таймеру), всякие "условно" редкие процессы(100us - 100мс), но которые также отсосящиеся к критически важным с четким таймингом. Эта часть кода тоже полностью моя. Она соотсветственно может безопасно прерываться 1-ой категорией.  Так же она является мостом/буфером связи между 1 и 3 категорией. Т.е. процессы из 3-ей категории не имеют прямой доступ ни к периферии ни к данным процессов 1-категории.

 

3 категория. Тут уже просто валовый софт, который работает со всякими не детерминированными процессами - работа с флешкой/диском, работа с монитором, каким то долгим интерфейсом ну и  т.д.

 


Прошу прощения за столько букв)))) А теперь собственно вопрос! 
Допустим для 3-ей категории я хочу использовать какую-нибудь RTOS, да бы не писать всякие рутинные вещи, допустим даже FreeRTOS так как по ней много доков.
Насколько удобно и в принципе возможно запустить ее так сказать поверх другого более приоритетного кода?

 

Сразу оговорюсь - я не жду от RTOS работы с периферией с моим МК, периферийные дрова для работы с ней я буду сам писать, также мне не принципиально поддержка STM32, так как в обозримом будущем я не буду на них работать.
По сути мне нужен крепкий такой шедуллер, в таски которого я из своего софта 2-категории кину, например, "Запиши вот это на диск". В таске этот запрос обрабатывается и кидается запрос на API ядра RTOS который работает с файловой системой, Выход этого API подцеплен к моему драйверу, допустим SPI, который уже кинет raw поток (сформированный API) на SPI-периферию (а она уже на флешку соответственно).

 

Еще раз простите, тяжело это все описать))) если вы что то сумели понять, подскажите пожалуйста 
"Насколько удобно и в принципе возможно запустить FreeRTOS так сказать поверх другого более приоритетного кода?"

Изменено пользователем Quantum1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 minutes ago, Quantum1 said:

"Насколько удобно и в принципе возможно запустить FreeRTOS так сказать поверх другого более приоритетного кода?"

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 3/27/2024 at 5:40 PM, aaarrr said:

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

Вот! Я собственно и имел ввиду, так как не работал с RTOS до этого,  насколько безопасна для RTOS, такая штука, когда у нас есть регулярные массивные прерывания приоритнее чем RTOSовские...   Есть ли какие-то участки работы RTOS, которые опасно для нее прерывать?

про синхронизацию - да тут как раз и не страшно и понятно)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 minutes ago, Quantum1 said:

Есть ли какие-то участки работы RTOS, которые опасно для нее прерывать?

Нет: какая может быть опасность, если только не рушить данные и контекст?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если прям там реалтайм реалтаймович, то самым надежным способом будет поставить ПЛИС или SoC CPU + FPGA, на ней крутить этот самый реалтайм, а управлять CPU.

Выцеплять даже микросекунды на обычных CPU/MCU - дело бесперспективное.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если нужна прямо такая лютая риалтаймовость, то почему просто не выполнять этот код (4 мкс) прямо в обработчике прерывания?

К тому же, на фоне 200 МГц тактовой проца 10 мкс выглядят не так уж мало, а тормознутость RTOS -- понятие растяжимое. Если не обременяться сложными планировщиками, не цеплять толстые хуки на процессы переключения контекстов, то там время передачи управления вполне себе не страшное -- например, на Cortex-M4 при 168 МГц время передачи управления (не просто переключение контекстов, а именно от возникновения события до получения управления кодом потока) порядка 900 нс. Это для самого приоритетного потока.  Можно распихать этот требующий риалтайма код по приоритетным потокам (которые будут сами нагло отбирать управление у менее приоритетных, когда им надо) и не придумывать ничего.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

13 минут назад, dxp сказал:

а тормознутость RTOS -- понятие растяжимое.
например, на Cortex-M4 при 168 МГц время передачи управления (не просто переключение контекстов, а именно от возникновения события до получения управления кодом потока) порядка 900 нс.

Речь о какой RTOS?

А вот FreeRTOS вводит критические секции на свои сервисные и функции ядра, пока ходит по спискам списков и т.д. и переключение контекста вообще не показатель "быстроты" ОСРВ при оценке задержек.

На каком-нибудь ARM7 с обычными прерываниями FIQ/IRQ вход в критическую секцию запрещает все прерывания, а не только групповые, как у Cortex-M.

Так что размазывать наносекунды по таким CPU, да еще и с системой кэшей, работающими DMA с борьбой за системную шину и т.д. дело, обреченное на провал, ИМХО🙂

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 3/27/2024 at 6:04 PM, Arlleex said:

Если прям там реалтайм реалтаймович, то самым надежным способом будет поставить ПЛИС или SoC CPU + FPGA, на ней крутить этот самый реалтайм, а управлять CPU.

Выцеплять даже микросекунды на обычных CPU/MCU - дело бесперспективное.

Да вы совершенно правы, в крупных проектах, так и будет. 

Есть мелкие где ПЛИС, явно избыточен.

"""

Выцеплять даже микросекунды на обычных CPU/MCU - дело бесперспективное.

"""

Вообще без проблем. Если тайминго критические вещи писать на ассемблере(или супер прозрачном С) и запускать все это в прерываниях с таймером. То легко получается джиттер такого кода в районе 1, ну 2 тактов. А то и вообще без него.

On 3/27/2024 at 6:27 PM, dxp said:

Если нужна прямо такая лютая риалтаймовость, то почему просто не выполнять этот код (4 мкс) прямо в обработчике прерывания?

К тому же, на фоне 200 МГц тактовой проца 10 мкс выглядят не так уж мало, а тормознутость RTOS -- понятие растяжимое. Если не обременяться сложными планировщиками, не цеплять толстые хуки на процессы переключения контекстов, то там время передачи управления вполне себе не страшное -- например, на Cortex-M4 при 168 МГц время передачи управления (не просто переключение контекстов, а именно от возникновения события до получения управления кодом потока) порядка 900 нс. Это для самого приоритетного потока.  Можно распихать этот требующий риалтайма код по приоритетным потокам (которые будут сами нагло отбирать управление у менее приоритетных, когда им надо) и не придумывать ничего.

Благодарю за ответ! Насколько я понимаю логику RTOS, 1 процесс по хорошему должен выполнять 1 раз в 1 квант времени. Иначе никак не сделать четкое временное детерминирование. Теоритически можно в них сделать минимальный квант времени 10 мкс. Но! Практически это не целесообразно, так как вы правильно заметили, только вход в таск будет уже 900нс(с системным прерыванием)! плюс код, допустим 4 мкс... и далее остается 5 мкс. Я видел в статьях по FreeRTOS, что всякие функции семафоров, очередей, на по моему 180МГц(там тоже Cortex-M4 был), занимали от 5 до 25 мкс. Так что тут так не выйдет.

Изменено пользователем Quantum1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 минут назад, Quantum1 сказал:

Вообще без проблем. Если тайминго критические вещи писать на ассемблере(или супер прозрачном С) и запускать все это в прерываниях с таймером. То легко получается джиттер такого кода в районе 1, ну 2 тактов. А то и вообще без него.

Попробуйте нагрузить систему большим количеством параллельно работающих шинных мастеров: DMA, Ethernet/USB DMA, алгоритмами, активно пользующимися групповой загрузкой/сохранением LDM/STM на реализациях CPU (я про Cortex-M) без возможности рестарта их после прерываний и т.д. Никаких 1, 2 и даже 10 тактов там не будет🙂 А потом, например, кэш-контроллеру указание обновить линию или вовсе регион памяти дали. Тыщу способов подвесить процессор на неопределенное количество тактов. А если еще чтоб универсально - про ARM7 с одноранговыми прерываниями и костылями в виде программной эмуляции вложений - тоже не забыть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 3/27/2024 at 5:56 PM, aaarrr said:

Нет: какая может быть опасность, если только не рушить данные и контекст?

А вот допусти такая

On 3/27/2024 at 6:40 PM, Arlleex said:

На каком-нибудь ARM7 с обычными прерываниями FIQ/IRQ вход в критическую секцию запрещает все прерывания, а не только групповые, как у Cortex-M.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Только что, Quantum1 сказал:

А вот допусти такая

Это не рушит внутренности ОСРВ как таковой. Она как и обычно будет думать, что только она и запущена на проце и никаких прерываний вовсе нет. А они есть, и смещают идеальную временную диаграмму обработки событий и реакцкию на них.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 3/27/2024 at 7:00 PM, Arlleex said:

Попробуйте нагрузить систему большим количеством параллельно работающих шинных мастеров: DMA, Ethernet/USB DMA, алгоритмами, активно пользующимися групповой загрузкой/сохранением LDM/STM на реализациях CPU (я про Cortex-M) без возможности рестарта их после прерываний и т.д. Никаких 1, 2 и даже 10 тактов там не будет🙂

опять же без проблем ))) Допустим на том же RM47(у STM-ов тоже разделение есть, но я не помню какое) шина разделена на несколько грубо говоря секторов(кросс-мультиплексирование), на одном секторе висит одна периферия, на другом другая, на третьем DMA, на четвертой еще RAM ну и т.д. Если нет пересечения то паралельные потоки на одной шине друг друга вообще не чувствуют

К примеру

Допустим SPI в одном секторе, Таймеры в третьем, АЦП в четвертом.

Допустим у тебя проц постоянно дергает АЦП тогда пишешь так, что бы в сектор АЦП лез только CPU (но тогда конечно да остальную периферию на этом секторе ты как бы "потеряешь" для других мастеров). А DMA переносит дату с SPI в конкретную область RAM, к которой обращается CPU только в определенное время, когда гарантировано туда не лезет DMA, и в таймер. В итоге вот пример когда все работает и нет ни одного пересечения и задержек.

""""""

LDM/STM на реализациях CPU (я про Cortex-M) без возможности рестарта их после прерываний

""""""

а это как? Это ж прямая потеря данных. LDM в любом случае выполнится

Изменено пользователем Quantum1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 3/27/2024 at 7:06 PM, Arlleex said:

Это не рушит внутренности ОСРВ как таковой. Она как и обычно будет думать, что только она и запущена на проце и никаких прерываний вовсе нет. А они есть, и смещают идеальную временную диаграмму обработки событий и реакцкию на них.

А есть в FreeRTOS функционал выделения ему только конкретных прерываний? Допустим полностью запретить FIQ, и разрешить несколько IRQ конкретных(допустим от периферии). 

On 3/27/2024 at 7:06 PM, Arlleex said:

Это не рушит внутренности ОСРВ как таковой. Она как и обычно будет думать, что только она и запущена на проце и никаких прерываний вовсе нет. А они есть, и смещают идеальную временную диаграмму обработки событий и реакцкию на них.

т.е. в ее ядре нет обязательного функционала какой-нибудь сторожевой собаки?))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, Quantum1 сказал:

Вообще без проблем. Если тайминго критические вещи писать на ассемблере(или супер прозрачном С) и запускать все это в прерываниях с таймером. То легко получается джиттер такого кода в районе 1, ну 2 тактов.

Не верю! Сказки не надо рассказывать. Один вход или выход в ISR занимает уже десятки тактов (это если контекст FPU не сохраняется/восстанавливается; иначе будет ещё печальнее).
Точно такие же сказки - максимальное время активации задачи во FreeRTOS == 900нс. По причине (как уже сказали выше) - что сервисы РТОС выполняются как правило при запрещённых прерываниях.

ЗЫ: Сказочникам советую почитать описание CPU и посмотреть исходный код сервисов FreeRTOS. Для спуска с небес на землю...

2 часа назад, Arlleex сказал:

Если прям там реалтайм реалтаймович, то самым надежным способом будет поставить ПЛИС или SoC CPU + FPGA, на ней крутить этот самый реалтайм

Кроме ПЛИС можно взять МК с богатой периферией, и реализовать нужный функционал силами этой периферии.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 3/27/2024 at 8:32 PM, jcxz said:

Не верю! Сказки не надо рассказывать. Один вход или выход в ISR занимает уже десятки тактов (это если контекст FPU не сохраняется/восстанавливается; иначе будет ещё печальнее).
Точно такие же сказки - максимальное время активации задачи во FreeRTOS == 900нс. По причине (как уже сказали выше) - что сервисы РТОС выполняются как правило при запрещённых прерываниях.

ЗЫ: Сказочникам советую почитать описание CPU и посмотреть исходный код сервисов FreeRTOS. Для спуска с небес на землю...

Кроме ПЛИС можно взять МК с богатой периферией, и реализовать нужный функционал силами этой периферии.

Вам осциллограмму снять? Ну да десятки, я не спорю, Время входа по событию от периферии в FIQ с выгрузкой всех регистров в стек при 160 МГц на Cortex-R4F, у RM47 равно около 63 тактов вроде(ща уже не помню). Но это очень стабильное время, я ж говорю +-1...2 такта максимум, оно никуда не плавает, поэтому его спокойно можно точно учитывать. Но это очень много т.к. у RM47, прерывания хитрые там висит куча защит(они для промышленности и автоиндустрии) и как прерывания, так и внутренние шины медленные. На stm32 быстрее бегать должно) но насколько стабильно я уже не и помню лет 13 с ними дела уже не имел.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...