|
State machine, Приведите примеры реализации |
|
|
|
Feb 2 2005, 12:29
|
Группа: Новичок
Сообщений: 10
Регистрация: 6-07-04
Пользователь №: 265

|
Где можно почитать по теме/посмотреть примеры на С, асме
|
|
|
|
|
 |
Ответов
(1 - 74)
|
Feb 2 2005, 12:41
|

Частый гость
 
Группа: Свой
Сообщений: 174
Регистрация: 4-11-04
Из: zp.ua
Пользователь №: 1 046

|
Сайты: http://is.ifmo.ruhttp://softcraft.ru - раздел Автоматы еще см. на сайте iar.com программу VisualState
--------------------
Имей мужество пользоваться своим собственным разумом! (с) И.Кант
|
|
|
|
|
Feb 3 2005, 12:02
|

Частый гость
 
Группа: Свой
Сообщений: 146
Регистрация: 4-11-04
Из: Московская область
Пользователь №: 1 040

|
Цитата(sat @ Feb 2 2005, 15:29) ...посмотреть примеры на С, асме Прямо здесь  и сейчас  : void main (void) { while (1) { automat_1 (); automat_2 (); ... automat_N (); } } void automat_i (void) { static char state=0; switch (state) { case 0: // чтото полезное может быть делаем if (некоторое условие) state=... ; // если условие выполнено, перейдем в другое состояние return; case 1: // используем подчиненный автомат: if (slave_automat_1 ()) state = .. ; return; ... case K: return; default: state=0; return; // авария !! } } Важно понимать на уровне инстинктов: - Все обьекты материального Мира - автоматы состояний - придется полностю перестроить мозги - возможно это удасться не сразу, зато окупится потом. - что переход из состояния в состояние это как правило наиболее сложная часть и может быть представлена множеством состояний а лучше отдельным подчиненным автоматом. Или их совокупностью. - "автомат в состоянии" - это как правило ожидание условия перехода в другие состояния. Но не всегда.
--------------------
- ЗАМЕНЯТЬ ДЕТАЛИ НА ХОДУ ВОСПРЕЩАЕТСЯ !!! -
|
|
|
|
|
Feb 3 2005, 15:52
|
Группа: Новичок
Сообщений: 11
Регистрация: 3-02-05
Пользователь №: 2 403

|
1. IAR VisualSTATE - в пакете примеры (под разные контроллеры), есть симулятор самого автомата, т.е. в среде можно отладить логику работы автомата 2. TS Controls - программа для разработки автоматов состояний с генерацией кода на C и С++
|
|
|
|
|
Feb 4 2005, 12:44
|
Местный
  
Группа: Свой
Сообщений: 437
Регистрация: 27-08-04
Пользователь №: 551

|
Цитата(ALys @ Feb 3 2005, 18:52) 2. TS Controls - программа для разработки автоматов состояний с генерацией кода на C и С++ Что то не ставится на ХР. Или это аддон к чему - то? Может есть какой нибудь официальный сайт или мож какое нибудь описание?
|
|
|
|
|
Feb 7 2005, 11:50
|
Группа: Новичок
Сообщений: 10
Регистрация: 6-07-04
Пользователь №: 265

|
Что то не ставится на ХР. Или это аддон к чему - то? Может есть какой нибудь официальный сайт или мож какое нибудь описание? [/quote] Вроде нормально встал http://www.tscontrols.com/support.html - вот такое адрес
|
|
|
|
|
Feb 7 2005, 19:54
|
Знающий
   
Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32

|
Цитата(maegg @ Feb 7 2005, 16:17) Может коротенько объясните, зачем это нужно и в каких случаях стоит применять? Некая обособленная подзадача в программе имеет набор состояний, в которых может находиться, и условий, согласно которым она переходит из одного состояния в другое. Реализация не должна мешать выполняться другим подзадачам. Типичные примеры - реализация коммуникационного протокола, выдача согласованных по времени управляющих сигналов, и т. п.
--------------------
Главная линия этого опуса ясна мне насквозь!
|
|
|
|
|
Feb 8 2005, 13:07
|
Группа: Новичок
Сообщений: 11
Регистрация: 3-02-05
Пользователь №: 2 403

|
Что то не ставится на ХР. Или это аддон к чему - то? Может есть какой нибудь официальный сайт или мож какое нибудь описание? [/quote] Прекрастно ставится и на XP и w2k и NT. Сам файл программы называется VState.exe Сайта поддержки нет. (Прога - что называется проверенная временем) В комплекте справка и примеры - все довольно прозрачно. Выходной код С и С++;
|
|
|
|
|
Feb 17 2005, 12:50
|
Группа: Новичок
Сообщений: 3
Регистрация: 17-02-05
Пользователь №: 2 707

|
SWITCH MACRO local MYP CLR ZH ADZ (MYP>>1) IJMP /*Уйдем на обработчик*/ MYP MyPrep VAR $ REPT \1 RJMP \2 ENDR ENDM
CASE MACRO val VAR $ ORG MyPrep+2*(\1) RJMP ?Prg\1 ORG val Public ?Prg\1 ?Prg\1 ENDM
SWITCHC $80,?badEvnt /*где $80 - индекс переключателЯ*/
?badEvnt /*прекратить разбор -обработка ошибки*/ RET
CASE $48 /*48 -команда */ CASE $4A /*4A -команда */ RJMP ?exit1
CASE $42 /*42 -команда */ CASE $44 /*44 -команда */ CASE $46 /*46 -команда */ RET
|
|
|
|
|
Sep 9 2005, 09:30
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 21-06-04
Пользователь №: 70

|
Уважаемые, подскажите, пожалуйста, среды разработки для конечных автоматов. Я попробовал работать и на VisualState и на TS Control, обе генерят медленный код. Может, есть какие-нибудь другие проги?
--------------------
Настоящее чревато будущим.
|
|
|
|
|
Sep 12 2005, 10:29
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 19-01-05
Из: Москва
Пользователь №: 2 064

|
Код /*************************************************** * definitions Section ***************************************************/ typedef void(*PVOID)(void); typedef PVOID(*STATE)(void);
/*************************************************** * Export Variables Section ***************************************************/ STATE State_ptr = state_1;
/*************************************************** * Function Prototype Section ***************************************************/ STATE State_1(); STATE State_2(); STATE State_3();
/************************************************** * Function name : void main (void) * Created by : tmx * Date created : 12.09.2005 14:27 * Description : main **************************************************/ void main (void) { while (1) { State_ptr = (STATE) State_ptr(); } }
/************************************************** * Function name : STATE State_1() * Created by : tmx * Date created : 12.09.2005 14:23 * Description : STATE function * Notes : called by ptr from main cycle in bgnd **************************************************/ STATE State_1() { if (event_1) { return (STATE) State_2; } else return (STATE) State_1; }
/************************************************** * Function name : STATE State_2() * Created by : tmx * Date created : 12.09.2005 14:24 * Description : STATE function * Notes : called by ptr from main cycle in bgnd **************************************************/ STATE State_1() { if (event_1) { return (STATE) State_3; } else return (STATE) State_2; }
/************************************************** * Function name : STATE State_3() * Created by : tmx * Date created : 12.09.2005 14:24 * Description : STATE function * Notes : called by ptr from main cycle in bgnd **************************************************/ STATE State_3() { if (event_3) { return (STATE) State_1; } else return (STATE) State_3; }
|
|
|
|
|
Sep 12 2005, 11:14
|
Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 21-06-04
Пользователь №: 70

|
Этот код Вы наверняка писали руками. А есть ли проги, в которых можно нарисовать граф переходов, отладить, а потом сгенерить код по этому графу? Есть VisualState и на TS Control, но код они генерят - просто атас, особенно VisualState. В качестве примера я как-то сваял такой граф. Power - всегда нажатая кнопка, LEDon и LEDoff - состояния, в которых диод горит или потушен соответственно. Гонял на MSP430 на частоте 8,192 МГц. В случае VisualState диод моргал с частотой около 3 кГц, т.е. переход по состояниям выполнялся с частотой 6 кГц, или один переход выполнялся через 8192/6 = 1365 тиков тактовой частоты. Многовато для такого простого графа. В случае TS Control диод моргал с частотой 20 кГц, если отключить очередь событий, то 40 Кгц, т.е. один переход через 100 тиков. Лучше, конечно, но в TS Control нет симулятора. Так вот может кто знает прогу , в которой есть симулятор и которая генерит более-менее приемлемый код? А теорию я знаю.
Эскизы прикрепленных изображений
--------------------
Настоящее чревато будущим.
|
|
|
|
|
Sep 15 2005, 16:34
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 19-01-05
Из: Москва
Пользователь №: 2 064

|
Цитата(Tran @ Sep 12 2005, 14:14) Этот код Вы наверняка писали руками. А есть ли проги, в которых можно нарисовать граф переходов, отладить, а потом сгенерить код по этому графу? Есть VisualState и на TS Control, но код они генерят - просто атас, особенно VisualState. В качестве примера я как-то сваял такой граф. Power - всегда нажатая кнопка, LEDon и LEDoff - состояния, в которых диод горит или потушен соответственно. Гонял на MSP430 на частоте 8,192 МГц. В случае VisualState диод моргал с частотой около 3 кГц, т.е. переход по состояниям выполнялся с частотой 6 кГц, или один переход выполнялся через 8192/6 = 1365 тиков тактовой частоты. Многовато для такого простого графа. В случае TS Control диод моргал с частотой 20 кГц, если отключить очередь событий, то 40 Кгц, т.е. один переход через 100 тиков. Лучше, конечно, но в TS Control нет симулятора. провел эксперимент: PIC18F6620 / 11.059 МГц: 47.67 КГц с откл. прерываниями по поводу автоматической программы: по совету bialix тоже смотрел VisualState разложил по затратам времени на этапах: 1. Написание драйверов в/в, служ.прг, и т.п. (вручную) - 30 % 2. рисование диаграммы состояний и согласование с заказчиком - 40% (как минимум - 2 - 3 вида на каждый автомат) 3. реализация кода вручную - 5% 4. отладка и тестирование на макете - 25% автоматическая генерация кода не оказывает существенного влияния, как мне кажется.
|
|
|
|
|
Mar 4 2009, 17:31
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 19-01-05
Из: Москва
Пользователь №: 2 064

|
Цитата(Владимир_2010 @ Mar 4 2009, 16:54)  Применение теории конечных автоматов к программированию микроконтроллеров очень заинтересовало. Привидите пожалуйста простой (конкретный пример для двух-трех состояний (код в codevision или winavr) для микроконтроллера семейства avr?! Я пока не могу разобраться с кодом и идеей изложенной в теме форума. С теорией немного знаком – в институте на курсах по автоматизации учили рисовать графы состояния, а потом переходить к релейно-контакторной схеме. Хотелось посмотреть как это реализовать на С "вручную" применительно к микроконтроллерам avr. Спасибо за внимание. Ок. На самом деле в предыдущих постах все описано достаточно хорошо. А язык С удобен тем, что позволяет писать переносимый код. Сначала общие слова: Задача: светофор имеет выходы: три лампы (кр, жел, зел), входы: кнопка. Есть встроенный таймер (внутренний вход). Как работает в штатном режиме лень объяснять, при нажатии на кнопку старается зажечь зеленый. Практическая реализация: сначала надо это промоделировать (изобразить), это можно сделать по-разному, кому как нравится. 1. можно в каждом состоянии опрашивать только требуемые события - самый простой способ. 2. можно все события представит в виде битового поля, предварительно опрашивать их, заполнять поле, а потом в каждом состоянии опрашивать при переходе в новое состояние выполнять действия. Подход Шалыто, хорош тем, что диаграмма состояний изображается в виде булевых выражений, можно применить аппарат дискр.математики для минимизации состояний. 3. можно каждое состояние представить в виде "состояние вообще", у которого есть действия, предпринимаемые при входе в состояние и действия, предпринимаемые при переходах в другие состояния. Это подход HSM. Удобен для реализации в ООП. эти три подхода можно рассматривать с различных точек зрения. например, с точки зрения потоков управления: в первом случае функции автомата все делают сами, во втором битовое поле сначала заполняется в каком-то диспетчере, в третьем - обычно все управление происходит в диспетчере, а классы состояний автомата просто описательные. И т.п. На этапе рисования состояний следует решить, как будет осуществляться ввод-вывод. Классический подход: считать входы, прокрутить автомат, выставить выходы (как в ПЛК). Еще надо выбрать политику моделирования: рисуем много состояний, или вводим дополнительные переменные (или иерархии для HSM). Пример: можно сделать одно состояние "горит желтый" и в нем опрашивать флаг нажатия кнопки, а можно два: "желтый, кнопка была нажата", "желтый, кнопка не была нажата". В первом случае требуется ОЗУ, во втором ПЗУ, отлаживать легче второй. Про реализацию напишу позже
|
|
|
|
|
Mar 4 2009, 17:33
|
Частый гость
 
Группа: Участник
Сообщений: 84
Регистрация: 1-08-06
Пользователь №: 19 250

|
Рекомендую ознакомиться с реализацией иерархических конечных автоматов от Миро Самека - http://www.state-machine.com. С тех пор, как проникся этой концепцией, ничего другого и не хочется. Диспетчер использую самописный, работает пошустрее и GPL не нарушает. В простейшем виде, без иерархии, это выглядит как набор функций-обработчиков, по одной на каждое состояние. В каждой функции switch/case с перечислением всех интересующих в этом состоянии событий и связанных с ними действий, прямо в теле функции. Отдельно хранится указатель на текущее состояние (текущую функцию-обработчик). При смене состояния этот указатель изменяется. Как только в системе происходит событие, номер события кладется в очередь сообщений (например, из прерывания). В main-е диспетчер выгребает событие из очереди, вызывает обработчик по указателю текущего состояния и передает ему событие как аргумент. Если интересно, могу рассказать и про вариант с иерархией. Всякие графические генераторы конечных автоматов (нетривиальных) малополезны, а код после них невозможно модифицировать. Имхо, конечно же. Другое дело - визуализация уже написанного на низком уровне конечного автомата.
|
|
|
|
|
Mar 5 2009, 06:54
|
Частый гость
 
Группа: Участник
Сообщений: 120
Регистрация: 16-02-08
Пользователь №: 35 087

|
Diz спасибо за ссылку на книги. В сети также есть «Samek Miro, Practical UML Statecharts in C/C++. 2008». Diz писал: Цитата Другое дело – визуализация уже написанного на низком уровне конечного автомата Нельзя ли в этом месте поподробней?! Задачи по дискретным системам автоматики я решал в основном по методе/идее изложено в книге «Юдицкий С.А. Проектирование дискретных систем автоматики. 1980». На русском искал, но больше ничего не встречал по этой теме. Встречались книги просто про конечные автоматы, без приложений к автоматике. Но там одна математика. Вот как я решал задачки по автоматике: по методе вначале рисовал конечный автомат (графы с переходами) в пакете Stateflow от Matlab, затем проверял логику работы автомата моделируя различные состояния, далее записывал граф в виде уравнений/формул (вручную на бумажке), оптимизировал (вручную на бумажке) если требовалось конечный автомат с применением методов дискретной математики. Потом формулы рисовал в виде релейно-контакторной схемы (или функционально-логической схемы – триггеры, или, и, не), писал программу на Step7 (софт для программирования логических контроллеров Siemens) или на CX-Programmer (софт плк Omron) и прогонял логику работы с использованием симулятора для этих контроллеров. Применяя эту методу к нескольким различным задачам, убедил себя (возможно зря) что самое главное для любой задачи по автоматике на плк это нарисовать правильно конечный автомат (графы с переходами) и проверить его работу средствами моделирования – все остальное дело техники, рутинный труд, все можно делать по одному шаблону/правилам, выключив мозг, нужно только время. Хотел даже весь этот процесс автоматизировать и написать автоматический генератор из графов всех этих формул и схем. Но потом подумал, что не надо горячиться: наверняка все это давным-давно уже сделано кем-то. Теперь вот вижу что на языке Си IAR реализует этот подход в VisualState, Telelogiс, великий ученый Шалыто А. А. и его друзья. Вопросы: 1) Какие инструменты для моделирования/визуализации абстрактного конечного автомата есть кроме VisualState, Stateflow? Кто чем пользуется, опишите пожалуйста и поделитесь впечатлениями. 2) Какие инструменты для визуализация/моделирования/отладки уже написанного на языке С алгоритма есть?! Если применительно к мк AVR: в Proteus если загнать hex файл – не видно кода на Си и видны только входы/выходы с мк, при отладке в AVRStudio – код на Си виден, но не наглядно – нет временных диаграмм. И еще: может есть другие инструменты, без приложениям к мк?! 3) Есть ли что-нибудь из книг наподобие Miro Samek на русском для Cи?! TMX писал Цитата Про реализацию напишу позже Ждем, интересны детали – уверен, что каждый по-разному генерирует код из графов. Diz писал Цитата Если интересно, могу рассказать и про вариант с иерархией Интересно все и с иерархией и без. Если это возможно – то с простыми примерами, постановка задачи, с графом на 3-4 состояния, с кодом и с комментариями, желательно на Си для микроконтроллеров. Все в форум не войдет – может быть в rar(е) куда-нибудь выложите. Спасибо.
Сообщение отредактировал Владимир_2010 - Mar 5 2009, 07:17
|
|
|
|
|
Mar 5 2009, 14:29
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 19-01-05
Из: Москва
Пользователь №: 2 064

