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

 
 
> Реализация конечного автомата на 8битном контроллере., Около 20 состояний. Хорошие исходники бы посмотреть.
sigmaN
сообщение Jul 9 2017, 10:42
Сообщение #1


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Всем привет!
Сейчас сделано как-то так.
Прекрасно работает, расширяется. Всем доволен, но хотелось бы сравнить с тру 8ми битным подходом. Собственно какую-нибудь хорошую реализацию конечного автомата и хотелось бы где-то посмотреть.
Код
enum DeviceEvents
{
    DEVEV_HEARTBEAT,            //this event occures every ~100ms
    DEVEV_STARTBTN_PRESSED,
    //etc...
    DEVEV_NO_EVENT = 0xff,
}

enum DeviceState_enum
{
    DEVSTATE_OFF,              
    DEVSTATE_LOCKED,
    //etc....
    DEVSTATE_INVALID = 0xff,
}

//state interface class
struct DeviceStateImplementation
{
    virtual void EnterThisStateFrom( const DeviceState_enum &prevState ) = 0;
    //Handles event and returns new device state in response of event
    virtual DeviceState_enum HandleEvent( const DeviceEvents &event ) = 0;
};

//Implementation of DEVSTATE_OFF state
class StateImpl_OFF: public DeviceStateImplementation
{
    timestamp_t MillisecondsCounter;
    uint8_t MinutesCounter;
    bool ReactOnStartBTNRelease;

    void ResetMillisecondsCounter();
public:
    virtual void EnterThisStateFrom( const DeviceState_enum &prevState );
    virtual DeviceState_enum HandleEvent( const DeviceEvents &event );
};

//Implementation of DEVSTATE_OFF state
void StateImpl_OFF::EnterThisStateFrom( const DeviceState_enum &prevState )
{
    TurnOffAllOutputs();
    DisableRPMMeasure();
    G_SettingsStateSelector.ResetPressCounter();
    ReactOnStartBTNRelease = false;
    ResetMillisecondsCounter();
}

void StateImpl_OFF::ResetMillisecondsCounter()
{
    MillisecondsCounter = GetTickCount();
    MinutesCounter = 0;
}

DeviceState_enum StateImpl_OFF::HandleEvent( const DeviceEvents &event )
{
    DeviceState_enum retval = DEVSTATE_OFF;

    switch(event)
    {
    case DEVEV_HEARTBEAT:
        ACC_LEDBlinker.DoTheJob();

        if( G_SettingsStateSelector.GetSelectedState() != DEVSTATE_INVALID )
        {
            ACC_LEDBlinker.StartEndlessBlinkSequence(100, 100);//fast blinking indicating some settings mode was selected
        }
        break;

    case DEVEV_STARTBTN_PRESSED:
        ReactOnStartBTNRelease = true;
        break;

    case DEVEV_STARTBTN_RELEASED:
        //react on release only if press also was made in this state
        if( ReactOnStartBTNRelease )
        {
            ResetMillisecondsCounter();
            if( GlobalVarsRef.BrakePedal.GetButtonState() == GPIOBTNSTATE_PUSHED )
            {
                DeviceState_enum SelectedSettingsModeState = G_SettingsStateSelector.GetSelectedState();
                if( SelectedSettingsModeState != DEVSTATE_INVALID )
                    retval = SelectedSettingsModeState;
                else
                    retval = DEVSTATE_CRANKING;
            }
            else
            {
                retval = DEVSTATE_IGNON;
            }
        }
        break;

    case DEVEV_STARTBTN_LONGPRESS:
        if( GlobalVarsRef.BrakePedal.GetButtonState() == GPIOBTNSTATE_PUSHED )
            retval = DEVSTATE_FORCEDCRANKING;
        else
            retval = DEVSTATE_ACCON;
        break;

    case DEVEV_BREAKPEDAL_PRESSED:
        ResetMillisecondsCounter();
        G_SettingsStateSelector.SelectorWasPressed();

        ACC_LED::Clear();
        ACC_LEDBlinker.StartBlinkSequence(2, 50, 100);
        break;

    case DEVEV_BREAKPEDAL_RELEASED:
        ACC_LED::Clear();
        ACC_LEDBlinker.AbortBlinkSequence();
        break;

    case DEVEV_ENGINE_STARTED:
        retval = DEVSTATE_RUNNING;
        break;

    case DEVEV_ENGINE_STALLED:
        break;
    }

    return retval;
}

