реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Синхронное взаимодействие программных модулей
demiurg1978
сообщение Feb 7 2017, 12:47
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709



Подбросьте идей, как реализовать синхронность программных модулей. Организация программ на данный момент у меня следующая. Модульность. Никаких долгих циклов. Модули, задачи, процессы дробятся условиями, флагами, состояниями конечных автоматов. Итерация основного цикла выполняется с запасом за один системный тик. В основном системный тик у меня - 1 мс. Использую программные таймеры. То есть, у меня псевдопараллельность процессов.
Иногда бывают ситуации, когда несколько модулей после определенного события должны выполнить определенные действия. Речь идет не о быстром поочередном выполнении, а, скажем, в течении одной итерации основного цикла.

Сообщение отредактировал demiurg1978 - Feb 7 2017, 12:49
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Feb 7 2017, 13:25
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Не совсем понял суть проблемы. Как вариант

CODE
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);
}


Если ставить флаг в прерывании, то чтение и сброс надо переделать на атомарное
Go to the top of the page
 
+Quote Post
demiurg1978
сообщение Feb 7 2017, 14:45
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709



Попробую поточнее выразиться. Событие генерируется по условию и времени. Скажем, подавление дребезга контактных датчиков и входов. Одни входы - это контактные датчики, другие - контактные группы пускателей. У пускателей свои времянки включения-выключения. И чтобы не произошло сбоя, нужно синхронизировать действия модулей. Повторяю, речь не быстро-быстро выполнить действия. А о синхронизации действий в заданных рамках. Возьмем за такую рамку и условие, к примеру, итерацию основного цикла. Обработали все времянки подавления дребезга, по условиям модуль генерирует событие (что-то). Другими модулями видится это что-то, и выполняются определенные действия. Скажем, за итерацию основного цикла. Прошла итерация, это что-то больше не выставлено. Главное условие, сохранить инкапсуляцию программных модулей.

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

Подсмотрено у ЛИ.
Код
//----------------------------- Переменные: ----------------------------------

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);               //обслуживание измерителя
  }
}


Сообщение отредактировал demiurg1978 - Feb 7 2017, 14:49
Go to the top of the page
 
+Quote Post
gte
сообщение Feb 7 2017, 14:51
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 318
Регистрация: 13-02-05
Из: Липецкая область
Пользователь №: 2 613



Цитата(demiurg1978 @ Feb 7 2017, 17:14) *
Попробую поточнее выразиться. Событие генерируется по условию и времени.

Не ручаюсь за то что правильно понял. В пром. контроллерах текущие состояние входов считывают в буфер в начале программного цикла, работают с буфером в пределах одного программного цикла, в конце цикла записывают значения из буфера в выходы.
Go to the top of the page
 
+Quote Post
demiurg1978
сообщение Feb 7 2017, 15:02
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709



Цитата(gte @ Feb 7 2017, 20:51) *
Не ручаюсь за то что правильно понял. В пром. контроллерах текущие состояние входов считывают в буфер в начале программного цикла, работают с буфером в пределах одного программного цикла, в конце цикла записывают значения из буфера в выходы.

Что считаем входами?
Go to the top of the page
 
+Quote Post
zombi
сообщение Feb 7 2017, 16:01
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(demiurg1978 @ Feb 7 2017, 16:47) *
как реализовать синхронность программных модулей

нужно на нескольких выходах, в зависимости от входов, формировать состояние синхронно каждую мс?
Или нужно нечто другое?
«Правильно заданный вопрос – половина ответа»(с)
Go to the top of the page
 
+Quote Post
demiurg1978
сообщение Feb 7 2017, 16:13
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709



Я понимаю, что каждый разумеет в меру своего понимания и опыта. Общаясь на подобных форумах, каждый спрашивает в меру своего понимания и опыта, каждый отвечает в меру своего понимания и опыта.
Есть такое понятие, как допустимое время реакции системы. Также нужно учитывать в расчетах время реакции исполнительных механизмов и время реакции датчиков. Исходим из этого. Соответственно, отбрасываем в этом обсуждении ответы начинающих, которые оперируют только байтами и тактами. И "быстрой-быстрой" реакцией. Прерывания и все такое прочее. Хотя надо признать, что некоторое время назад я именно так и рассуждал... sm.gif Эти байтики, такты, быстро-быстро обработать...

Сообщение отредактировал demiurg1978 - Feb 7 2017, 16:20
Go to the top of the page
 
+Quote Post
gte
сообщение Feb 7 2017, 19:13
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 318
Регистрация: 13-02-05
Из: Липецкая область
Пользователь №: 2 613



Цитата(demiurg1978 @ Feb 7 2017, 18:02) *
Что считаем входами?

Ну это Вам видней.
"Одни входы - это контактные датчики, другие - контактные группы пускателей."
Так как это Ваш контроллер, то что назначите.
Если интересны подробности того о чем я написал, то стоит почитать описания на тот же Симатик.

Go to the top of the page
 
+Quote Post
zombi
сообщение Feb 7 2017, 20:29
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(demiurg1978 @ Feb 7 2017, 15:47) *
Речь идет не о быстром поочередном выполнении, а, скажем, в течении одной итерации основного цикла.

Т.е. Вам нужно медленно и параллельно?
Попробуйте переписать Ваше сообщение после первой запятой понятнее, так что бы "дошло" до всех участников форума независимо от опыта и квалификации.
Go to the top of the page
 
