RTOS во встроенных системах., Критерии применения. |
Здравствуйте, гость ( Вход | Регистрация )
RTOS во встроенных системах., Критерии применения. |
4.8.2010, 21:36
Сообщение
#21
|
|
сундук Группа: Пользователи Сообщений: 4043 Регистрация: 21.11.2009 Из: Ростов-на Дону Пользователь №: 15 |
1. Без гнусной фичи работы с метками, оно не на всех компилерах работает - switch не всегда превращается в таблицу переходов. Тоже геморрой. 2. Сами по себе прототреды - это уже не удивительно. Удивительно, как систему можно "прятать" в функцию idle() - обеспечивая при этом блокировку повторного вызова функций-тредов. Вот этим я и начал пользоваться в последнее время ... Как-то сложно это все... Указатели на указатели... Впрочем, мнение сугубо личное. Отличная статья про прототреды. Для тех, кто не доверяет операционным системам Опять костыли. А что? По простому не получается? |
|
|
Гость_MrYuran_* |
4.8.2010, 21:46
Сообщение
#22
|
Гости |
|
|
|
4.8.2010, 22:10
Сообщение
#23
|
|
сундук Группа: Пользователи Сообщений: 4043 Регистрация: 21.11.2009 Из: Ростов-на Дону Пользователь №: 15 |
Да уж куда проще! Препроцессорный макрос разворачивается в автомат Переносимость 100% Не люблю макросы. Особенно, когда все в одну строку. И автомат это не тот. Пример. Запись во внутренний EEPROM МК. Процесс медленный и нудный. Сама функция записи инициализирует счетчик байт, стартовый адрес EEPROM, стартовый адрес записываемого массива байт. И осуществляет старт записи первого байта, чтобы инициировать прерывание по концу записи. А все остальное выполняется в прерываниях. Когда счетчик байт становится равным 0, выставляется признак освобождения EEPROM. Прерывания прекращаются сами собой. Получается псевдоавтомат с двумя состояниями. Роль переменной состояния выполняет счетчик байт. |
|
|
5.8.2010, 7:19
Сообщение
#24
|
|
тот самый Группа: Мод Сообщений: 13629 Регистрация: 24.11.2009 Из: Харьковская обл., UA Пользователь №: 25 |
Запись во внутренний EEPROM МК. Процесс медленный и нудный. не только нудный, но и насмерть блокирующий доступ к еепрому для всех остальных параллельных процессов. Это, тсз, одна классическая бяка. Вторая - например, 1-wire, там, где надо и интервалы с точностью микросекунды выдержать, и долго курить бамбук, пока, сброс проходит. Решения получаются кривоватыми. Вложу пример. Таймер с микросекундной точностью, позволяющей оказаться в нужное время в нужном месте - вот что нужно. В постановке задачи для 1-wire не обязательно ждать точно 60 мкс - достаточно не менее 60 мкс. А вот если надо точно, и от нескольких потоков - у каждого свой запрос на "будильник"? |
|
|
Гость_MrYuran_* |
5.8.2010, 7:34
Сообщение
#25
|
Гости |
Ну и чему это противоречит?
Пишите себе в ЕЕПРОМ по прерываниям, а в это время основная система работает в штатном порядке. То же самое с прерываниями от УАРТа - кидает себе байты в буфер (или из), а по приёму (отправке) пакета выставляет эвент. В это время система также работает, как ни в чём не бывало, не подозревая, что там какие-то байты куда-то летают В постановке задачи для 1-wire не обязательно ждать точно 60 мкс - достаточно не менее 60 мкс. А вот если надо точно, и от нескольких потоков - у каждого свой запрос на "будильник"? Организовать доступ через один драйвер. То есть отдельный поток общается с 1Wire сетью, остальные - через эту прослойку. Как тут не вспомнить про операционки с ихними очередями и мутексами! |
|
|
5.8.2010, 7:51
Сообщение
#26
|
|
тот самый Группа: Мод Сообщений: 13629 Регистрация: 24.11.2009 Из: Харьковская обл., UA Пользователь №: 25 |
Ну и чему это противоречит? Пишите себе в ЕЕПРОМ по прерываниям, а в это время основная система работает в штатном порядке. А если у нее нету RWW? Тогда надо кешировать чтение, а памяти и так жалко. Цитата Организовать доступ через один драйвер. То есть отдельный поток общается с 1Wire сетью, остальные - через эту прослойку. Дык таким образом все и делается. Например, драйвер ds18b20 уже над owire.h, оформлен а-ля protothread, бегает внутри idle() Код Thread_Pure_Def(DS18B20_thread,pc) { if(pc !=NULL) goto *pc; static timer_t time; time = get_time(0); return &&Powered; Powered: if(get_time(time) < POWERUP_TIME) return pc;//power up 2 sec Sampling: OW_reset(); OW_byte_write(DS18B20_SKIP_ROM); OW_byte_write(DS18B20_READ_SCRATCHPAD); uint8_t *pos = (uint8_t *)&scratch_pad; uint8_t lrc = 0; for(uint_fast8_t j=0; j<sizeof(scratch_pad);j++) { uint8_t wrk; wrk = OW_byte_read(); *pos++ = wrk; if(j < offsetof(ds_scratchpad_t,crc)) lrc = OW_crc_update(lrc,wrk); else if(lrc != wrk) ds_state = ds_BAD_CRC; } if(ds_state == ds_OK) ambient = (int8_t)(scratch_pad.temperature >> 4); // next sample OW_reset(); OW_byte_write(DS18B20_SKIP_ROM); OW_byte_write(DS18B20_WRITE_SCRATCHPAD); for(uint_fast8_t j=0;j<3;j++) OW_byte_write(0);//default configs OW_reset(); OW_byte_write(DS18B20_SKIP_ROM); OW_byte_write(DS18B20_CONVERT_TEMP); time = get_time(0); #if(DEBUGLEVEL == 1) #define DS18b20_Sampling_Time 500 #else #define DS18b20_Sampling_Time (10*T1sec) #endif Awaiting: if(get_time(time)< DS18b20_Sampling_Time) return &&Awaiting; ds_state = ds_OK; return &&Sampling; } Типа того. Но я вообще-то о совместном использовании микросекундных таймеров, что есть трудность. Кашпировский был неправ, говоря "Ваш будильник разбудит Вас вовремя" - не получаеццо... |
|
|
Гость_MrYuran_* |
5.8.2010, 7:58
Сообщение
#27
|
Гости |
Но я вообще-то о совместном использовании микросекундных таймеров, что есть трудность. Микросекундные никак. Честно отсчитывать тайм-слот в критических местах, в это время все остальные задачи в пролёте. Даже если использовать ОСРВ (по определению, с гарантированным временем отклика), то там время реакции меньше 50мкс ставить нецелесообразно, из-за сильно возрастающих накладных расходов по времени Но даже если делать всё на прерываниях (апологетом данного подхода является Прохожий ), то всё равно джиттер в несколько мкс, а то и десятков мкс, неизбежен. Есть, конечно, накрайняк "железные" выходы защёлок таймера, но это уже вообще... Потом, в случае чего, черт ногу сломит в этих джунглях костылей... |
|
|
5.8.2010, 8:46
Сообщение
#28
|
|
тот самый Группа: Мод Сообщений: 13629 Регистрация: 24.11.2009 Из: Харьковская обл., UA Пользователь №: 25 |
Как-то сложно это все... Указатели на указатели... Впрочем, мнение сугубо личное. Если перевести на нормальный язык, то: вызов функции блокируется, если переменная, в которой хранится адрес точки входа, имеет значение, равное адресу этой самой функции. Т.е. для блокировки рекурсивного вызова надо, чтобы Код { void *temp; temp = pc; pc= &somefunc;// эта строчка безжалостно выкидывается оптимизатором. pc= somefunc(temp); } Отсюда и сложности. всё равно джиттер в несколько мкс, а то и десятков мкс, неизбежен. Самое главное - для чего? Ногами дрыгать, да тайм-стамп поставить. Других задач, извините, не вижу. У мну системные тики тикают по миллисекунде. В принципе, можно и до 10 мкс без боли разгонять, на макс. тактовой. И local continuations в гнусном варианте- тоже, знаете ли, обеспечивают время реакции довольно быстрое. Далее пример конкретно про АВР. Берем прерывание достаточно высокого приоритета, например, Int0. Настраиваем его, чтобы срабатывало по уровню и засаживаем ногу проца, чтобы запросы на прерывание шли постоянно. Получаем возможность выполнять в прерывании самый приоритетный поток. После каждой выполненной команды у нас будет прерывание. Таким образом можно и паузы микросекундные обработать. |
|
|
5.8.2010, 18:08
Сообщение
#29
|
|
сундук Группа: Пользователи Сообщений: 4043 Регистрация: 21.11.2009 Из: Ростов-на Дону Пользователь №: 15 |
Но даже если делать всё на прерываниях (апологетом данного подхода является Прохожий ), то всё равно джиттер в несколько мкс, а то и десятков мкс, неизбежен. Есть, конечно, накрайняк "железные" выходы защёлок таймера, но это уже вообще... Потом, в случае чего, черт ногу сломит в этих джунглях костылей... Какой такой джиттер? Меня лично он не волнует. Волнует всегда только одно - максимальное время реакции на событие. Оно должно быть минимально. При моем подходе - это так. Если же это не так, берется булыжник пошустрее. И опять все хорошо. А насчет ломанья ног чертом, скажу только одно. Пока у меня нет пристойного инструмента, все процессы (элементарные автоматы) у меня разбросаны по обработчикам прерываний. Пример. MODBUS/ASCII. Код ------------------------------------------------------------------------------------------------------------- | Состояние | Действие | Блок, где обрабатывается | ------------------------------------------------------------------------------------------------------------- | WaitRX | Ожидание символа ':' | Прерывание от приемника USART | ------------------------------------------------------------------------------------------------------------- | Reception | Заполнение буфера, HEX -> BIN и подсчет LRC "на лету" | Прерывание от приемника USART | ------------------------------------------------------------------------------------------------------------- | WaitEOF | Ожидание признака конца пакета 'LF'. RTS=1. | Прерывание от приемника USART | ------------------------------------------------------------------------------------------------------------- | Parse | Проверка LRC и разбор пакета и формирование ответа | Основной суперлуп | ------------------------------------------------------------------------------------------------------------- | WaitToReply | Регулируемая задержка ответа | Прерывание от системного таймера | ------------------------------------------------------------------------------------------------------------- | PreTransmit | Отсылка заголовка ':' | Прерывание от передатчика USART | ------------------------------------------------------------------------------------------------------------- | Transmit | Передача пакета. BIN -> HEX и подсчет LRC "на лету" | Прерывание от передатчика USART | ------------------------------------------------------------------------------------------------------------- | PostTransmit | LRC ->HEX и ее отправка | Прерывание от передатчика USART | ------------------------------------------------------------------------------------------------------------- | EndTransmit | Отправка хвоста CR, LF | Прерывание от передатчика USART | ------------------------------------------------------------------------------------------------------------- | EndRTS | RTS=0 | Прерывание от системного таймера | ------------------------------------------------------------------------------------------------------------- Вот. Приблизительно так. Представляете, какая каша? Но для меня проблем здесь нет. Поскольку в автоматике и PLC это - общепринятая практика. |
|
|
5.8.2010, 18:18
Сообщение
#30
|
|
тот самый Группа: Мод Сообщений: 13629 Регистрация: 24.11.2009 Из: Харьковская обл., UA Пользователь №: 25 |
Пример. MODBUS/ASCII. Это не тот пример. Проблемы со временем реакции маячат в RTU в части обнаружения конца пакета, либо в TCP/IP. К слову сказать. Угадайте, как написаны у мну софты для приводов? Правильно, вся генерация - на прерываниях, весь УАРТ - на прерываниях |
|
|
5.8.2010, 18:28
Сообщение
#31
|
|
сундук Группа: Пользователи Сообщений: 4043 Регистрация: 21.11.2009 Из: Ростов-на Дону Пользователь №: 15 |
Это не тот пример. Проблемы со временем реакции маячат в RTU в части обнаружения конца пакета, либо в TCP/IP. MODBUS/RTU делал. Работает - проблем с обнаружением конца пакета нет. Максимальная скорость 115200. Проверялось совместно с VariSpeed7 от OMRON и с различными ОВЕН-ами ПЛК 150 и ИП320. Подход аналогичный. А с Modbus over TCP/IP вообще заморачиваться не буду. Для этого есть W5100. |
|
|
Гость_MrYuran_* |
5.8.2010, 18:49
Сообщение
#32
|
Гости |
Какой такой джиттер? Меня лично он не волнует. Речь шла об 1Wire, там очень критично начало тайм-слота, по крайней мере первые 60мкс. Плюс, есть некоторые задачи. Нарпимер, управление синхронным детектором. На МСП430 я реализовывал заданные сдвиги фаз без джиттера с помощью железных выходов таймера, благо их там 7+3. Цитата Вот. Приблизительно так. Представляете, какая каша? Представляю. Ужоснах. Второй месяц перерабатываю подобное творчество к более-менее приемлемому виду. У начальника выражение лица такое, как будто его наё... Бывают, конечно, задержки при проектировании, но тут вроде бы, казалось, отлаженное изделие, его бы чуть видоизменить... Но у меня уже нервы не выдержали среди этих костылей, и я взял большой лом и начал крушить направо и налево. Проще было (как я теперь уже понимаю) написать с нуля на своём шаблоне, а оттуда вытащить нужную математику. Проблема ещё в том, что программа "нанизана" на протокол обмена. То есть автомат, управляемый извне. Это, мсм, предел маразма. Особенно учитывая, что внешняя часть не моя и там могут быть свои глюки. У меня совершенно другой подход. Блок работает автономно, а извне можно посмотреть некоторые параметры или выполнить команды. Но протокол обмена сбоку, он никак не влияет на структуру основной программы и уж тем более не является её стержнем. Проблема ещё в том (из-за чего я и стремлюсь к унификации), что поректы схожие, но у каждого своя специфика. В среднем цикл разработки 1-2 года, параллельно 3-4 проекта, причём в любых комбинациях. Нарпимер, прибегает ГК и говорит: помнишь, мол, ты нам год назад вот это делал (а я то что было вчера, уже не помню ) Так вот, надо заменить то на это, плюс приделать вот это. До конца дня. Время пошло. Вот и хочется менять только верхнюю логику, не влезая в нижние слои и уж тем более не вспоминая, где какие регистры и какой таймер подо что занят. Идеальный мэйн: { OS::Run(); } |
|
|
5.8.2010, 19:32
Сообщение
#33
|
|
сундук Группа: Пользователи Сообщений: 4043 Регистрация: 21.11.2009 Из: Ростов-на Дону Пользователь №: 15 |
Речь шла об 1Wire, там очень критично начало тайм-слота, по крайней мере первые 60мкс. Плюс, есть некоторые задачи. Нарпимер, управление синхронным детектором. На МСП430 я реализовывал заданные сдвиги фаз без джиттера с помощью железных выходов таймера, благо их там 7+3. Ну, 60 мкс при моем подходе - без проблем. А вообще 1Wire - протокол дурацкий. Поэтому и не прижился особо. Представляю. Ужоснах. Второй месяц перерабатываю подобное творчество к более-менее приемлемому виду. Это от того, что у Вас нет подобного опыта. Надо будет принести Вам программку от одной из наших машин. На PLC, который работает исключительно по событиям. В их контексте - считай прерываниям. Порядка нескольких мегабайт подобного кода. "Размазанные" автоматы - в порядке вещей. Со временем все это воспринимается вполне нормально. Проблема ещё в том, что программа "нанизана" на протокол обмена. То есть автомат, управляемый извне. Это, мсм, предел маразма. Особенно учитывая, что внешняя часть не моя и там могут быть свои глюки. А вот это уже интересно. Если можно, хотелось бы подробностей. У меня совершенно другой подход. Блок работает автономно, а извне можно посмотреть некоторые параметры или выполнить команды. Но протокол обмена сбоку, он никак не влияет на структуру основной программы и уж тем более не является её стержнем. Это совершенно нормальный подход. Сам не люблю смешивать мелкое с мягким. Но, здесь, ПМСМ, важно понять ход мыслей автора текста. Он же о чем-то думал, наверное... .... Вот и хочется менять только верхнюю логику, не влезая в нижние слои и уж тем более не вспоминая, где какие регистры и какой таймер подо что занят. В какой-то мере согласен с Вами. Но за это надо платить. 1. Изучать РТОС, продираясь через многочисленные авторские заморочки. И все равно останутся сомнения. 2. Возрастает оверхед, так или иначе. 3. Программист полностью отрывается от железа, а это плохо. Тем более, что в конце концов у меня получается тоже самое. На верхнем уровне уже ничего не смешивается. К примеру, терморегулятор. Внизу - все это безобразие, а на верху - расчет полиномов для различных термопар, взятый из C++Builder-а практически без переделок. |
|
|
5.8.2010, 19:46
Сообщение
#34
|
|
Админ с Элха Группа: Пользователи Сообщений: 735 Регистрация: 28.7.2010 Из: Москва Пользователь №: 188 |
Цитата 1. Изучать РТОС, продираясь через многочисленные авторские заморочки. И все равно останутся сомнения. Автор uC/OS-II описал свою ОС РВ со всеми заморочками, причем очень классно описал. Цитата 3. Программист полностью отрывается от железа, а это плохо. Если не заморачиваться межплатформенностью, то Вы правы. Но современная жизнь диктует иной подход: если Ваш программист создал прошивку/софт для одной платформы, Вам через некоторое время может потребоваться решение подобной проблемы на другой аппаратной платформе. Если писать софт в виде слоеного пирога так, чтобы аппаратнозависимые части были в отдельном слое, тогда жить можно. |
|
|
5.8.2010, 20:04
Сообщение
#35
|
|
сундук Группа: Пользователи Сообщений: 4043 Регистрация: 21.11.2009 Из: Ростов-на Дону Пользователь №: 15 |
Автор uC/OS-II описал свою ОС РВ со всеми заморочками, причем очень классно описал. Как бы хорошо автор не написал документацию, все равно ее надо читать с карандашом в руках, т. е. тратить свое время на "вторяк". Желательно при этом заранее освежить в памяти теоретические знания по этому вопросу, что тоже требует временных затрат. Не лучше ли вместо этого изучить поглубже новую платформу, железо, т. е. "первяк" для нашего случая. Если писать софт в виде слоеного пирога так, чтобы аппаратнозависимые части были в отдельном слое, тогда жить можно. А при моем подходе так и есть. Да и вообще, трудно себе представить, чтобы расчет вышеупомянутых полиномов, правильность которого я проверял вообще на PC, как-то пересекался с работой того же дельта-сигма АЦП, подключенного к тому же по I2C. Вопрос в другом, где проводить границу? И сколько слоев в данной селедке под шубой? Я за их минимизацию. Исходя из принципа бритвы Оккама. |
|
|
Гость_MrYuran_* |
5.8.2010, 20:08
Сообщение
#36
|
Гости |
Но современная жизнь диктует иной подход: если Ваш программист создал прошивку/софт для одной платформы, Вам через некоторое время может потребоваться решение подобной проблемы на другой аппаратной платформе. Если писать софт в виде слоеного пирога так, чтобы аппаратнозависимые части были в отдельном слое, тогда жить можно. Именно. 2 года назад ещё применяли кое-где AT89S8253, нынче кругом МСП-шки. Да и по ходу жизни одного и того же изделия плата может меняться несколько раз, а уж версия программы и подавно. Заявленный срок эксплуатации - 10 лет. В течение этого времени всё должно поддерживаться. Сейчас думаем перейти то ли на кортексы, то ли на цыгналы. Опять всё перелопачивать. Если даже раз в три года переносить все изделия на новую платформу, ни на что больше времени не останется. Однако, если менять только самый нижний уровень (HAL) и не привязываться слишком сильно к особенностям конкретного контроллера, то всё значительно упрощается. Хотел было тему поднять о корпоративном стиле программирования (назрела насущная необходимость такого документа), да пока времени нет. Там же планирую подумать насчёт платформонезависимости. Идеал - это если программу верхнего уровня можно будет перенести без изменений на ПК для создания эмулятора и технологических утилит, и обратно. |
|
|
5.8.2010, 20:13
Сообщение
#37
|
|
Админ с Элха Группа: Пользователи Сообщений: 735 Регистрация: 28.7.2010 Из: Москва Пользователь №: 188 |
Цитата Идеал - это если программу верхнего уровня можно будет перенести без изменений на ПК для создания эмулятора и технологических утилит, и обратно. Без этого не смог бы часть проектов реализовать, так как софт часто приходится делать, когда еще железа нет. |
|
|
5.8.2010, 20:49
Сообщение
#38
|
|
сундук Группа: Пользователи Сообщений: 4043 Регистрация: 21.11.2009 Из: Ростов-на Дону Пользователь №: 15 |
Сейчас думаем перейти то ли на кортексы, то ли на цыгналы. Опять всё перелопачивать. А смысл? Хотел было тему поднять о корпоративном стиле программирования (назрела насущная необходимость такого документа), да пока времени нет. Там же планирую подумать насчёт платформонезависимости. Очень интересные темы. Если желаете, можно обсудить. Идеал - это если программу верхнего уровня можно будет перенести без изменений на ПК для создания эмулятора и технологических утилит, и обратно. Тогда огребете все проблемы больших ПК. За все надо платить, к сожалению... |
|
|
5.8.2010, 20:53
Сообщение
#39
|
|
Админ с Элха Группа: Пользователи Сообщений: 735 Регистрация: 28.7.2010 Из: Москва Пользователь №: 188 |
После перехода на ARM9 + Linux мы сразу обленились, даже простые задачи, которые раньше на Сигналах (Силабс) делали, сейчас тиражируем на Арме. Тут тебе и USB Host и TCP/IP по полной программе. Дороже, да, но при многократном повторении платформы для разных задач, затраты на ее разработку вместе с частью софта давно оправдались: портированная версия АльтЛинукс и их репозиторий на 6000 пакетов. По многим задачам софт уже не пишем, а используем готовые пакеты, например для Modbus, NMEA и т.д.
|
|
|
Гость_MrYuran_* |
5.8.2010, 21:03
Сообщение
#40
|
Гости |
А смысл? Динамика сейчас очень сильная. Например, приходит снабженец и говорит: у мсп-шек f149 срок поставки внезапно стал 3 месяца. Так что готовьтесь в случае чего пересесть на f249. Их обещают за три недели. А мы их потребляем несколько сотен в месяц. Мы давай метаться, инфу качать, но потом успокоились. Там различия минимальны, а корпус вообще пин-то-пин. Но в любой момент может что угодно произойти, и надо быть к этому готовым. То экранчики не достать, то это, то другое... Ну и опять же, если переходить, то оптом, сразу везде. Чтобы закупаться большими ящиками по нормальной цене, а не у барыг втридорога. |
|
|
Текстовая версия | Сейчас: 28.3.2024, 10:33 |