|
Цитата(Владимир_2010 @ Mar 5 2009, 10:54)  Применяя эту методу к нескольким различным задачам, убедил себя (возможно зря) что самое главное для любой задачи по автоматике на плк это нарисовать правильно конечный автомат (графы с переходами) и проверить его работу средствами моделирования – все остальное дело техники, рутинный труд, все можно делать по одному шаблону/правилам, выключив мозг, нужно только время. Хотел даже весь этот процесс автоматизировать и написать автоматический генератор из графов всех этих формул и схем. Но потом подумал, что не надо горячиться: наверняка все это давным-давно уже сделано кем-то. Теперь вот вижу что на языке Си IAR реализует этот подход в VisualState, Telelogiс, великий ученый Шалыто А. А. и его друзья. Присоединяюсь. У нас вообще рисуют , отлаживают и реализуют автоматы разные люди. В разных средах. Примерные этапы разработки: 1. Разделение уровня драйверов и автоматов. 2. Спецификация на драйверы. 3. Разработка драйверов для микроконтроллера. 3. Разработка драйверов для LabWindows/CVI 3. Рисование автоматов. 4. Реализация автоматов на С. 5. Отладка на PC в среде CVI. 6. Перенос на мк (сборка). автоматы очень удобны для написания протоколов обмена, в этом случае отладка на PC не всегда возможна. используем ДРАКОН, рисуем в EDGE Diagrammer
|
|
|
|
|
Mar 5 2009, 15:17
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 19-01-05
Из: Москва
Пользователь №: 2 064

