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

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Реализация конечного автомата на 8битном контроллере., Около 20 состояний. Хорошие исходники бы посмотреть.
jcxz
сообщение Jul 11 2017, 10:46
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(sigmaN @ Jul 11 2017, 13:02) *
Error[Pe020]: identifier "__even_in_range" is undefined main.cpp 140

__even_in_range() встречал только в IAR for MSP430. Сдаётся мне, что макрос этот характерен только для данного ядра.
Насколько помню: там (в MSP430) значения некоторых регистров периферии, содержащие перечисления, сделаны с шагом ==2 (т.е. - значения enum-ов для них идут с шагом 2, а не 1 как в стандарте).
Сделано это чтобы такое значение можно было просуммировать с адресом начала таблицы переходов (по switch) и сразу выполнить ветвление без лишних команд.
even - потому что через 2, так как размер памяти - 16 бит.
В этом макросе первый аргумент - это регистр, содержащий перечисление в таком формате, второй аргумент определяет размер таблицы переходов.
В STM8 регистры периферии с перечислениями не выполнены в таком формате, соответственно и макрос этот там бесполезен.
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jul 11 2017, 10:52
Сообщение #17


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

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



Цитата(sigmaN @ Jul 11 2017, 13:02) *
Error[Pe020]: identifier "__even_in_range" is undefined main.cpp 140
sad.gif

есть в IAR/MSP430 - используется в switch которые в векторах прерываний.
(для ускорения работы и для "одноразового" чтения параметра switch - если в кач-ве параметра исползован регистр с "автосбросом")

Есть смысл посмотреть в DASM как отрабатывают вирт. таблицы в Вашем компиляторе.
Скорее всего по томуже принципу.




Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 11 2017, 11:08
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(k155la3 @ Jul 11 2017, 13:52) *
Есть смысл посмотреть в DASM как отрабатывают вирт. таблицы в Вашем компиляторе.
Скорее всего по томуже принципу.

Нет. В STM8 нет регистров периферии организованных по такому принципу. И система команд там совсем другая. Поэтому такой макрос там бессмысленнен.
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jul 11 2017, 11:47
Сообщение #19


I WANT TO BELIEVE
******

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



С этим разобрались, осталось провести эксперименты и определить на сколько vtable проигрывает switch

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

Честно говоря пока у меня складывается впечатление, что если полиморфизм и проиграет голым уродливым свитчам то не значительно. Но без замеров это всё конечно пустые слова.


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


Местный
***

Группа: Свой
Сообщений: 339
Регистрация: 5-05-11
Пользователь №: 64 797



Цитата(sigmaN @ Jul 11 2017, 14:47) *
Честно говоря пока у меня складывается впечатление, что если полиморфизм и проиграет голым уродливым свитчам то не значительно. Но без замеров это всё конечно пустые слова.


По поводу C++ vs C есть замечательное видео:
https://www.youtube.com/watch?v=D7Sd8A6_fYU...eature=youtu.be
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Jul 11 2017, 13:15
Сообщение #21


I WANT TO BELIEVE
******

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



Видел. Там даже мой лайк имеется под этим видео ))
Жалко что это немного не по теме получается


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


Гуру
******

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



Цитата(pokk @ Jul 11 2017, 09:38) *
А то как не крути вечно такой колхоз получается

Что касается такого колхоза, то этого хватает у каждого.
И вообще это не колхоз, это классика - см ниже! wink.gif
Если речь идет о автоматах, кроющих практически всю функциональность устройства, то тут все становится сложнее, потому что не есть проблема реализовать это все, а проблемой является выбор собственного стиля и подхода, чтобы было все понятно и прозрачно в первую очередь для самого себя.

CODE

#define TRANSPORT_TIMEOUT_SERIAL_SEC 10
#define TRANSPORT_TIMEOUT_TCPIP_SEC 5
#define LONG_RUN_TIMEOUT_SEC 60
#define AUTO_PICKUP_TIME_MS 500
#define NUM_RETRIES 3

// added by me timeouts:
#define RECEIVE_TIMEOUT_MS 1000
#define ANSWER_TIMEOUT_MS 100









enum {
errNO=0,
errMESSAGE_SIZE,
errOP_CODE,
errRECORDS_QTY,
errINDEX1,
errINDEX2,
errINDEX3,
errNOT_SUPPORTED,
errREAD_ONLY,
errWRONG_SIZE,
errWRITE_ONLY,
errWRONG_OPCODE,
errSIZE,
};


