В разработке электроники часто приходится делать отладку при помощи графических монохромных дисплеев типа SSD1306. Типа таких https://habr.com/ru/articles/741164/

Есть и вовсе законченные устройства с графическим монохромным экраном: научные калькуляторы, диктофоны, автомобильные OBDII тестеры/сканеры, MP3 players, рации, приборные панели автомобилей, фотовспышки, бесперебойные источники питания, бегущие строки в вагонах метро и может быть ещё что-нибудь.

Вот например LoRa трансивер TTGO Т-Beam c графическим дисплеем.

Есть и огромные графические монохромники в метро

В чем трудности при работе с графическими дисплеями?

  1. Проблема в том, что если мы захотим отладить код для сложной графики на большом компьютере, то с удивлением обнаружим, что у языка Си для PC нет встроенной библиотеки для отрисовки битовых матриц в отдельном окне на канве подобно тому как это есть в python или С#. Одновременно с этим прошивки пишут на Си, а не на руthon и С#.

  2. Для написания поддержки сложной графики (бегущая строка, приборная панель, экранное меню, экранная клавиатура, QR код) на графических экранах надо много итераций пере прошивки микроконтроллеров. Это долго, приходится ожидать окончания процесса компиляции потом окончания процесса пере прошивки, чтобы наконец увидеть результат.

  3. Отладка графики на устройстве также требует наличия самого Target устройства и дополнительного оборудования: программатор, источник питания кабели USB-UART. Это особенно трудно в условиях R&D, когда платы разрабатывают параллельно с написанием прошивки и у программистов просто по полгода нет электронной платы для отладки кода.

Есть ли способ отлаживать GUI код графики прямо на LapTop(е) при этом не меняя язык программирования Си? Ответ: да.

Что надо из софтвера?

Утилита

Назначение

1

Компилятор языка Graphviz

Утилита которая из кода DOT строит графику и сохраняет в *.png *.svg *.pdf *.bmp

2

компилятор GCC

Для сборки Cи программы на PC

3

Браузер Chrome

Программа для просмотра файлов

4

Plug-in браузера Chrome для авто обновления вкладки

Для имитации анимации.

Как же отлаживать графику на Си работая на LapTop(е)?

Суть проста. Состоит из трех шагов.

Фаза 1

На С(ях) сгенерировать Graphviz код в виде отдельного файла Display.gv для разметки положения 1024 пикселей и их цветов.

static bool display_render_segment(uint16_t x, int16_t p,
                                   uint8_t segment, 
                                   DisplayHandle_t* Node){
    bool res = false;
    if (segment) {
        LOG_DEBUG(DISPLAY, "(%d,%d):RenderSegment 0x%x=%s",
                  x,
                  p*8,segment, 
                  utoa_bin8(segment));
    }
    int8_t sy = 0;
    for(sy=0; sy<=7; sy++) {
        int16_t y = - sy - p*8;
        char CommonAttributes[200] = "";
        sprintf(CommonAttributes,
                "[height=%f][width=%f][shape=square][label=\"\"][style=filled]",
                Node->pixel_size,Node->pixel_size);
        if(    segment&(1<<sy)    ) {
            /*Pix On*/
            fprintf(Node->file_ptr, 
                    "node_%u %s[color=%s][pos =\"%f,%f!\"];\n",
                    Node->pix_cnt,CommonAttributes,
                    DataMatrixVal2Color(0),
                    ((double)x)*Node->pixel_size,
                    ((double)y)*Node->pixel_size);
        } else {
            /*Pix Off*/
            fprintf(Node->file_ptr, 
                    "node_%u %s[color=%s][pos =\"%f,%f!\"];\n",
                    Node->pix_cnt,CommonAttributes,
                    DataMatrixVal2Color(1),
                    ((double)x)*Node->pixel_size,
                    ((double)y)*Node->pixel_size);
        }
        Node->pix_cnt++;
    }
    return res;
}

Фаза 2

Преобразовать файл *.gv в *.svg или *.gv в *.png при помощи утилиты dot.exe. Для рендеринга надо использовать именно движок neato. Этот движок учитывает желаемые координаты фигур Graphviz.

        char CmdCommand[200] = "";
        sprintf(CmdCommand, "start /B dot.exe -Kneato -Tpng  %s -o %s", 
                            FileNameGv,
                            FileNamePng);
        res = win_cmd_run(CmdCommand);

Фаза 3

Отобразить рисунок *.svg или *.png браузер(ом). Например сhrome.exe.

Фаза 4

Сделать авто обновление вкладки браузера плагином Easy Auto Refresh.

После этого получится отрисовка дисплея в реальном времени. Как будто перед тобой реальная электронная плата с дисплеем SSD1306

При этом Вы можете менять цвет пикселей, менять обводку пикселей, вставлять во внутрь пикселей надписи и прочее. Всё это можно делать средствами синтаксиса языка разметки Graphviz.

Обычно FPS получается порядка 0.33 Hz .

Вот суть всего этого метода.

Ваш симулятор прошивки может работать с Win консолью, имитируя UART-CLI. Вы можете прямо в run-time через консоль приказывать отобразить на симуляторе дисплея текст или фигуру.

