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

 
 
4 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Принцип построения консоли управления устройством, Поделитесь опытом кто как делает :)
mempfis_
сообщение Aug 12 2009, 08:43
Сообщение #1


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

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Стоит задача разаработать устройство которое должно иметь возможность управляться через UART.
Думаю встроить отладочную консоль чтобы можно было посылать в устройство комманды и получать ответы.
Комманды в виде одиночных символов реализовал. Теперь хочу расширить функциональность консоли и реализовать длинные команды
(наподобие АТ-комманд). Причём хочется сделать аппаратно-независимую консоль чтобы можно было переносить из проекта в проект меняя только низкоуровневые функции приёма/отправки символовов через UART.

Подскажите кто как делает подобные консоли. Интересует прежде всего как осуществляется поиск комманд в потоке принимаемых символов (выделение слов длиной 2 и более символа)? Какие стандартные библиотеки можно использовать?

Сейчас реализована входная FIFO-UART которая заполняется в прерываниях и функция считывания символа из FIFO которая возвращает -1 если нет данных или принятый символ. Одиночные символы отлавливать легко (считал - обработал), два - уже сложнее но пока реализую устанавливая флаги.
Как отловить три и более символа - вот тут нужны идеи smile.gif
Go to the top of the page
 
+Quote Post
ukpyr
сообщение Aug 12 2009, 10:17
Сообщение #2


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

Группа: Участник
Сообщений: 1 264
Регистрация: 17-06-08
Из: бандустан
Пользователь №: 38 347



нужен приемный буфер на макс.количество символов в команде и обнулением счетчика по тайм-ауту.
признак завершения команды - символ CR.
для парсера команд как минимум нужна функция парсера DEC/HEX чисел.
парсер HEX легко реализуется путем преобразования Char HEX->BIN и сдвига на 4 бита влево.
DEC - нужно дополнительное преобразование BCD->BIN (поразрядным умножением на степени 10 или сдвигом+BCD коррекцией).
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Aug 12 2009, 10:26
Сообщение #3


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Собираете словарь команд (ASCIIZ), например
Код
const char cmd0[] ="READ";
const char cmd1[] ="ERASE";
const char cmd2[] ="WRITE";
const char *command_set[3] = {&cmd0,&cmd1,&cmd2};

Затем, поочередно сравниваете принятый токен со строками словаря, до тех пор, пока следующий символ из словаря не будет равен \0.
Дальше - все зависит от синтаксиса - допускаете ли Вы у себя разделители токенов или нет... Если разделители необязательны - возвращаете индекс, соответствующий command_set[j] указателю на распознанную команду, и текущую позицию в буфере, подразумевающую дальнейший разбор аргументов. Далее - switch() и тд произвольной сложности.

Игнорирование регистра символа делаете?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 12 2009, 11:24
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(_Pasha @ Aug 12 2009, 13:26) *
Собираете словарь команд (ASCIIZ), например

С размахом smile.gif
Код
int command( struct Cmd *cmd )
{
//---------------------------------------------------------------------------
case 'sst ':
...
        break;

case 'psst':
....
        break;

//--- Dummy arguments print -----------
case 'aa  ':
        printf( "\nargc=%i ls='%s'\r", cmd->argc, cmd->command_line );
        for( int i=0; i<= cmd->argc; i++ )
            printf( "argn[%i]=%08lX\r", i, cmd->argn[i] );
        break;

Команды - по первым четырем (для 32битника) символам. Стандартная разборка на аргументы делается заранее.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Aug 12 2009, 11:40
Сообщение #5


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(zltigo @ Aug 12 2009, 14:24) *
Стандартная разборка на аргументы делается заранее.

Дык это разбиение на токены заранее можно сделать... а разбор аргументов команды - личное дело самой команды smile.gif Или Вы оговорились?
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Aug 12 2009, 12:06
Сообщение #6


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



Длинные команды - бессмысленное пижонство.


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
Goodefine
сообщение Aug 12 2009, 14:31
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581



Зато обеспечивают детерминированное поведение системы, при значительном потоке символов...


--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Aug 12 2009, 15:44
Сообщение #8


Гуру
******

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



Цитата(Goodefine @ Aug 12 2009, 17:31) *
Зато обеспечивают детерминированное поведение системы, при значительном потоке символов...

Сказано мощно.
Это что, длинные команды как средство нейтрализации ошибок реализации протокола? smile.gif

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


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Goodefine
сообщение Aug 12 2009, 15:50
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581



Цитата(Dog Pawlowa @ Aug 12 2009, 18:44) *
Это что, длинные команды как средство нейтрализации ошибок реализации протокола? smile.gif

Не совсем smile.gif
В качестве контрпримера можно рассмотреть поведение управляемого объекта, с односимвольным набором команд, на вход которого постоянно что-то приходит. Без ошибок. При прочих равных, разумеется...


--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Aug 12 2009, 17:21
Сообщение #10


Гуру
******

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



Цитата(Goodefine @ Aug 12 2009, 18:50) *
В качестве контрпримера можно рассмотреть поведение управляемого объекта, с односимвольным набором команд, на вход которого постоянно что-то приходит. Без ошибок. При прочих равных, разумеется...

И что, как контрпример себя ведет?
Использую односимвольные наборы команд в обе стороны. Никаких проблем.
Очень удобно - в одну сторону идут коды нажатых клавиш, а в другую - коды символов, подлежащих отображению. Полный дуплекс, физический и логический. Если русский язык не нужен, коды управления дисплеем помещаются в правую сторону ASCII без проблем.
Тут главное - не пытаться придумывать что-то посредине между "простым" протоколом и "нормальным" протоколом, в результате получится зависающая хрень.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Aug 12 2009, 17:49
Сообщение #11


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Dog Pawlowa @ Aug 12 2009, 23:21) *
Очень удобно - в одну сторону идут коды нажатых клавиш, а в другую - коды символов, подлежащих отображению. Полный дуплекс, физический и логический.


