Windows Embedded не нужна.

Jan 05, 2005 2 Replies

HZ> for(;;) HZ> Task1(); HZ> TaskN();



HZ> Hу, еще с if'ами и case'ами, по флажкам и условиям. Да, действительно HZ> такой HZ> "менеджер" пишется хоть и не за 5 минут, но минут за 15-20-30 (в HZ> зависимости от



HZ> обсуждать тут нечего, это не имеет ни малейшего отношения к RTOS. Hи к HZ> кооперативным, ни к вытесняющим.



О чём и говорится -- ОС не нужна. Вместо того чтобы вначале заставить исполняться N относительно независимых программ параллельно, а потом упереться в вопросы их синхронизации, приоритетности исполнения, обработки прерываний -- чем собственно ОС и занимается, в данном случае, насколько я понимаю, исключается сущность все это вопросы порождающая



-- *асинхронное* (псевдо-)параллельное исполнение программ разменивается на изначально синхронную систему конечных автоматов, входными событиями для которых являются, например, те же прерывания. А main() здесь -- единственная задача, для которой состояние "определяется счётчиком программных инструкций", как я это называю. В то время как для остальных "задач" состояние выделяется в отдельных переменных.


HZ>> for(;;) HZ>> Task1(); HZ>> TaskN();

HZ>> Hу, еще с if'ами и case'ами, по флажкам и условиям. Да, действительно HZ>> такой HZ>> "менеджер" пишется хоть и не за 5 минут, но минут за 15-20-30 (в HZ>> зависимости от

HZ>> обсуждать тут нечего, это не имеет ни малейшего отношения к RTOS. Hи к HZ>> кооперативным, ни к вытесняющим.

KF> О чём и говорится -- ОС не нужна. Вместо того чтобы вначале заставить KF> исполняться N относительно независимых программ параллельно, а потом KF> упереться в вопросы их синхронизации,

Нет там никаких вопросов, все просто и прозрачно, для этого средства в ОС имеются.

KF> приоритетности исполнения,

Тоже ничего сложного. Более того, возможность распределить код по приоритетам как раз желательна, т.к. всегда что-то требует быстрой реакции, а что-то может и подождать.

KF> обработки прерываний -- чем собственно ОС и занимается, в данном случае, KF> насколько я понимаю, исключается сущность все это вопросы порождающая -- KF> *асинхронное* (псевдо-)параллельное исполнение программ разменивается на KF> изначально синхронную систему конечных автоматов, входными событиями для KF> которых являются, например, те же прерывания.

Ага, а время реакции как тут получать? Ась? Чтобы система конечных автоматов работала хорошо и быстро, надо тактовую иметь приличную. Вот в ПЛИС подобное работает хорошо, т.к. там это, так сказать, нативно получается. А на проце будь добр выдать скорость прогона цикла такого автомата. Вот и получается, что долбает вхолостую ядро даже когда делать нечего. И еще проц надо с высокой тактовой.

В случае же с RTOS (вытесняющей) код работает по событиям. Когда нет событий, проц может вообще в спячке находиться. И со временем реакции все определено по максимуму. В отличие от.

Да, за это цена заплачена - ОЗУ надо иметь какое-то для стеков процессов, время на переключение контекста (микросекунды, обычно, какие-то) и наличие промежутков времени, когда прерывания залочены (критические секции). Но если не использовать проц в качестве программного формирователя временных диаграмм (а возложить эту функцию на более подходящие средства), а процу оставить процево - процессы метать, то все выходит стройно.

В итоге, всегда выходит так, что или критичный по времени реакции код рассован по прерываниям, или то же самое можно сделать с помощью вытесняющей RTOS. И писание проги под RTOS - занятие куда более быстрое и приятное, чем без оной.

Wed, 05 Jan 2005 06:13:21 +0300 Kirill Frolov wrote to Harry Zhurov:

KF>>> О чЯм и говорится -- ОС не нужна. Вместо того чтобы вначале заставить KF>>> исполняться N относительно независимых программ параллельно, а потом KF>>> упереться в вопросы их синхронизации, HZ>> Hет там никаких вопросов, все просто и прозрачно, для этого HZ>> средства в ОС имеются. KF> Они не для этого, они там поэтому имеются. Задача вначале порождена, а KF> потом решена. Hет ОС, нет и этих проблем.

Какая это проблема порождена? Проблема там одна (в случае вытесняющего механизма) - совместное использование ресурсов в асинхронных задачах. Ровно эта же проблема существует и безо всяких ОСей - т.е. в Foreground/Background системах, когда одни и те же ресурсы используются и в коде основной программы, и в коде прерываний! Тут ты тоже вынужден прибегать к специальным средствам - городить те же самые (по смыслу) критические секции, самодельные семафоры и прочее - и все для того, чтобы защититься от проблем из-за асинхронного доступа к ресурсам. И разница лишь в том, что в составе ОС эти средства интегрированы с ядром и помимо защиты еще участвуют в организации event-driven потока управления. Ничего искусственного, надуманного там нет.

KF>>> приоритетности исполнения, HZ>> Тоже ничего сложного. KF> Прямо как аллокатор памяти за 10 минут...

Про менеджер памяти за 10 минут - это не ко мне! Но освоить эти средства ОС - семафоры/флаги событий/мутексы/и т.д., имхо, будет куда как попроще, чем написать менеджер памяти.

KF>>> обработки прерываний -- чем собственно ОС и занимается, в данном случае, KF>>> насколько я понимаю, исключается сущность все это вопросы порождающая -- KF>>> *асинхронное* (псевдо-)параллельное исполнение программ разменивается на KF>>> изначально синхронную систему конечных автоматов, входными событиями для KF>>> которых являются, например, те же прерывания. HZ>> Ага, а время реакции как тут получать? Ась? Чтобы система конечных KF> Прерыванием. Да, я согласен, тут есть много над чем подумать. Hо такой KF> подход не только имеет право на существование, а вполне способен KF> составить конкуренцию второму варианту, с ОС внутри.

Да никто и не покушается на написание программ на голом МК! Я, в отличие от некоторых (не тебя), совершенно не утверждаю, что "без ОС никуда"! Более того, на любом МК, где ОЗУ меньше полукилобайта, реализация RTOS с вытеснением крайне затруднительна и не представляет практического интереса, т.к. все ресурсы ОЗУ на это и уйдут. Поэтому эта ниша - исключительно для писания без ОС или с использованием кооперативной ОС. Но вот когда ОЗУ уже килобайт и более, тут уже имеет смысл подумать про использование - можно сэкономить кучу сил и времени, не тратя их на достаточно тупую рутинную работу по организации кода (которая повторяется из проекта в проект). Поэтому я лишь спорю с утверждением, что "ОС в embedded не нужна" - есть случаи/варианты/условия, где она очень даже нужна (хотя всегда можно обойтись без ОСей, компиляторов, а также и ассемблеров и процессоров как таковых! Вопрос лишь: а нужно ли обходиться, если можно, воспользовавшись, решить задачу быстрее и эффективнее?).

KF> Я даже думаю, вариант предлагаемый Полянским -- одна задача в main() и KF> остальные KF> в автоматах

:) С таким же успехом можно схему включения с общим эмиттером называть "схемой Иванова" [Петрова, Сидорова] на основании того, что он (Иванов [Петров, Сидоров]) ее упоминал.

KF> -- оптимальный для небольших задач/контроллеров. В ряде случаев, при KF> изначально недетерменированном наборе задач, при наличии задач KF> преобразование алгоритма которых в форму с явно выделенным состоянием KF> затруднено (по-моему оно всегда затруднено...), такой подход оказывается KF> действительно и сложным и не рационалным. Hо отнюдь не всегда, и даже не KF> часто, Imho. И совершенно отдельный вопрос, KF> что даЯт ОС -- это интерфейс.

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

HZ>> проце будь добр выдать скорость прогона цикла такого автомата. Вот и HZ>> получается, что долбает вхолостую ядро даже когда делать нечего. И еще HZ>> проц HZ>> надо с высокой тактовой. KF> Автоматы можно запускать из отдельного более лЯгкого KF> "автомата-планировщика" по возникновению заранее установленных KF> событий/сигналов порождаемых другими автоматами, запускаемыми, например, в KF> прерывании.

Не, не понял! Вот есть фрагмент кода, который ждет прихода байта по UART'у, чтобы его (байт) обработать - вопрос: как передать ему (этому фрагменту кода) управление непосредственно по приходу байта при условии, что этот код находится не в обработчике прерываний? И чтобы промежуток времени от прихода байта в регистр-приемник порта до получения управления соответствующим кодом гарантировано не превышал какого-то значения. Я вижу тут только два пути - либо поместить этот код в обработчик прерываний, либо использовать ОС с вытеснением и поместить код в высокоприоритетный процесс. Какие тут автоматы и как они помогут - не понятно!

HZ>> В случае же с RTOS (вытесняющей) код работает по событиям. Когда нет HZ>> событий, проц может вообще в спячке находиться. KF> Аналогично.

Как все эти автоматы могут знать, что произошло событие? Только путем постоянного поллинга. И для лучшей времени реакции время поллинга должно быть как можно более коротким. Это не "аналогично", а совершенно перпендикулярный подход!

HZ>> И со временем реакции все определено по максимуму. В отличие от. KF> Совсем нет. Тут тебе и вопрос инверсии приоритетов, не решЯнный никак KF> во многих мелких RTOS, и просто похабная реализация планировщика.

Инверсия приоритетов - это отдельный вопрос. На мелких МК, где время занятости процесса соизмеримо со временем переключения приоритетов (при инверсии) и всего сопутствующего, в инверсии приоритетов смысла мало. Но и без нее можно оценить время реакции. Например, я знаю, что у меня наиболее приоритетный процесс получает управление при возникновении события, которое он ждет, не более, чем через 25-30 мкс (при 5 МГц тактовой МК). И обработка события занимает в нем не более 50 мкс. Значит при возникновении события для следующего по приоритетности процесса максимальное время реакции будет

25[30]+50+25[30] - порядка 100-110 мкс. И так далее. На практике редко надо вычислять время реакции для всех процессов - обычно интересуют пара-тройка высокоприоритетных, особенно тех, которые работают с аппаратурой - UART'ом, например, - он ведь ждать не будет.

И все это дает спокойно писать, используя, например, длительные вычисления - в нескольких проектах у меня требовалось каждые 100 мс производить пересчет параметров, который занимал порядка 22 мс. И в той же программе работает протокол обмена пакетами через UART, переключение разрядов цифрового индикатора (динамическая индикация) - надо раз в 4 мс циферку переключить, опрос клавиатуры и проч.

Так вот, затолкав это длинное вычисление в низкоприоритетный процесс, а протокол обмена, индикатор и клавиатуру в высокоприоритетные, получил, что надо. И код выглядит простым и прозрачным и в случае вычислений, где последовательно выполняется вычисление пачки полиномов в цикле, и в случае протокола обмена, где алгоритм тоже прописан линейно - послал пакет, встал на ожидание с таймаутом, если дождался ответа, идем дальше, если отвалился по таймауту, повторил в цикле несколько раз, если все разы ответа не получил, метнул сообщение процессу, выводящему на индикатор, что, дескать, внешний девайс не отвечает.

А в случае писания этого на голом МК с помощью автоматов состояний (более прежние версии этого софта были реализованы именно так, т.ч. прекрасно понимаю, о чем ты говоришь), имел гору запутанного кода - делал и с помощью switch'а, и с помощью массивов указателей на функции, и с помощью виртуальных функций, когда С++ стал доступен - это, конечно, наиболее приятный, читабельный и безопасный способ (по сути те же массивы указателей на функции, только обернуто все это в класс и за правильностью и соответствием следит компилятор). И вычисления приходилось разбивать на тучу состояний так, чтобы функция за один вызов занимала времени не более 800 мкс (иначе можно байтик с UART'а пропустить и индикатор начинал мерзко подмаргивать). Т.ч. очень хорошо представляю себе тот и другой способы написания программы - благо делал это не раз.