|
Цитата(Владимир_2010 @ Mar 5 2009, 10:54)  Интересно все и с иерархией и без. Если это возможно – то с простыми примерами, постановка задачи, с графом на 3-4 состояния, с кодом и с комментариями, желательно на Си для микроконтроллеров. Все в форум не войдет – может быть в rar(е) куда-нибудь выложите. Спасибо. C для микроконтроллеров не бывает. Потому-то он так популярен, что где алгоритм не запусти, если стандарту соответствует, то работать будет. К сожалению, на русском языке можно почитать Шалыто и Парондажанова. На английском есть пяток книг, но там самые азы - только Самек предлагает интересную реализацию. Если нужно протокол сваять, то можно взять реализацию COCO/R для С и написать в L1 грамматике правила обработки, там генерится автомат, работает очень быстро. Правила обработки распознанных пакетов тоже удобно описывать автоматом, но на другом уровне. Продолжаю про автоматы - светофор как я думаю, вы и сами создать сможете, достаточно будет одного состояния. Простейшая реализация: состояния автомата нумеруются. пишется функция, в которой выбирается текущее состояние, в этом состоянии опрашиваются условия перехода в другое состояние. функция периодически вызывается. Код enum (RED, GREEN, YELLOW);
static char automaton_state = RED;
void super_auto(void) { switch (automaton_state) { case RED: if (timer_flag) { output_control(RED_LAMP, OFF); output_control(GREEN_LAMP, ON); start_timer (GREEN_DELAY); automaton_state = GREEN; } break; case YELLOW: ... ... } } преимущества: просто и понятно, минимальное использование стека, что для процессоров HOLTEK, например, весьма важно. недостатки: если состояний много, то они могут перебираться долго. На самом деле здесь помог бы переход по изменяемой метке, типа GOTO STATE, но в С такого нет. есть несколько модернизированных реализаций такого типа.
|
|
|
|
|
Mar 5 2009, 15:38
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(TMX @ Mar 5 2009, 18:17)  недостатки: если состояний много, то они могут перебираться долго. На самом деле здесь помог бы переход по изменяемой метке, типа GOTO STATE, но в С такого нет. есть несколько модернизированных реализаций такого типа. Позволю себе немного поправить Вас: С недавних пор реализация оператора switch() отдана на откуп оптимизатору, т.е если структура приводится к таблице переходов - никакого перебора не будет. За таким подходом - будущее. В принципе, компиляторы смогут даже патчить входные значения, например Код switch(state)
{
case 1:
case 2:
case 14:
case 15:
} Что мешает в "рваных" вариантах и вычислять адрес в таблице перехода по какому-нибудь вспомогательному алгоритму? По поводу вычисляемого goto - в гнусях такая фича ведь есть и давно. Если она войдет в "скрижали"...
|
|
|
|
|
Mar 5 2009, 16:55
|
Частый гость
 
