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

Пример взят из реальной задачи - нужно было при каждой смене состояния сохранять

его во внешней eeprom, чтобы восстановить при пропадании питания. Лог переходов писать смысла нет, так как не важно, каким путем мы попали в данное состояние - важен сам факт попадания.

Индекс - один байт, пишется атомарно. При загрузке легко его проверить на попадание

в диапазон разрешенных состояний. Если будет восстановлено неверное состояние,

неприятно, но не так разрушительно как вызов функции по неверному указателю.

Еще одна особенность - прошивка могла быть обновлена, и обработчики

могли бы лежать на других адресах.

 

я не уверен в содержимом eeprom, если запись ведется в момент пропадания питания. В свое время тестировали - операция записи атомарна с точки зрения программирования. А так она занимает довольно большое время и содержимое слетает. К тому же eeprom может быть внешним.

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

 

Да все тупо...

то есть, если надо убрать одну функцию из центра списка, придется перенумеровывать все последующие?

 

с событиями не совсем ясно:

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

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

А если, допустим, первое событие - кнопка нажата, а второе - таймер сработал. Тогда при нажатой кнопке даже в состоянии "ждать таймер" система не будет не него реагировать.

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


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

то есть, если надо убрать одну функцию из центра списка, придется перенумеровывать все последующие?

Вовсе нет. Если это состояние не используется, есть два пути:

1) не делать ничего, разместив указатель на пустую функцию

 

#define stSelfTest 1 >> #define st1 1

#define f1 fSelfTest >> #define f1 fEmpty

 

2) или, если два байта в таблице вдруг понадобились, перенести сюда функцию, последнюю в списке.

 

с событиями не совсем ясно:

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

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

А если, допустим, первое событие - кнопка нажата, а второе - таймер сработал. Тогда при нажатой кнопке даже в состоянии "ждать таймер" система не будет не него реагировать.

Разумеется, тут есть ограничения, которые закладываются на уровне проектирования системы. Они всегда есть, реализовывать, например, подавление дребезга с помощью такого автомата бессмысленно. Точнее, можно, но в отдельном автомате, и события для отдельного автомата должны быть другие. Я обычно предусматриваю отдельно до написания автомата все входящие события с запасом по ресурсам, все, требующее быстрой реакции, выносится в background (прерывания и общий цикл).

 

Состояние не должно реагировать на все события, тут Вы не правы.

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


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

Индекс - один байт, пишется атомарно.

 

Здесь и далее - плюспицот за каждое слово :) К тому же, состояний, критичных к пропаданию питания, не должно быть много.

 

 

я не уверен в содержимом eeprom, если запись ведется в момент пропадания питания.

В приличных девайсах надо закладывать раннюю диагностику пропадания питания. :(

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


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

Состояние не должно реагировать на все события, тут Вы не правы.

Возможно, я не совсем понял про функции опроса событий. Если они работают как написано ниже, то я был не прав:

Все события обрабатываются однократно - функция опроса возвращает номер каждого события один раз.

По окончании обработки переменная сбрасывается в ноль.

При следующем опросе функция возвращает ноль - т.к. событие уже было отослано.

 

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

А вот насчет вашей реализации - похоже на реализацию Gomez, но event driven, и те же недостатки.

 

Простой switch по состояниями имеет меньше источников ошибок, поскольку там нет нумерации и перечисление событий только в одном месте.

 

Здесь и далее - плюспицот за каждое слово :) К тому же, состояний, критичных к пропаданию питания, не должно быть много.

 

В приличных девайсах надо закладывать раннюю диагностику пропадания питания. :(

 

А "много" это сколько? "Плюспицот" - это много? Тестировали атомарность записи в eeprom? А если да, то как?

 

Я имею дело со всякими девайсами и разными процессорами. В различных средах разработки, кстати. Поэтому молиться на IAR как-то не тянет.

Например, были готовые серийные девайсы с внешней EEPROM на программном SPI. Именно с проблемой восстановления.

Я - за рациональные решения. Объясните, пожалуйста, зачем нужна ранняя диагностика питания и как она сказывается на приличности? Если результата можно добиться программными средствами - это красиво и целесообразно.

Уточняю - это не для всех случаев. Я не против диагностики, я даже за резевный ионистор в НЕОБХОДИМЫХ случаях. А вопросы о приличности оставляю на рассмотрение депутатов.

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


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

Тестировали атомарность записи в eeprom? А если да, то как?

 

Я заходил с другого края: при получении инфы о падении питания все операции запрещаются и пишется блок состояния контроллера с тем расчетом, что пока питание будет падать - времени для записи обязано хватить. Вариант с 24хх тоже рулит благодаря тому, что пишется сразу страница. Несложный комплекс мер, в том числе блочная CRC/LRC, кеширование данных из eeprom итд, навсегда убирают из обихода понятие "атомарность". Имхо, если речь заходит об  атомарности записи в eeprom - значит возможность обеспечить нормальную работу контроллера  отсутствует либо недоступна какая-то часть софта.

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


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

А вот насчет вашей реализации - похоже на реализацию Gomez, но event driven, и те же недостатки.

Мне важно иметь механизм, а с недостатками можно смириться. Для сведения - в устройстве более 100 состояний.

 

Простой switch по состояниями имеет меньше источников ошибок, поскольку там нет нумерации и перечисление событий только в одном месте.

Когда "одно место" растягивается на много страниц, меня лично это раздражает, и я делаю больше ошибок.

А со списком я вижу на три строчки, в которых перечислено название состояния (с суффиксами номера и функции) и текст, который выводится в терминал (или на дисплей) для его идентификации.

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


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

Мне важно иметь механизм, а с недостатками можно смириться. Для сведения - в устройстве более 100 состояний.

Странно люди относятся к инструментам, которыми пользуются.

К примеру, просто машину (не состояний) они тщательно выбирают, взвешивают все за и против, смотрят на внешний вид и удобство посадки. Тратят на это немало времени, читают журналы, просматривают интернет. Пожалуй, стоит взять на вооружение фразу "мне важно иметь механизм, а с недостатками можно смириться, для сведения - я проезжаю 100 км за раз" :a14:

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

 

По поводу списка:

в случае switch все состояния тоже переименовываются с помощью enum. Так что, вот и список (1 шт.).

Кстати, для основных автоматов я использую не switch, а возврат функцией состояния указателя на следующую функцию состояния. Там тоже список прототипов функций (1 шт.).

 

В одном из устройств у меня в фоновом процессе крутилось параллельно около 10 взаимосвязанных автоматов от 10 до 60 состояний в каждом. Плюс протокол обмена - порядка 100 состояний.

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


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

К примеру, просто машину (не состояний) они тщательно выбирают, взвешивают все за и против, смотрят на внешний вид и удобство посадки. Тратят на это немало времени, читают журналы, просматривают интернет. Пожалуй, стоит взять на вооружение фразу "мне важно иметь механизм, а с недостатками можно смириться, для сведения - я проезжаю 100 км за раз"

Честно признаюсь - я свою машину купил за 10 минут и нисколько не жалею. Любая машина - кусок железа. Главное, что она выполняет свои функции. Так и с машиной состояний :) Недостатки, которые знаешь, становятся просто фичами.

 

