ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
29 марта
911520 Топик полностью
Связанные сообщения
Event DrivenRtosEmbedded Os
Подскажите про FreeRTOS. Можно ли её настроить на работу с вложенными прерываниями? Если что, архитектура ARM9.2022-11-07
Два вопроса за раз хочу спросить, смежные в каком-то смысле: 1) есть литература или цикл статей может, по которым можно навести ...2022-06-28
А можно немного мыслей? Несмотря на кучу существующих ОС, набирающих разную популярность, всё же появляются новые. FreeRTOS, pro...2021-10-08
[Японские RTOS T-Kernel 2.0, μT-Kernel 3.0 и много других]. Регистрируют автоматом сразу, все дают качать. Очень качестве...2021-10-08
Очевидно, что без механизма ожидания -- получается полная ерунда, которая ничем не лучше биглупа. Когда событий станет мн...2020-12-06
RTOS для этой архитектуры. Список от 2016 года, но интересно.2020-08-23
Есть мысль перейти на RTOS для снижения временных затрат на реализацию программной части, отладку и профилировку. Важна поддержк...2020-06-18
Прототреды это биг-луп вывернутый наизнанку. Или наоборот. То же самое, что конечные автоматы им. Шалыто, switch-технология. Удо...2020-06-11
Есть ли "нормальный mutex" в IAR ARM ?2020-06-09
Да, примерно об этом я и думаю. Что систему КА можно запускать параллельно, на пуле потоков, по выбирая готовые к запуску по мер...2019-10-22
Как запустить параллельную систему КА написано у Шалыто лет 20 тому назад. Впрочем и самому додуматься можно. Тема уже изъезженн...2019-10-22
Ровно наоборот. Конечные автоматы подразумевают ЯВНОЕ выделение всех возможных состояний программы (как множества состояний сист...2019-10-21
CTL (CrossWorks Tasking Library) Written in plain, portable C, Complete source code, No per-product or other runtime roy...2019-10-20
Выскажу ещё раз: FreeRTOS сырая недоделка, смысла особого, без реализации ряда перечисленного (см. ниже) не имеет и, хуже того, ...2019-10-18
"В контексте МК" никаких задач не должно быть! :) Контроллер рассчитан на обслуживание периферии, а потому никаких других событи...2019-09-20
Кооперативную не хотите попробовать? Написана на С, без ассемблера2019-09-02
Это какое-то твоё определение. И оно не выполнимо, т.к. твои же задачи будут конкурировать и оттягивать на себя процессор, как т...2018-05-18
[Список RTOSов] всяких разных -> Проект osrtos.com2017-11-15
Обновлено: трехколесный вялошипет с квадратными колесами (многозадачка на Си). Рожалось в муках, труд всей жизни :)2015-11-16
Кто-нибудь использует RTOS (не ядра) в своих проектах? Интересует их работа в защищённом режиме, взаимодействие пользовательског...2014-11-15
Давно холиваров не было. Как насчёт RTOS vs Main Loop? Поделитесь практическим опытом. Сам RTOS не применял, да и не очень хочет...2013-07-24
правильное использование RTOS - научите уму разуму2011-12-21
Вот колеблюсь, какую RTOS использовать для ARM7. Вот приглянулись TN Kernel, ScmRTOS. Советуют AMX и FreeRTOS. Кто что подскажет...2011-11-28
Нефиг си пинать за то, что он не хаскель ;)2011-08-14
Тут очень любят рассуждать о RTOS и всём таком. Но как-то массово замалчивается, что стандартная C-библиотека для неопределённог...2011-08-13
Ось для cortex-M3, в которой декларируется: "Interrupt latency is 0". В документации сказано, что критические секции организован...2009-12-08
Статья про атомарный доступ к битовым полям.2009-03-03
fk0, легенда (20.03.2019 02:13, просмотров: 902) ответил IBAH на Опять к вопросу об ОС для МК. Чтобы понять для чего нужны ОС для МК, решил
Смотря какая ОС. В основном ОС делятся по типу: бывают корпоративные ОС и любительские. Первые созданы для зарабатывания денег, а всё остальное вторично. А вторые обычно созданы с непонятными целями, just for fun. В целом вытесняющие ОС помогают уменьшить во-первых время реакции на событие (т.к. не всегда можно всё до последнего автомата развернуть, не всегда можно избавиться от блокирующих функций, наконец иногда нужно просто вытеснение как есть, например при длительных расчётах). Кроме того, ОС позволяют как-то упорядочить обработку событий. Голые автоматы без ничего не заработают, им тоже нужен какой-то планировщик, чтоб, например, те же события положить в очередь, потом поочередно вынимать их оттуда и отдавать соответствующим автоматам (примерно так работала Quantum Leaps). Если по методу Шалыто автоматы сами будут опрашивать состояния других автоматов и всё в таком духе, без планировщика, то по мере роста системы автоматов этот опрос будет занимать чудовищное время -- в этом недостаток отсутствия ОС. Возможны конечно некоторые полумеры, о которых я здесь писал (http://caxapa.ru/279767.html). Нужно ещё к проблемам вытесняющих ОС отнести, что C-библиотека должна быть готовой к такой ОС (http://caxapa.ru/266984.html) Многие embedded C-библиотеки не явпяются потокобезопасными. Т.е. использование ОС -- отказ от C-библиотеки. Странный выбор. Кооперативных ОС это не касается -- нет вытеснения, нет проблем с потокобезопасностью. Что ещё нужно сказать. В популярной литературе почему-то вводится ложная логическая посылка, мол многозадачность -- это обязательно многопоточность. Это совершенно не так! Тот же биг луп с автоматами -- вполне себе многозадачный. В нём же, в конце концов, много задач одновременно выполняется, как и, например, в кооперативной ОС. Но поток там всегда один. А многопоточность тянет за собой ряд сложных проблем, изначально плохо очевидных, наиболее значимые: 1) необходимость синхронизации потоков (и бесконечные баги связанные с дедлоками, с отсутствием синхронизации); 2) нужен большой объём оперативной памяти для стеков потоков, что тянет за собой следующий пункт; 3) ряд алгоритмов (особенно рекурсивных, обычная сортировка, обычной библиотечной функцией qsort) может вызывать исчерпание стека в неожиданном месте и в неожиданный момент времени (в зависимости от того насколько неупорядочены данные); 4) наконец эффективная реализация механизмов синхронизации возможна только на процессорах с некоторыми специальными инструкциями, а при отсутствии таковых может оказаться достаточно дорогостоящей. По пункту 4, какие инструкции процессора нужны: * ряд алгоритмов использует "атомарные" инструкции для реализации т.н. lockless алгоритмов, в основном это compare-and-swap инструкция, которой нет в "устарелых" ядрах (или в ядрах изначально не расчитанных на многозадачность); * конечно compare-and-swap может эмулироваться на обычном мьютексе, но намного менее эффективно, а для реализации самого мьютекса тоже бы неплохо иметь ту же compare-and-swap или какой-то аналог test-and-set, а без последнего реализация мьютекса воистину чудовищна настолько, что практически так никто не делает (проще сменить процессор: алгоритмы Петерсона, Деккера, Лэмпорта... мог что-то напутать, но практичность нулевая); * нужно атомарное увеличение/уменьшение счётчика с одновременным тестированием результата (fetch-and-add), старые CISC-процессоры имеют обычно инструкцию INC (reg), с косвенной адресацией и установкой флагов, а вот с RISC может быть очень сложно; * современные RISC реализуют link-load/store-conditional пару инструкций, позволяющие огородить ими участок кода и знать, если он был прерван вытеснением, что позволяет реализовать другие примитвы описанные выше; * отнесу сюда же, что нужно так же уметь находить область переменных (TLS) специфичную для текущего потока, да вообще узнать номер текущего потока, что тоже является в общем нетривиальной задачей и современные процессоры имеют для того спец. регистры, в общем случае конечно достаточно указателя стека, но там снежный ком сопутствующих проблем нарастает очень быстро, сложно без поддержки процессора; * конечно, на многих процессорах простая инструкция запрета прерываний (если доступна в соответствующем режиме!) может сделать любую последовательность команд атомарной, но это не всегда применимый способ. Ещё нужна поддержка компилятора. Как минимум компилятор должен обладать понятием "барьера памяти" и выполнять все записи в память перед барьером. Чтоб обращение к памяти могло быть упорядоченным, в том виде как расчитывает программист, а не каким попало. Здесь ситуация двоякая: с одной стороны все современные компиляторы GCC умеют, нужно лишь им объяснить это, иначе компилятор сам по себе может наломать больших дров. С другой стороны старые компиляторы могут не уметь, но и вытворять такие чудеса, на которые способен gcc они тоже обычно не спешат. Но насколько этому можно доверять? Да, volatile позволяет записать что-то в память. Но он же не говорит сделай это сейчас. А на RISC процессоре у gcc полно свободных регистров, чтоб запомнить что ты хотел записать в регистре и сделать это сильно потом, на выходе из функции (ибо вызов функции является "естесственным" барьером). И если абсолютно всё не объявить volatile, что явно не рационально или невозможно даже, то способа добиться в нужном порядке нет. Можно проблемный код выносить в отдельные функции и тогда стандарт обязывает... но не факт что компилятор реализует, если у него заявляется очень сильная оптимизация, с инлайн-включениями функций и всем таким прочим. Ведь однопоточная программа всё равно остаётся формально правильной. Конечно программа с прерываниями уже неправильная, но там шансов нарваться на проблему существенно меньше, чем в многопоточной программе. Можно ещё делать вставки на ассемблере... Что я вообще хотел сказать, многопоточное программирование не так безоблачно как его малюют, обычно оно сулит много проблем. И более того, в больших системах, где казалось бы нет проблем с памятьи, с потокобезопасной C-библиотекой, процессор имеет всю нужную поддержку, часто многопоточность применяется ограниченно, верней даже сказать не применяется. Как это выглядит. Да, может быть множество потоков в процессе, но каждый обычно выполняет изолированную задачу, с другими взаимодействует мало, это что-то очень специфичное. Основная же логика выполняется в одном единственном потоке. Типичнейший пример: любое GUI-приложение. Практически нет многопоточных GUI-фреймворков, почти все работают в одном потоке. Потому, что иначе было бы сложно сделать -- высокая связность отдельных частей GUI-приложений делает задачу синхронизации многопоточной реализации практически очень сложной. Поэтому почти все GUI-приложения являются событийно-управляемыми. Другой частый пример, что приложение в целом является многопоточным и событийно-управляемым одновременно. Событий, их обработчиков, отдельных задач реализованных через событийный механизм сильно больше чем потоков. И при этом существует очень ограниченное множество потоков, буквально несколько штук, в контексте которых выполняется "планировщик" событийного механизма. Пример: библиотека libevent. Почему так поступают: потому, что событийно-ориентированный подход, который в чём-то похож на автоматный, позволяет избавиться от необходимости синхронизации потоков в первую очередь, ограничить число самих потоков до разумной величины (и связанных с ними ресурсов, всё-таки поток в "большой" ОС может весить десятки-сотни килобайт). И наверное будущее embedded-программирования примерно в такой же системе. Когда есть ограниченный thread pool, например всего десять потоков. Из них часть выполняет совсем уж не связанные ни с чем другим задачи, но требующие, например, быстрой реакции, а часть используется совместно большим количеством (десятки-сотни-тысячи) задач реализованных в рамках событийно-ориентированной модели программирования. И имеется планировщик, который в цикле извлекает очередное событие из списка/очереди и запускает на очередном свободном потоке обработчик события, и так до исчерпания свободных потоков, потом ждёт пока какой-то поток не освободится. Разумеется обработчики событий за редкими исключениями не являются блокирующимися (да, само наличие thread pool, а не единственного потока, позволяет иногда кому-то заблокироваться на небольшое время, или выполнить длительные вычисления, и не сильно нарушить общую работу), они быстро выполняют обработку и ждут следущего события. То-есть важными компонентами для построения такой системы являются: 1) всё-таки обычная вытесняющая многозадачная ОС; 2) современный компилятор поддерживающий необходимые стандарты в полной мере; 3) потокобезопасная C-библиотека; 4) процессор имеющий вспомогательные команды и функции для многозадачных ОС; 5) специальная библитека -- планировщик, упорядочивающая каким-либо образом порядок обработки событий, организующая пул потоков, наконец обеспечивающая связь источников событий с их обработчиками, например, по принципу сигналов и слотов, наподобии того как сделано в Qt. Одного пункта 1 только не достаточно... Про планировщик наподобии того, что был сделан в Quantum Leaps, да про любой планировщик с именно очередями сразу возникает ряд неприятных вопросов. Мол в очередь событий накидают, больше чем он успевает за единицу времени обработать, и приехали. И действительно это так и даже сильно хуже. Дело в том, что в любой такой системе будет неизбежно большое число не только каких-то внешних событий (нажатие пользователем кнопок на пульте), но и внутренних, через которые разные задачи могут обмениваться между собой информацией, сообщать об изменении состояния и т.п. И возможны эффекты, вызванные архитектурой системы, когда поступление одного внешнего события (к которым можно относить, к слову, и кванты времени), может порождать долго не затухающую лавину внутренних. Это нормально, это так и должно быть, так программисты спроектировали систему. Но эта лавина может переполнить очередь планировщика, и когда ему будет некуда записать очередное событие -- работа будет фатальным образом нарушена. Кроме того есть и вторая проблема -- приоритеты. Само понятие очереди подразумевает уже, что обрабатываться события из очереди будут в порядке очереди... И малозначимые события могут опять же занять большую часть очереди. А в обычной RTOS задачи запускаются по своим приоритетам, а не по очереди возникновения событий приведших к их запуску... Ответом это может быть использование priority queue, т.е. упорядочивания событий не по времени поступления, а по приоритету связанных с событием обработчиков. Так приоритет сохраняется, но нарушается другое свойство: события будут обрабатываться не в порядке поступления. T.e. это уже не обычная очередь событий, что следует иметь ввиду. Например если пользователь вводил на клавитуре строку текста, то не следует полагаться, что буковки будут получены в том же порядке, а не в каком-то другом! Из этого можно сделать важный вывод, что такие события теперь не могут нести какую-то ассоциированную с событием информацию (код клавиши, например), а могут только быть говорить, о том, что событие произошло когда-то в прошлом, или нет. Последнее подводит нас к понятию события как атома. События, которое говорит, что оно когда-то произошло в прошлом или нет. Но не говорит о том произошло оно один раз или несколько (не может быть счётным), произошло раньше или позже относительно других событий. Атомарное событие говорит только о том, что как минимум одно событие такого типа происходило когда-то в прошлом. Больше ничего. Следует запустить обработчик события, проверить другие интересующие условия, выполнить соответствующие действия. Атомарное событие даёт ответ на проблему переполнения очереди сообщения. Если теперь события представить битовым полем, где один бит -- одно произошедшее (по меньшей мере один раз) в прошлом событие, то переполняться больше нечему. Нужные биты могут устанавливаться два, три и много раз подряд, всё равно это будет говорить только о том, что планировщик в очередной раз должен перезапустить обработчик соответствующего события, а он уже должен, если ему вообще это нужно, через другие какие-то механизмы проверить, сколько событий и с какими дополнительными свойствами произошли. Например, в случае клавиатуры, драйвер клавиатуры может коды клавиш помещать в отдельный FIFО-буфер, а обработчик оттуда их считывать. И если пользователь нажимает очень много клавиш одновременно, это не будет переводить к переполнению общей (как у Quantum Leaps) очереди сообщений и остановке всей системы, а будет максимум переполнен только буфер самой клавиатуры. И как было сказано выше, для многих типов событий на самом деле нет "проблемы переполнения" -- при очередном запуске обработчика абсолютно безразлично, сколько раз оно произошло до того как был запущен обработчик. А для тех событий где это важно, может использоваться что-то вроде отдельного FIFO-буфера как для клавиатуры, отдельный счётчик для подсчёта числа событий, или другие специфичные для самого события механизмы. Выше я описал систему, как я вижу построение относительно большой embedded системы в будущем, на bare metal, на микроконтроллере, без тяжёлых ОС типа Linux. Конечно и в Linux можно работать подобным образом, но там и другие подходы, за счёт избыточных ресурсов, оказываются вполне приемлимые. В рамках этой системы есть место типичной многозадачной ОС, но сама такая ОС является лишь механизмом для построения другой, событийно-ориентированной многозадачной системы, а не реализует многозадачность как есть, сама по себе. Потому, что многозадачная ОС -- это всего лишь механизм, строительный кирпич, деталь другого более сложного механизма, но не законченное решение сама по себе. Как законченное решение она имеет много недостатков (чрезмерное расходование памяти, сложность синхронизации потоков).
[ZX]