/////main state machine implementation
class MainStateMachine
{
public:
    void EnterStateForced( const DeviceState_enum &state );
    void ProcessEvent( const DeviceEvents &evnt );

private:
    DeviceStateImplementation *CurrentDevStateImplementation; //<----pointer to state interface class
    DeviceState_enum CurrentDevState;

    void SetNewDeviceState( const DeviceState_enum &newDevState );
};

void MainStateMachine::ProcessEvent( const DeviceEvents &evnt )
{
    DeviceState_enum newDevState = CurrentDevStateImplementation->HandleEvent( evnt );
    if( newDevState != CurrentDevState )
        SetNewDeviceState( newDevState );
}

void MainStateMachine::SetNewDeviceState( const DeviceState_enum &newDevState )
{
    switch( newDevState )
    {

    case DEVSTATE_OFF:
        CurrentDevStateImplementation = &OFFState;
        break;
    case DEVSTATE_LOCKED:
        CurrentDevStateImplementation = &LockedState;
        break;
    }
    CurrentDevStateImplementation->EnterThisStateFrom( CurrentDevState );
    CurrentDevState = newDevState;
}


//main loop simplifiyed
int main()
{
    while(1)
    {
        event = DEVEV_HEARTBEAT;
        while( event != DEVEV_NO_EVENT )
        {
            MainStateMachine.ProcessEvent( event );
            event = DetectOneMoreEvents();
        }
    }
}




--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 14)
iosifk
сообщение Jul 9 2017, 12:50
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(sigmaN @ Jul 9 2017, 13:42) *
Всем доволен, но хотелось бы сравнить с тру 8ми битным подходом. Собственно какую-нибудь хорошую реализацию конечного автомата и хотелось бы где-то посмотреть.

В ИТМО есть Шалыто А.А. И у них есть сайт со статьями по "switch-тенологиям"...
is.ifmo.ru


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jul 9 2017, 16:33
Сообщение #3


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



iosifk, спасибо, кажется нашел пдфку с которой стоит начать http://is.ifmo.ru/books/_book.pdf


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
iosifk
сообщение Jul 9 2017, 18:59
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(sigmaN @ Jul 9 2017, 19:33) *
iosifk, спасибо, кажется нашел пдфку с которой стоит начать http://is.ifmo.ru/books/_book.pdf

Еще в КиТ, в архиве статей 2006-11 и до 2007-8 статьи, автор Татарчевский...



--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jul 10 2017, 07:37
Сообщение #5


Гуру
******

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



Цитата(sigmaN @ Jul 9 2017, 13:42) *
Всем доволен, но хотелось бы сравнить с тру 8ми битным подходом. Собственно какую-нибудь хорошую реализацию конечного автомата и хотелось бы где-то посмотреть.

Биты то при чем?

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


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jul 10 2017, 07:53
Сообщение #6


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Биты при том, что при моей нынешней реализации(которую я вкратце привел) У меня при всём удобстве в редактировании и расширении маленько так сожрало и флэша и памяти.
Труды Шалыто А.А. я конечно изучу, полезно будет по любому, но думал может ещё народ скинет разных исходников "на посмотреть".

Может есть что-то готовое и красиво реализованное, например как protothreads, где switch красиво обыгран макросами или я не знаю... Реализацию табличного какого-нибудь подхода глянуть.
И именно 8ми битный контроллер был обозначен для того, чтоб не приводили полномасштабных вариантов с UI


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jul 10 2017, 09:09
Сообщение #7


Гуру
******

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



Цитата(sigmaN @ Jul 10 2017, 10:53) *
Биты при том, что при моей нынешней реализации(которую я вкратце привел) У меня при всём удобстве в редактировании и расширении маленько так сожрало и флэша и памяти.
И именно 8ми битный контроллер был обозначен для того, чтоб не приводили полномасштабных вариантов с UI

UI - это не GUI, это всего лишь дисплей 2х16, 4 кнопки и STM8.
Давайте адрес почты, пришлю файлов, но не весь проект.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jul 10 2017, 09:21
Сообщение #8


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Спасибо, будет интересно посмотреть!
altersoft mail.ru


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
XVR
сообщение Jul 10 2017, 10:30
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(sigmaN @ Jul 9 2017, 19:33) *
iosifk, спасибо, кажется нашел пдфку с которой стоит начать http://is.ifmo.ru/books/_book.pdf
Хм. Читать осторожно - у неподготовленного читателя может вызвать взрыв мозга. sm.gif