Почему бы не потратить время на поиск удачных решений?

Логично, потратил.

 

в случае switch все состояния тоже переименовываются с помощью enum. Так что, вот и список (1 шт.).

Не понял, как привязываются функции к состоянию. Поясните, плз. Зачем этот список состояний, если ниже :

 

Кстати, для основных автоматов я использую не switch, а возврат функцией состояния указателя на следующую функцию состояния. Там тоже список прототипов функций (1 шт.).

 

одном из устройств у меня в фоновом процессе крутилось параллельно около 10 взаимосвязанных автоматов от 10 до 60 состояний в каждом. Плюс протокол обмена - порядка 100 состояний.
Померялись :biggrin:

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


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

Не понял, как привязываются функции к состоянию. Поясните, плз. Зачем этот список состояний, если ниже :

Просто мы используем несколько реализаций машин состояний:

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

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

Ну а для меню написали специальную библиотеку и приложение под windows, которое генерирует уже инициализированную таблицу меню.

 

Померялись :biggrin:

Дело в том, что при с ростом сложности задачи, генерация и реализация автомата становится рутинной операцией. Проблемой становится выбор правил моделирования.

На данный момент меня интересуют следующие вещи:

1. преимущества и недостатки моделей управляемых событиями и по опросу. Пока ясно, что модель по опросу менее требовательна к ресурсам в прерываниях.

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

 

В принципе, я давно этой темой интересуюсь. Многие иностранные книжки по этой теме у меня в бумажном варианте. Но кроме Samek'а ничего оригинального не предлагается - почти везде switch + UML модель по опросу.

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


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

Просто мы используем несколько реализаций машин состояний...

В принципе, я давно этой темой интересуюсь. ...

Понятно ... Где-то рядом ходим, только я меньше теорией интересуюсь, потому как следующий шаг - RTOS- в общем то напрашивается. А я не хочу.

Приложение на PC тоже есть, но уже для ARM с ЖКИ, вместе с графикой, автоматически готовятся данные для SD-карты, и менюшка работает по данным SD-карты. В идеале код править не нужно - просто вставить другую карточку и получилось другое устройство. В форуме АРМов я эту тему затрагивал.

Вопросы взаимодействия автоматов я в каком-то виде решил, обычно сочетаю явно редкие события плюс опросы состояний.

Поскольку быстродействие switch по большому счету непредсказуемо, часто использую массив функций, что в сочетании с pragma inline дает великолепные результаты.

Успехов :) Готов всегда поддержать дискусиию :rolleyes:

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


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

что в сочетании с pragma inline дает великолепные результаты.
Ваш аргумент был последним, который перевесил соблазн пользоваться гнутым косвенным goto. Надолго :)

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


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

Понятно ... Где-то рядом ходим, только я меньше теорией интересуюсь, потому как следующий шаг - 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! получаем кооперативную многозадачность.

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


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

Если автоматы по опросу (т.е. циклически вызываются), то можно сделать так:

...И в анализе приоритетов пишем

 

 

if(automata.priority >= priority_sentinel) automata_list.auto_ptr();

 

А priority_sentinel ужЕ увеличивается/уменьшается в зависимости от частоты запросов на повышение приоритета.

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


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

это я показал round-robin с постоянным приоритетом, но разным доступом к ресурсам процессора.

т.е. автоматы с низким приоритетом (большим значением priority) вызываются реже.

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

 

Вопрос в организации запросов к ресурсам и ожидания.

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


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

Вопрос в организации запросов к ресурсам и ожидания.

Организация ожидания. Если нетрудно, осветите проблемы. Интересно. Еще добавлю линк на тему: http://electronix.ru/forum/index.php?showtopic=48243

 

Имхо, я добился полезного решения.

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


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

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

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

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

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

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

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

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

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

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