Группа: Участник
Сообщений: 84
Регистрация: 1-08-06
Пользователь №: 19 250

|
Что касается визуализации, то я имел в виду следующее. Автомат описывается на С. Перед компляцией запускается утилита, которая парсит C-файл, находит все, относящееся к автомату - состояния, события, переходы, иерархию - после чего рисует красивый statechart. Который можно окинуть взглядом и убедиться, что все в порядке. Вот, для примера Pelican (светофор) от Самека:
pelican.pdf ( 94.3 килобайт )
Кол-во скачиваний: 301
|
|
|
|
|
Mar 5 2009, 17:09
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 19-01-05
Из: Москва
Пользователь №: 2 064

|
Цитата(_Pasha @ Mar 5 2009, 18:38)  Позволю себе немного поправить Вас:
С недавних пор реализация оператора switch() отдана на откуп оптимизатору, т.е если структура приводится к таблице переходов - никакого перебора не будет. За таким подходом - будущее. В принципе, компиляторы смогут даже патчить входные значения, например Встречал такое в аппнотах для PIC. Но это не бесплатно: таблица переходов тоже место занимает, кроме того, если вычисляемое значение, то компилятор может пустыми операциями забивать место. Реально проблема встает в дешевых контроллерах, где мало памяти, стека, скорости и т.п. или при реализации автомата в обработчике прерываний. Чтобы не полагаться на компилятор используются модернизированные методы: выше упоминалась ссылка http://www.embedded.com/2000/0012/0012feat1.htmтам Martin Gomez вручную забивает таблицу переходов: http://i.cmpnet.com/embedded/gifs/2000/001...t1_listing1.gifНедостатки: во-первых, надо записывать в трех местах и легко ошибиться. Во-вторых, вообще не понятно, зачем такая громоздкая реализация: состояние храниться в виде номера, функции и указателя на функцию. по номеру выбирается ссылка на функцию состояний и вызывается сама функция. Реализация требует и память и стек. Гораздо проще хранить состояние в виде ссылки на функцию. Память не используется, стек используется. Ошибиться при переходе сложнее. Цитата(Diz @ Mar 5 2009, 19:55)  Что касается визуализации, то я имел в виду следующее. Автомат описывается на С. Перед компляцией запускается утилита, которая парсит C-файл, находит все, относящееся к автомату - состояния, события, переходы, иерархию - после чего рисует красивый statechart. Который можно окинуть взглядом и убедиться, что все в порядке. Вот, для примера Pelican (светофор) от Самека:
pelican.pdf ( 94.3 килобайт )
Кол-во скачиваний: 301не слышал о таком, есть программа, которая flowchart генерирует. Писать программу без картинки - если получается, тогда зачем картинка?
|
|
|
|
|
Mar 5 2009, 17:31
|
Частый гость
 
Группа: Участник
Сообщений: 84
Регистрация: 1-08-06
Пользователь №: 19 250

|
Цитата(TMX @ Mar 5 2009, 20:09)  не слышал о таком, есть программа, которая flowchart генерирует. Писать программу без картинки - если получается, тогда зачем картинка? На самом деле картинка это побочный эффект. У меня упомянутая утилита (скрипт на питоне) собирает информацию об автомате и создает h-файл с несколькими дополнительными таблицами. Нужными для ускорения переходов между состояними в полностью иерархическом автомате - то, как сделано у Самека, с реалтаймовым поиском наименьшего общего предка в графе, жутко медленно. Ну а заодно можно и проверить нарушения правил кодирования statechart-а, и картинку сделать. Картинка - в первую очередь для самодокументации.
Сообщение отредактировал Diz - Mar 5 2009, 17:32
|
|
|
|
|
Mar 5 2009, 17:50
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(TMX @ Mar 5 2009, 20:09)  там Martin Gomez вручную забивает таблицу переходов no comment  Цитата в виде номера, функции и указателя на функцию. по номеру выбирается ссылка на функцию состояний и вызывается сама функция. Реализация требует и память и стек.
Писать программу без картинки - если получается, тогда зачем картинка? 1. А что? Дорого? Зато может способствовать уменьшению количества функций 2.Например, для повышения уровня языка реализации до проблемно-ориентированного http://www.citforum.ru/internet/xml/graphml/
|
|
|
|
|
Mar 6 2009, 07:35
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 19-01-05
Из: Москва
Пользователь №: 2 064

|
Цитата(_Pasha @ Mar 5 2009, 20:50)  no comment  Возможно, я не совсем понятно выразился - Gomez забивает не всю таблицу переходов автомата, а только одномерный массив jump table, указателей на функции состояний. Там в самом начале листинга можно ее увидеть. В любом случае это не дает преимуществ по сравнению с прямым присвоением: Код void(*state_pointer)(void) = RED_state; void main (void) { while(1) { state_pointer(); } }
void RED_state (void) { if (timer_flag) { output_control(RED_LAMP, OFF); output_control(GREEN_LAMP, ON); start_timer (GREEN_DELAY); state_pointer = GREEN_state; return; } if (button_flag) ...................... } Преимущества: работает быстро, фактически как вычисляемое GOTO Недостатки: требует стек для вызова функций, при реализации в прерываниях вызова по ссылке компилятор обычно сохраняет весь контекст, это долго и требует много стека. По поводу объема: в 8-битных процессорах если указатель занимает 2 байта, то каждое присвоение требует 2 команды ассемблера. Соответственно для автомата на 50 состояний и 150 переходов потребуется 300 команд в ПЗУ (600Б для AVR), для switch с переменной состояния типа char потребуется 300Б ПЗУ на переходы, для Gomez-технологии потребуется 300Б на переходы и 100Б на jump_table, итого 400Б. Для 16-ти и 32-х битных объем switch и присвоения указателей практически одинаков, а для Gomeza все равно дополнительно требуется место для jump table. Цитата 1. А что? Дорого? Зато может способствовать уменьшению количества функций 2.Например, для повышения уровня языка реализации до проблемно-ориентированного http://www.citforum.ru/internet/xml/graphml/1. За счет чего? C использованием switch вообще одна функция. 2.Обычно проблему снаала описывают, а потом реализуют. если еще есть интерес, могу продолжить про реализации...
|
|
|
|
|
Mar 6 2009, 14:35
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 19-01-05
Из: Москва
Пользователь №: 2 064