Что касается автоматов на МК с минимумум ресурсов (будем так называть '8ми битные контролеры') то тут явно напрашивается нечто на голом С либо в виде большого switch, либо таблицей переходов (в зависимости от количества состояний, переходов и архитектуры самого МК). А что бы не было 'мучительно больно' это все поддерживать (как минимум модифицировать) напрашивается какой нибудь генератор (либо из готовых, что были упомянуты в статье, либо что нибудь самописное на каком нибудь Perl'е или Python'е)

Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jul 10 2017, 10:56
Сообщение #10


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Цитата
Что касается автоматов на МК с минимумум ресурсов (будем так называть '8ми битные контролеры') то тут явно напрашивается нечто на голом С либо в виде большого switch, либо таблицей переходов
Вот на исходнички чего-нибудь такого и было бы интересно посмотреть. В частности интересно реализовать одинаковые автоматы двумя разными способами и сравнить их по быстродействию/занимаемой памяти....


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jul 10 2017, 12:37
Сообщение #11


Гуру
******

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



Цитата(XVR @ Jul 10 2017, 13:30) *
либо в виде большого switch, либо таблицей переходов


уже десять лет назад IAR AVR делал таблицу из большого свича на высоких уровнях оптимизации.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jul 10 2017, 23:02
Сообщение #12


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Вот дойдут как-нибудь руки до сравнений и будет интересно посмотреть на результаты.

Так то в моей текущей реализации вызов обработчика событий идет через указатель CurrentDevStateImplementation, который является указателем на интерфейс класса, хотя записан туда адрес конкретной реализации. Что при вызове метода через этот указатель ВНЕЗАПНО biggrin.gif приводит к использованию vtable https://ru.wikipedia.org/wiki/%D0%A2%D0%B0%...%B4%D0%BE%D0%B2

В связи с чем и становится интересно, а будет ли реальная экономия хоть чего-нибудь если все эти состояния положить в огромный switch, который потом IAR доблестно превратит в таблицу с адресами функций... Что в итоге будет снова ооочень напоминать vtable )


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jul 11 2017, 06:33
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(sigmaN @ Jul 11 2017, 02:02) *
. . .
В связи с чем и становится интересно, а будет ли реальная экономия хоть чего-нибудь если все эти состояния положить в огромный switch, который потом IAR доблестно превратит в таблицу с адресами функций... Что в итоге будет снова ооочень напоминать vtable )

Смотря как компилятором реализуется работа vtable и какая "вложенность".
Если использовать правильный switch (опятьже зависит от комилятора) который генерирует "вычисляемые" переходы.
"правильный" - это в IAR конструкция
Код
switch ( __even_in_range(TBIV, 14)  )
{ ...

Go to the top of the page
 
+Quote Post
pokk
сообщение Jul 11 2017, 06:38
Сообщение #14


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

Группа: Участник
Сообщений: 91
Регистрация: 3-07-11
Пользователь №: 66 028



Dog Pawlowa, можно тоже исходники глянуть? m65535625@gmail.com

А то как не крути вечно такой колхоз получается
(Передача пакета данных по usart)
CODE
void Sendpackage(void){
static uint8_t mode;
static uint16_t counter;
uint8_t* Data;
switch(mode){
case 0:{
//---------------------------------------------
//--------Ожидание команды на отправку---------
//---------------------------------------------
if(TransmitDataStart==Transmit_START){
TransmitDataStart=Transmit_STOP;
Data=&Protocol;
mode=1;
}
break;
}
//-------------------------------------------------
case 1:{
if(counter<sizeof(ProtocolExchange_t)){
if(USART3->SR & USART_SR_TC){
USART3->DR =(uint8_t)Data[counter];
counter++;
}
}else{
mode=0;
}
break;
}
//-------------------------------------------------
}
}

Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jul 11 2017, 10:02
Сообщение #15


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Цитата
Смотря как компилятором реализуется работа vtable и какая "вложенность".
Ну "вложенность" получается 1. Указатель на абстрактный класс указывает на реализацию класса.

Про __even_in_range() не знал, протестируем

Add:
Последний IAR STM8
Error[Pe020]: identifier "__even_in_range" is undefined main.cpp 140
sad.gif


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th June 2025 - 16:52
Рейтинг@Mail.ru


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