Есть такая классическая технология отладки Firmware как интерфейс командной строки поверх UART. Почему UART? Ответ прост. UART самый дешевый и простой проводной интерфейс. Для него доступны как переходники UART-USB (CP2102) так и софт(TeraTerm/Putty).
Бытует мнение якобы: “Да нам UART-CLI не нужна так как у нас устройство удаленное и к нему нет доступа кроме беспроводных интерфейсов”.
Это высказывание можно перефразировать так: “Да нам JTAG/SWD не нужен так как у нас устройство удаленное и к нему нет доступа кроме беспроводных интерфейсов”
Иллюзия таких рассуждений в следующем.
1–Во первых. У вас после какого-то коммита сломался ваш беспроводной интерфейс или CAN. И что вы будете делать? Чтобы понять, что сломалось, вам поможет 2 минуты с и пара команд диагностики из UART-CLI или 1 день прочесывания кода GDB отладчиком по JTAG/SWD.
2–Во вторых UART-CLI нужна в основном для отладки в Debug(жной) сборке. В Relese(ных) артефактах Shell можно и выпилить. Причем если вы собираете из самописных Makefile(ов), то выпиливание CLI это заменить один символ в *.mk файле с конфигами с (Y на N).
3–В третьих CLI можно пустить по любому интерфейсу и протоколу: CAN, LoRa, UDP. Просто в этом случае придется писать консольную утилиту-переходник для 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 отлаживают мультиметром или логическим анализатором.
20 причин почему вам пригодится UART-Shell
1–Допустим у вас плата без HeartBeat LED(а). Ну пожалели разработчики денег, ну бывает. Вы накатили прошивку и ничего не происходит. Вообще ничего не поменялось. А вот UART CLI позволит произвести такой простой Smoke тест как “А не зависла ли прошивка?”. Для этого достаточно просто открыть UART консоль и нажать Enter. Если появился курсор, то тест пройден. Прошивка вертится. Успех.
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"). Или запустить только один конкретный тест.
13–Через CLI можно верифицировать функционал. Заставить испустить синус определенной частоты на DAC или распечатать в UART содержимое файла в FatFS.
14–CLI стимулирует писать более модульный код так как для каждого компонента надо где-то хранить список его внутренних команд.
15–CLI побудит вас сделать общий на все компоненты API для доступа к периферии, компонентам и драйверам. Это позволит вам в будущем быстро мигрировать с одного микроконтроллера на другой просто определив API(шные) функции для очередного чипа. А это первый шаг к методологии AUTOSAR.
16–Через CLI можно обновить прошивку. Можно передавать куски прошивки в формате base64 или просто hex в виде ASCII (получается base16). Или по протоколу zModem поверх CLI.
17--CLI это вообще универсальный протокол. Можно и прошивку кидать, и конфиги прописывать, и различную диагностику выгребать. CLI понимает и человек и компьютер. Для CLI не нужен вспомогательный софт. Всё работает из коробки.
18–CLI не нарушает timing(и) время исполнения программ протекает в естественном режиме. Это вам не точки останова JTAG, которые останавливают программу на несколько секунд и полностью нарушают логику приложения. Для современных процессоров 1 секунда это как для человека вечность. С Shell получается none disturb отладка.
19–Cli позволяет до программировать Target уже в RunTime(е). Вы всё равно не предусмотрите все возможные обстоятельства в статической прошивке. CLI позволит менять поведение устройства на лету. Shell позволит упростить поведение самой прошивки и просто составить скрипты CLI для каждого отдельного случая. На PC много места там все скрипты поместятся.
20--UART CLI можно через переходник USB_TypeС - UART подключить к Android смартфону и управлять платой с телефона.
CLI в прошивке это как строительные леса в civil engineering(е). Вы где-нибудь видели, чтобы строители летали на JetPack(ах) c кисточкой и ведром при покраске фасада многоэтажек?
Почему же тогда большинство российских программистов МК на 15м году опыта говорят:
"Что еще за UART-CLI? Вы о чем? ... A что, так можно было что ли?!"
Да, в программировании МК тоже есть такое понятие как инфраструктурный код. В программировании MCU инфраструктурный код это UART Shell и модульные тесты. Без этого ваш проект банально рухнет под собственной тяжестью спустя год и произойдет это в самый неподходящий момент. Или код просто не будет работать, а вы об этом даже не будете догадываться.
Причем есть же примеры очень успешных продуктов, которые с самого начала заложили shell в свой toolchain. Это загрузчик U-Boot, анализатор NanoVNA V2, трансивер FlipperZero, приемник GNSS U-Blox ODIN C099-F9P. Трансивер BC127, в кодовой базе Zephyr project есть Shell. Очевидно, что оглушительный успех этих продуктов в значительной мере определен наличием удобной и развитой CLI.
Вот список наиболее часто употребительных команд CLI безотносительно к конкретному проекту:
Показать список доступных команд Help/TAB, перезагрузиться, запустить модульные тесты, установить/считать напряжение на GPIO, установить подтяжку напряжения на GPIO, показать напряжение на входах ADC, запуск аппаратных таймеров, включить/отключить конкретное прерывание, перенастроить частоту процессорного ядра, прыгнуть в загрузчик, показать версию софта и железа, показать историю команд, установить уровень логирования для конкретного компонента, показать таблицу состояния потоков и их свойства (стек, приоритет), показать счетчик принятых/отправленных пакетов по всем протоколам, показать список файлов в файловой системе FatFs, отобразить в UART содержимое конкретного файла, Просканировать шину I2C, пульнуть произвольные данные в SPI/I2C/I2S/MDIO, Вычитать кусок памяти из REG RAM FLASH, Найти адрес по значению, повторить конкретную команду N раз с периодом P,
У меня в среднем на каждую сборку приходится максимум 120 Shell команд.
Недостатки CLI
1--Нет контрольной суммы CRC в PDU. Пользователя же не заставишь в уме высчитывать CRC32 того, что он там написал и приписывать в конце 32 битный hex. Иначе прошивка не ответит. Это было бы просто смешно. Однако не все так плохо. Если вы используете в консоли Putty коды цветов и цвета отображаются плюс/минус норм, то это уже хороший знак того, что данные в трафике валидные.
2--В самом простом виде UART-CLI это открытый текст. Можно перехватить трафик. Можно похитить ценнейшие метрики (логин-пароль, ключи шифрования). Но я подчеркиваю, что UART-CLI это только для отладки софта и железа внутри офиса.
3--Надо защищать устройство от несанкционированного доступа к CLI так как в этом случае можно получить тотальный доступ к устройству, превратить его в BotNet(а). Можно добавить логин и пароль как в Linux. Либо выпускать отдельную desktop tool(у)-терминал для шифровки и расшифровки shell трафика между человеком и платой. Так сделали авторы прошивки радиостанции MeshTastic. Там python скрипты-посредники для конфигурации и диагностики LoRa трансивера TBream.
4-- Можно нечаянно набрать опасную Shell команду. Например стереть прошивку или замкнуть H-мост на GPIO. Поэтому надо добавить запрос "вы уверены что хотите выполнять эту опасную команду?" или просто выпилить все опасные команды для каждой конкретной сборки.
5-- нет контроля непрерывности трафика так как нет как такового заголовка пакета. CLI трафик это просто текстовые строки, оканчивающиеся переноси строки. Поэтому каждая Shell команда должна быть самодостаточной и не зависать от предыдущих команд.
Вывод
В общем плюсов больше чем минусов. Добавляйте в свои прошивки UART-Shell. Никто не заставляет вас оставлять shell в релизной сборке, однако в отладочной сборке shell должен быть обязательно. Shell того стоит. CLI позволяет обеими руками по локоть забраться в исполняемый процесс и найти там любой бит при этом не помешав самому потоку исполнения кода. Эта технология позволит вам говорить с устройством на понятном обоим сторонам языке.
Links
Комментарии (15)
Zuy
21.10.2022 10:16+2Эх, ну вот опять, декларируется обязательность UART CLI. Мы уже вроде обсуждали это в другом посте, но я повторюсь.
В той же Tesla S, около 200 ECU, и ни в одном из них нет UART, все делается только по CAN и совсем они там от этого не страдают. Model 3 и Supercharger тоже на CAN. UART в Supercharger прикрутил я в CCS версию т. к. нужно было TCP/IP отлаживать.
В своих проектах я всегда UART первым поднимаю, но индустрия в целом вполне обходится без него и без CLI.
По CAN сильно удобней работать если это много устройств как в автомобиле. Достаточно подключиться в одном месте к шине и можно отлаживать или обновлять прошивку на всех устройствах на этой шине. Ну вот как вы такой трюк с UART провернёте
rsashka
21.10.2022 10:46+6Вы мешаете теплое с кислым. Как вам поможет CAN для отладки прошивки?
И то что UART не выводится в блоках Tesla совершенно не означает, что его нет блоках и он не использовался для отладке или тестировании блока при производстве. Ведь UART это не внешний интерфейс, каким является шина CAN.
Zuy
21.10.2022 17:33+1CAN для отладки помогает отлично. Туда выводятся все нужные сигналы, записывают трейсы и анализируют их во времени. Мало того, это все делается ещё и удаленно, когда трейс отправляется на сервер и можно видеть все сигналы в онлайн. Это дело ещё и работает не просто на один блок а сразу на всю машину и на одном графике можно смотреть сигналы от разных блоков.
aabzel Автор
21.10.2022 13:32-1По CAN достаточно подключиться в одном месте к шине и можно отлаживать или обновлять прошивку на всех устройствах на этой шине. Ну вот как вы такой трюк с UART провернёте?
Легко, можно подключится ноде A к ее UART CLI и набрать shell команду проброса данных из UART в CAN (Data Forwarding) и этими командами по UART обновить прошивку на любой ноде подключенной к этой же CAN мети.
Сама нода ECU выступает как переходник UART<->CAN.
mpa4b
21.10.2022 15:47+7Цена JTAG программаторов, кажется, вообще ничем не ограничена. Видел от 7kRUB до 5kEUR.
Вот прям сейчас посмотрел на али -- клон j-linkа стоит около 300 рублей (из дешёвых).
UART-CLI менее подвержен статическому электричеству в сравнении с SWD и JTAG.
Чото вообще не в тему. Если статикой вынести IO-ногу, то ни swd/jtag, ни uart с дохлым пином не заработают.
так как нужно всего 4 провода (Rx Tx GND VDD) вместо 20 проводов JTAG.
Можно обойтись тремя (без питания). В том числе и с SWD.
Можно передавать куски прошивки в формате base64 или просто hex в виде ASCII (получается base16).
А можно ещё Z-modem :)
madcatdev
21.10.2022 17:32+1Использую такую вещь в своих разработках, но с некоторыми отличиями - мк не отправляет обратно каждый введенный символ, а реагирует только на строку с /n. Работа с терминальными программами вроде putty в данном случае невозможна, зато возможен вывод информации в процессе ввода команды.
Mike-M
22.10.2022 12:17+1CLI это вообще универсальный протокол.
CLI — это вообще-то Command Line Interface, а не протокол.
В недостатки я бы добавил пару пунктов:CLI не нарушает timing(и) время исполнения программ протекает в естественном режиме.
CLI нежелательно использовать для вывода значений переменных и прочей информации в runtime, поскольку на подпрограмму обработки UART тоже требуется время.
На форуме Electronix видел реальные случаи влияния на работу прошивки с UART-отладкой и без неё.
CLI и подпрограмма обработки занимает место, как в постоянной, так и в оперативной памяти МК.
В противоположность этому интерфейс JTAG/SWD реализован на уровне ядра МК и не требует дополнительного софта на нём.
Не против CLI, но поддерживаю комментаторов выше:
— вместо 20-pin разъема давно уже изобрели разъём c гораздо меньшим числом выводов
— вместо дорогого JTAG/SWD отладчика можно обойтись более дешевым
volodyaleo
23.10.2022 12:16CLI не просто требует памяти, а еще и не везде влезет. Это занимает место в буферах и ROM. И вносит задержки.
Выглядит прикольно, но. Зачастую вместо него можно логи на одну TX ножку в debug сборке тащить, а RX не инициализировать. И настроить логгер который можно переключать при компиляции дефайнами: включать-выключать для модуля или уровень подробности менять.
Далее два подхода к тестам:
1) Модульные тесты, которые на железе пускаются с включенными логами и проверяются куски кода по сценариям. Тут можно наловить урожай достаточный чтобы дальше вручную не проверять много всего.
2) Интеграционные - собирать стенд, который умеет продёргивать ножки или по сети команды бросать и собирать логи. Цеплять такое можно к CI/CD (никто из команды не уронит код на мастере). Если макетировать на отладках, там уже часто есть board controller к которому в тестах можно цепляться по тому же CLI и ножки переключать. Сами тесты на каком-нибудь питоне можно писать наподключив кучу библиотек, которые умеют все что надо делать. И сами производители чипов для сетевых протоколов специфичных не редко дают библиотеки на питоне.
Второй подход дороже по времени, но позволяет тестировать и Debug и Release. При тестах дебаг сборки можно бонусом получить логи с железки в тест репорте и быстро продиагностировать.
Звучит как будто на тесты уйдет прилично времени. И да и нет. CLI написать тоже время - и каждый раз поддерживать, лечить при обновках. Тест написать один раз - и он будет автоматически проверяться каждый запуск. Не надо ничего каждый раз отлаживать вручную.
CLI только один раз понадобился в жизни чтобы сделать "нано утилиту" на один вечер.
kipar
Большинство перечисленных плюсов относятся и к чему-нибудь типа MODBUS (RTU). Только с ним ещё можно вывести графики, битовые поля и смотреть как себя ведут десятки параметров в реальном времени, что бывает незаменимо при отладке. А если, например, чаще работаешь с частотными преобразователями чем с ядром линукса, то modbus поймут все твои коллеги и все сторонние устройства, а вот CLI не сможет полноценно пользоваться никто из коллег. У modbus, конечно, есть и свои недостатки, так что я свой велосипед предпочитаю.
В общем конкретно CLI — удобный протокол, но мне кажется важнее само наличие общей структуры проектов, соответствующего метода отладки, протокола общения с устройством и набора сопутствующих утилит. И такой есть, наверное, у всех embedded программистов которых я видел. Но у всех разный.