Я, к слову, весьма удивлен, что в России (MSK и SPB) среди программистов-микроконтроллеров практически никто не знает и не догадывается о существовании языка Graphviz/Dot. А ведь Dot очень полезен также для составления схем конечных автоматов, построения трансляторов разнообразных типов данных из строчек, описания Toolchain(ов), авто генерации документации и прочего и прочего.

Вывод

Графические монохромные дисплеи можно с легкостью моделировать на большом компьютере. Это позволяет отлаживать сложную графику и сэкономить время на пере прошивке микроконтроллера.

Если вам известны ещё примеры современных электронных устройств с графическим монохромным дисплеем, то напишите про это в комментариях.

Словарь

Акроним

Расшифровка

FPS

frames per second

GUI

graphical user interface

CLI

Command-line interface

Links

https://habr.com/ru/articles/741164/

https://habr.com/ru/articles/337078/
https://habr.com/ru/articles/499170/
https://habr.com/ru/articles/688542/
https://habr.com/ru/articles/662561/

Комментарии (13)


  1. gudvinr
    23.08.2023 23:05
    +6

    Есть ли способ отлаживать GUI код графики прямо на LapTop(е) при этом не меняя язык программирования Си? Ответ: да.

    Если использовать lvgl, можно вообще его и на компьютере запустить:
    https://docs.lvgl.io/latest/en/html/get-started/pc-simulator.html


    SDL и Skia тоже можно было бы рассмотреть в качестве вариантов, которые позволяют рисовать простые элементы без углубления в opengl/directx/и т.д.


  1. lorc
    23.08.2023 23:05
    +7

    Если вы все равно генерируете файл, то почему сразу не генерировать .bmp? Формат у него довольно простой формат, прямо в википедии описан. Так исключается лишний шаг в виде запуска graphviz.

    Еще несколько лет назад можно было бы вообще использовать XBM, но в последнее время его выпиливают из браузеров.


    1. vassabi
      23.08.2023 23:05
      +2

      я бы наверно вообще генерировал файл с 0 и 1, а уже рисовал его чем-то другим - все равно вон у него идет вызов

      sprintf(CmdCommand, "start /B dot.exe -Kneato -Tpng %s -o %s", FileNameGv,FileNamePng);

      res = win_cmd_run(CmdCommand);

      или даже еще проще - генерировал HTML, а в нем body с одной table (и там воттакенные пыксели в ячейках).
      и все - не нужно никаких промежуточных программ


    1. aabzel Автор
      23.08.2023 23:05

      Если вы все равно генерируете файл, то почему сразу не генерировать .bmp?

      Сгенерировать текстовый файл graphviz проще (4 строчки кода ) чем бинарный *.bmp.


      1. pvvv
        23.08.2023 23:05
        +1

        так-то заголовок не самый сложный, только разрешение по горизонтали должно быть кратно 4, чтобы без padding. вроде бы так:

        int s = 54+w*h*3;
        char header[54] = {'B', 'M', s, s>>8, s>>16, s>>24, 0, 0, 0, 0, 54, 0, 0, 0, 40, 0, 0, 0, w, w>>8, w>>16, w>>24, h, h>>8, h>>16, h>>24, 1, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; дальше w*h*3 байт данных пикселей

        а можно через popen открыть gnuplot, сказать ему

        fprintf(f, "set view map\n");

        fprintf(f, "splot '-' matrix with image\n");

        потом данные и e\ne\n в конце

        вылезет окошко с пикселями https://gnuplot.sourceforge.net/demo/heatmaps.html


  1. alef13
    23.08.2023 23:05
    -1

    на Си надо сразу генерировать .svg


  1. PrinceKorwin
    23.08.2023 23:05

    Это долго, приходится ожидать окончания процесса компиляции потом окончания процесса пере прошивки, чтобы наконец увидеть результат.

    Хм. У вас есть предложение как это можно сделать без ожидания процесса компиляции? Если нет, то зачем упоминать компиляцию?


    1. aabzel Автор
      23.08.2023 23:05

      Если внесли изменение в DashBoard для экрана SSD1306 в прошивке, то её по любому надо пере собирать и затем заливать на target. А это 3,5 + 2 = 5.5 минут.

      Поставили пробел в коде, а код вступает в бой только через 6 минут.


      1. PrinceKorwin
        23.08.2023 23:05
        +1

        А в вашем решении без заливки на target какие тайминги и на что?


        1. aabzel Автор
          23.08.2023 23:05

          15 сек сборка FW симулятора и 1 сек на запуск. Код вступает в бой через 16 секунд. В 24 раза быстрее, чем если бы я отлаживался на STM32!


          1. PrinceKorwin
            23.08.2023 23:05
            +1

            А пересобирать код? Это те самые 3.5 мин, нет?


            1. aabzel Автор
              23.08.2023 23:05
              +1

              Сборка FW Simulator собирается быстрее так как в ней полностью отсутствует HAL. Только Си-код приложения.


      1. lorc
        23.08.2023 23:05
        +2

        У меня ядро линукса пересобирается секунд за 30, если я пробел в драйвере ставлю. И то, основное время оно перелинковывается по три раза. Zephyr RTOS естественно пересобирается еще быстрее. В обоих случаях это инкрементальная сборка, конечно же. Зачем каждый раз компилировать то что не менялось?