|
Цитата(Diz @ Mar 6 2009, 16:20)  Наверное, jumptable может быть полезен для сохранения текущего состояния в eeprom и восстановления после сбоя. Пишем лишь индекс, а не потенциально опасный указатель. сомнительно. все равно потом по указателю функция вызывается, для таких случаев обычно пишут лог переходов в том или ином виде, ну и список разрешенных переходов (собственно, он у Гомеса есть). реализовать кооперативную многозадачность с помощью конечных автоматов - собственно, этим я хотел закончить про реализации.
|
|
|
|
|
Mar 10 2009, 13:42
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 19-01-05
Из: Москва
Пользователь №: 2 064

|
Недостатки прямого присваивания значения переменной состояния, типа Код state = NEW_state в том, что при большом количестве ветвлений можно случайно пропустить присваивание. Одним из методов контроля на этапе компиляции является следующий: функция состояния возвращает значение следующего состояния Код void main (void) { static char state = STATE_X; while(1) { state = state_function(state); } }
char state_function (char state) { switch(state) { case STATE_X: if (event) { return STATE_Y; } else return STATE_X; case STATE_Y: ... case STATE_Z: ... } } кроме некоторого контроля за присваиванием, такой подход не дает никаких премуществ. Просто на практике не всегда бывает возможно обеспечить полноту тестов.
|
|
|
|
|
Mar 10 2009, 16:14
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(TMX @ Mar 6 2009, 18:35)  сомнительно. все равно потом по указателю функция вызывается, Индекс проще проверит на валидность. Всего лишь на максимум. Индекс удобно использовать при генерации события по смене состояния. Индекс удобно использовать для возврата в старое состояние. Кароч, я использую индексы и массивы функций. Иногда двумерный массив functions[state][event] в каком-нить менюшном сервисе.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Mar 10 2009, 16:57
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 19-01-05
Из: Москва
Пользователь №: 2 064

|
Цитата(Dog Pawlowa @ Mar 10 2009, 19:14)  Индекс проще проверит на валидность. Всего лишь на максимум. Индекс удобно использовать при генерации события по смене состояния. Индекс удобно использовать для возврата в старое состояние.
Кароч, я использую индексы и массивы функций. Иногда двумерный массив functions[state][event] в каком-нить менюшном сервисе. с первым согласен. Только какой смысл в такой проверке? Проверка в рантайме - от какого бага она спасает? Если на этапе отладки - использование только поименованных констант не позволит вызвать неописанное состояние. С другой стороны, где гарантия, что индексы идут подряд. со вторым и третьим - не могу ничего сказать. Не могли бы вы написать пример реализации поподробнее? Для одномерного и двумерного массива? Особенно, для functions[state][event], что является индексом массива? я считаю, что удобство понятие не только субъективное. Удобно - когда логическая ошибка проявляется как можно раньше. Например, на этапе компиляции (стоимость обнаружения) Удобно - когда при введении нового состояния его надо прописывать как можно в меньшем количестве списков (связность). И компилятор следит за правильностью (стоимость). Неудобно - когда в нескольких списках описание состояния должно быть с одинаковым номером (связность). Цитата(-=TRO=- @ Mar 10 2009, 19:47)  Внутри программируемой логики собирают микропроцесоры и пишут для них программы. На микроконтроллерах пишут программы эмулирующие логику(конечные автоматы). Походу использовать компоненты по назначению сегодня не модно. насколько я знаю, в 70-х годах было мнение, что наиболее перспективная парадигма в программировании - автоматный подход. "Лучше забивать молотком шурупы, чем закручивать отверткой гвозди"
|
|
|
|
|
Mar 10 2009, 17:36
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(TMX @ Mar 10 2009, 20:57)  с первым согласен. Только какой смысл в такой проверке? В некоторых случаях смысл есть. Например, после ресета можно вернуться в нужную точку. Делал прибор, который, зараза, был чувствителен к ESD. Вот и пришлось решать проблему программно. Цитата(TMX @ Mar 10 2009, 20:57)  Не могли бы вы написать пример реализации поподробнее? Для одномерного и двумерного массива? Да все тупо... CODE // Определения состояний и функций
#define stRestart 0 #define f0 fRestart
#define stSelfTest 1 #define f1 fSelfTest
#define stWaiting 2 #define f2 fWaiting
// массив функций const VECTORS function[stQty] = { f0, f1, f2, f3,..}
//основной цикл процесса
event=GetTimerEvent(); if (!event) event=GetOtherEvent(); // тут собыий много может быть ... if (!event) if (state-old_state) event=evNew; function[state](); event=0;
// пример функции
void fRestart(void) { switch (event) { case evNew: .... GetDateAndTime(); SetLcdPos(1,2); printf("%s",rtc_date); Old(); break;
case ev500ms: switch (restart_counter) { ... сase 4: if (!LowPowerStart) state= stSelfTest; else {SetLcdPos(1,2); printf(msgStartLowVoltage[lang]); } } break; if (restart_counter<4) restart_counter++; break;
case evUpDn: state=stStartUserMenu; break; } }
Причина редактирования: Уменьшение видимого размера цитаты исходника.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Mar 11 2009, 07:18
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(ReAl @ Mar 10 2009, 22:51)  Тада, и я это предложение даже проиллюстрировал уже... LOL : чуть дальше "Но реально не применяю :-), как-то не жмёт пока обычный switch()... " Вот и меня не жмет. А switch или таблица - это вопрос качества монитора и разрешения Если все case не помещаются на два-три экрана, то лучше бить на таблицу. Если помещаются, то лучше помолиться за IAR, который при оптимизации ту же таблицу сам нарисует.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Mar 11 2009, 08:24
|
Частый гость
 
Группа: Участник
Сообщений: 84
Регистрация: 1-08-06
Пользователь №: 19 250

|
Цитата(TMX @ Mar 6 2009, 17:35)  сомнительно. все равно потом по указателю функция вызывается, для таких случаев обычно пишут лог переходов в том или ином виде, ну и список разрешенных переходов (собственно, он у Гомеса есть). Пример взят из реальной задачи - нужно было при каждой смене состояния сохранять его во внешней eeprom, чтобы восстановить при пропадании питания. Лог переходов писать смысла нет, так как не важно, каким путем мы попали в данное состояние - важен сам факт попадания. Индекс - один байт, пишется атомарно. При загрузке легко его проверить на попадание в диапазон разрешенных состояний. Если будет восстановлено неверное состояние, неприятно, но не так разрушительно как вызов функции по неверному указателю. Еще одна особенность - прошивка могла быть обновлена, и обработчики могли бы лежать на других адресах.
|
|
|
|
|
Mar 11 2009, 09:06
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 19-01-05
Из: Москва
Пользователь №: 2 064

