|
|
  |
Инкрементирующийся define, c помощью препроцессор Си |
|
|
|
Jul 14 2016, 09:14
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 14-02-10
Пользователь №: 55 490

|
Цитата(Andrew_Q @ Jul 14 2016, 09:55)  состояние-событие-выполнить действие-перейти в новое состояние Как быть с ветвлением, т.е. если новое состояние определяется исходом действия?
--------------------
#define TRUE (4==(2*2))
|
|
|
|
|
Jul 14 2016, 09:23
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(adnega @ Jul 14 2016, 10:53)  А кто придумывает номера для "состояний"? При добавлении новой записи нужно править поле "перейти в новое состояние" предыдущей записи? Или можно ставить только поля "событие" и "выполнить действие" а выполняться все будет линейно пока не дойдет до конца таблицы? Чтобы не заморачиваться с ручной адресацией массива-таблицы, можно примерно так. (но таблиц нужно 2 - одна состояний, вторая - переходов, в которую включены указатели на функции-обработчики) IMHO Код enum FSM_StateGo { A1, A2, A3, A_Stop, B1, B2, B3, B_Stop, . . . . };
enum FSM_State { STATE_A, STATE_B . . . };
TRun_Table RT[] = { [A1] = { STATE_A, A2 . . . . . }, [A2] = { STATE_A, B2 . . . . . }, [A3] = { STATE_A, A1 . . . . . }, [A_STOP] = { STATE_A, A_STOP . . . . . }, [B1] = { STATE_B, A2 . . . . . }, [B2] = { STATE_B, B2 . . . . . }, [B3] = { STATE_B, A1 . . . . . }, [B_STOP] = { STATE_A, A_STOP . . . . . }, . . . . . };
Сообщение отредактировал k155la3 - Jul 14 2016, 09:36
|
|
|
|
|
Jul 14 2016, 09:29
|
Группа: Участник
Сообщений: 7
Регистрация: 27-05-05
Пользователь №: 5 449

|
Цитата(Владивольт @ Jul 14 2016, 14:14)  Как быть с ветвлением, т.е. если новое состояние определяется исходом действия? По исходу действия генерируем событие, в таблице описываем переход по этому событию в нужное состояние. У меня таблица выглядит так CODE __flash state_table_type STATE_MODBUS_NASTER_TABLE[]= // Таблица состояний, условий перехода и действий режима ModBus мастер { /* из состояния по событию выполнить в состояние в режим */
{ANY_STATE, NOT_NET_ACCESS, init_state_mashine, INIT, MODBUS_MASTER}, {ANY_STATE, TIMER_OVFL, init_state_mashine, INIT, MODBUS_MASTER}, {INIT, NET_ACCESS, request_ana_from_monoblock, WAIT_MONOBLOCK_ANA, MODBUS_MASTER}, {WAIT_MONOBLOCK_ANA, MONOBLOCK_DATA_RECEIVED,send_ana_to_modbus, WAIT_CHECK_MODBUS_ANA, MODBUS_MASTER}, {WAIT_CHECK_MODBUS_ANA, MODBUS_SENDED, receive_ana_modbus_check, NO_NEW_STATE, MODBUS_MASTER}, {WAIT_CHECK_MODBUS_ANA, MODBUS_RECEIVED, test_ana_modbus_check, NO_NEW_STATE, MODBUS_MASTER}, }
|
|
|
|
|
Jul 14 2016, 09:45
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(Andrew_Q @ Jul 14 2016, 12:29)  __flash state_table_type STATE_MODBUS_NASTER_TABLE[]= Терминология MONOBLOCK и _ana_ не из оперы modbus. Всегда поражаюсь людям изобретающим велосипеды... Цитата PDU (Protocol Data Unit) — общая для всех физических уровней часть пакета MODBUS. Включает в себя код функции и данные пакета. ADU (Application Data Unit) — полный пакет MODBUS. Включает в себя специфичную для физического уровня часть пакета и PDU.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Jul 14 2016, 09:50
|
Группа: Участник
Сообщений: 7
Регистрация: 27-05-05
Пользователь №: 5 449