#define RECEIVED_MESSAGE_LENGTH ((int)com1.rx_buf[1]+((int)com1.rx_buf[2])<<8)
#define RECEIVED_TYPE (com1.rx_buf[3])
#define RECEIVED_SEQUENCE (com1.rx_buf[4])
#define ctrlRECEIVED (com1.rx_buf[5])
#define ctrlACK ('A')
#define ctrlNAK ('N')
#define ctrlEND ('E')
#define ctrlWAIT ('W')
#define ctrlPICKUP ('P')
#define ctrlDROP ('D')
#define XML_PTR_FIRST (char*)(com1.rx_buf+5)
#define XML_PTR_LAST (com1.rx_buf+RECEIVED_MESSAGE_LENGTH-4)
#define ETX_INDEX (RECEIVED_MESSAGE_LENGTH-3)

/*
Control message
1 byte STX StartMessage
2 byte Unsigned Binary Length Length of the entire message; including StartMessage and EndMessage but excluding CRC bytes
1 byte ASCII Type 'C'
1 byte Unsigned Binary Sequence 0x00 is invalid value
1 byte ASCII ControlFunction 'A' ACK
'N' NAK
'E' End Sequence
'W' Wait
'P' Pickup
'D' Drop Link
1 byte ETX EndMessage
2 byte Binary CRC See CRC Calculation


Payload message
1 byte STX StartMessage
2 byte UnsignedBinary Length Length of the entire message; including StartMessage and EndMessage but excluding CRC bytes
1 byte ASCII Type 'P'
1 byte Unsigned Binary Sequence 0x00 is invalid value
Variable Unsigned Binary Payload The transported application protocol message
1 byte ETX EndMessage
2 byte Unsigned Binary CRC See CRC Calculation

*/

#define XML_START_OFFSET 5
#define XML_END_OFFSET 2

char payload_sent_wait_control;
char payload_sent_time;
char payload_sent_qty;





void PrepareTransportPayloadHeader(void)
{ com1.tx_head=com1.tx_buf;
*com1.tx_head++=STX;
com1.tx_head+=2; // pass length
*com1.tx_head++='P'; // payload type
*com1.tx_head++=RECEIVED_SEQUENCE;
}

void PrepareTransportControlMessage(char com)
{
int my_checksum;

com1.tx_head=com1.tx_buf;
*com1.tx_head++=STX;
*com1.tx_head++=7; // length = 7
*com1.tx_head++=0;
*com1.tx_head++='C'; // control type
*com1.tx_head++=RECEIVED_SEQUENCE;
*com1.tx_head++=com;
*com1.tx_head++=ETX;
my_checksum=crc16_ccitt(com1.tx_buf, 7);
*com1.tx_head++=(char)(my_checksum&0x00ff);
*com1.tx_head++=(char)(my_checksum>>8);
}

void PrepareTransportTrailer(void)
{
int my_size;
int my_checksum;

*com1.tx_head++=ETX;
my_size=com1.tx_head- com1.tx_buf;
com1.tx_buf[1]=(char)(my_size&0x00ff);
com1.tx_buf[2]=(char)(my_size>>8);
my_checksum=crc16_ccitt(com1.tx_buf, my_size);
*com1.tx_head++=(char)(my_checksum&0x00ff);
*com1.tx_head++=(char)(my_checksum>>8);

}




enum { UNCONFIGURED,
RESTART_RX,
WAITING_STX,
WAITING_ETX,
WAITING_BCC1,
WAITING_BCC2,
ANALYSE_MESSAGE,
PREPARE_MESSAGE,
START_SEND_MESSAGE,
WAITING_START_TRANSMIT,
WAITING_END_TRANSMIT,
FINAL,
PREPARE_NAK,
PREPARE_DROP,
PREPARE_END };

char transport_error;

#define USE_TIMEOUT 1

u16 TimeoutRunning(void)
{
#ifdef USE_TIMEOUT
return com1.timeout;
#else
return 1;
#endif
}


