Есть такая классическая технология отладки 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)


  1. kipar
    21.10.2022 09:41
    +2

    Большинство перечисленных плюсов относятся и к чему-нибудь типа MODBUS (RTU). Только с ним ещё можно вывести графики, битовые поля и смотреть как себя ведут десятки параметров в реальном времени, что бывает незаменимо при отладке. А если, например, чаще работаешь с частотными преобразователями чем с ядром линукса, то modbus поймут все твои коллеги и все сторонние устройства, а вот CLI не сможет полноценно пользоваться никто из коллег. У modbus, конечно, есть и свои недостатки, так что я свой велосипед предпочитаю.

    В общем конкретно CLI — удобный протокол, но мне кажется важнее само наличие общей структуры проектов, соответствующего метода отладки, протокола общения с устройством и набора сопутствующих утилит. И такой есть, наверное, у всех embedded программистов которых я видел. Но у всех разный.


  1. 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 провернёте


    1. rsashka
      21.10.2022 10:46
      +6

      Вы мешаете теплое с кислым. Как вам поможет CAN для отладки прошивки?

      И то что UART не выводится в блоках Tesla совершенно не означает, что его нет блоках и он не использовался для отладке или тестировании блока при производстве. Ведь UART это не внешний интерфейс, каким является шина CAN.


      1. Zuy
        21.10.2022 17:33
        +1

        CAN для отладки помогает отлично. Туда выводятся все нужные сигналы, записывают трейсы и анализируют их во времени. Мало того, это все делается ещё и удаленно, когда трейс отправляется на сервер и можно видеть все сигналы в онлайн. Это дело ещё и работает не просто на один блок а сразу на всю машину и на одном графике можно смотреть сигналы от разных блоков.


    1. aabzel Автор
      21.10.2022 13:26
      -1

      все делается только по CAN


      В прошивке ECU после коммита сломался CAN. Нет CAN Link(а).
      Ваши действия?


      1. Zuy
        21.10.2022 17:34
        +2

        Сделаю bisect по изменениям и найду что его сломало.


    1. aabzel Автор
      21.10.2022 13:32
      -1

      По CAN достаточно подключиться в одном месте к шине и можно отлаживать или обновлять прошивку на всех устройствах на этой шине. Ну вот как вы такой трюк с UART провернёте?

      Легко, можно подключится ноде A к ее UART CLI и набрать shell команду проброса данных из UART в CAN (Data Forwarding) и этими командами по UART обновить прошивку на любой ноде подключенной к этой же CAN мети.

      Сама нода ECU выступает как переходник UART<->CAN.


      1. Zuy
        21.10.2022 17:36

        Это все можно, но зачем? CAN уже есть, весь софт для апдейта и отладки по CAN уже есть и это даже отраслевой стандарт. Зачем тут ещё и UART с CLI нужен?


        1. aabzel Автор
          21.10.2022 17:58

          переходники USB-UART дешевле чем переходники USB-CAN


    1. man_of_letters
      21.10.2022 13:37
      +2

      >как вы такой трюк с UART провернёте
      RS-485


      1. Zuy
        21.10.2022 17:43

        Ах да, точно, забыл про него.


  1. 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 :)


  1. madcatdev
    21.10.2022 17:32
    +1

    Использую такую вещь в своих разработках, но с некоторыми отличиями - мк не отправляет обратно каждый введенный символ, а реагирует только на строку с /n. Работа с терминальными программами вроде putty в данном случае невозможна, зато возможен вывод информации в процессе ввода команды.


  1. Mike-M
    22.10.2022 12:17
    +1

    CLI это вообще универсальный протокол.
    CLI — это вообще-то Command Line Interface, а не протокол.

    В недостатки я бы добавил пару пунктов:
    CLI не нарушает timing(и) время исполнения программ протекает в естественном режиме.
    CLI нежелательно использовать для вывода значений переменных и прочей информации в runtime, поскольку на подпрограмму обработки UART тоже требуется время.
    На форуме Electronix видел реальные случаи влияния на работу прошивки с UART-отладкой и без неё.

    CLI и подпрограмма обработки занимает место, как в постоянной, так и в оперативной памяти МК.
    В противоположность этому интерфейс JTAG/SWD реализован на уровне ядра МК и не требует дополнительного софта на нём.

    Не против CLI, но поддерживаю комментаторов выше:
       — вместо 20-pin разъема давно уже изобрели разъём c гораздо меньшим числом выводов
       — вместо дорогого JTAG/SWD отладчика можно обойтись более дешевым


  1. volodyaleo
    23.10.2022 12:16

    CLI не просто требует памяти, а еще и не везде влезет. Это занимает место в буферах и ROM. И вносит задержки.

    Выглядит прикольно, но. Зачастую вместо него можно логи на одну TX ножку в debug сборке тащить, а RX не инициализировать. И настроить логгер который можно переключать при компиляции дефайнами: включать-выключать для модуля или уровень подробности менять.

    Далее два подхода к тестам:

    1) Модульные тесты, которые на железе пускаются с включенными логами и проверяются куски кода по сценариям. Тут можно наловить урожай достаточный чтобы дальше вручную не проверять много всего.

    2) Интеграционные - собирать стенд, который умеет продёргивать ножки или по сети команды бросать и собирать логи. Цеплять такое можно к CI/CD (никто из команды не уронит код на мастере). Если макетировать на отладках, там уже часто есть board controller к которому в тестах можно цепляться по тому же CLI и ножки переключать. Сами тесты на каком-нибудь питоне можно писать наподключив кучу библиотек, которые умеют все что надо делать. И сами производители чипов для сетевых протоколов специфичных не редко дают библиотеки на питоне.

    Второй подход дороже по времени, но позволяет тестировать и Debug и Release. При тестах дебаг сборки можно бонусом получить логи с железки в тест репорте и быстро продиагностировать.

    Звучит как будто на тесты уйдет прилично времени. И да и нет. CLI написать тоже время - и каждый раз поддерживать, лечить при обновках. Тест написать один раз - и он будет автоматически проверяться каждый запуск. Не надо ничего каждый раз отлаживать вручную.

    CLI только один раз понадобился в жизни чтобы сделать "нано утилиту" на один вечер.