|
Цитата(Diz @ Mar 11 2009, 11:24)  Пример взят из реальной задачи - нужно было при каждой смене состояния сохранять его во внешней eeprom, чтобы восстановить при пропадании питания. Лог переходов писать смысла нет, так как не важно, каким путем мы попали в данное состояние - важен сам факт попадания. Индекс - один байт, пишется атомарно. При загрузке легко его проверить на попадание в диапазон разрешенных состояний. Если будет восстановлено неверное состояние, неприятно, но не так разрушительно как вызов функции по неверному указателю. Еще одна особенность - прошивка могла быть обновлена, и обработчики могли бы лежать на других адресах. я не уверен в содержимом eeprom, если запись ведется в момент пропадания питания. В свое время тестировали - операция записи атомарна с точки зрения программирования. А так она занимает довольно большое время и содержимое слетает. К тому же eeprom может быть внешним. Поэтому писали лог (из двух последовательных состояний) - запись на входе и на выходе. Тут даже проверка может быть очень простой - значения совпадают, значит состояние валидное. Не совпадают - брать предыдущую пару. Цитата(Dog Pawlowa @ Mar 10 2009, 20:36)  Да все тупо... то есть, если надо убрать одну функцию из центра списка, придется перенумеровывать все последующие? с событиями не совсем ясно: насколько я понял, функции опроса событий возвращают 0, если события нет и номер события, если событие есть. Как происходит нумерация событий? Получается, что события имеют приоритет, в порядке которого они опрашиваются. Из этого следует, что в любом состоянии приоритет событий одинаков. Более того, каждое состояние должно реагировать на все события. А если, допустим, первое событие - кнопка нажата, а второе - таймер сработал. Тогда при нажатой кнопке даже в состоянии "ждать таймер" система не будет не него реагировать.
Причина редактирования: Излишнее цитирование.
|
|
|
|
|
Mar 11 2009, 10:12
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(TMX @ Mar 11 2009, 12:06)  то есть, если надо убрать одну функцию из центра списка, придется перенумеровывать все последующие? Вовсе нет. Если это состояние не используется, есть два пути: 1) не делать ничего, разместив указатель на пустую функцию #define stSelfTest 1 >> #define st1 1 #define f1 fSelfTest >> #define f1 fEmpty 2) или, если два байта в таблице вдруг понадобились, перенести сюда функцию, последнюю в списке. Цитата(TMX @ Mar 11 2009, 12:06)  с событиями не совсем ясно: насколько я понял, функции опроса событий возвращают 0, если события нет и номер события, если событие есть. Как происходит нумерация событий? Получается, что события имеют приоритет, в порядке которого они опрашиваются. Из этого следует, что в любом состоянии приоритет событий одинаков. Более того, каждое состояние должно реагировать на все события. А если, допустим, первое событие - кнопка нажата, а второе - таймер сработал. Тогда при нажатой кнопке даже в состоянии "ждать таймер" система не будет не него реагировать. Разумеется, тут есть ограничения, которые закладываются на уровне проектирования системы. Они всегда есть, реализовывать, например, подавление дребезга с помощью такого автомата бессмысленно. Точнее, можно, но в отдельном автомате, и события для отдельного автомата должны быть другие. Я обычно предусматриваю отдельно до написания автомата все входящие события с запасом по ресурсам, все, требующее быстрой реакции, выносится в background (прерывания и общий цикл). Состояние не должно реагировать на все события, тут Вы не правы.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Mar 11 2009, 13:22
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 19-01-05
Из: Москва
Пользователь №: 2 064

|
Цитата(Dog Pawlowa @ Mar 11 2009, 13:12)  Состояние не должно реагировать на все события, тут Вы не правы. Возможно, я не совсем понял про функции опроса событий. Если они работают как написано ниже, то я был не прав: Все события обрабатываются однократно - функция опроса возвращает номер каждого события один раз. По окончании обработки переменная сбрасывается в ноль. При следующем опросе функция возвращает ноль - т.к. событие уже было отослано. Фактически, это модель с монитором однократных событий. Сложно сказать, какие преимущества и недостатки у моделей. А вот насчет вашей реализации - похоже на реализацию Gomez, но event driven, и те же недостатки. Простой switch по состояниями имеет меньше источников ошибок, поскольку там нет нумерации и перечисление событий только в одном месте. Цитата(_Pasha @ Mar 11 2009, 14:40)  Здесь и далее - плюспицот за каждое слово  К тому же, состояний, критичных к пропаданию питания, не должно быть много. В приличных девайсах надо закладывать раннюю диагностику пропадания питания.  А "много" это сколько? "Плюспицот" - это много? Тестировали атомарность записи в eeprom? А если да, то как? Я имею дело со всякими девайсами и разными процессорами. В различных средах разработки, кстати. Поэтому молиться на IAR как-то не тянет. Например, были готовые серийные девайсы с внешней EEPROM на программном SPI. Именно с проблемой восстановления. Я - за рациональные решения. Объясните, пожалуйста, зачем нужна ранняя диагностика питания и как она сказывается на приличности? Если результата можно добиться программными средствами - это красиво и целесообразно. Уточняю - это не для всех случаев. Я не против диагностики, я даже за резевный ионистор в НЕОБХОДИМЫХ случаях. А вопросы о приличности оставляю на рассмотрение депутатов.
|
|
|
|
|
Mar 11 2009, 13:46
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(TMX @ Mar 11 2009, 17:22)  А вот насчет вашей реализации - похоже на реализацию Gomez, но event driven, и те же недостатки. Мне важно иметь механизм, а с недостатками можно смириться. Для сведения - в устройстве более 100 состояний. Цитата(TMX @ Mar 11 2009, 17:22)  Простой switch по состояниями имеет меньше источников ошибок, поскольку там нет нумерации и перечисление событий только в одном месте. Когда "одно место" растягивается на много страниц, меня лично это раздражает, и я делаю больше ошибок. А со списком я вижу на три строчки, в которых перечислено название состояния (с суффиксами номера и функции) и текст, который выводится в терминал (или на дисплей) для его идентификации.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Mar 12 2009, 12:14
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 19-01-05
Из: Москва
Пользователь №: 2 064

|
Цитата(Dog Pawlowa @ Mar 11 2009, 16:46)  Мне важно иметь механизм, а с недостатками можно смириться. Для сведения - в устройстве более 100 состояний. Странно люди относятся к инструментам, которыми пользуются. К примеру, просто машину (не состояний) они тщательно выбирают, взвешивают все за и против, смотрят на внешний вид и удобство посадки. Тратят на это немало времени, читают журналы, просматривают интернет. Пожалуй, стоит взять на вооружение фразу "мне важно иметь механизм, а с недостатками можно смириться, для сведения - я проезжаю 100 км за раз" В то же время, с помощью методов и средств программирования мы зарабатываем деньги, в том числе, на автомобили. Почему бы не потратить время на поиск удачных решений? По поводу списка: в случае switch все состояния тоже переименовываются с помощью enum. Так что, вот и список (1 шт.). Кстати, для основных автоматов я использую не switch, а возврат функцией состояния указателя на следующую функцию состояния. Там тоже список прототипов функций (1 шт.). В одном из устройств у меня в фоновом процессе крутилось параллельно около 10 взаимосвязанных автоматов от 10 до 60 состояний в каждом. Плюс протокол обмена - порядка 100 состояний.
|
|
|
|
|
Mar 13 2009, 09:21
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(TMX @ Mar 12 2009, 15:14)  К примеру, просто машину (не состояний) они тщательно выбирают, взвешивают все за и против, смотрят на внешний вид и удобство посадки. Тратят на это немало времени, читают журналы, просматривают интернет. Пожалуй, стоит взять на вооружение фразу "мне важно иметь механизм, а с недостатками можно смириться, для сведения - я проезжаю 100 км за раз" Честно признаюсь - я свою машину купил за 10 минут и нисколько не жалею. Любая машина - кусок железа. Главное, что она выполняет свои функции. Так и с машиной состояний  Недостатки, которые знаешь, становятся просто фичами. Цитата(TMX @ Mar 12 2009, 15:14)  Почему бы не потратить время на поиск удачных решений? Логично, потратил. Цитата(TMX @ Mar 12 2009, 15:14)  в случае switch все состояния тоже переименовываются с помощью enum. Так что, вот и список (1 шт.). Не понял, как привязываются функции к состоянию. Поясните, плз. Зачем этот список состояний, если ниже : Цитата(TMX @ Mar 12 2009, 15:14)  Кстати, для основных автоматов я использую не switch, а возврат функцией состояния указателя на следующую функцию состояния. Там тоже список прототипов функций (1 шт.). Цитата(TMX @ Mar 12 2009, 15:14)  одном из устройств у меня в фоновом процессе крутилось параллельно около 10 взаимосвязанных автоматов от 10 до 60 состояний в каждом. Плюс протокол обмена - порядка 100 состояний. Померялись
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Mar 13 2009, 10:07
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 19-01-05
Из: Москва
Пользователь №: 2 064