|
Опечатка? Я хронический лентяй, программа работает на изделии с 2002 года. Исправлять лениво :-) Цитата(demiurg_spb @ Jul 14 2016, 14:45)  Терминология MONOBLOCK не из оперы modbus. Всегда поражаюсь людям изобретающим велосипеды... Моноблок - это блоки нашей разработки на кастомном протоколе. А сие поделие является шлюзом в Modbus. Вот, кстати, ссылка на автомат конечных состояний, описанный таблицей, управляемый событиями. http://chipenable.ru/index.php/programming...nizatsiya-progr
Сообщение отредактировал Andrew_Q - Jul 14 2016, 10:05
|
|
|
|
|
Jul 15 2016, 03:47
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(jcxz @ Jul 15 2016, 06:26)  А как быть если после некоторых состояний необходимо пройти через определённую цепочку состояний, а затем вернуться к исходной цепочке? Ваш пример похож на последовательность выполнения строк на бэйсике, соответственно используется что-то типа GOSUB  Ну и объединить цепочку состояний в одно состояние с дополнительным индексом ничего не мешает. Регулярность и простота автоматов - хорошо, но все же иногда нужно немного и усложнять реализацию.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jul 15 2016, 05:11
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Dog Pawlowa @ Jul 15 2016, 09:47)  Ваш пример похож на последовательность выполнения строк на бэйсике, соответственно используется что-то типа GOSUB  Ну и объединить цепочку состояний в одно состояние с дополнительным индексом ничего не мешает. Регулярность и простота автоматов - хорошо, но все же иногда нужно немного и усложнять реализацию. Объединить? А что тогда мешает объединить все остальные состояния автомата в одно? Если ничего - то и автомат не нужен, так как всего одно состояние осталось. А если есть автомат - значит он для чего-то нужен и нельзя объединить состояния. А если нужен доплнительный индекс, то как потом возвращаться к основному? А если не один уровень вложенности, а больше? Стек хранения состояний городить?
|
|
|
|
|
Jul 15 2016, 06:02
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(jcxz @ Jul 15 2016, 08:11)  Объединить? А что тогда мешает объединить все остальные состояния автомата в одно? Если ничего - то и автомат не нужен, так как всего одно состояние осталось. А если есть автомат - значит он для чего-то нужен и нельзя объединить состояния. Почему это нельзя объединить? Ну не будьте уж таким догматиком. Одну и ту же задачу могут выполнять автомат с одной переменной состояния, которое может принимать, допустим 16 значений и фрагмент программы, использующий 16 битовых флагов. И выглядеть они будут похоже, всего вместо case будет if, ну и присвоение чуть по другому. А между этими двумя реализациями целый диапазон возможных решений. Цитата(jcxz @ Jul 15 2016, 08:11)  А если нужен дополнительный индекс, то как потом возвращаться к основному? А если не один уровень вложенности, а больше? Стек хранения состояний городить? Усложняете. Вот кода, описывающего одно состояние с дополнительными промежуточными состояниями проверки индикации. Код void fSelfTest(void) { if (old_status-status) { StatusFirstTimeReady("Tst"); SET_TIMER(N500ms); } if (event==evTimer) { switch (status_var) { case 0: OnWorkRed1(); break; case 1: OnChemLed(); break; case 2: OnWaterLed(); break; case 3: ToggleWorkColor(); OffChemWaterLeds(); case 4: status= sWaiting; break; default: status_var=-1; } status_var++; } } Что касается стека... Стек, не стек, но что мешает запоминать предыдущее состояние и при необходимости туда возвращаться? Если интерфейс пользователя - один большой автомат, некоторые функции вызываются из разных меню, возвращаться нужно именно в предыдущее состояние. Можно назвать это одноуровневым стеком.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jul 15 2016, 07:00
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (Dog Pawlowa @ Jul 15 2016, 09:02)  Что касается стека... Стек, не стек, но что мешает запоминать предыдущее состояние и при необходимости туда возвращаться? Если интерфейс пользователя - один большой автомат, некоторые функции вызываются из разных меню, возвращаться нужно именно в предыдущее состояние. Можно назвать это одноуровневым стеком. Вот и дошли до того, что при создании реальных автоматов стек состояний (как бы Вы его не назвали другими словами ) тоже можно и нужно использовать. Что тоже уменьшает безмерное разрастание состояний. У меня почти уже в привычке использовать в минимальной "базе" три состояния - текущее, предыдущее и то, на которое сейчас текущее будет измененно. Так же огромное знвчение стека в диагностике работы в РЕАЛЬНЫХ условиях - как дошли до ошибки.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jul 15 2016, 07:32
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(zltigo @ Jul 15 2016, 10:00)  е и то, на которое сейчас текущее будет изменено. А как Вы заглядываете в будущее оперируете с этим значением ? У меня обычно просто - присвоил текущему и вышел, а анализ смены состояния в начале вызова обработчика автомата.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jul 15 2016, 08:20
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Dog Pawlowa @ Jul 15 2016, 12:02)  Что касается стека... Стек, не стек, но что мешает запоминать предыдущее состояние и при необходимости туда возвращаться? Если интерфейс пользователя - один большой автомат, некоторые функции вызываются из разных меню, возвращаться нужно именно в предыдущее состояние. Можно назвать это одноуровневым стеком. Конечно ничто не мешает. Только код становится уже плохо читаемым, слишком громоздким с такой реализацией на классических автоматах. В этом случае я делаю псевдозадачу (которую можно считать к.автоматом). Только она не вытесняется принудительно другими задачами как обычная задача ОС, а вытеснение задачи происходит по логике её работы, при переходе к очередному состоянию автомата. А состояния автомата при этом - это значения PC, которые сохраняются в стеке при вытеснении задачи и на которые происходит переход при активации задачи. И код становится читаемым даже при наличии сложных ветвлений и вложенных состояний автомата.
|
|
|
|
|
Jul 15 2016, 08:27
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (Dog Pawlowa @ Jul 15 2016, 10:32)  А как Вы заглядываете в будущее оперируете с этим значением ? Хотим изменить текущее состояние автомата - "будущее" это то значение на которое изменим. "Прошлое" это сохраненное котрое было до текущего. QUOTE У меня обычно просто - присвоил текущему и вышел... А присвоение текущему уже в конце обработчика - так и правильнее, ибо состояние сменилось, когда ВСЕ действия сопутствующие смене состояния уже произведены. Таким образом в процессе переключения типично известны ТРИ состояния прошлое-настояшее-будущее.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|