RT-Thread – это операционная система реального времени с открытым исходным кодом, используемая для программирования устройств Интернета вещей (IoT). FinSH – это компонент командной строки RT-Thread , который предоставляет набор рабочих интерфейсов, позволяющих пользователям связываться с устройством из командной строки. В основном он используется для отладки или просмотра системной информации.
Обычно отладка разработки отображается с помощью аппаратных отладчиков и printfжурналов. Однако в некоторых случаях эти два метода не очень полезны, потому что они абстрагируются от того, что работает, и их может быть сложно проанализировать. RT-Thread – это многопоточная система, что полезно, когда вы хотите узнать состояние запущенного потока или текущее состояние системы ручного управления. Поскольку он многопоточный, у вас может быть интерактивная оболочка, поэтому вы можете вводить команды, вызывать функцию непосредственно на устройстве для получения необходимой информации или управлять поведением программы. Это может показаться вам обычным, если вы привыкли только к современным операционным системам, таким как Linux или BSD, но для аппаратных хакеров это большая роскошь, и совсем не то, чтобы прокладывать последовательные кабели непосредственно на платы, чтобы увидеть ошибки.
printf
FinSH имеет два режима:
msh
В режиме интерпретации на языке C FinSH может анализировать выражения, которые выполняют большую часть языка C, и получать доступ к функциям и глобальным переменным в системе с помощью вызовов функций. Он также может создавать переменные из командной строки.
В mshрежиме FinSH работает аналогично традиционным оболочкам, таким как Bash.
Когда мы разрабатывали FinSH, мы узнали, что прежде чем вы сможете написать приложение командной строки, вам необходимо ознакомиться со стандартами командной строки GNU. Эта структура стандартных практик помогает сделать интерфейс более привычным, что помогает разработчикам чувствовать себя комфортно и продуктивно при его использовании.
Полная команда GNU состоит из четырех основных частей:
Вы можете увидеть это в действии с любой командой. Возьмем Git в качестве примера:
git reset --hard HEAD~1
Что разбивается как:
Исполняемая команда – git , reset --hard , используется опция –head , а аргумент – HEAD ~ 1 .
reset --hard
Другой пример:
systemctl enable --now firewalld
Исполняемая команда – systemctl , подкоманда – enable , параметр – –now , а аргумент – firewalld .
Представьте, что вы хотите написать программу командной строки, соответствующую стандартам GNU, с использованием RT-Thread. В FinSH есть все необходимое, и он будет запускать ваш код должным образом. Более того, вы можете положиться на это соответствие, чтобы уверенно переносить свои любимые программы Linux.
Вот пример RT-Thread, выполняющего команду, которую разработчики RT-Thread используют каждый день.
usage: env.py package [-h] [--force-update] [--update] [--list] [--wizard] [--upgrade] [--printenv] optional arguments: -h, --help show this help message and exit --force-update force update and clean packages, install or remove the packages by your settings in menuconfig --update update packages, install or remove the packages by your settings in menuconfig --list list target packages --wizard create a new package with wizard --upgrade upgrade local packages list and ENV scripts from git repo --printenv print environmental variables to check
Как вы понимаете, он выглядит знакомо и действует как большинство приложений POSIX, которые вы, возможно, уже запускали в Linux или BSD. Справка предоставляется при использовании неправильного или недостаточного синтаксиса, поддерживаются как длинные, так и короткие варианты, а общий пользовательский интерфейс знаком всем, кто использовал терминал Unix.
Есть много разных вариантов, и по длине их можно разделить на две основные категории:
-h
pkgs -h
--target
scons- --target-mdk5
Вы можете разделить эти варианты на три категории в зависимости от того, есть ли у них аргументы:
Как и следовало ожидать от большинства команд Linux, синтаксический анализ параметров FinSH является довольно гибким. Он может отличить параметр от аргумента на основе пробела или знака равенства в качестве разделителя или просто извлекая сам параметр и предполагая, что все последующее является аргументом (другими словами, без разделителя вообще):
wavplay -v 50
wavplay -v50
wavplay --vol=50
Если вы когда-либо писали приложение командной строки, вы, возможно, знаете, что обычно существует библиотека или модуль для вашего языка, который называется optparse. Он предоставляется программистам, так что параметры (такие как -v или –verbose ), введенные как часть команды, могут быть проанализированы относительно остальной части команды. Это то, что помогает вашему коду узнать вариант из подкоманды или аргумента.
При написании команды для FinSH optparseпакет ожидает такой формат:
optparse
MSH_CMD_EXPORT_ALIAS(pkgs, pkgs, this is test cmd.);
Вы можете реализовать варианты, используя длинную или краткую форму, или и то, и другое. Например:
static struct optparse_long long_opts[] = { {"help" , 'h', OPTPARSE_NONE}, // Long command: help, corresponding to short command h, without arguments. {"force-update", 0 , OPTPARSE_NONE}, // Long comman: force-update, without arguments {"update" , 0 , OPTPARSE_NONE}, {"list" , 0 , OPTPARSE_NONE}, {"wizard" , 0 , OPTPARSE_NONE}, {"upgrade" , 0 , OPTPARSE_NONE}, {"printenv" , 0 , OPTPARSE_NONE}, { NULL , 0 , OPTPARSE_NONE} };
После создания параметров напишите команду и инструкции для каждого параметра и его аргументов:
static void usage(void) { rt_kprintf("usage: env.py package [-h] [--force-update] [--update] [--list] [--wizard]\n"); rt_kprintf(" [--upgrade] [--printenv]\n\n"); rt_kprintf("optional arguments:\n"); rt_kprintf(" -h, --help show this help message and exit\n"); rt_kprintf(" --force-update force update and clean packages, install or remove the\n"); rt_kprintf(" packages by your settings in menuconfig\n"); rt_kprintf(" --update update packages, install or remove the packages by your\n"); rt_kprintf(" settings in menuconfig\n"); rt_kprintf(" --list list target packages\n"); rt_kprintf(" --wizard create a new package with wizard\n"); rt_kprintf(" --upgrade upgrade local packages list and ENV scripts from git repo\n"); rt_kprintf(" --printenv print environmental variables to check\n"); }
Следующий шаг – разбор. Пока вы не можете реализовать его функции, структура проанализированного кода такая же:
int pkgs(int argc, char **argv) { int ch; int option_index; struct optparse options; if(argc == 1) { usage(); return RT_EOK; } optparse_init(&options, argv); while((ch = optparse_long(&options, long_opts, &option_index)) != -1) { ch = ch; rt_kprintf("\n"); rt_kprintf("optopt = %c\n", options.optopt); rt_kprintf("optarg = %s\n", options.optarg); rt_kprintf("optind = %d\n", options.optind); rt_kprintf("option_index = %d\n", option_index); } rt_kprintf("\n"); return RT_EOK; }
Вот файл заголовка функции:
#include "optparse.h" #include "finsh.h"
Затем скомпилируйте и загрузите на устройство.
Аппаратное программирование может показаться пугающим, но с IoT это становится все более распространенным явлением. Не все можно или нужно запускать на Raspberry Pi, но с RT-Thread вы можете сохранить знакомое ощущение Linux благодаря FinSH.
Если вам интересно программировать на «голом железе», попробуйте RT-Thread.
Продолжая использовать данный сайт вы принимаете политику конфиденциальности и cookies