|
Цитата(Dog Pawlowa @ Mar 13 2009, 12:21)  Не понял, как привязываются функции к состоянию. Поясните, плз. Зачем этот список состояний, если ниже : Просто мы используем несколько реализаций машин состояний: Для фоновой задачи, где много состояний - контроль оборудования, взаимодействие с пользователем и т.п. используется реализация с возвратом указателя (описана в раннем посте), она удобна для отладки. Поскольку обычно требования меняются по ходу разработки. В прерываниях или в случаях ограниченных ресурсов (маленький аппаратный стек, например) используется реализация с помощью switch. Ну а для меню написали специальную библиотеку и приложение под windows, которое генерирует уже инициализированную таблицу меню. Цитата(Dog Pawlowa @ Mar 13 2009, 12:21)  Померялись  Дело в том, что при с ростом сложности задачи, генерация и реализация автомата становится рутинной операцией. Проблемой становится выбор правил моделирования. На данный момент меня интересуют следующие вещи: 1. преимущества и недостатки моделей управляемых событиями и по опросу. Пока ясно, что модель по опросу менее требовательна к ресурсам в прерываниях. 2. организация взаимодействия между автоматами. Возможно, в некоторых случаях выгоднее применять иерархическую модель с управлением по событиям. В принципе, я давно этой темой интересуюсь. Многие иностранные книжки по этой теме у меня в бумажном варианте. Но кроме Samek'а ничего оригинального не предлагается - почти везде switch + UML модель по опросу.
|
|
|
|
|
Mar 13 2009, 14:59
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(TMX @ Mar 13 2009, 14:07)  Просто мы используем несколько реализаций машин состояний... В принципе, я давно этой темой интересуюсь. ... Понятно ... Где-то рядом ходим, только я меньше теорией интересуюсь, потому как следующий шаг - RTOS- в общем то напрашивается. А я не хочу. Приложение на PC тоже есть, но уже для ARM с ЖКИ, вместе с графикой, автоматически готовятся данные для SD-карты, и менюшка работает по данным SD-карты. В идеале код править не нужно - просто вставить другую карточку и получилось другое устройство. В форуме АРМов я эту тему затрагивал. Вопросы взаимодействия автоматов я в каком-то виде решил, обычно сочетаю явно редкие события плюс опросы состояний. Поскольку быстродействие switch по большому счету непредсказуемо, часто использую массив функций, что в сочетании с pragma inline дает великолепные результаты. Успехов  Готов всегда поддержать дискусиию
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Mar 13 2009, 16:08
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 19-01-05
Из: Москва
Пользователь №: 2 064

|
Цитата(Dog Pawlowa @ Mar 13 2009, 17:59)  Понятно ... Где-то рядом ходим, только я меньше теорией интересуюсь, потому как следующий шаг - RTOS- в общем то напрашивается. А я не хочу. Если автоматы по опросу (т.е. циклически вызываются), то можно сделать так: Код struct auto_struct { void *auto_ptr (void); int priority; int cnt; } automata_list = { automaton_1, 1, 0, automaton_2, 2, 0, automaton_3, 3, 0, };
while (1) { for (i = 0; i < sizeof(automata_list) / sizeof(struct auto_struct); i++) { if (--automata_list.cnt == 0) { automata_list.auto_ptr(); automata_cnt = automata.priority; } } } добавляем общие состояния ожидания с возвратом в предыдущее состояние и Voila! получаем кооперативную многозадачность.
|
|
|
|
|
Mar 13 2009, 16:23
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(TMX @ Mar 13 2009, 19:08)  Если автоматы по опросу (т.е. циклически вызываются), то можно сделать так: ...И в анализе приоритетов пишем Код if(automata.priority >= priority_sentinel) automata_list.auto_ptr(); А priority_sentinel ужЕ увеличивается/уменьшается в зависимости от частоты запросов на повышение приоритета.
|
|
|
|
|
Mar 13 2009, 21:30
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(Dog Pawlowa @ Mar 11 2009, 09:18)  LOL : чуть дальше "Но реально не применяю :-), как-то не жмёт пока обычный switch()... " По крайней мере я не пользуюсь этой возможностью не потому, что я о ней не знаю :-) Мне просто не нужен эффект от неё, а я с какого-то фига стараюсь не использовать нечто очень специфическое - хотя иногдасамому непонятно почему. Используют же работающие с IAR его всякие красивости и в ус не дуют. Впрочем, потихоньку прорывает, недавно таки поставил диапазонный case там, где он был удобен, чуть раньше локальную (вложенную) функцию использовал там, где она очень просилась.В подобных же темах часто обсуждается как бы выжать ещё немного объёма и скорости и в таком месте вычисляемый goto вполне в строку. Имеет общие черты как функцй, возвращющих указатели на фунции, так и switch
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Mar 14 2009, 13:07
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(Diz @ Mar 14 2009, 13:13)  Интересно, а как сделать с набором параллельно работающих конечных автоматов (без RTOS) долго работающую задачу, требующую активного участия процессора ? Например, работу с FAT (сектор может читаться значительное время) или рендеринг экрана для UI (тоже небыстро). Разбивать на отдельные этапы некрасиво и неудобно, а иначе задача будет блокировать другие на долгое время. Да, есть некоторая проблема. Там, где обращение к УВВ гробит интерфейс пользователя, делаем упреждающее чтение в память при включении устройства (ну типа Windows  ). Там где это невозможно... ну работали же раньше с дискетами? Часики, песочек...
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Mar 15 2009, 09:26
|
Частый гость
 
Группа: Участник
Сообщений: 84
Регистрация: 1-08-06
Пользователь №: 19 250

|
Цитата(singlskv @ Mar 15 2009, 01:23)  Разбивать на этапы, и других вариантов особо и нет... Ну или хитрое разделение с задачами выполняемыми в прерываниях. Вообщем, для таких вещей напрашивается RTOS. Или разделение на несколько процессоров, если задача позволяет.
Сообщение отредактировал Diz - Mar 15 2009, 09:27
|
|
|
|
|
Mar 17 2009, 20:14
|
Частый гость
 