+Quote Post
Владивольт
сообщение Feb 7 2017, 23:05
Сообщение #10


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 14-02-10
Пользователь №: 55 490



По коду в сообщении #4:
Не затрагивая способы организации очерёдности вызовов, замечу,
что нет необходимости в переменной fTick, обработчике прерывания,
разрешении прерывания таймера.

Просто настраиваем и запускаем таймер и в основном цикле проверяем аппаратный флаг:
Код
if ( TIFR1 & (1<<OCF1A) )
{
  TIFR1 = (1<<OCF1A); // не забыть сбросить флаг

  {/*полезные действия*/}
}


--------------------
#define TRUE (4==(2*2))
Go to the top of the page
 
+Quote Post
Obam
сообщение Feb 8 2017, 08:10
Сообщение #11


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Цитата(demiurg1978 @ Feb 7 2017, 20:13) *
Я понимаю, что каждый разумеет в меру своего понимания и опыта. Общаясь на подобных форумах, каждый спрашивает в меру своего понимания и опыта, каждый отвечает в меру своего понимания и опыта.
Есть такое понятие, как допустимое время реакции системы. Также нужно учитывать в расчетах время реакции исполнительных механизмов и время реакции датчиков. Исходим из этого. Соответственно, отбрасываем в этом обсуждении ответы начинающих, которые оперируют только байтами и тактами. И "быстрой-быстрой" реакцией. Прерывания и все такое прочее. Хотя надо признать, что некоторое время назад я именно так и рассуждал... sm.gif Эти байтики, такты, быстро-быстро обработать...


Так вы диаграммку временнУю нарисовали бы и всём стало бы понятнее…


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Feb 8 2017, 08:25
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(demiurg1978 @ Feb 7 2017, 19:13) *
Я понимаю, что каждый разумеет в меру своего понимания и опыта. Общаясь на подобных форумах, каждый спрашивает в меру своего понимания и опыта, каждый отвечает в меру своего понимания и опыта.
Есть такое понятие, как допустимое время реакции системы. Также нужно учитывать в расчетах время реакции исполнительных механизмов и время реакции датчиков. Исходим из этого. Соответственно, отбрасываем в этом обсуждении ответы начинающих, которые оперируют только байтами и тактами. И "быстрой-быстрой" реакцией. Прерывания и все такое прочее. Хотя надо признать, что некоторое время назад я именно так и рассуждал... sm.gif Эти байтики, такты, быстро-быстро обработать...


Вы бы все таки сформулировали задачу rolleyes.gif

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

Или задача звучит по другому?
Go to the top of the page
 
+Quote Post
demiurg1978
сообщение Feb 23 2017, 15:39
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709



Цитата(Непомнящий Евгений @ Feb 8 2017, 14:25) *
Я так понял, что вы хотите, чтобы все модули, которые заинтересованы в некотором событии, уведомлялись о его наступлении. При этом модули не знаю друг про друга, а источник события не знает список заинтересованных в нем модулей ("не знает" в том смысле, что эти модули не прописаны в нем явно).

Поднимаю тему. Опять столкнулся с этим. Да, вы точно описали мою проблему. Запутался уже как это реализовать.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Feb 23 2017, 17:35
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(demiurg1978 @ Feb 23 2017, 18:39) *
Запутался уже как это реализовать.

Создаете переменную СОБЫТИЕ, в которой 8 бит, по числу модулей.
Если событие происходит, то приравниваете СОБЫТИЕ = 0xFF
Эту переменную читают все модули. Прочитав, и выполнив действия, которые нужно выполнить, модуль сбрасывает соответствующий "свой" бит, поэтому действия выполняются каждым модулем один раз.
Если система спроектирована правильно, то все модули обрабатывают событие раньше, чем произойдет новое событие.



--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Д_М
сообщение Jun 5 2017, 19:05
Сообщение #15


Частый гость
**

Группа: Участник
Сообщений: 121
Регистрация: 15-04-05
Из: Краснодар
Пользователь №: 4 185



Программы систем реального времени, по моему мнению, следует строить по принципу - на каждое событие есть свой обработчик. Завершилось преобразование АЦП, сработало прерывание, нужно сохранить данные и вызывать обработчик фоновой задачи, который преобразует сырые данные АЦП в формат с плавающей точкой. После завершения математики можно разрешать новое преобразование. Запускать новое преобразование АЦП, до того, как процессор завершит обработку, смысла нет. Чтобы программа так работала нужен диспетчер многозадачности. Вытесняющая многозадачность для одной единственной программы, которую пишешь сам - перебор. Кооперативной вполне достаточно. Есть два заблуждения. Заблуждение первое - кооперативная многозадачность создаёт множество неудобств. Заблуждение второе - вытесняющая многозадачность эти удобства решает. По степени важности обработчики делятся на три уровня - аппаратные прерывания (срочно, срочнее некуда), программные прерывания (не так срочно, как аппаратное прерывание, но срочнее, чем фоновая задача), фоновая задача (по остаточному принципу - сложная математика). Обработчик аппаратного прерывания инициирует либо программное прерывание, либо фоновую задачу. Системный таймер - надстройка над механизмом программного прерывания.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 8th July 2025 - 00:02
Рейтинг@Mail.ru


Страница сгенерированна за 0.01513 секунд с 7
ELECTRONIX ©2004-2016