demiurg1978 1 7 февраля, 2017 Опубликовано 7 февраля, 2017 (изменено) · Жалоба Подбросьте идей, как реализовать синхронность программных модулей. Организация программ на данный момент у меня следующая. Модульность. Никаких долгих циклов. Модули, задачи, процессы дробятся условиями, флагами, состояниями конечных автоматов. Итерация основного цикла выполняется с запасом за один системный тик. В основном системный тик у меня - 1 мс. Использую программные таймеры. То есть, у меня псевдопараллельность процессов. Иногда бывают ситуации, когда несколько модулей после определенного события должны выполнить определенные действия. Речь идет не о быстром поочередном выполнении, а, скажем, в течении одной итерации основного цикла. Изменено 7 февраля, 2017 пользователем demiurg1978 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 7 февраля, 2017 Опубликовано 7 февраля, 2017 · Жалоба Не совсем понял суть проблемы. Как вариант struct Action { bool todo = false; Action *next = 0; }; Action *event1; void registerAction(Action **event, Action *a) { a->next = *event; *event = a; } void setOn(Action *event) { while(event) { event->todo = true; event = event->next; } } // модуль 1 Action mod1_event1; registerAction(event1, mod1_event1); void loop() { if (mod1_event.todo) { mod1_event.todo = false; // ... } } // модуль 2 Action mod2_event1; registerAction(event1, mod2_event1); void loop() { if (mod2_event.todo) { mod2_event.todo = false; // ... } } // где-то еще ISR(isr) { setOn(event1); } Если ставить флаг в прерывании, то чтение и сброс надо переделать на атомарное Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg1978 1 7 февраля, 2017 Опубликовано 7 февраля, 2017 (изменено) · Жалоба Попробую поточнее выразиться. Событие генерируется по условию и времени. Скажем, подавление дребезга контактных датчиков и входов. Одни входы - это контактные датчики, другие - контактные группы пускателей. У пускателей свои времянки включения-выключения. И чтобы не произошло сбоя, нужно синхронизировать действия модулей. Повторяю, речь не быстро-быстро выполнить действия. А о синхронизации действий в заданных рамках. Возьмем за такую рамку и условие, к примеру, итерацию основного цикла. Обработали все времянки подавления дребезга, по условиям модуль генерирует событие (что-то). Другими модулями видится это что-то, и выполняются определенные действия. Скажем, за итерацию основного цикла. Прошла итерация, это что-то больше не выставлено. Главное условие, сохранить инкапсуляцию программных модулей. Хмм... Как такая идея. Берем за временную засечку системный таймер и очередность выполнения модулей основной цикл. В обработчике системного таймера будет определена глобальная переменная флаг. Определенный модуль выставляет этот флаг. Определяем также еще одну переменную-флаг. Когда происходит прерывание системного таймера, мы сбрасываем первый флаг и выставляем следующий. В начале основного цикла, если установлен этот флаг, выполняем действия в пределах итерации основного цикла. При следующей итерации так как первый флаг сброшен, больше ничего не выставляется. Подсмотрено у ЛИ. //----------------------------- Переменные: ---------------------------------- volatile bool fTick; //флаг обновления системного таймера static bool tick; //флаг начала нового системного интервала //------------------ Инициализация системного таймера ------------------------ void Main_Timer_Init(void) { // bla-bla fTick = 1; //принудительное обновление } //--------------------- Проверка системного таймера: ------------------------- __monitor bool Main_GetTick(void) { if(!fTick) return(0); //проверка нового системного интервала fTick = 0; //очистка флага return(1); //новый системный интервал } //------------------- Прерывание системного таймера: ------------------------- #pragma vector = TIMER1_COMPA_vect __interrupt void Timer(void) { fTick = 1; //новый системный интервал } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- //-------------------------- Основная программа: ----------------------------- //---------------------------------------------------------------------------- void main(void) { Main_Timer_Init(); //инициализация системного таймера __enable_interrupt(); //разрешение прерываний while(1) //основной цикл { tick = Main_GetTick(); //опрос системного таймера Meter_Exe(tick); //обслуживание измерителя } } Изменено 7 февраля, 2017 пользователем demiurg1978 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gte 6 7 февраля, 2017 Опубликовано 7 февраля, 2017 · Жалоба Попробую поточнее выразиться. Событие генерируется по условию и времени. Не ручаюсь за то что правильно понял. В пром. контроллерах текущие состояние входов считывают в буфер в начале программного цикла, работают с буфером в пределах одного программного цикла, в конце цикла записывают значения из буфера в выходы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg1978 1 7 февраля, 2017 Опубликовано 7 февраля, 2017 · Жалоба Не ручаюсь за то что правильно понял. В пром. контроллерах текущие состояние входов считывают в буфер в начале программного цикла, работают с буфером в пределах одного программного цикла, в конце цикла записывают значения из буфера в выходы. Что считаем входами? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zombi 0 7 февраля, 2017 Опубликовано 7 февраля, 2017 · Жалоба как реализовать синхронность программных модулей нужно на нескольких выходах, в зависимости от входов, формировать состояние синхронно каждую мс? Или нужно нечто другое? «Правильно заданный вопрос – половина ответа»(с) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg1978 1 7 февраля, 2017 Опубликовано 7 февраля, 2017 (изменено) · Жалоба Я понимаю, что каждый разумеет в меру своего понимания и опыта. Общаясь на подобных форумах, каждый спрашивает в меру своего понимания и опыта, каждый отвечает в меру своего понимания и опыта. Есть такое понятие, как допустимое время реакции системы. Также нужно учитывать в расчетах время реакции исполнительных механизмов и время реакции датчиков. Исходим из этого. Соответственно, отбрасываем в этом обсуждении ответы начинающих, которые оперируют только байтами и тактами. И "быстрой-быстрой" реакцией. Прерывания и все такое прочее. Хотя надо признать, что некоторое время назад я именно так и рассуждал... :) Эти байтики, такты, быстро-быстро обработать... Изменено 7 февраля, 2017 пользователем demiurg1978 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gte 6 7 февраля, 2017 Опубликовано 7 февраля, 2017 · Жалоба Что считаем входами? Ну это Вам видней. "Одни входы - это контактные датчики, другие - контактные группы пускателей." Так как это Ваш контроллер, то что назначите. Если интересны подробности того о чем я написал, то стоит почитать описания на тот же Симатик. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zombi 0 7 февраля, 2017 Опубликовано 7 февраля, 2017 · Жалоба Речь идет не о быстром поочередном выполнении, а, скажем, в течении одной итерации основного цикла. Т.е. Вам нужно медленно и параллельно? Попробуйте переписать Ваше сообщение после первой запятой понятнее, так что бы "дошло" до всех участников форума независимо от опыта и квалификации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vladivolt 0 7 февраля, 2017 Опубликовано 7 февраля, 2017 · Жалоба По коду в сообщении #4: Не затрагивая способы организации очерёдности вызовов, замечу, что нет необходимости в переменной fTick, обработчике прерывания, разрешении прерывания таймера. Просто настраиваем и запускаем таймер и в основном цикле проверяем аппаратный флаг: if ( TIFR1 & (1<<OCF1A) ) { TIFR1 = (1<<OCF1A); // не забыть сбросить флаг {/*полезные действия*/} } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 30 8 февраля, 2017 Опубликовано 8 февраля, 2017 · Жалоба Я понимаю, что каждый разумеет в меру своего понимания и опыта. Общаясь на подобных форумах, каждый спрашивает в меру своего понимания и опыта, каждый отвечает в меру своего понимания и опыта. Есть такое понятие, как допустимое время реакции системы. Также нужно учитывать в расчетах время реакции исполнительных механизмов и время реакции датчиков. Исходим из этого. Соответственно, отбрасываем в этом обсуждении ответы начинающих, которые оперируют только байтами и тактами. И "быстрой-быстрой" реакцией. Прерывания и все такое прочее. Хотя надо признать, что некоторое время назад я именно так и рассуждал... :) Эти байтики, такты, быстро-быстро обработать... Так вы диаграммку временнУю нарисовали бы и всём стало бы понятнее… Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 8 февраля, 2017 Опубликовано 8 февраля, 2017 · Жалоба Я понимаю, что каждый разумеет в меру своего понимания и опыта. Общаясь на подобных форумах, каждый спрашивает в меру своего понимания и опыта, каждый отвечает в меру своего понимания и опыта. Есть такое понятие, как допустимое время реакции системы. Также нужно учитывать в расчетах время реакции исполнительных механизмов и время реакции датчиков. Исходим из этого. Соответственно, отбрасываем в этом обсуждении ответы начинающих, которые оперируют только байтами и тактами. И "быстрой-быстрой" реакцией. Прерывания и все такое прочее. Хотя надо признать, что некоторое время назад я именно так и рассуждал... :) Эти байтики, такты, быстро-быстро обработать... Вы бы все таки сформулировали задачу :rolleyes: Я так понял, что вы хотите, чтобы все модули, которые заинтересованы в некотором событии, уведомлялись о его наступлении. При этом модули не знаю друг про друга, а источник события не знает список заинтересованных в нем модулей ("не знает" в том смысле, что эти модули не прописаны в нем явно). Или задача звучит по другому? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg1978 1 23 февраля, 2017 Опубликовано 23 февраля, 2017 · Жалоба Я так понял, что вы хотите, чтобы все модули, которые заинтересованы в некотором событии, уведомлялись о его наступлении. При этом модули не знаю друг про друга, а источник события не знает список заинтересованных в нем модулей ("не знает" в том смысле, что эти модули не прописаны в нем явно). Поднимаю тему. Опять столкнулся с этим. Да, вы точно описали мою проблему. Запутался уже как это реализовать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 23 февраля, 2017 Опубликовано 23 февраля, 2017 · Жалоба Запутался уже как это реализовать. Создаете переменную СОБЫТИЕ, в которой 8 бит, по числу модулей. Если событие происходит, то приравниваете СОБЫТИЕ = 0xFF Эту переменную читают все модули. Прочитав, и выполнив действия, которые нужно выполнить, модуль сбрасывает соответствующий "свой" бит, поэтому действия выполняются каждым модулем один раз. Если система спроектирована правильно, то все модули обрабатывают событие раньше, чем произойдет новое событие. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Д_М 0 5 июня, 2017 Опубликовано 5 июня, 2017 · Жалоба Программы систем реального времени, по моему мнению, следует строить по принципу - на каждое событие есть свой обработчик. Завершилось преобразование АЦП, сработало прерывание, нужно сохранить данные и вызывать обработчик фоновой задачи, который преобразует сырые данные АЦП в формат с плавающей точкой. После завершения математики можно разрешать новое преобразование. Запускать новое преобразование АЦП, до того, как процессор завершит обработку, смысла нет. Чтобы программа так работала нужен диспетчер многозадачности. Вытесняющая многозадачность для одной единственной программы, которую пишешь сам - перебор. Кооперативной вполне достаточно. Есть два заблуждения. Заблуждение первое - кооперативная многозадачность создаёт множество неудобств. Заблуждение второе - вытесняющая многозадачность эти удобства решает. По степени важности обработчики делятся на три уровня - аппаратные прерывания (срочно, срочнее некуда), программные прерывания (не так срочно, как аппаратное прерывание, но срочнее, чем фоновая задача), фоновая задача (по остаточному принципу - сложная математика). Обработчик аппаратного прерывания инициирует либо программное прерывание, либо фоновую задачу. Системный таймер - надстройка над механизмом программного прерывания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться