Во-первых, приношу свои извинения за те места, где был излишне эмоционален.
Перечитал нашу переписку и понял, что выгляжу не очень хорошо.
Еще раз извините...
Цитата(dxp @ 9.1.2012, 12:59)
Отнюдь не так проста как кажется - особенно по сравнению с альтернативным вариантом, где три строчки линейного кода и больше ничео - ни таймеров, ни счётчиков, ни автоматов (во, сколько лишних сущностей на пустом месте). И это в таком простейшем примере.
Это базовые сущности. Они будут всегда.
Вне зависимости от примера.
Причем, с увеличением технической сложности примера, структура и сущности остаются.
Цитата(dxp @ 9.1.2012, 12:59)
Что вы понимаете под скоростью? Поясните?. Скорость реакции на событие - например, timer expiration, в моём варианте будет лучше - процесс сразу получит управление по выходу из таймерного прерывания, это время предсказуемое. А как у вас это осуществляется, я так и не понял, извините. Накладные расходы в случае вытесняющей RTOS будут больше, главным образом по расходу ОЗУ на стеки процессов. Но и только. На современных копеечных МК это вообще не проблема.
В моем случае время реакции на простое событие - конец отсчета таймера - это время, необходимое МК для входа в обработчик прерывания (прерывание пипелайна и аппаратное сохранение контекста). В случае сложного события - когда этот таймер увязан еще на что-то - к этому времени добавляются простые логические операции. Все считается с точностью до такта.
Цитата(dxp @ 9.1.2012, 12:59)
Ваш код выглядит длиннее. И в целом будет длиннее, если в программе будет не один такой фрагмент. У меня же используются общие для всех частей программы механизмы RTOS. Футпринт RTOS, которую я использую составляет для MSP430 1.2K (из примера с тремя пользовательскими процессами) при 60К доступной флеши. При этом имеет полноценное приоритетное вытеснение и все плюшки в виде межпроцессного взаимодействия.
Еще раз извините, но Вы пока еще не поняли сути подхода, о котором я рассказываю. Попытаюсь объяснить.
Заодно, отвечу и на эти вопросы:
Цитата(dxp @ 9.1.2012, 12:59)
Вы описали логику работы, а я спрашивал не про это, а про то, как осуществляется передача управления. Т.е. когда таймер досчитал до нужного значения - тут нужно немедленно передать управление в основную программу - именно в тот автомат, который ждёт события. Как это осуществляется у вас? Поллингом? Или карусель в суперлупе?
Извините, если буду банален и будет много букофф.
Любую программу, выполняемую на МК, в простейшем виде можно представить как последовательность неких операторов.
В примитивной модели - это суперлуп, когда анализируя входные переменные мы выполняем или пропускаем те или иные последовательности этих самых операторов.
Попутно застревая в продолжительных участках долгоиграющего кода, в тот момент, когда надо бы выполнить что-то более существенное и важное.
Желая разорвать этот порочный круг мы можем сделать вставки в долгоиграющий код с проверками, типа, а не пришло ли время проверить такие-то и такие-то условия?
И тут возникает вопрос - как это сделать, тем более асинхронно? И желательно быстро, чтобы реакция на события была как можно более короткой.
Все решения, которые приходят в голову, кроме RTOS, которая инкапсулирует так или иначе это безобразие, выглядят кургузо и коряво.
Но на самом деле все очень просто. Если отойти в сторону от парадигмы непременной линейности кода, за которую Вы ратуете.
Каждый процесс представляется в виде автомата, иногда вырожденного, как в моем примере. И переход этого автомата из состояния в состояние осуществляется в прерываниях с действиями на переходах. Программа в этом случае может вообще не иметь суперлупа, а МК может переходить в спячку до следующего события.
Т. е. каждое событие, приписанное к данному процессу, вызывает условно мгновенную реакцию (за вычетом аппаратных издержек самого МК) этого процесса на это событие.
Вы можете законно возразить - действия на переходах могут быть очень долгими и обслуживание прерывания может затянуться.
В этом случае действие на переходе осуществляется в суперлупе. Т. е. в самом низкоприоритетном месте программы.
Которое всегда может быть прервано другими процессами, чьи события наступили в текущий момент времени.
Таким образом, процесс сам меняет приоритеты в зависимости от того, в каком состоянии он находится.
Вот более сложный пример, чтобы было понятно, о чем идет речь.
Нажмите для просмотра прикрепленного файлаЕсли пользоваться всеми возможностями современных контроллеров прерываний, то можно изменять приоритеты динамически.
Но лично я этого пока не делал. Но непременно буду - есть для чего.
При таком подходе скорость обслуживания событий максимальная и определяется в случае совпадения событий с прерыванием только аппаратными издержками МК.
Нет необходимости изучать дополнительную документацию по RTOS.
Документирование ведется на этапе проектирования.
А сами недостатки имеются и это:
Цитата(dxp @ 9.1.2012, 12:59)
Ещё один недостаток - замусоривание глобального пространства имён. Такой простой код уже добавляет прилично мусора, что же там будет твориться в действительно большой программе?
не самый главный.
Я вообще не заморачиваюсь насчет глобальных переменных.
Памяти в современных МК более, чем достаточно.
И документирование при таком подходе - вещь отработанная.
Цитата(dxp @ 9.1.2012, 12:59)
Извините, вот это (выделенное) я никак принять не могу. Драйвер - это программный код, предназначенный для абстрагирования управления аппаратурой от конкретного устройства аппаратуры. К процессам, потокам выполнения программы это не имеет ни малейшего отношения. Драйвера прекрасно живут в окружении, где может быть вообще только один поток выполнения.
Правильно. Но при работе даже одного потока пользователя, драйвера обязаны работать во всей свое совокупности. Т. е. реально имеем выполнение нескольких задач одновременно. Просто драйвера лежат ниже уровня HAL и Вы эти задачи не видите.
А когда между человеком и железом МК никого нет, то достигать нужного уровня приходится самостоятельно.
Поверьте, мне тоже неудобно смешивать низ и верх. Поэтому я и стремлюсь к их разделению.
Цитата(dxp @ 9.1.2012, 12:59)
Гуд. Изобразите ваш вариант насчёт этого полинома:
Код
float P3x(const float Coeffs[3], const float x)
{
float x2 = x*x;
return Coeffs[0]*x2*x + Coeffs[1]*x2 + Coeffs[2]*x + Coeffs[3];
}
Условия: в программе происходит обмен через UART на скорости 9600 бод (примерно 1 мс на символ), данный полином вычисляется за время порядка 5 мс (MSP430 @5MHz).
Да нет проблем.
Кусок из пресловутого терморегулятора:
Код
float t;
char i;
...
switch (ThermoType)
{
case 'R':
if(e>=-0.226&&e<1.923)
{
t=R0[10]*e;
for(i=9;i>0;i--) t=(t+R0[i])*e;
t=t+R0[0];
}
else if(e>=1.923&&e<11.361)
{
t=R1[9]*e;
for(i=8;i>0;i--) t=(t+R1[i])*e;
t=t+R1[0];
}
else if(e>=11.361&&e<19.739)
{
t=R2[5]*e;
for(i=4;i>0;i--) t=(t+R2[i])*e;
t=t+R2[0];
}
else if(e>=19.739&&e<=21.103)
{
t=R3[4]*e;
for(i=3;i>0;i--) t=(t+R3[i])*e;
t=t+R3[0];
}
break;
............
Ну и так далее для остальных типов термопар.
Здесь е - нормализованное значение термо ЭДС, ThermoType - номер типа термопары.
t - температура.
R0, R1, R2, R3 - массивы коэффициентов полиномов для каждого из диапазонов термо ЭДС для термопары типа R.
Цитата(dxp @ 9.1.2012, 12:59)
У меня в программе он именно так и реализован, я голову не грею себе...
Дык, и я тоже.
Цитата(dxp @ 9.1.2012, 12:59)
Абсолютно. Это относительно большая программа, которая выполняет кучу задач от обслуживания обмена по сериальным протоколам, взаимодействие с ПЛИС, корректировка параметров видеотракта, управление исполнительными устройствами, сбор и обработка данных от датчиков (температура приёмника, углы наклона, клавиатура), GUI и ещё много всяких более мелких задач. Не вижу причин ограничивать себя в удобстве проектирования и создании читабельного и сопровождаемого кода.
Без всяких шуток. А Вы на людях эксперименты проводили? Давали посмотреть свой код кому-нибудь еще?
Ведь читаемость и сопровождаемость - понятия относительные и очень субъективные.
Поверьте человеку, который вынужден сопровождать кучу разных девайсов, в том числе и программных.
Разница есть и существенная.
Цитата(dxp @ 9.1.2012, 12:59)
Только это не характеризует уровень его достижений в МКстроении. Не вижу причин отдавать ему предпочтение на фоне TI, ADI и других фирм.
ADI - это кто? Гугель на вскидку дает
это.
Я с Вами соглашусь, когда среды разработки будут бесплатными.
Цитата(dxp @ 9.1.2012, 12:59)
А что вы понимаете под "полновесной" средой разработки?
1. Наличие адекватного симулятора.
2. Наличие удобной IDE. Никаких make файлов (только по запросу, если сильно кому надо).
3. Наличие удобных дебуггеров.
Цитата(dxp @ 9.1.2012, 12:59)
Ну, это-то дело плёвое, не то, что осовить RTOS, общий объём сорцов которой составляет меньше сотни килобайт.
Вы меня не поняли. Среда CoDeSys в варианте TwinCat, с которой я имею дело, как простой юзер, перегружает Кернел, как в Винде, так и в Линуксе.
При этом софт-PLC на основе любого либо x-86, либо ARM работает в реал тайме.
Его жесткость можете оценить самостоятельно, если хотите - дам ссылку на первоисточник.
В моем варианте это PC от Beckhoff и их же удаленка на ProfiBus-е.
Для линии, упаковывающей по 300 пачек сигарет в минуту вполне хватает.
Цитата(dxp @ 9.1.2012, 12:59)
Пардон. Вот у меня в текущем проекте время передачи управления (т.е. при возникновении события, через сколько времени ожидающий этого события код получит управление) составляет 1.5 мкс. Это на Blackfin @200MHz. И это время детерминировано. Детерминированность именно обеспечивается используемыми простыми механизмами. Какие времена даёт венда? Как они детерминированы? Да никак. Именно этим RTOS и отличается от просто OS.
Ого! Целых 300 команд. Расточительно, однако.
Цитата(dxp @ 9.1.2012, 12:59)
Очень сильное заявление.
Наверное, чтобы разобраться в этом вопросе, нужно дать определение терминам - что такое "МК" и что такое "ОС". Тогда сразу станет ясно, на самом ли деле MK == OS.
Скажу как художник художнику. Я так вижу!
Цитата(dxp @ 9.1.2012, 12:59)
Уж не убожище ли MPLab вы хотите противопоставить?
Не такое оно и убожище. Всегда можно сделать лучше - это понятно.
С Эклипсом дело имел очень мало в варианте от ARM-KEIL.
Честно скажу, не увидел в нем ничего особо выдающегося.
Может быть я его готовить не умею?
Цитата(dxp @ 9.1.2012, 12:59)
Cortex-M - очень продуманная серия процессоров. При изучении документации постоянно ловлю себя на мысли, что люди, которые его спроектировали, прошли определённый путь, тут чувствуется школа. Вы как-то погорячились насчёт него, не разобрались. К сведению, сам по себе NVIC поддерживает до 250 уровней прерываний. Просто не во всех МК это количество реализовано, т.к. там просто не надо.
Я очень давно приглядываюсь к ARM. Может быть там все так и есть, как Вы говорите. Но у меня есть рад вопросов к архитектуре ядра и к NVIC, на которые вразумительных ответов в документации я не нашел. Качество самой документации от ARM - очень низкое. По крайней мере на Thumb2.
В отличие от...
Но это выходит за рамки применения RTOS. Если хотите, можно сделать отдельную тему - "Изучаем/Применяем ARM Cortex М".