void fRnt(void)
{

static u16 my_checksum;
static u16 message_checksum;


switch (pstate)
{ case UNCONFIGURED:
Com1Init();
pstate++;
break;

case RESTART_RX:
Com1SetReceive(COM1_WAIT_STX);
prot_error=errNO;
pstate++;
OFF_LED5();
OFF_LED4();

break;

case WAITING_STX:
if ( payload_sent_wait_control )
{ if (payload_sent_qty<2)
{ if (event==evSec)
{ if (payload_sent_time<10)
payload_sent_time++;
else
{ pstate=START_SEND_MESSAGE;
payload_sent_qty++;
payload_sent_time=0;
}
}
}
else // all attempts done
payload_sent_wait_control=0;
}
else
{ payload_sent_qty=0;
payload_sent_time=0;
}


switch (com1.rx_status)
{ case COM1_RECEIVED:
pstate=RESTART_RX; // buffer is over
break;

case COM1_RECEIVING_:
pstate=WAITING_ETX;
com1.timeout=RECEIVE_TIMEOUT_MS;
break;
}
break;

case WAITING_ETX:
ON_LED4(); // recieving starts
if (TimeoutRunning())
{ if (com1.rx_head>com1.rx_tail)
{ switch (*com1.rx_tail)
{
case ETX:
// case EOT:
com1.rx_tail++;
if (com1.rx_tail>com1.rx_buf+5)
pstate++;
break;

default:
com1.rx_tail++;
break;
}
}
}
else
pstate=RESTART_RX;
break;

case WAITING_BCC1:
if (TimeoutRunning())
{ if (com1.rx_head>com1.rx_tail)
{ com1.rx_tail++;
pstate++;
}
}
else
pstate=RESTART_RX;
break;

case WAITING_BCC2:

if (TimeoutRunning())
{ if (com1.rx_head>com1.rx_tail)
{ com1.rx_tail++;
pstate++;
Com1SetReceive(COM1_PASSIVE);
}
}
else
pstate=RESTART_RX;
break;


case ANALYSE_MESSAGE:
OFF_LED4();
if (com1.rx_head<com1.rx_buf+8) // too short message
{ pstate=RESTART_RX;
break;
}
my_checksum=crc16_ccitt(com1.rx_buf, com1.rx_tail-com1.rx_buf-2);
message_checksum= ( ((unsigned int)*(com1.rx_head-2)) ) |
( ((unsigned int)*(com1.rx_head-1))<<8 );

#if (defined IGNORE_CHECKSUM)

#elif (defined USE_CHECKSUM)
if ( (my_checksum!=message_checksum) || // wrong checksum
(*(com1.rx_head-3) !=ETX) //not ETX
)
{ pstate=RESTART_RX;
break;
}
#else
#error "What to do with checksum?"
#endif



switch (RECEIVED_TYPE)
{ case 'C': // control message
switch (ctrlRECEIVED)
{ case ctrlEND:
pstate=PREPARE_END;
break;
case ctrlDROP:
pstate=PREPARE_DROP;
break;

default:
pstate=RESTART_RX;
break;
}
break;

case 'P': //
if (!AnalyseXmlOk(XML_PTR_FIRST,(char*)com1.rx_head-4))
pstate=PREPARE_NAK;
else
pstate=PREPARE_MESSAGE;
break;

}
break;

case PREPARE_MESSAGE:
ON_LED5(); // answering started
com1.tx_head=com1.tx_buf;
PrepareTransportPayloadHeader();
PrepareXml();
PrepareTransportTrailer();
pstate++;
payload_sent_wait_control=1;
payload_sent_time=0;
break;

case START_SEND_MESSAGE:
SET_TRANSMIT(); // for driver
pstate++;
com1.timeout=ANSWER_TIMEOUT_MS;
break;


case WAITING_START_TRANSMIT:
if (!com1.timeout)
{ Com1SetTransmit(COM1_TRANSMITTING);
pstate++;
}
break;

case WAITING_END_TRANSMIT:
if (com1.tx_status==COM1_TRANSMITTED)
if (TRANSMIT_OVER())
{ com1.timeout=0;
pstate++;
}
break;

case FINAL:
OFF_LED5();
pstate=RESTART_RX;
break;


case PREPARE_NAK:
pstate = UNCONFIGURED;
break;

case PREPARE_DROP: //0207004300440389AC
ON_LED5();
PrepareTransportControlMessage('D');
com1.timeout=ANSWER_TIMEOUT_MS;
SET_TRANSMIT();
pstate=WAITING_START_TRANSMIT;
break;

case PREPARE_END:
ON_LED5();
PrepareTransportControlMessage('E');
com1.timeout=ANSWER_TIMEOUT_MS;
SET_TRANSMIT();
pstate=WAITING_START_TRANSMIT;
payload_sent_wait_control=0;
break;

default:
pstate = UNCONFIGURED;
break;
}
}


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
501-q
сообщение Jul 25 2017, 05:57
Сообщение #23


Участник
*

Группа: Участник
Сообщений: 38
Регистрация: 24-02-09
Из: Екатеринбург
Пользователь №: 45 296



https://www.state-machine.com/
https://state-machine.com/psicc2/

Илья
Go to the top of the page
 
+Quote Post

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

 


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


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