|
Строковый парсер на VHDL |
|
|
|
Jul 3 2017, 07:44
|
Знающий
   
Группа: Участник
Сообщений: 518
Регистрация: 29-09-11
Пользователь №: 67 450

|
Цитата(Jenya7 @ Jul 3 2017, 11:41)  а как мне определить строку? как массив байтов? Я бы разбирал непосредственно поток байтов на входе парсера. А шаблоны - константы и переходы в машине состояний. Попробуйте написать парсер на Си в виде функции, принимающей входной поток побайтно и разбирающей его с использованием статических переменных предыдущего состояния. А потом переписать это на VHDL.
|
|
|
|
|
Jul 3 2017, 08:06
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(novikovfb @ Jul 3 2017, 12:44)  Я бы разбирал непосредственно поток байтов на входе парсера. А шаблоны - константы и переходы в машине состояний. Попробуйте написать парсер на Си в виде функции, принимающей входной поток побайтно и разбирающей его с использованием статических переменных предыдущего состояния. А потом переписать это на VHDL. шутите? с С на VHDL? это прием строки по UART Код void USART1_IRQHandler(void) { /* RXNE handler */ if ((USART1->SR & USART_IT_RXNE) != RESET) // Received character? { /* Copy data into RX Buffer */ uint8_t chr = (USART1->DR & (uint16_t)0x01FF); if (chr=='\r') //0xD,0xA { usart1_rx_buf[usart1_rx_idx] = '\0'; usart1_rx_idx = 0; usart1_rx_ready = 1; } else { if(chr=='\b') { if (usart1_rx_idx > 0) usart1_rx_idx--; return; } if(usart1_rx_idx < RX1_BUFFERSIZE) //no overflow { usart1_rx_buf[usart1_rx_idx] = chr; usart1_rx_idx++; } else usart1_rx_overflow = 1; } /* Clear RXDATAV interrupt */ //USART_IntClear(UART0, UART_IF_RXDATAV); USART1->SR = (uint16_t)~USART_FLAG_RXNE; } } а это парсер строки Код uint32_t PARSER_ParseInputString(char* str, char** args) { uint32_t argc=0;
args[argc] = strtok(str, ARGS_DELIM);
while (args[argc] != NULL) { if(argc >= ARGS_MAX) return (ARGS_MAX+1); args[++argc] = strtok (NULL, ARGS_DELIM); }
return argc; }
uint32_t PARSER_ParseCommand(char *str) { uint32_t len = strlen(str); char temp_str[len]; strcpy (temp_str, str); uint32_t argc = PARSER_ParseInputString(temp_str, args); if (!argc) return ST_PARSE_NO_ARGS; uint32_t arg_count = (argc - 1); uint32_t i; uint32_t result; char *com = ToLower(args[0]); for (i = 0; i < sizeof(commands); i++) { //command found if (com_found) break; if (strcmp(commands[i].name,com)==0) { com_found = 1; if (arg_count < commands[i].minargs) return ST_PARSE_WRONG_ARGS; if (arg_count > commands[i].maxargs) return ST_PARSE_WRONG_ARGS; result = commands[i].fp(arg_count, args); switch (result) { case MSG_OK: Parser_SendString(USART2, msg_ok, print_out); break; case MSG_INV_INP: Parser_SendString(USART2, msg_invinp, print_out); break; case MSG_INV_ARG: Parser_SendString(USART2, msg_invarg, print_out); break; case MSG_MIS_ARG: Parser_SendString(USART2, msg_misarg, print_out); break; } } } if (com_found) com_found = 0; else { Parser_SendString(USART2, msg_wrncom, print_out); return ST_PARSE_WRONG_COM; } return ST_PARSE_OK; } и как это переписать на VHDL?
|
|
|
|
|
Jul 3 2017, 08:14
|
Знающий
   
Группа: Участник
Сообщений: 518
Регистрация: 29-09-11
Пользователь №: 67 450

|
Цитата(Jenya7 @ Jul 3 2017, 12:06)  и как это переписать на VHDL? Прием строки - совсем не в тему, надо читать байты из порта на аппаратном уровне, а парсер переписать без использования библиотечных функций, с побайтовым анализом. Т.е. считан байт из порта, по его значению переходим на соответствующую ветку состояний (все команды, начинающиеся на этот байт), по следующему байту - уточняем состояние и т.д. Вот если команды не имеют явных разделителей - будет тоскливо: придется буферизировать входной поток и искать в нем требуемые последовательности, что гораздо затратнее. Почитайте про машины состояний. И еще, после изучения и попыток написать на VHDL, возможно, придет понимание, что с встраиванием микропроцессоров в ПЛИС люди заморачиваются не от нечего делать, а для облегчения таких действий = громоздких и не требующих большого быстродействия.
|
|
|
|
|
Jul 3 2017, 11:39
|

я только учусь...
     
Группа: Модераторы
Сообщений: 3 447
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839

|
Цитата(novikovfb @ Jul 3 2017, 11:14)  Прием строки - совсем не в тему, надо читать байты из порта на аппаратном уровне, а парсер переписать без использования библиотечных функций, с побайтовым анализом. Т.е. считан байт из порта, по его значению переходим на соответствующую ветку состояний (все команды, начинающиеся на этот байт), по следующему байту - уточняем состояние и т.д. Вот если команды не имеют явных разделителей - будет тоскливо: придется буферизировать входной поток и искать в нем требуемые последовательности, что гораздо затратнее. Почитайте про машины состояний. И еще, после изучения и попыток написать на VHDL, возможно, придет понимание, что с встраиванием микропроцессоров в ПЛИС люди заморачиваются не от нечего делать, а для облегчения таких действий = громоздких и не требующих большого быстродействия. не всегда, иногда наоборот берут N микропроцессоров от не знания технологий FPGA Потом мучаются с синхронизацией процессов приема/обработки/передачи данных Цитата(Jenya7 @ Jul 3 2017, 10:19)  Это я и хочу. Попробовать парсить. Но я не знаю как подойти к этому вопросу на VHDL. Для этого делают програмный протокол обмена. Например 1 байт - синхробайт 2 байт - адрес получателя 3 байт - команда (0-255 команд в один байт можно запихнуть) 4 байт - количество данных 5-N байт - данные N+1 байт - CRC по такому Вы уже делаете автомат... Который принимает/отправляет данные. Для простоты желательно чтобы длина пакета была фиксированной Не забываем про взаимную синхронизацию приемника и передатчка в UART. Мое мнение лучше FTDI - SPI (не надо думать про синхронизацию)
--------------------
If it doesn't work in simulation, it won't work on the board.
"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
|
|
|
|
|
Jul 3 2017, 11:46
|

фанат Linux'а
    
Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008

|
Цитата(Jenya7 @ Jul 3 2017, 11:06)  и как это переписать на VHDL? Это не надо переписывать на VHDL. Во-первых на Verilog  Во-вторых, не надо переписывать, а лучше сделать абсолютно новую реализацию. Судя по коду, протокол простой текстовый, не вижу сложностей. Только вот, можно ли взглянуть на команды и пакеты в их первозданном виде? Еще рекомендация: для подобного парсера идеально использовать симулятор и отлаживать при помощи соответствующего тестбенча.
--------------------
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|