1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/gbesalex-letter-shell

Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

letter shell 3.0

version standard build license

Мощный встроенный shell

shell_info.png

Введениеletter shell 3.0 — это встроенный shell, написанный на языке C и предназначенный для встраивания в программу. Он ориентирован на встраиваемые устройства и использует функции C в качестве единиц выполнения. Shell можно вызывать через командную строку для выполнения функций программы.В отличие от версии 2.x, версия 3.0 добавляет управление пользователями и правами доступа, а также поддержку файловой системы в будущем.

Кроме того, версия 3.0 изменила формат и определение команд, поэтому проекты на версии 2.x потребуют небольших изменений для миграции.

Если требуется использование только базовых функций, можно использовать версию letter shell 2.x.

Инструкции по использованию можно найти в Letter shell 3.0: Новый старт

функции

  • Автоматическое завершение команд
  • Определение быстрых клавиш
  • Управление правами доступа команд
  • Управление пользователями
  • Поддержка переменных
  • Агентские функции и анализ параметров

инструкции по переносу

  1. Определение объекта shell

    Shell shell;
  2. Определение функций чтения и записи 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);
  3. Запросить область буфера

    char shellBuffer[512];
    ```4. Вызов shellInit для инициализации
    
    ```C
    shell.read = shellRead;
    shell.write = shellWrite;
    shellInit(&shell, shellBuffer, 512);
  4. Вызов (создание) задачи shell

    Для работы в операционной системе создайте задачу shellTask (убедитесь, что конфигурация в shell_cfg.h верна), параметром задачи является объект shell

    OsTaskCreate(shellTask, &shell, ...);

    Для работы в режиме без операционной системы вызовите shellTask в основном цикле или при получении данных вызовите shellHandler

  5. Объяснение

    • Для использования shell в режиме прерываний не нужно определять shell->read, но необходимо вызывать shellHandler в прерываниях
    • Для работы в операционной системе включите макрос SHELL_TASK_WHILE, затем создайте задачу shellTask
  6. Другие настройки

    • Определите макрос SHELL_GET_TICK() как функцию получения системного тика, включите двойное нажатие клавиш, автозавершение длинных команд помощи
  7. Макросы конфигурации Файл 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, ...). Эти способы определения функций подходят для различных сценариев.

Форма функции main

Пример определения функции в такой форме:

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

Форма обычной C-функции

Пример определения функции в такой форме:

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-объектов можно изменить, задав макрос 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.

  1. Экспорт команд через определение констант

    Внешние команды определяются с помощью констант, например:

    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 = .;
  2. Экспорт команд через таблицу команд

    • При использовании других компиляторов, которые не поддерживают экспорт команд, необходимо добавить команды в таблицу команд в файле 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 предоставляет макросы для определения исполняемых команд, кнопок, пользователей и переменных.

  1. Определение исполняемых команд

    Используйте макрос 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 \
            }
  2. Определение переменных

    Используйте макрос 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 \
            }
  3. Определение пользователей

    Используйте макрос SHELL_EXPORT_USER для определения пользователей, определение представлено ниже ```C /**

    • @brief Определение пользователя в командной строке
    • @param _attr Атрибуты пользователя
    • @param _name Имя пользователя
    • @param _password Пароль пользователя
    • @param _desc Описание пользователя */ #define SHELL_EXPORT_USER(_attr, _name, _password, _desc)
      const char shellCmd##_name[] = #_name;
      const char shellPassword##_name[] = #_password;
      const char shellDesc##_name[] = #_desc;
      const ShellCommand
      shellUser##_name SECTION("shellCommand") =
      {
      .attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_USER),
      .data.user.name = shellCmd##_name,
      .data.user.password = shellPassword##_name,
      .data.user.desc = shellDesc##_name
      }
    
    Используйте макрос `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 )

Вы можете оставить комментарий после Вход в систему

Введение

буква shell Развернуть Свернуть
MIT
Отмена

Обновления

Пока нет обновлений

Участники

все

Язык

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/gbesalex-letter-shell.git
git@api.gitlife.ru:oschina-mirror/gbesalex-letter-shell.git
oschina-mirror
gbesalex-letter-shell
gbesalex-letter-shell
master