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

Организация программ

Все это выглядит ужасно в бесконечном цикле.

 

Подскажите, как сделать грамотно.

Не знаю, грамотно или нет, но все, что вы описали, а меня в главном цикле выглядит как

ProcessADC(&adc);

где реализован конечный автомат, работающий с АЦП и привязанный к конкретной структуре с набором параметров.

Естественно, никаких заднржек, ожиданий и тд. - атомарное действие и возврат

 

глобально объявляется структура adc (или несколько, если многоканальная система), а буфера и прочую требуху можно (нужно) вынести в отдельный модуль и объявить static, чтобы не лазить туда грязными ручками (и ножками)

 

буфера тоже в виде структур с необходимыми параметрами (включая указатели на обработчики). и вообще все это плавно приводит к необходимости перехода на с++, т.к.там это все реализуется естественным образом без ручных костылей.

 

а мэйн будет выглядеть так:

Init();
while(1){
  ClearWDT();
  ProcessADC(&adc);
  ProcessData(&data);
  Poll(&interface);
  ProcessComand(&interface);
}

можно, конечно, сделать из батона троллейбус примотать сюда РТОС, но зачем?

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


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

Не знаю, грамотно или нет, но все, что вы описали, а меня в главном цикле выглядит как

ProcessADC(&adc);

 

а мэйн будет выглядеть так:

Init();
while(1){
  ClearWDT();
  ProcessADC(&adc);
  ProcessData(&data);
  Poll(&interface);
  ProcessComand(&interface);
}

можно, конечно, сделать из батона троллейбус примотать сюда РТОС, но зачем?

тогда вы должны быть уверены, что время выполнения

Poll(&interface);

и

ProcessComand(&interface);

детерминировано. Иначе возможны пропуски данных от ацп.

 

можно, конечно, сделать из батона троллейбус примотать сюда РТОС, но зачем?

РТОС нужна для выставления приоритета задач. У вас бы ProcessADC(&adc) имел наивысший приоритет. Наверное, с РТОС проще работать, если задач становится с десяток или больше... :rolleyes:

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


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

Наверное, с РТОС проще работать, если задач становится с десяток или больше... :rolleyes:

Скорее, если над проектом работает десяток взаимозаменяемых студентов и нет времени каждому объяснять, что почем.

Каждый пишет свой линейный кусочек, как учили в школе.

 

Как удачно однажды кто-то брякнул, снижается порок вхождения :)

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


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

Скорее, если над проектом работает десяток взаимозаменяемых студентов и нет времени каждому объяснять, что почем.

Каждый пишет свой линейный кусочек, как учили в школе.

 

Как удачно однажды кто-то брякнул, снижается порок вхождения :)

Далеко не только студенты пишут с использованием ртос. С ртос программу гараздо проще модифицировать. Хотя конечно если человек работает и хочет быть уверен что его не уволят так как исходный код прошивок может читать только он - тогда наверное лучше не использовать ртос.

 

Здесь в начале темы кто-то ссылку давал на статью хабра. Там хорошо описано требование использовать ртос.

Я видел программы где нужно было синхронизировать до 100 различных событий. Это все надо как- то синхронизировать. Зачем изобретать свой велосипед? Программа была написана на dsp/bios.

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


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

Скорее, если над проектом работает десяток взаимозаменяемых студентов и нет времени каждому объяснять, что почем.

Каждый пишет свой линейный кусочек, как учили в школе.

Ну-ну...

Очевидно, что вы пишете только простые программы.

Представьте, что в вашей ProcessData() возможны моменты времени, когда требуется ей потратить много тактов CPU (например - прогнать данные через тяжёлый фильтр), а в ProcessADC() - необходима быстрая реакция на какие-то события (и нельзя вынести в ISR). Что будете делать в вашем суперцикле?

Другой случай:

Требуется энергосбережение и программа большую часть времени спит, просыпаясь только для обработки событий. Событий много, события составляют последовательность событий (событие1, за ним сбытие2, событие3, и т.п - это всё цепочка последовательных событий для одной задачи; у других задач - свои цепочки событий). Как будете обрабатывать их вашим суперциклом? При любом событии будете проходить весь цикл, все автоматы состояний для каждой из цепочек? В случае РТОС будет разбужена только одна задача, которая отвечает за обработку данного события (одной цепочки), которая восстановит контекст в точку обработки событияN цепочки M, обработает его, контекст сохранится в новой точке программы и CPU опять уйдёт в сон.

 

Суперцикл годен только для сравнительно простых программ. Скорее программок.

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

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

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


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

Очевидно, что вы пишете только простые программы.

Может хватит со своими очевидно? Были тут такие уже...

Представьте...

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

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


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

. . . .

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

 

Я конечно извиняюсь, что влез, но действительно не все очевидно.

То, с чем долбусь я. Есть 2 реализации проекта - на цикле на на RTOS (scmRTOS, freeRTOS)

Блок работы с внешней флеш-памятью. После подачи команды на флеш (запись, стирание) флеш работает асинхронно.

И таймауты на эту работу не детерменированы. При реализации на ОС код намного читабельнее и логичнее чем на цикле

(в цикле приходится работать с флагами и прокручивать основной цикла на время ожидания )

 

В ОС

. . . .

while( !CompleteFlash() ) Sleep(100);

. . . .

 

Как альтернатива - использовать ОС в кооперативном режиме (в freeRTOS - coroutine)

 

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


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

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