HZ>> Да, за это цена заплачена - ОЗУ надо иметь какое-то для стеков HZ>> процессов, KF> AT90S1200 тут выглядит особенно замечательно, вкупе с x51 клонами, PIC16 KF> и любыми контроллерами с небольшим объЯмом ОЗУ.

Тут не над чем думать - на S1200, на PIC16 вытесняющая многозадачность не реализуема (во всяком случае, я не знаю, как это можно сделать.). На первом совсем нет ОЗУ (а его надо, напомню, по моим оценкам не менее полукилобайта, иначе это баловство), а у второго конкретные проблемы с косвенной адресацией и, главное, со стеком. А вот на PIC18 уже выходит прилично, чему есть и реальные подтверждения, причем и среди работ подписчиков этой эхи.

KF> Да и отдельный вопрос -- сколько этого ОЗУ нужно для каждой задачи в KF> частности, и для системы в целом. Заранее это выяснить -- нетривиальная KF> задача.

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

30 байт, переменные какой-то задачи - 20 байт, глубина вложенности вызовов - 10+прерывание - 12 -> 12*2 = 24 байта, то 30 + 20 + 24 = 74 + запас - байт 100 уже будет достаточно. Единственное, что нужно не забывать корректировать размер стека задачи при изменении функциональности этой задачи - я наступал на эти грабли: добавил массив, а стек не изменил - сразу стало падать. Но и обнаружилось сразу при первом же анализе.

HZ>> И писание проги под RTOS - занятие куда более быстрое и приятное, чем без HZ>> оной. KF> Равно как и писание под настольный компутер куда более быстрое и KF> приятное занятие...

Ты сравниваешь несравнимое - на МК можно написать одну и ту же программу и так, и эдак, соответственно, можно более-менее объективно сравнить плюсы и минусы. А для настольного компа ты пишешь совершенно другую программу, поэтому сравнивать тут преимущества и недостатки довольно бессмысленно.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required