Но это вроде немного не то, что хотел топикстартер?

Я лично применяю более-менее полноценную консоль, типа такого:

CODE
// обработчик команды.
typedef int (* CmdHandler)(char * args);

// структура с информацией о команде
typedef struct
{
char * command_name; // имя
CmdHandler handler; // обработчик
}
Command;

const Command CommandTable[] =
{
{"GET", GetCommandHandler},
{"SET", SetCommandHandler},
{"TERM", TermHandler},
...
};

int parse_command_line(char * buf)
{
char *lt;
char *token;
int i;

token = GetToken(buf, &lt);
if (!token) return FALSE;

for (i=0; i<sizeof(CommandTable) / sizeof(CommandTable[0]); i++)
if (!strcmp(CommandTable[i].command_name, token))
{
if (!CommandTable[i].handler)
return FALSE;
return CommandTable[i].handler(lt);
}

return FALSE;
}

void interpreter(void)
{
char buf[81];
for (;;)
{
rs_puts("\r\n=>");
rs_gets(buf, 80);
if (!parse_command_line(buf))
rs_puts("ERR");
}
}


Гораздо приятнее писать "SET PARAM1=23.4", чем "sA34", имея заодно возможность отредактировать строку при неверном вводе.
Да и не накладно это особо.
Причина редактирования: Уменьшение видимого размера цитаты исходника.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Aug 12 2009, 18:27
Сообщение #12


Гуру
******

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



Цитата(AHTOXA @ Aug 12 2009, 20:49) *
Гораздо приятнее писать "SET PARAM1=23.4"...


Если уж пошла речь о том, что приятнее, то я пришел к выводу, что лучше ПиСишное приложение, одно на все устройства, а из устройства может быть прочитано, какой физический смысл имеет PARAM1. Типа SNMP.

Хотя протокол именно текстовый - чтобы было "приятнее писать".


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Aug 12 2009, 19:06
Сообщение #13


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Dog Pawlowa @ Aug 13 2009, 00:27) *
Если уж пошла речь о том, что приятнее, то я пришел к выводу, что лучше ПиСишное приложение, одно на все устройства, а из устройства может быть прочитано, какой физический смысл имеет PARAM1. Типа SNMP.


Согласен, так тоже неплохо. Но есть, как мне кажется, пара аргументов против. Первый - универсальность. Линукс/виндовз/что-то там ещё, разные версии... Ну и можно банально забыть писишную программуsmile.gif Терминалка же есть везде.
И второй аргумент - в терминале можно не только конфигурировать устройство (SET/GET), но и выполнять что-то специфическое. Например, непрерывный вывод значения АЦП до нажатия любой кнопки, дрыгание заданной ножкой с заданной частотой. Интерактив, короче. Для таких применений сложно придумать универсальную программу для ПиСи, имхо.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Aug 12 2009, 19:08
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Читал протокол Пирамида. Правда это надпротокольный уровень. Основная идея состоит в том, что терминальное (писишное) приложение прочитает инфу с любого прибора и правильно её отобразит. То есть прибор(изделие) выдаёт по спец запросу - свою структуру, список полей и их тип, а приложение универсальное. Я предпочитаю INI файлы текстовые.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Aug 12 2009, 19:10
Сообщение #15


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Dog Pawlowa @ Aug 12 2009, 21:27) *
из устройства может быть прочитано, какой физический смысл имеет PARAM1.

+1 Все хинты и информация о параметре (разме/знаковость/диапазон) хранятся в приборе. Пустая консоль только спрашивает номер параметра в списке.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 19th July 2025 - 09:42
Рейтинг@Mail.ru


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