Посчитали и оказалось, что в одной из веток алгоритма иногда надо выполнить тяжёлый фильтр (когда накопится достаточное кол-во сэмплов), а в другой - БПФ, тоже иногда. При этом в другой функции надо быстро реагировать на какие-то события, время этой реакции - должно быть много меньше времени выполнения фильтра или БПФ.

Ваши действия? Что будете делать с вашим "легко просчитанным временем"?? :laughing:

С РТОС я БПФ и фильтр легко вынесу в низкоприоритетную задачу и решу проблему. А что делать с суперциклом?

 

И таймауты на эту работу не детерменированы. При реализации на ОС код намного читабельнее и логичнее чем на цикле

(в цикле приходится работать с флагами и прокручивать основной цикла на время ожидания )

Это понятно. Вот для таких случаев как раз удобно использовать ОС.

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

Зато можно разбить процессы по приоритетам на более и менее важные.

 

Как альтернатива - использовать ОС в кооперативном режиме (в freeRTOS - coroutine)

Это усложнит код программы. Вам придётся каждую функцию приспосабливать под вашу ОС, просчитывать время её выполнения и пр. Но зачем? Мартышкин труд. Если можно использовать вытесняющую ОС. Другое дело - когда не хаватает ресурсов (памяти например для стеков задач), тогда можно объединить некоторые операции в пределах одной задачи вытесняющей ОС.

Я нередко делаю так (чтобы сократить объём необходимой памяти под стеки задач): объединяю несколько (2-3) процессов с примерно одним временем реакции и временем выполнения в один суперцикл и помещаю его внутрь одной задачи вытесняющей ОС. Процессы с другим временем выполнения (и с другой требуемой скоростью реакции на события) - в другую задачу, с другим приоритетом.

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


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

. . .

Это усложнит код программы. Вам придётся каждую функцию приспосабливать под вашу ОС, просчитывать время её выполнения и пр. Но зачем? Мартышкин труд. Если можно использовать вытесняющую ОС. Другое дело - когда не хаватает ресурсов (памяти например для стеков задач), тогда можно объединить некоторые операции в пределах одной задачи вытесняющей ОС.

. . .

В моем случае приходится извращаться, так как в максимальном приоритете - экономичность (батарейное питание).

А вытесняющая OC подразумевает тики для планировщика. В нашей реализации тикало с периодом 16 мс - очень

не экономично. Можно конечно переключать этот период (на 250мс) для неактивно-рабочего режима (без оператора).

В общем, эта тема у меня недостаточно раскурена.

 

 

 

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


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

Здесь в начале темы кто-то ссылку давал на статью хабра. Там хорошо описано требование использовать ртос.

В какой статье какого кодекса значится описанное в статье требование?

На ту статью был дан адекватный ответ другой статьей. (Альтернативный подход к проектированию ПО для Embedded)

 

 

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


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

В моем случае приходится извращаться, так как в максимальном приоритете - экономичность (батарейное питание).

А вытесняющая OC подразумевает тики для планировщика.

Не обязательно.

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

Я так делал в одном батарейном проекте с uCOS. Делал надстройку над функциями ОС - каждая задача вызывающая объект с синхронизации с таймаутом или просто уходящая в IDLE на N тиков, сообщала при этом вызове минимально- и максимально-возможное время этого IDLE-состояния которое ей требуется. Это всё запоминалось и когда шедулер обнаруживал момент простоя всей системы, он анализировал эти времена и выбирал оптимальное время сна, так чтобы максимально оптимально уложиться в интервалы требований для разных задач (не превышая максимально-допустимый сон для каждой задачи и стараясь максимально увеличить время сна).

Если полученное значение интервала сна получалось менее какого-то порога, то просто выполнялась WFE, если более - выполнялся вход в глубокий сон (вход и выход в который естественно дольше).

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


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

Не обязательно.

....

Спасибо за инф. по варианту решения.

 

 

 

 

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


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

Добрый день, для своих программ использовал Switch подход, но до пары до времени...

Понадобилась спортировать свою программу на другую плату, а там почти вся периферия сидит на I2C

а это 2 термодатчика, календарь, расширитель порта->(Светодиоды,Кнопки и LCD). И все это должно работать

и отрабатывать замыкания линий и тд, и в случае если отвалится термодатчик то LСD Должен работать.

Сначала пошёл городить Switch на это все, но получилось как-то запутано, и ешё не нравилось, что

есть куча проходов функций, пока там до LCD дойдет. Ну и соответственно с обработкой аварии были проблемы.

Так что сейчас решил написать свою ОС, с минимальными возможностями сохранения и переключения контента,

и во всех задержках(ожидания флага или времени LCD) поставить переключение на другие задачи.

Сделал пару процессов, и теперь думаю над тем как разделить опрос медленных процессов(Термодатчика) от быстрых(опрос клавиатуры(матричной)).

 

Но все же интересно, если другие способы это все организовать?

 

А и еше как можно ОС протестировать и погонять, что она не разваливается?

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


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

. . .

Но все же интересно, если другие способы это все организовать?

А и еше как можно ОС протестировать и погонять, что она не разваливается?

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

переключать контекст не надо. "Планировщик" делаете на таймере и CCR - разбиваю период главного цикла на нужное кол-во фаз

с детерминированным времением исполнения каждой. Ожидание и приоритеты реализуются "прокруткой" главного цикла, софт-таймерами и флагами.

Мне на форуме посоветовали protothreads - тотже "упакованный" while - switch-case.

Если нужно переключение контекста - попробуйте scmRTOS - вполне себе работала у меня и с прерываниями и с I2C,

и с SPI, и с USART.

 

 

 

 

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


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

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

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

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

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

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

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

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

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

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