Группа: Участник
Сообщений: 84
Регистрация: 1-08-06
Пользователь №: 19 250

|
Еще один интересный вариант реализации машины состояния на плюсах, использовали в одном проекте.
Каждое состояние представляется отдельным классом, унаследованным от базового. Все обработчики событий заданы в базовом классе как виртуальные функции: virtual void eventButtonPressed() = 0 ; virtual void eventTimerExpired() = 0 ;
Определяются конкретные обработчики уже в производных классах (состояниях). Также существует указатель, указывающий на текущее состояние (экземпляр класса). По приходу события просто вызывается нужная функция-член из класса по указателю.
Преимущества:
Базовый класс не обязательно должен быть абстрактным. Некоторые обработчики можно сразу определить в нем и получить реакцию на событие по умолчанию. Как пример, обработчик тика системного таймера, на который надо реагировать одинаково во всех состояниях.
Можно сделать более сложную иерархию классов. Унаследовать класс от базового, определить в нем обработчик (напр. eventPacketReceived). От этого класса наследовать еще несколько подсостояний, но там этот обработчик не определять. В итоге подстостояния унаследуют реакцию на eventPacketReceived от своего суперкласса. Получается простая реализация иерархической машины состояний.
Можно инкапсулировать в класс данные, нужные только для конкретного состояния - например, счетчик принятых пакетов.
Вменяемый плюсовый компилятор делает очень хороший код с оптимизацией - на такие задачи он и рассчитан, вообщем-то.
Хорошие IDE умеют показывать иерархию классов, что приятно для визуализации во время кодирования.
Недостатки:
Много писанины, много однострочных функций. Наглядности без визуализации IDE никакой.
Требуется еще одна таблица или switch для выбора метода по приходу события.
Компилятор может оказаться невменяемым :-)
|
|
|
|
|
Mar 19 2009, 20:12
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Diz @ Mar 15 2009, 12:26)  Вообщем, для таких вещей напрашивается RTOS. Или разделение на несколько процессоров, если задача позволяет. Какой нафиг RTOS...  вот буквально последняя задачка, опрос 6 дискретов с тактом 50мкс с фильтрацией (это быстрый процесс) и обмен по уарт на 230400("медленный" процесс), обмен при этом на скорости ~19Кбайт/сек все решает точное деление на состояния автомата обмена по уарту...
|
|
|
|
|
Mar 19 2009, 21:32
|
Частый гость
 
Группа: Участник
Сообщений: 84
Регистрация: 1-08-06
Пользователь №: 19 250

|
Цитата(singlskv @ Mar 19 2009, 23:12)  Какой нафиг RTOS...  вот буквально последняя задачка, опрос 6 дискретов с тактом 50мкс с фильтрацией (это быстрый процесс) и обмен по уарт на 230400("медленный" процесс), обмен при этом на скорости ~19Кбайт/сек все решает точное деление на состояния автомата обмена по уарту... Ну, это деление не этапы опять же :-) Иногда хочется использовать готовую библиотеку (для того же FAT) - бить на состояния уже непросто. Проще даже переписать с нуля.
Сообщение отредактировал Diz - Mar 19 2009, 21:35
|
|
|
|
|
Mar 20 2009, 20:10
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Dog Pawlowa @ Mar 20 2009, 12:05)  Да, большие готовые библиотеки лишают автоматы всяческих преимуществ... Однако тупик с автоматами... Не, не всегда так все печально..., если есть "жирная"(библиотечная в том числе) функция, то она работает в основном цикле проги, автоматы просто выносятся в прерывания, например в прерывания системного тика (10мс, 1мс, 100мкс, 25мкс...) Конечно при этом нужно "вручную" рулить приоритетами и занимаемым автоматами временем, но как бонус, 100% загрузка проца и максимальные параметры по автоматам(при удачном ручном распределении) Вобщем особых ограничений к использованию автоматов все равно не просматривается.... есть только частные ограничения реализации.
|
|
|
|
|
Mar 22 2009, 04:53
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Diz @ Mar 14 2009, 11:13)  Интересно, а как сделать с набором параллельно работающих конечных автоматов (без RTOS) долго работающую задачу, требующую активного участия процессора ? Например, работу с FAT (сектор может читаться значительное время) или рендеринг экрана для UI (тоже небыстро). Разбивать на отдельные этапы некрасиво и неудобно, а иначе задача будет блокировать другие на долгое время. ..... С FAT пример неудачен. Сектор то читается драйверком SPI, и пока он читается задача отдыхает (не требует активного участия CPU). Рендеринг экрана - подходящий пример. Посмотрим по аналогии. Есть Borland'овский VCL, где вся графика обслуживается исключительно в основном потоке приложения, и при запуске какой-то длительной задачки в том же основном потоке прорисовка приложения намертво тормозится. Чтобы пользователь не подумал, что программа зависла, можно и нужно было либо стартовать доп поток, либо, что значительно проще - иногда вызвать функцию: Application->ProcessMessages(); Вот так же можно поступить и тут. Что мешает реализовать некую функцию yield / idle - которую любой затяжной процесс сможет вызвать сам, чтобы дать поработать всем остальным процессам? Для того чтобы такую функцию можно было реализовать, необходимо чтобы был список задач(автоматов) с возможностью модификации в Run-Time (чтобы процесс вызывающий эту функцию мог быть удален из списка процессов на время своего испонения). Сосбно вот: CODE typedef void (* p_cb)(void);
#define COUNT(arr) (sizeof(arr) / sizeof((arr)[0]))
p_cb list[4];
void add_task( p_cb Callback) { for(int i = 0; i < COUNT(list); i++) if (!list[ i ]) { list[ i ] = Callback; break; } }
void idle(void) { for(int i = 0; i < COUNT(list); i++) if (list[ i ]) { p_cb cb = list[ i ]; list[ i ] = NULL; cb(); list[ i ] = cb; } }
void foo_1(void) { }
void foo_2(void) { }
// это долгий процесс делающий рендеринг void foo_long(void) { volatile unsigned long x = -1UL; while( x--) { // ... do complex stuff
if ( (x & 0xFF) == 0 ) // 255 iterations passed { // дадим поработать другим задачам idle(); } } }
void main(void) { add_task( foo_1 ); add_task( foo_2 ); add_task( foo_long ); for(;;) idle(); } Цитата Да, большие готовые библиотеки лишают автоматы всяческих преимуществ... Однако тупик с автоматами... Раскидать idle()'ов по ключевым точкам и автоматы получают вторую жизнь.
Причина редактирования: Уменьшение видимого размера цитаты исходника.
|
|
|
|
|
Mar 23 2009, 09:57
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(defunct @ Mar 22 2009, 07:53)  Раскидать idle()'ов по ключевым точкам и автоматы получают вторую жизнь. Конкретный пример. Готовая библиотека efsl. Вставка готового порта заняла час. Как по быстрому применить автомат для разделения процессов? Потратить несколько дней на разбиение на куски? Запихнуть процессы в прерывания? Да у меня под отладкой вообще прерывания глючат, все разобраться некогда. Тупик может не с автоматами, а в голове. Завтра выставка
--------------------
Уходя, оставьте свет...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|