Мощный встроенный shell
Кроме того, версия 3.0 изменила формат и определение команд, поэтому проекты на версии 2.x потребуют небольших изменений для миграции.
Если требуется использование только базовых функций, можно использовать версию letter shell 2.x.
Инструкции по использованию можно найти в Letter shell 3.0: Новый старт
Определение объекта shell
Shell shell;
Определение функций чтения и записи shell, прототипы функций следующие
/**
* @brief Прототип функции чтения данных shell
*
* @param char shell считывает символ
*
* @return char 0 — успешное чтение данных
* @return char -1 — неудачное чтение данных
*/
typedef signed char (*shellRead)(char *);
/**
* @brief Прототип функции записи данных для shell
*
* @param const char символ для записи
*/
typedef void (*shellWrite)(const char);
Запросить область буфера
char shellBuffer[512];
```4. Вызов shellInit для инициализации
```C
shell.read = shellRead;
shell.write = shellWrite;
shellInit(&shell, shellBuffer, 512);
Вызов (создание) задачи shell
Для работы в операционной системе создайте задачу shellTask
(убедитесь, что конфигурация в shell_cfg.h
верна), параметром задачи является объект shell
OsTaskCreate(shellTask, &shell, ...);
Для работы в режиме без операционной системы вызовите shellTask
в основном цикле или при получении данных вызовите shellHandler
Объяснение
shell->read
, но необходимо вызывать shellHandler
в прерыванияхSHELL_TASK_WHILE
, затем создайте задачу shellTask
Другие настройки
SHELL_GET_TICK()
как функцию получения системного тика, включите двойное нажатие клавиш, автозавершение длинных команд помощиМакросы конфигурации Файл shell_cfg.h содержит все макросы для настройки shell, которые необходимо настроить перед использованием | Макропараметр | Описание | | ---------------- | ------------------------------ | | SHELL_TASK_WHILE | Использовать ли по умолчанию цикл while для задач shell | | SHELL_USING_CMD_EXPORT | Использовать ли метод экспорта команд | | SHELL_HELP_LIST_USER | Включать ли пользователей в список команд помощи | | SHELL_HELP_LIST_VAR | Включать ли переменные в список команд помощи | | SHELL_HELP_LIST_KEY | Включать ли клавиши в список команд помощи | | SHELL_ENTER_LF | Использовать LF как триггер ввода команд | | SHELL_ENTER_CR | Использовать CR как триггер ввода команд | | SHELL_ENTER_CRLF | Использовать CRLF как триггер ввода команд | | SHELL_COMMAND_MAX_LENGTH | Максимальная длина команды shell | | SHELL_PARAMETER_MAX_NUMBER | Максимальное количество параметров команды shell | | SHELL_HISTORY_MAX_NUMBER | Максимальное количество записей истории команд | | SHELL_DOUBLE_CLICK_TIME | Интервал между двойным щелчком (мс) | | SHELL_MAX_NUMBER | Максимальное количество управляемых shell | | SHELL_GET_TICK() | Получить системное время (мс) | | SHELL_SHOW_INFO | Выводить ли информацию о shell | | SHELL_CLS_WHEN_LOGIN | Очистить ли командную строку при входе | | SHELL_DEFAULT_USER | По умолчанию пользователь shell | | SHELL_DEFAULT_USER_PASSWORD | Пароль по умолчанию для пользователя shell | | SHELL_LOCK_TIMEOUT | Время ожидания автоматического блокирования shell |## Способы использования### Определение функций
Letter Shell 3.0 поддерживает два способа определения функций: подобно определению функции main func(int argc, char *argv[])
и обычное определение C-функции func(int i, char *str, ...)
. Эти способы определения функций подходят для различных сценариев.
Пример определения функции в такой форме:
int func(int argc, char *argv[])
{
printf("%d параметр(ов)\r\n", argc);
for (char i = 1; i < argc; i++)
{
printf("%s\r\n", argv[i]);
}
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), func, func, test);
Вызов из терминала:
letter:/$ func "hello world"
2 параметр(ов)
hello world
Пример определения функции в такой форме:
int func(int i, char ch, char *str)
{
printf("входное целое: %d, символ: %c, строка: %s\r\n", i, ch, str);
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), func, func, test);
Вызов из терминала:
letter:/$ func 666 'A' "hello world"
входное целое: 666, символ: A, строка: hello world
Shell управляет определенными shell-объектами с помощью статического массива. Количество shell-объектов можно изменить, задав макрос SHELL_MAX_NUMBER
(для избежания динамического выделения памяти, используется массив для управления). В функциях, выполняемых shell, можно вызвать shellGetCurrent()
для получения текущего активного объекта shell, что позволяет реализовать различные поведения функции в разных shell-объектах. Также можно использовать этот метод для получения объекта shell и вызова shellWriteString(shell, string)
для вывода в shell.## Определение команд
Letter Shell 3.0 объединяет определение исполняемых функций, команд, кнопок и переменных в единое определение команд, используя одинаковую структуру для хранения, поиска и выполнения.
Letter Shell поддерживает добавление команд с помощью метода экспорта команд и таблицы команд. Метод экспорта команд контролируется макросом SHELL_USING_CMD_EXPORT
. Поддержка экспорта команд осуществляется для Keil, IAR (не тестировано) и GCC.
Экспорт команд через определение констант
Внешние команды определяются с помощью констант, например:
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_DISABLE_RETURN, help, shellHelp, "показывает информацию о команде\r\nhelp [cmd]");
При использовании Keil для компиляции, необходимо добавить опцию --keep shellCommand*
в настройках цели, чтобы предотвратить оптимизацию определенных команд.
При использовании GCC для компиляции, необходимо добавить следующее в файле линковщика (LD):
_shell_command_start = .;
KEEP (*(shellCommand))
_shell_command_end = .;
Экспорт команд через таблицу команд
shell_cmd_list.c
:const SHELL_CommandTypeDef shellDefaultCommandList[] =
{
SHELL_CMD_ITEM(
SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_DISABLE_RETURN,
help, shellHelp, "показывает информацию о команде\r\nhelp [cmd]"),
};
```### Описание макросов
Letter Shell 3.0 предоставляет макросы для определения исполняемых команд, кнопок, пользователей и переменных.
Определение исполняемых команд
Используйте макрос SHELL_EXPORT_CMD
для определения исполняемых команд:
#define SHELL_EXPORT_CMD(_attr, _name, _func, _desc) \
const char shellCmd##_name[] = #_name; \
const char shellDesc##_name[] = #_desc; \
const ShellCommand \
shellCommand##_name SECTION("shellCommand") = \
{ \
.attr.value = _attr, \
.data.cmd.name = shellCmd##_name, \
.data.cmd.function = (int (*)())_func, \
.data.cmd.desc = shellDesc##_name \
}
Определение переменных
Используйте макрос SHELL_EXPORT_VAR
для определения переменных:
/**
* @brief Определение переменной shell
*
* @param _attr Атрибуты переменной
* @param _name Имя переменной
* @param _value Значение переменной
* @param _desc Описание переменной
*/
#define SHELL_EXPORT_VAR(_attr, _name, _value, _desc) \
const char shellCmd##_name[] = #_name; \
const char shellDesc##_name[] = #_desc; \
const ShellCommand \
shellVar##_name SECTION("shellCommand") = \
{ \
.attr.value = _attr, \
.data.var.name = shellCmd##_name, \
.data.var.value = (void *)_value, \
.data.var.desc = shellDesc##_name \
}
Определение пользователей
Используйте макрос SHELL_EXPORT_USER
для определения пользователей, определение представлено ниже ```C
/**
Используйте макрос `SHELL_EXPORT_KEY` для определения кнопок, определение представлено ниже
```C
/**
* @brief Определение кнопки в командной строке
*
* @param _attr Атрибуты кнопки
* @param _value Значение кнопки
* @param _func Функция кнопки
* @param _desc Описание кнопки
*/
#define SHELL_EXPORT_KEY(_attr, _value, _func, _desc) \
const char shellDesc##_value[] = #_desc; \
const ShellCommand \
shellKey##_value SECTION("shellCommand") = \
{ \
.attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_KEY), \
.data.key.value = _value, \
.data.key.function = (void (*)(Shell *))_func, \
.data.key.desc = shellDesc##_value \
}
Значение кнопки представляет собой последовательность символов, отправляемых терминалом при нажатии кнопки. Например, при нажатии кнопки Tab в SecureCRT отправляется 0x0B, поэтому значение кнопки равно 0x0B000000. Если нажать кнопку вверх, будут отправлены последовательно 0x1B, 0x5B, 0x41, поэтому значение кнопки равно 0x1B5B4100.
attr
, которое представляет атрибуты команды, подробное определение представлено ниже:union
{
struct
{
unsigned char permission : 8; /**< permission */
ShellCommandType type : 4; /**< тип команды */
unsigned char enableUnchecked : 1; /**< доступен без проверки пароля */
unsigned char disableReturn : 1; /**< отключить вывод возвращаемого значения */
unsigned char reserve : 2; /**< резерв */
unsigned char paramNum : 4; /**< количество параметров */
} attrs;
int value;
} attr;
При определении команды необходимо указать эти значения, что можно сделать с помощью макросов SHELL_CMD_PERMISSION(permission)
, SHELL_CMD_TYPE(type)
, SHELL_CMD_ENABLE_UNCHECKED
, SHELL_CMD_DISABLE_RETURN
, SHELL_CMD_PARAM_NUM(num)
для быстрого объявления.## Прокси-функции и анализ параметров
Letter Shell 3.0 нативно поддерживает передачу целых чисел, символов, строковых параметров и, в некоторых случаях, параметров с плавающей запятой непосредственно в функцию, выполняющую команду. Обычно эти типы параметров полностью удовлетворяют потребности отладки. Однако в некоторых случаях пользователи действительно нуждаются в передаче других типов параметров. В этом случае можно определить команду в виде основной функции, используя строки для передачи параметров, а затем самостоятельно анализировать эти параметры. Кроме того, Letter Shell предоставляет механизм прокси-функций, который позволяет пользователю выполнять пользовательский анализ для любого типа параметров.
Для получения информации о реализации прокси-функций и примерах их использования, обратитесь к анализу прокси-функций Letter Shell.
Для использования прокси-функций пользователь должен определить пользовательский анализатор параметров прокси, то есть функцию или макрос, который преобразует базовые параметры (целые числа, символы, строковые параметры) в параметры целевого типа. Letter Shell по умолчанию реализует анализатор параметров с плавающей запятой SHELL_PARAM_FLOAT(x)
.Затем используйте макросы для экспорта команд прокси-функций, например, для функции, которая передает несколько параметров с плавающей запятой:
void test(int a, float b, int c, float d)
{
printf("%d, %f, %d, %f \r\n", a, b, c, d);
}
SHELL_EXPORT_CMD_AGENCY(SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC),
test, test, test,
p1, SHELL_PARAM_FLOAT(p2), p3, SHELL_PARAM_FLOAT(p4));
В отличие от обычного экспорта команд, экспортирование команд прокси-функций первые четыре параметра совпадают с обычной формой экспорта команд, а последующие параметры передаются в целевую функцию. Letter Shell по умолчанию поддерживает определение команд прокси-функций с максимум семью параметрами (p1~p7). Для параметров, которые не требуют анализа параметров прокси, достаточно указать px(x=1~7)
, как в примере выше для p1
и p3
. Для параметров, которые требуют анализа параметров прокси, необходимо использовать соответствующий анализатор параметров, как в примере выше для p2
и p4
.
Управление правами в Letter Shell 3.0 тесно связано с определением пользователем. Letter Shell 3.0 использует 8 бит для представления прав доступа к команде. Если результат побитового умножения прав пользователя и команды дает истину, или права доступа к команде равны нулю, то пользователь имеет право использовать эту команду.- Для портирования на последовательный порт рекомендует использовать программу SecureCRT. Кнопочные отображения в letter shell настроены в соответствии с SecureCRT, поэтому при использовании других программ для последовательного порта могут потребоваться изменения значений кнопок.
В letter shell 3.0 включен инструмент для перебора команд, экспортированных из проекта, расположенный по пути tools/shellTools.py. Для его запуска требуется среда Python 3. Он позволяет вывести все имена команд, экспортированных с помощью SHELL_EXPORT_XXX
, а также их местоположения. В сочетании с VS Code это позволяет быстро перейти к нужным местам.
python shellTools.py project
Примечание: инструмент shellTools перебирает все файлы в указанной директории, поэтому при большом количестве файлов в проекте процесс может быть медленным. Рекомендуется использовать его только для перебора директорий пользовательских модулей.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )