![Вы только посмотрите насколько красивым может быть ваш монитор, если использовать UART-CLI Вы только посмотрите насколько красивым может быть ваш монитор, если использовать UART-CLI](https://habrastorage.org/getpro/habr/upload_files/685/d64/adc/685d64adc5adb49bbf11717056371089.png)
Есть такая классическая технология отладки Firmware как интерфейс командной строки поверх UART (Real Time Terminal). Как её только не называют: TUI, СLI, Shell, RTT, консоль, последовательный терминал и прочее. Это уже намёк на то, что штука это полезная и используют её по-разному.
Почему UART? Ответ прост. UART самый дешевый и простой проводной интерфейс. Для него доступны как переходники UART-USB (CP2102) так и готовый стабильный софт (TeraTerm/Putty).
Бытует мнение якобы: “Да нам UART-CLI не нужна так как у нас устройство удаленное и к нему нет доступа кроме беспроводных интерфейсов”.
Это высказывание можно перефразировать так: “Да нам JTAG/SWD не нужен так как у нас устройство удаленное и к нему нет доступа кроме беспроводных интерфейсов”
Иллюзия таких рассуждений в следующем.
1–Во первых. У вас после какого-то коммита сломался ваш беспроводной интерфейс или CAN. И что вы будете делать? Предаваться конвульсиям и судорогам? Чтобы понять, что сломалось, вам поможет 2 минуты с и пара команд диагностики из UART-CLI или 1 день прочесывания кода пошаговым GDB отладчиком по JTAG/SWD. Лично я выбираю первый вариант.
![Вот CLI выдала список текущих состояний GPIO. Ваша прошивка так умеет? Вот CLI выдала список текущих состояний GPIO. Ваша прошивка так умеет?](https://habrastorage.org/getpro/habr/upload_files/ef6/142/163/ef6142163cfce64646e9bc143d88288f.png)
2–Во вторых UART-CLI нужна в основном для отладки в Debug(жной) сборке. В Relese(ных) артефактах Shell можно и выпилить. Причем если Вы собираете из самописных Makefile(ов), то выпиливание CLI это заменить один символ в *.mk файле с конфигами с (Y на N).
Про торжество makefile(ов) есть вообще отдельный текст https://habr.com/ru/articles/723054/
3–В третьих CLI можно пустить по любому интерфейсу и протоколу: CAN, LoRa, UDP, UWB. Просто в этом случае придется писать консольную утилиту-переходник для LapTop(а). Хипстерская Tool(а) типа с stdin/stdout текстовый CLI в конкретный бинарный протокол + драйвер интерфейса. А если жалко трафика, то придется еще и пропускать CLI трафик через программный компонент компрессии. Заметьте, никакой GUI(ни) пока не нужно.
4–В четвертых, UART CLI нужна как раз для отладки и верификации механизмов удаленного доступа (например стека LTE/Ethernet/TCP/IP/LoRa). Сами по себе беспроводные стеки это тонна кода, который тоже надо как-то отлаживать. Я могу сказать, что даже для запуска того же LoRa надо подтянуть кучу зависимостей: GPIO, SPI, DMA, FlashFS, UART, TIMERS, SX1262. В BlueTooth зависимостей на два порядка больше. И для стабильного Link(а) эти зависимости все по отдельности должны работать безупречно.
Общая канва такова, что более сложный программный компонент можно отладить только менее сложным компонентом. Ethernet отлаживают, в частности, при помощи UART-Shell. UART отлаживают связкой GPIO+JTAG. GPIO отлаживают мультиметром или логическим анализатором.
Тут можно провести аналогию. У каждого микропроцессора есть система команд. Это список Assembler инструкций, которые может исполнять этот микропроцессор. Аналогично и у электронной платы должна быть тоже своя система команд. То есть список действий, которые может выполнять эта конкретная плата. Вот такое простое рассуждение приводит к заключению, что у прошивки должна быть UART-CLI.
Нужен како-то портал для доступа к прошивке.
29 причин почему Вам пригодится UART-Shell
1–Допустим у вас плата без HeartBeat LED(а). Ну пожалели разработчики денег, ну бывает. Вы накатили прошивку и ничего не происходит. Вообще ничего не поменялось. А вот UART CLI позволит произвести такой простой Smoke тест как “А не зависла ли прошивка?”. Для этого достаточно просто открыть UART консоль и нажать Enter. Если появился курсор (-->), то тест пройден. Прошивка вертится. Успех.
![](https://habrastorage.org/getpro/habr/upload_files/b8f/29e/96c/b8f29e96c43f6a827e453e3c249799dd.png)
2–С UART CLI можно автоматизировать работу с Target(ом). Автоматически прогнать тесты. Автоматически прописать серийный номер. Автоматически прописать ключи шифрования.
3--Если у вас перестал работать Ethernet, то UART-CLI поможет понять в чем загвоздка. Это обыкновенное резервирование для отладки.
4–Оборудование для отладки через UART CLI дешевле, чем оборудование для отладки по JTAG в сотни раз, так как не нужен дорогой программатор. Цена JTAG программаторов, кажется, вообще ничем не ограничена. Видел от 7kRUB до 5kEUR.
5–UART-CLI менее подвержен статическому электричеству в сравнении с SWD и JTAG. У SWD программаторов часто нет Link(а) c Target(ом). UART же работает всегда.
6–UART-CLI harness можно протянуть на большую длину чем SWD/JTAG. SWD обычно не работает уже при длине шлейфа около 40 см. Для UART 1 м до HIL cтенда это вообще ни о чем.
7–Отладка через UART CLI удобнее, чем отладка по JTAG так как нужно всего 4 провода (Rx Tx GND VDD) вместо 20 проводов JTAG.
8–CLI можно использовать как имитатор устройства. Человек может отправлять данные в CLI в конкретную API(шку) , а микроконтроллер будет реально думать, что это какой-то протокол или вообще устройство. То есть варианты комбинаций способов отладки с CLI ограничены только вашей фантазией.
9–Через CLI можно загрузить в устройство энергонезависимые конфиги. Например параметры модуляции беспроводных трансиверов.
10–CLI проста в использовании. Исполнять команды в CLI сможет даже необученный персонал просто следуя скачанной инструкции из pdf(ки) и вам не надо будет посылать программиста в командировку за Урал, чтобы тот настроил радар или перепрошил RFID СКУД.
11-- Из консоли TeraTerm можно скопипастить любой кусок текста. При работе с GUI-подобным конфигуратором часто скопипастить текст нельзя так как текст иногда отрисовывается прямо на канве как картинка.
12–Через CLI можно инициировать запуск модульных тестов и увидеть отчет исполнения тестов. Можно запустить только те тесты, которые имеют в своем имени конкретную подстроку (например "i2c").
![](https://habrastorage.org/getpro/habr/upload_files/4c1/392/2ea/4c13922eac0ea2433ee193cabb5172fd.png)
Или запустить только один конкретный тест. Можно отлаживать программу по частям подобно тому как в школьной математике функции интегрируют по частям.
13–Через CLI можно верифицировать функционал. Заставить испустить синус определенной частоты на DAC или распечатать в UART содержимое файла в FatFS.
14–CLI стимулирует писать более модульный код так как для каждого компонента надо где-то хранить список его внутренних команд.
15–CLI побудит вас сделать общий на все компоненты API для доступа к периферии, компонентам и драйверам. Это позволит вам в будущем быстро мигрировать с одного микроконтроллера на другой просто определив API(шные) функции для очередного чипа. А это первый шаг к методологии AUTOSAR или Zephyr Project.
16–Через CLI можно обновить прошивку. Можно передавать куски прошивки в формате base64 или просто hex в виде ASCII (получается base16). Или по протоколу zModem поверх CLI.
17--CLI это вообще универсальный протокол. Можно и прошивку кидать, и конфиги прописывать, и различную диагностику выгребать. CLI понимает и человек и компьютер. Для CLI не нужен вспомогательный софт. Всё работает из коробки.
18--UART CLI можно через переходник [USB_TypeС -USB-A(Nest)]--[USB-A(Fork)-UART (чип CP2102)] подключить к Android смартфону и управлять электронной платой с сенсорного экрана телефона по приложению Serial USB Terminal, прямо стоя на улице.
![Доступ к UART-Shell c мобильного телефона Доступ к UART-Shell c мобильного телефона](https://habrastorage.org/getpro/habr/upload_files/290/5b9/4ab/2905b94ab591ac0c046fdc2d6c6f67f1.png)
19--UART-CLI позволит вам воспроизводить известные баги. Вы просто напишите модульный тест, который проделает последовательность операций и запустите его из CLI.
20--CLI повышает вероятность, что написанный код вообще запустят хоть раз перед отгрузкой до 95%...100%.
21--Еще очень важный момент. Если в прошивке визуально работает UART-CLI, то это автоматически означает, что правильно сконфигурировалось тактирование процессорного ядра и периферии, значит что включен контроллер прерываний, что работает FIFO. Работающий CLI это отличный модульный тест.
22-- Эмуляция прошивки как процесса на PC. Если у вас в прошивке есть CLI, то вы можете собрать прошивку прямо на NetTop x86. Прошивку можно запустить на исполнение как Win консольное приложение в командой строке cmd.
![](https://habrastorage.org/getpro/habr/upload_files/b16/7cc/c3a/b167ccc3a8af4dc4fd118acf411cde38.png)
Затем, исполняя shell команды в stdin и наблюдая за цветным выводом в stdout вы можете отладить огромные куски кода, которым всё равно на архитектуру. Протестировать реализацию протоколов, математику, аллокаторы памяти, криптографию, компрессию/декомпрессию, fifo, lifo, циклический буфер, цифровые фильтры FIR, IIR, CIC, hashset(ы), алгоритмы расчета контрольных сумм, шрифты графических экранчиков, триггер Шмитта, распознаватели строчек, генераторы QR кодов и многое-многое друге, что не зависит от архитектуры. Без CLI вы бы не смогли отлаживать платформа-независимый микроконтроллерный кода на "большом компьютере".
23--UART-CLI позволит проводить контроль исполнения работы при работе в команде программистов. Вы просто откроете консоль TUI, запустите команды своего смежника и сразу поймете работает его программный компонент или драйвер или не работает.
Shell это самый очевидный способ доказать или опровергнуть наличие или отсутствие конкретного функционала в прошивке.
24–CLI не так грубо нарушает timing(и) время исполнения программ как пошаговая отладка , при отладке через CLI код протекает в естественном режиме и лишь изредка слегка замедляется редким выводом в UART. Это вам не точки останова JTAG, которые останавливают программу на несколько секунд и полностью нарушают логику приложения. Для современных 200MHz микроконтроллеров 1 секунда это как для человека эра. С Shell(ом) получается none disturb отладка.
25--Еще в далеком 1986 в микроконтроллерные устройства в прошивки встраивали интерпретаторы Basic(а). Примером тому служит гаджет Электроника МК-90. Получалось что устройство можно было допрограммировать уже в Run-Time(е)! Хорошая CLI это по сути тоже интерпретируемый язык программирования. Когда в устройстве есть CLI, то существует больше use case(ов) для этого устройства.
26--Дополнительная ценность
Когда у Вас в прошивке есть CLI, любое ваше устройство помимо базового функционала превращается в супер калькулятор покруче любого Cassio. Только вместо клавиатуры и дисплея два провода UART. Можно прямо в консоли TeraTerm/PuTTY попросить микроконтроллер расшифровать кусок Base64, RLE, AES256, вычислить SHA256, посчитать CRC16, решить задачку на поиск пересечения временных интервалов, определить точное количество дней между 2мя датами, вычислить расстояние между двумя GNSS координатами, найти угол между векторами, решить линейное уравнение, вычислить формулу и прочее и прочее.
Вот, например, прошивка рассчитывает ёмкость керамического конденсатора по его трехбуквенной маркировке. А раньше это была головная боль.
![Конденсаторный калькулятор Конденсаторный калькулятор](https://habrastorage.org/getpro/habr/upload_files/8e2/a39/b39/8e2a39b39e46b4122f22bd09860ac8fa.png)
Буквально недавно выручила консоль. Когда есть UART-CLI, вы можете из любого устройства с ADC сделать прибор для проверки напряжения для пальчиковых батареек AAA, AA.
Когда есть CLI прошивка превращается в Swiss Army Knife.
27--Простота работы c UART-CLI и гибкость
Работать с CLI по UART легко и приятно и UART-CLI ничем Вас не ограничивает в плане формата payload(а). Можете посылать открытый текст в любом удобном для данной ситуации способом (например в ascii), можете отрисовывать ACSII таблицы.
![ASCII таблица в UART CLI ASCII таблица в UART CLI](https://habrastorage.org/getpro/habr/upload_files/ac1/481/d62/ac1481d62eba7346b377d0cc811f09d0.png)
Читать вывод прямо глазами. Не нужно писать никаких вспомогательных host утилит, достаточно существующих TeraTerm/Putty.
28) CLI для экономии денег и времени
Если у вас в электронное плате нет UART-CLI, а только какой-то проприетарный бинарный протокол, то Вам надо тогда писать ещё утилиту переходник на PC чтобы подключиться к устройству. А потом еще такую же утилиту для Win, Linux, Mac, Android, iOS, MS-DOS, OS/2, IBM POWER8 и БЭСМ-6. Не проще ли просто реализовать текстовый UART-CLI протокол c раскраской логов, ASCI таблицами на уровне Firmware и подключаться по любому терминалу последовательного порта (Putty/TeraTerm), которые и так есть для всех OS? UART-CLI избавит Вас от написания калейдоскопа ненужных no-name утилит-переходников под все известные платформы. Ну сами подумайте, откуда у СНГ(шной) электронной embedded конторы деньги на зарплату 250kRUR/мес для С#/Java программиста для написания всех этих одноразовых PC утилит-переходинков?
19) Внешнее управление микроконтроллеров по UART.
Вы можете реализовать в UART-CLI всего 2 команды: чтение физического адреса и запись в физический адрес. Далее вы можете соединить target PCB и большой компьютер переходником USB UART и уже писать прошивку на PC. Говоря метафорично, микроконтроллер будет выступать марионеткой, DeskTop-PC кукловодом, а ниточками - 2 провода от UART. Таким образом вы становитесь никак не ограничены в размере бинаря и при этом можете сопрягать прошивку со всеми ресурсами PC: базы данных, монитор, доступ в интернет и прочее.
29) Пользователи продукта будут Вам благодарны за CLI
Даже если Вы добавите сокращенный Shell в релизную сборку для какого-н прибора то, пользователи будут Вам очень благодарны за такой extra функционал. Они смогут проделывать свои специфические операции с вашим прибором. Подключать его к большому компьютеру и писать для устройства скрипты. Примером устройств, где CLI оставлен в релизе являются векторный антенный анализатор NanoVNA V2, трансивер Flipper Zero, отладочная плата U-Blox ODIN, Bluetooth модуль BC127 и прочее. Поэтому можно сказать, что CLI нужна не сколько разработчику сколько продвинутому пользователю продукта.
---------------------
Можно и дальше перечислять достоинства CLI (будь то по UART или UDP). Метафорично CLI в прошивке это как строительные леса в civil engineering(е).
Когда строят дом, его облачают в строительные леса (scaffolding). Они выглядят кустарно, некрасиво однако отлично помогают строительству. И это же не значит, что эти строительные леса останутся навечно после использования дома. Так же и в программировании. Для строительства кода тоже нужны своеобразные строительные леса в виде другого кода: диагностика, printf отладка, CLI, модульные тесты, скрипты сборки.
Вы когда-н видели чтобы дом строили без строительных лесов? Вот и я не видел.
![](https://habrastorage.org/getpro/habr/upload_files/9e9/2f7/004/9e92f7004311aec9cec8b0f0d637d6b8.png)
Вы где-нибудь видели, чтобы строители летали на JetPack(ах) c кисточкой и ведром в руках при покраске фасада многоэтажек? Вот и я не видел.
СLI для программиста микроконтроллеров это как для врача биолога микроскоп. С CLI можно внимательно разглядеть внутренности программы во время исполнения.
Вот скажите мне после этого, почему же тогда большинство российских программистов МК на 15м-20м году опыта в свои 43 года говорят:
"Что еще за UART-CLI? О чём это вы? ... A чё, так можно было что ли?!"
Ответ: "Не можно, а нужно!". В программировании МК тоже есть такое понятие как инфраструктурный код. В программировании MCU(шек) инфраструктурный код это тандем UART Shell + модульные тесты. Без этого ваш проект банально рухнет под собственным весом спустя год и произойдет это в самый неподходящий момент. Или код просто не будет работать, а вы об этом даже не будете догадываться.
Причем есть же примеры очень успешных продуктов, которые с самого начала заложили UART-Shell в свой прошивки. Это загрузчик U-Boot, анализатор NanoVNA V2, трансивер FlipperZero, приемник GNSS U-Blox ODIN C099-F9P. Bluetooth трансивер BC127. Потом, в кодовой базе Zephyr project есть Shell.
Ещё в проекте Embox есть своя своеобразная UART-CLI.
![](https://habrastorage.org/getpro/habr/upload_files/1c2/81f/b2f/1c281fb2f64b88776a533efa9ea1af50.png)
https://habr.com/ru/articles/777302/
Для промышленной аппаратуры CLI и вовсе норма жизни (например авиационный RF приемник AW100Rx). Даже в домофонах есть UART-Shell вот (начало на 1:30): https://www.youtube.com/watch?v=Fkmt7N6he5U/
Очевидно, что оглушительный успех этих продуктов в значительной мере определен наличием удобной и развитой CLI.
Вот список наиболее часто употребительных команд CLI безотносительно к конкретному проекту:
№ | команда CLI |
1 | Показать список доступных команд Help/TAB |
2 | перезагрузиться |
3 | запустить модульные тесты |
4 | установить/считать напряжение на GPIO |
5 | установить подтяжку напряжения на GPIO |
6 | показать напряжение на входах ADC |
7 | запуск аппаратных таймеров |
8 | включить/отключить конкретное прерывание |
9 | показать версию софта и железа |
10 | прыгнуть в загрузчик |
11 | перенастроить частоту процессорного ядра |
12 | установить уровень логирования для конкретного компонента |
13 | показать таблицу состояния потоков и их свойства (стек, приоритет), |
14 | показать счетчик принятых/отправленных пакетов по всем протоколам |
15 | Вычитать кусок памяти из REG RAM FLASH |
16 | показать список файлов в файловой системе FatFs |
17 | пульнуть произвольные данные в SPI/I2C/I2S/MDIO |
18 | Найти адрес по значению |
19 | Просканировать шину I2C, |
20 | повторить конкретную команду N раз с периодом P |
21 | отобразить в UART содержимое конкретного файла |
У меня в среднем на каждую сборку приходится максимум 120 Shell команд.
![](https://habrastorage.org/getpro/habr/upload_files/fb6/6cc/be4/fb66ccbe4c11ae391841bf24954eb6d8.png)
Некоторые незначительные недостатки CLI
1--Нет контрольной суммы CRC в PDU(Protocol data unit). Пользователя же не заставишь в уме высчитывать CRC32 того, что он там написал, и приписывать в конце 32(x) битный hex. Иначе прошивка не ответит. Это было бы ну просто смешно. Однако и тут всё не так плохо. Если вы используете в консоли Putty коды цветов и цвета отображаются на глаз плюс/минус норм, то это уже очень такой хороший знак того, что данные в трафике валидные и не corrupt(тятся) .
![это напечатал микроконтроллер в UART это напечатал микроконтроллер в UART](https://habrastorage.org/getpro/habr/upload_files/0ac/8b5/c2c/0ac8b5c2c24ff9c8c95e3613c83d56fe.png)
2--В самом простом виде UART-Shell это открытый текст. Можно перехватить трафик. Можно похитить ценнейшие метрики (логин-пароль, ключи шифрования). Но я подчеркиваю, что UART-CLI это только для отладки софта и железа внутри офиса.
3--Надо защищать устройство от несанкционированного доступа к CLI так как в этом случае можно получить тотальный доступ к устройству, превратить его в BotNet(а). Как защитить терминал в UART? Можно добавить логин и пароль как в Linux. Либо выпускать отдельную desktop tool(у)-терминал для шифровки и расшифровки shell трафика между человеком и электронной платой. Именно так сделали авторы прошивки радиостанции MeshTastic. Там заложены python скрипты-посредники для конфигурации и диагностики LoRa трансивера TTGO T-Beam.
4-- Можно нечаянно набрать опасную Shell команду. Например стереть прошивку или замкнуть во внешнем H-мосте VBat на GPIO. Поэтому надо добавить запрос "вы уверены, что хотите выполнять эту опасную команду?" или просто выпилить для каждой конкретной сборки все опасные команды. Или добавить отдельный поток который будет оперативно выявлять и чинить сбои в конфигурациях.
5-- В TUI (text user interface) нет контроля непрерывности трафика так как нет как такового заголовка пакета. CLI трафик это атомарные текстовые строки, оканчивающиеся переносом строки. Поэтому каждая Shell команда должна быть самодостаточной и не зависать от предыдущих shell команд.
6--Есть небольшой overhead. Например DMA от UART-CLI временно блокирует шину данных на время отправки. Для компонента CLI надо немного RAM и Flash.
Вывод
В общем у Shell плюсов больше чем минусов. Смело добавляйте в свои прошивки UART-Shell. Никто не заставляет вас оставлять shell в релизной сборке, однако в отладочной сборке shell должен быть обязательно. Shell реально того стоит. CLI позволяет вам обеими руками по локоть забраться в исполняемый процесс и найти там любой бит при этом не помешав самому потоку исполнения кода. Эта технология позволит вам говорить с устройством на понятном обоим сторонам языке.
CLI в режиме IDLE вообще ничего не печатает в UART-TX и микроконтроллер не нагружается от слова совсем. UART-CLI только отвечает на редкие запросы, которые поступают в провод UART-RX.
Я заметил одну тенденцию. Те люди, которые трындят, что UART-консоль якобы не нужна банально не понимают про что идет речь эти CLI никогда в своей жизни не видели (GUI поколение) и они просто не в теме. К таким людям просьба относиться с пониманием.
Если вы знаете еще известные коммерческие встраиваемые системы с интерфейсом командной строки в serial порте (например маршрутизаторы Cisco), то пишете в комментариях. Интересна их реализация.
Акроним | Расшифровка |
TUI | Text-based user interface |
CLI | command-line interface |
UART | universal asynchronous receiver / transmitter |
JTAG | Joint Test Action Group |
LED | light-emitting diode |
CIC | Cascaded integrator–comb |
Links
Пишем терминальный сервер для микроконтроллера на С https://habr.com/ru/articles/572630/
embedded-cli https://github.com/funbiscuit/embedded-cli
MCU-CLI-w25Q80-emulEEPROM https://github.com/NetDm/MCU-CLI-w25Q80-emulEEPROM