Как стать автором
Обновить

Язык Dot для Описания Сложных ToolСhain(ов)

C *Программирование микроконтроллеров *Схемотехника *Подготовка технической документации *CAD/CAM *
Tutorial

Разработка софта это не только про код. Разработка софта это во многом про Toolchain(ы). Прежде чем начать исполняться исходники проходят гигантский путь и с каждым годом выходят все более и более массивные системы сборки. Современные технологии разработки софта настолько многостадийные, что понять их не просто.

Toolchain это как длинный конвейер. Есть действия, которые следуют одни за другими. После чего получается результат (артефакты). Большинство IDE(IAR, KEIL, MsVisualStudio и пр.) скрывают весь этот конвейер преобразования файлов. И программисты, которые привыкли торчать в IDE(шках) часто даже не догадываются, что в программировании существует что-то кроме *.h и *.сpp файликов. В этом плане IDE оказывают своим покупателям медвежью услугу, так как программисты привыкшие работать только в IDE имеют тенденцию становиться очень слабыми разработчиками.

По-настоящему разобраться как варятся артефакты сложно. Как же это сделать?

Надо прибегнуть к народной мудрости. Как говорит английская пословица: "картинка стоит тысячи слов". Значит надо нарисовать картинку. Схему ToolChain(а). Зачем еще нужны схемы ToolChain(ов)?

Схема может пригодиться для того чтобы ввести в курс дела новых людей. Например фирма chip maker может получить преимущество на рынке, если у нее есть качественная, понятная, доступная и разнообразная документация.

Как же нарисовать схему ToolChain(а)? Тут есть 2 варианта:

[1] Рисовать схему самому, мышкой в программе Inkscape.exe.

Плюс: Можно добиться очень высокой изобразительности и гибкости. Можно задействовать слои, линейки.

Минус: a)Ручное рисование весьма утомительно. Обязательно наступят боли в запястье. b) Использование мышки в программировании считается дурным тоном. c) Трудно подвергнуть *.svg файл версионному контролю. Конфликты при git merge *.svg так как это в сущности *.xml(ка).

[2] Составить описание графа или дерева на языке разметки графов Dot и автоматически одноименной утилитой dot.exe сгенерировать схему графа.

Плюсы: a) быстро, b) четно. c) легко перерисовать. d) легко подвергнуть версионному контролю. e) легко распределить между разными разработчиками сложной схемы.

Минус: a) Надо очень хорошо знать синтаксис и семантику языка Dot. Кластеры. Свойства вершин, свойства ребер. Способы раскраски. b) Схема может не скомпилироваться рендером, если есть ошибки в синтаксисе языка Dot. c) Cхема может отрисоваться самым неожиданным образом.

Как по мне, второй вариант выглядит намного предпочтительнее и позитивнее так как надо меньше пользоваться мышкой.

Надо установить компилятор Dot файлов. Советую брать с официального сайта https://graphviz.org/. Сейчас там версия 6.0.1. Можно конечно и из CygWin скачать Dot, но там версия устаревшая. Старый Dot может упасть в run-time из-за переполнения стека при отрисовке сложных графов. Не забываем прописать путь к dot.exe в переменную PATH.

Писать код на голом языке Dot это не эффективно. В реальных схемах слишком много повторяющихся синтаксических конструкций. Поэтому объединим Си(ишный) препроцессор (утилита cpp.exe) с языком dot. С препроцессору (cpp.exe) вообще все равно какой там язык (assembler, C++, DeviceTree). Задача утилиты cpp.exe это вставка и замена текста. Например деревья устройств в Linux тоже обрабатываются препроцессором cpp. И это всех устраивает. Поэтому будем также использовать препроцессор cpp для языка dot.

В качестве примера исследуемого сложного ToolChain(а) рассмотрим Zephyr project.

Определим только несколько полезных макросов для языка dot

#define BINARY [fillcolor = turquoise1]
#define GENERATED [fillcolor = moccasin]
#define SRC [style="filled"][fillcolor = green]
#define TOOL [shape = box][style="filled"]
#define SCRIPT [shape = box][style="filled"]   [fillcolor = plum1]
#define FILE [shape = note][fillcolor = gold][style="filled"]
#define DEVICE [shape = box][fillcolor = grey][style="filled"]

Определим файл *.doti с утилитами, которые будут участвовать в ToolChain(е). *.doti - значит, что это include.

     menuconfig TOOL
    clang_format [label="clang-format.exe"] TOOL
    eclipse [label="Eclipse.exe"] TOOL
    eclipsec [label="eclipsec.exe"] TOOL
    bash [label="bash.exe"] TOOL
    hexdump [label="hexdump.exe"] TOOL
    browser [label="chrome.exe"] TOOL
    inkscape [label="Inkscape.exe"] TOOL
    nrfjprog [label="nrfjprog.exe"] TOOL
    Cppcheck [label="Cppcheck.exe"]  TOOL
    dtc [label="dtc"]  TOOL
    gen_defines_py [label="gen_defines.py"] SCRIPT 
    readelf [label="readelf.exe"]TOOL
    jenkins [label="jenkins.exe"]TOOL
    cpp [label="cpp.exe"]TOOL
    chocolatey [label="chocolatey.exe"]TOOL
    git [label="git.exe"]TOOL
    buildprog [label="buildprog.py"]SCRIPT
    JLinkGDBServer [label="JLinkGDBServer.exe"]TOOL
    cpp_dot [label="cpp.exe"]TOOL
    guiconfig  TOOL
    cpp_3 [label="cpp.exe (preproc)"] TOOL
    linker [label="ld.exe (linker)"] TOOL
    compiler [label="gcc.exe (ARM Compiler)"] TOOL
    NotePadPp [label="Notepad++.exe"] TOOL
    cmd [label="cmd.exe"] TOOL
    GDB [label="gdb.exe"] TOOL
    cMake [label="cmake.exe"] TOOL
    west [label="west.py"] SCRIPT
    GN  [label="gn.exe"] TOOL
    scripts_kconfig [label="zephyr/scripts/kconfig.py"]  SCRIPT
    nrfjprog [label="nrfjprog.exe"]  TOOL
    Python [label="Python.exe"] TOOL
    make [label="make.exe"] TOOL
    ninja [label="ninja.exe"] TOOL
    objcopy [label="objcopy.exe"] TOOL
    as [label="as.exe"]TOOL
    nm [label="nm.exe"]TOOL
    addr2line [label="addr2line.exe"]TOOL
    dot [label="dot.exe"]TOOL
    ar [label="ar.exe"]TOOL
    { rank = same; ninja; make;}

Определим *.doti файл со списком расширений файлов, которые будут участвовать в ToolChain(е)

    dtsi[label="*.dtsi"] FILE SRC
    DotConf[label="*.conf (Kernel configuration)"] FILE SRC
    bat_file[label="*.bat"] FILE  SRC
    CMakeLists [label="CMakeLists.txt "]  FILE SRC
    sh_file[label="*.sh"] FILE SRC
    ld_file[label="*.ld"] FILE SRC
    mk_file[label="*.mk"] FILE SRC
    h_file[label="*.h"] FILE SRC
    c_file[label="*.c"] FILE SRC
    dot_file[label="*.dot"] FILE SRC
    doti_file[label="*.doti"] FILE SRC
    yaml[label="*.yaml"] FILE SRC
    Kconfig [label="Kconfig"] FILE SRC
    dts[label="*.dts"] FILE SRC
    zephyr_dts_pre[label="zephyr.dts.pre"] FILE
    cproject [label=".cproject "] FILE 
    project [label=".project (description file)"] FILE 
    Kconfig_zephyr[label="Kconfig.zephyr"] FILE 
    txt_file[label="*.txt"] FILE 
    obj_file[label="*.o"] FILE 
    CMakeCache_txt [label="CMakeCache.txt "] FILE 
    map_file[label="*.map"] FILE 
    a_file[label="*.a"] FILE 
    elf_file[label="*.elf"] FILE 
    hex_file[label="*.hex"] FILE 
    bin_file[label="*.bin"] FILE 
    build_ninja [label="build.ninja"]  FILE
    json_file[label="*.json"] FILE 
    svg_file[label="*.svg "] FILE
    west_yml[label="west.yml (manifest file)"] FILE
    MakeFile[label="Makefile"] FILE
    devicetree_generated_h[label="devicetree_generated.h"] FILE
    zephyr_dts[label="zephyr.dts "] FILE
    autoconfig_h [label="autoconfig.h"]  FILE
    s_file [label="*.S"]  FILE
    gn_file [label="BUILD.gn"]  FILE
    cmd_file [label="*.cmd"]  FILE
    pp_file [label="*.pp"]  FILE
    DotConfig [label=".config"]  FILE

Определим файл со связями утилит и файлов между собой.


digraph  graphname {
    rankdir=TB;
    splines=ortho;
    #include "ToolChain_nRF5340_hardware.doti"
    //overlap=scale;
    //overlap=prism;
    
    subgraph cluster_NetTop {
         style=filled;
            color=aliceblue;
            label = "NetTop";
            HostCpu
            HOST_USB
            subgraph cluster_Windows10 {
            	style=filled;
	        	color=lightblue;
                label = "Windows10";
                
                #include "ToolChain_nRF5340_tools.doti"
                #include "ToolChain_nRF5340_files.doti"
                
                NotePadPp->bat_file[label="*.bat"][dir="both"]
                NotePadPp->doti_file[label="*.doti"] [dir="both"]
                NotePadPp->sh_file[label="*.sh"][dir="both"]
                NotePadPp->mk_file[label="*.mk"][dir="both"]
                NotePadPp->c_file[label="*.c"][dir="both"]
                NotePadPp->h_file[label="*.h"][dir="both"]
                bat_file->cmd[label="*.bat"] 
            
                
                sh_file->bash[label="*.sh"] 
                
            subgraph cluster_JVM {
            	style=filled;
	        	color=lightgreen;
                label = "JVM";
                jenkins->bash
                eclipsec
                cproject->eclipse[label=".cproject"][dir="both"]
                project->eclipse[label=".project"][dir="both"]
     
            }
                
            subgraph cluster_BuildConfig {
                style=filled;
	            color=khaki1;
                label = "Build Configuration (buildsystem)";
                bash->buildprog
                cmd->buildprog
                Python->buildprog
                json_file->buildprog [label="*.json"]
                
                Python->west
                buildprog->west[label="?"]
                yaml->gen_defines_py[label="*.yaml"]
                dtsi->cpp[label="*.dtsi"]  
                dts->cpp
                cpp->zephyr_dts_pre
                zephyr_dts_pre ->gen_defines_py[label="zephyr.dts.pre"] 
                gen_defines_py->zephyr_dts[label="zephyr.dts"]
                gen_defines_py->devicetree_generated_h[label="devicetree_generated.h"] 
                zephyr_dts->dtc
                CMakeLists->cMake[label="CMakeLists.txt"] 
                west->cMake
                west->scripts_kconfig
                cMake->CMakeCache_txt[label="CMakeCache.txt"]  [dir="both"]
                gn_file->GN
                GN->build_ninja
                cMake->build_ninja[label="build.ninja"]  
                cMake->MakeFile
	            menuconfig  [label="menuconfig "] 
                Kconfig->menuconfig [label="Kconfig"] 
                Kconfig->Kconfig_zephyr
                    
   
                Kconfig->guiconfig[label="Kconfig"] 
                Kconfig->scripts_kconfig[label="Kconfig"] 
                DotConf->scripts_kconfig[label="*.conf"]
                scripts_kconfig->autoconfig_h[label="autoconfig.h"] 
                scripts_kconfig->DotConfig[label="*.config"] 
            }//cluster_BuildConfig
                  
                ld_file->git[label="*.ld"][dir="both"]
                sh_file->git[label="*.sh"][dir="both"]
                h_file->git[label="*.h"][dir="both"]
                c_file->git[label="*.c"][dir="both"]
                mk_file->git[label="*.mk"][dir="both"]
                doti_file->git[label="*.doti"][dir="both"]
                cproject->git[label=".cproject"][dir="both"]
                MakeFile->git[label="Makefile"][dir="both"]
                project->git[label=".project"][dir="both"]
                  
            c_file->eclipse[label="*.c "]
            h_file->eclipse[label="*.h"]
            eclipse->c_file[label="*.c "]
            eclipse->h_file[label="*.h"]
            eclipse->MakeFile[dir="both"][label="Makefile"]
            eclipse->mk_file[dir="both"][label="*.mk"]
            
             
                subgraph cluster_BuildArtefact {
                        	style=filled;
	            	color=gray100;
                    label = "Build Artefact";
                    build_ninja->ninja[label="Makefile"]  
                    ninja->cpp_3
                    h_file->cpp_3
                    c_file->cpp_3
                    autoconfig_h->cpp_3[label="autoconfig.h"]
                    devicetree_generated_h->cpp_3
                    pp_file->compiler
                    compiler->s_file   [label="*.S"]
                    s_file->as
                    compiler->ar
                    as->obj_file
                    obj_file->linker  [label="*.obj"] /*[tailport=s] [headport=n] */
                    obj_file->ar[label="*.o"]
                    ar->a_file[label="*.a"]
                    obj_file->nm[label="*.o"]
                    ld_file->linker [label="*.ld"]//[headport=n] 
                    cmd_file->linker[label="*.cmd"]
                    a_file->linker[label="*.a"]
                    linker->elf_file[label="*.elf"]  
                    linker->map_file[label="*.map"]  
                    elf_file->addr2line[label="*.elf"]
                    addr2line->eclipse[label=".txt"]
                    elf_file -> objcopy
                    objcopy->bin_file
                    objcopy->hex_file
                    elf_file->readelf[label="*.elf"]
                    elf_file->GDB[label="*.elf"]
                    GDB-> JLinkGDBServer[dir="both"][label="port:2331"]
                    bin_file->hexdump[label="*.bin"]
                    hexdump->txt_file[label="*.txt"]
                    mk_file->make[label="*.mk"]  
                    MakeFile->make[label="MakeFile"]  
                    make->cpp_3
                    cpp_3 -> pp_file
                    hex_file->nrfjprog
                   
        }
            
         

      subgraph cluster_BuildDoc {
                    style=filled;
	            	color=beige;
                    label = "Build Documentation";
                    doti_file->cpp_dot
                    cpp_dot->dot_file
                    dot_file->dot
                    dot->svg_file[label="*.svg"]
                    svg_file->browser[label="*.svg"]
                    svg_file->inkscape[label="*.svg"]
        }
                    clang_format->c_file[label="*.c"][dir="both"]
                    clang_format->h_file[label="*.h"][dir="both"]
                    h_file->Cppcheck[label="*.h"]
                    c_file->Cppcheck[label="*.c"]
            
             
                browser->jenkins[label="8080"]  
                
    
            }//Win10
            //NotePadPp->Monitor
    }//NetTop
 
    eclipse->Monitor
    nrfjprog->HOST_USB
    JLinkGDBServer->HOST_USB
    subgraph cluster_Board {
            style=filled;
            color=lightblue;
            label = "Board";
            USB_CONNECTOR_BOARD
            Programmator
            TargetMcu
     
    }
 
}

Теперь надо собрать, собственно, сам *.dot файл для утилиты рендера dot.exe, преобразовать *.dot в векторную графику *.svg и отобразить рисунок на экране монитора прямо в браузере. Вот такой микро-конвейер надо реализовать.

Тут нам как раз поможет утилита make. Вот ее код


CC=dot
RENDER="C:/Program Files/Google/Chrome/Application/chrome.exe"
#RENDER=chrome.exe
CURRENT_DIR = $(shell pwd)
$(info CURRENT_DIR=  $(CURRENT_DIR) )

CURRENT_DIR := $(subst /cygdrive/c/,C:/, $(CURRENT_DIR))
$(info CURRENT_DIR=$(CURRENT_DIR) )

SOURCES_DOT += $(CURRENT_DIR)/ToolChain_nRF5340.doti
SOURCES_DOT_RES += $(CURRENT_DIR)/ToolChain_nRF5340_res.dot

SOURCES_DOT := $(subst /cygdrive/c/,C:/, $(SOURCES_DOT))
$(info SOURCES_DOT=  $(SOURCES_DOT) )

ART_SVG := $(subst doti,svg, $(SOURCES_DOT))
ART_PDF := $(subst doti,pdf, $(SOURCES_DOT))

OPT +=
DOT_OPT +=-Tsvg 
DOT_OPT +=-v  
DOT_OPT +=-L1
#LAYOUT_ENGINE = -Kneato 
#LAYOUT_ENGINE = -Kfdp 
#LAYOUT_ENGINE = -Ksfdp
#LAYOUT_ENGINE = -Ktwopi
#LAYOUT_ENGINE = -Kosage
#LAYOUT_ENGINE = -Kpatchwork
LAYOUT_ENGINE = -Kdot 

preproc:$(SOURCES_DOT)
	$(info Preproc...)
	cpp $(SOURCES_DOT)  $(OPT) -E -o $(SOURCES_DOT_RES)

generate_pdf: preproc
	$(info route graph...)
	$(CC) -Tpdf $(LAYOUT_ENGINE) $(SOURCES_DOT_RES) -o $(ART_PDF)
  
generate_svg: preproc
	$(info route graph...)
	$(CC) $(DOT_OPT) $(SOURCES_DOT_RES) -o $(ART_SVG)

print_svg: generate_svg generate_pdf
	$(info print_svg)
	$(RENDER) -open $(ART_SVG)
	$(RENDER) -open $(ART_PDF)

all:  print_svg
	$(info All)

clean:
	$(info clean)
	rm ToolChain_nRF5340_res.svg
	rm $(SOURCES_DOT_RES)




#$(ART_SVG):$(ART_SVG)

Для любителей ninja я тоже накропал ninja скрипт

cflags =  -Tsvg
cur_dir =  C:\projects\code_base_workspace\code_base_firmware\docs\toolchain_nRF5340\
RENDER="C:/Program Files/Google/Chrome/Application/chrome.exe"
#RENDER=chrome.exe

rule preproc
  command = cpp $in -E -o $out

rule generate_svg
  command = dot $cflags  $in -o $out

rule print_in_browse
  command = $RENDER  -open $cur_dir/$in 
  
rule clean_temp
  command = rm  *_generated.svg 
  command = rm  *_res.dot

rule svg2pdf
  command = dot.exe -Tpdf  $in -o $out

  
build clean: clean_temp  

build ToolChain_nRF5340_res.dot: preproc  ToolChain_nRF5340.doti 

build ToolChain_nRF5340_generated.svg: generate_svg  ToolChain_nRF5340_res.dot 

build ToolChain_nRF5340_generated.pdf: svg2pdf  ToolChain_nRF5340_res.dot 

#build ToolChain_nRF5340_generated.pdf: svg2pdf ToolChain_nRF5340_generated.svg

build make_svg: print_in_browse  ToolChain_nRF5340_generated.svg    

build make_pdf: print_in_browse  ToolChain_nRF5340_generated.pdf    


default make_pdf

В результате мы собрали вот такую замечательную блок схемку.

Успех! Теперь все как на ладони. Причем даже Ctrl+F поиск есть!

Буквально пара слов про Zephyr. Видно, что Zephyr собирает проекты в два супер этапа. Сначала Zephyr собирает конфигурацию. Результат сборки конфигурации это Makefile или build.ninja плюс несколько заголовочных файлов, затем собирают сами артефакты на основе собранной ранее конфигурации. На схеме все прекрасно видно.

Вот полный *.dot код с выхода препроцессора для тех кто хочет изучить схему под увеличением

Hidden text
# 1 "C:/1_job/0_NPP_IT_ELMA/code_base_workspace/code_base_firmware/docs/toolchain_nRF5340/ToolChain_nRF5340.doti"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "C:/1_job/0_NPP_IT_ELMA/code_base_workspace/code_base_firmware/docs/toolchain_nRF5340/ToolChain_nRF5340.doti"






digraph graphname {
    rankdir=TB;
    splines=ortho;
# 1 "C:/1_job/0_NPP_IT_ELMA/code_base_workspace/code_base_firmware/docs/toolchain_nRF5340/ToolChain_nRF5340_hardware.doti" 1
    Monitor [label="Monitor"] [shape = box][fillcolor = grey][style="filled"]
    Programmator [label="Programmator"] [shape = box][fillcolor = grey][style="filled"]
    TargetMcu [label="nRF5340 ARM Cortex-M33 2x"] [shape = box][fillcolor = grey][style="filled"]
    HOST_USB [label="USB"] [shape = box][fillcolor = grey][style="filled"]
    USB_CONNECTOR_BOARD [label="USB"] [shape = box][fillcolor = grey][style="filled"]
    HostCpu [label="X86 AMD64"] [shape = box][fillcolor = grey][style="filled"]
    HostCpu->HOST_USB
    HOST_USB->USB_CONNECTOR_BOARD[label="USB"]
    USB_CONNECTOR_BOARD->Programmator[label="USB"]
    Programmator->TargetMcu[label="SWD"]
# 11 "C:/1_job/0_NPP_IT_ELMA/code_base_workspace/code_base_firmware/docs/toolchain_nRF5340/ToolChain_nRF5340.doti" 2



    subgraph cluster_NetTop {
         style=filled;
            color=aliceblue;
            label = "NetTop";
            HostCpu
            HOST_USB
            subgraph cluster_Windows10 {
             style=filled;
          color=lightblue;
                label = "Windows10";

# 1 "C:/1_job/0_NPP_IT_ELMA/code_base_workspace/code_base_firmware/docs/toolchain_nRF5340/ToolChain_nRF5340_tools.doti" 1



    menuconfig [shape = box][style="filled"]
    clang_format [label="clang-format.exe"] [shape = box][style="filled"]
    eclipse [label="Eclipse.exe"] [shape = box][style="filled"]
    eclipsec [label="eclipsec.exe"] [shape = box][style="filled"]
    bash [label="bash.exe"] [shape = box][style="filled"]
    hexdump [label="hexdump.exe"] [shape = box][style="filled"]
    browser [label="chrome.exe"] [shape = box][style="filled"]
    inkscape [label="Inkscape.exe"] [shape = box][style="filled"]
    nrfjprog [label="nrfjprog.exe"] [shape = box][style="filled"]
    Cppcheck [label="Cppcheck.exe"] [shape = box][style="filled"]
    dtc [label="dtc"] [shape = box][style="filled"]
    gen_defines_py [label="gen_defines.py"] [shape = box][style="filled"] [fillcolor = plum1]
    readelf [label="readelf.exe"][shape = box][style="filled"]
    jenkins [label="jenkins.exe"][shape = box][style="filled"]
    cpp [label="cpp.exe"][shape = box][style="filled"]
    chocolatey [label="chocolatey.exe"][shape = box][style="filled"]
    git [label="git.exe"][shape = box][style="filled"]
    buildprog [label="buildprog.py"][shape = box][style="filled"] [fillcolor = plum1]
    JLinkGDBServer [label="JLinkGDBServer.exe"][shape = box][style="filled"]
    cpp_dot [label="cpp.exe"][shape = box][style="filled"]
    guiconfig [shape = box][style="filled"]
    cpp_3 [label="cpp.exe (preproc)"] [shape = box][style="filled"]
    linker [label="ld.exe (linker)"] [shape = box][style="filled"]
    compiler [label="gcc.exe (ARM Compiler)"] [shape = box][style="filled"]
    NotePadPp [label="Notepad++.exe"] [shape = box][style="filled"]
    cmd [label="cmd.exe"] [shape = box][style="filled"]
    GDB [label="gdb.exe"] [shape = box][style="filled"]
    cMake [label="cmake.exe"] [shape = box][style="filled"]
    west [label="west.py"] [shape = box][style="filled"] [fillcolor = plum1]
    GN [label="gn.exe"] [shape = box][style="filled"]
    scripts_kconfig [label="zephyr/scripts/kconfig.py"] [shape = box][style="filled"] [fillcolor = plum1]
    nrfjprog [label="nrfjprog.exe"] [shape = box][style="filled"]
    Python [label="Python.exe"] [shape = box][style="filled"]
            make [label="make.exe"] [shape = box][style="filled"]
            ninja [label="ninja.exe"] [shape = box][style="filled"]
    objcopy [label="objcopy.exe"] [shape = box][style="filled"]
    as [label="as.exe"][shape = box][style="filled"]
    nm [label="nm.exe"][shape = box][style="filled"]
    addr2line [label="addr2line.exe"][shape = box][style="filled"]
    dot [label="dot.exe"][shape = box][style="filled"]
    ar [label="ar.exe"][shape = box][style="filled"]
# 26 "C:/1_job/0_NPP_IT_ELMA/code_base_workspace/code_base_firmware/docs/toolchain_nRF5340/ToolChain_nRF5340.doti" 2
# 1 "C:/1_job/0_NPP_IT_ELMA/code_base_workspace/code_base_firmware/docs/toolchain_nRF5340/ToolChain_nRF5340_files.doti" 1
    dtsi[label="*.dtsi"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green]
    DotConf[label="*.conf (Kernel configuration)"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green]
    bat_file[label="*.bat"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green]
    CMakeLists [label="CMakeLists.txt "] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green]
    sh_file[label="*.sh"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green]
    ld_file[label="*.ld"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green]
    mk_file[label="*.mk"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green]
    h_file[label="*.h"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green]
    c_file[label="*.c"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green]
    dot_file[label="*.dot"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green]
    doti_file[label="*.doti"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green]
    yaml[label="*.yaml"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green]
    Kconfig [label="Kconfig"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green]
    dts[label="*.dts"] [shape = note][fillcolor = gold][style="filled"] [style="filled"][fillcolor = green]
    zephyr_dts_pre[label="zephyr.dts.pre"] [shape = note][fillcolor = gold][style="filled"]
    cproject [label=".cproject "] [shape = note][fillcolor = gold][style="filled"]
    project [label=".project (description file)"] [shape = note][fillcolor = gold][style="filled"]
    Kconfig_zephyr[label="Kconfig.zephyr"] [shape = note][fillcolor = gold][style="filled"]
    txt_file[label="*.txt"] [shape = note][fillcolor = gold][style="filled"]
    obj_file[label="*.o"] [shape = note][fillcolor = gold][style="filled"]
    CMakeCache_txt [label="CMakeCache.txt "] [shape = note][fillcolor = gold][style="filled"]
    map_file[label="*.map"] [shape = note][fillcolor = gold][style="filled"]
    a_file[label="*.a"] [shape = note][fillcolor = gold][style="filled"]
    elf_file[label="*.elf"] [shape = note][fillcolor = gold][style="filled"]
    hex_file[label="*.hex"] [shape = note][fillcolor = gold][style="filled"]
    bin_file[label="*.bin"] [shape = note][fillcolor = gold][style="filled"]
    build_ninja [label="build.ninja"] [shape = note][fillcolor = gold][style="filled"]
    json_file[label="*.json"] [shape = note][fillcolor = gold][style="filled"]
    svg_file[label="*.svg "] [shape = note][fillcolor = gold][style="filled"]
    west_yml[label="west.yml (manifest file)"] [shape = note][fillcolor = gold][style="filled"]
    MakeFile[label="Makefile"] [shape = note][fillcolor = gold][style="filled"]
    devicetree_generated_h[label="devicetree_generated.h"] [shape = note][fillcolor = gold][style="filled"]
    zephyr_dts[label="zephyr.dts "] [shape = note][fillcolor = gold][style="filled"]
    autoconfig_h [label="autoconfig.h"] [shape = note][fillcolor = gold][style="filled"]
    s_file [label="*.S"] [shape = note][fillcolor = gold][style="filled"]
    gn_file [label="BUILD.gn"] [shape = note][fillcolor = gold][style="filled"]
    cmd_file [label="*.cmd"] [shape = note][fillcolor = gold][style="filled"]
    pp_file [label="*.pp"] [shape = note][fillcolor = gold][style="filled"]
    DotConfig [label=".config"] [shape = note][fillcolor = gold][style="filled"]
# 27 "C:/1_job/0_NPP_IT_ELMA/code_base_workspace/code_base_firmware/docs/toolchain_nRF5340/ToolChain_nRF5340.doti" 2

                NotePadPp->bat_file[label="*.bat"][dir="both"]
                NotePadPp->doti_file[label="*.doti"] [dir="both"]
                NotePadPp->sh_file[label="*.sh"][dir="both"]
                NotePadPp->mk_file[label="*.mk"][dir="both"]
                NotePadPp->c_file[label="*.c"][dir="both"]
                NotePadPp->h_file[label="*.h"][dir="both"]
                bat_file->cmd[label="*.bat"]


                sh_file->bash[label="*.sh"]

            subgraph cluster_JVM {
             style=filled;
          color=lightgreen;
                label = "JVM";
                jenkins->bash
                eclipsec
                cproject->eclipse[label=".cproject"][dir="both"]
                project->eclipse[label=".project"][dir="both"]

            }

            subgraph cluster_BuildConfig {
                style=filled;
             color=khaki1;
                label = "Build Configuration (buildsystem)";
                bash->buildprog
                cmd->buildprog
                Python->buildprog
                json_file->buildprog [label="*.json"]

                Python->west
                buildprog->west[label="?"]
                yaml->gen_defines_py[label="*.yaml"]
                dtsi->cpp[label="*.dtsi"]
                dts->cpp
                cpp->zephyr_dts_pre
                zephyr_dts_pre ->gen_defines_py[label="zephyr.dts.pre"]
                gen_defines_py->zephyr_dts[label="zephyr.dts"]
                gen_defines_py->devicetree_generated_h[label="devicetree_generated.h"]
                zephyr_dts->dtc
                CMakeLists->cMake[label="CMakeLists.txt"]
                west->cMake
                west->scripts_kconfig
                cMake->CMakeCache_txt[label="CMakeCache.txt"] [dir="both"]
                gn_file->GN
                GN->build_ninja
                cMake->build_ninja[label="build.ninja"]
                cMake->MakeFile
             menuconfig [label="menuconfig "]
                Kconfig->menuconfig [label="Kconfig"]
                Kconfig->Kconfig_zephyr


                Kconfig->guiconfig[label="Kconfig"]
                Kconfig->scripts_kconfig[label="Kconfig"]
                DotConf->scripts_kconfig[label="*.conf"]
                scripts_kconfig->autoconfig_h[label="autoconfig.h"]
                scripts_kconfig->DotConfig[label="*.config"]
            }

                ld_file->git[label="*.ld"][dir="both"]
                sh_file->git[label="*.sh"][dir="both"]
                h_file->git[label="*.h"][dir="both"]
                c_file->git[label="*.c"][dir="both"]
                mk_file->git[label="*.mk"][dir="both"]
                doti_file->git[label="*.doti"][dir="both"]
                cproject->git[label=".cproject"][dir="both"]
                MakeFile->git[label="Makefile"][dir="both"]
                project->git[label=".project"][dir="both"]

            c_file->eclipse[label="*.c "]
            h_file->eclipse[label="*.h"]
            eclipse->c_file[label="*.c "]
            eclipse->h_file[label="*.h"]
            eclipse->MakeFile[dir="both"][label="Makefile"]
            eclipse->mk_file[dir="both"][label="*.mk"]



                subgraph cluster_BuildArtefact {
                         style=filled;
              color=gray100;
                    label = "Build Artefact";
                    build_ninja->ninja[label="Makefile"]
                    ninja->cpp_3
                    h_file->cpp_3
                    c_file->cpp_3
                    autoconfig_h->cpp_3[label="autoconfig.h"]
                    devicetree_generated_h->cpp_3
                    pp_file->compiler
                    compiler->s_file [label="*.S"]
                    s_file->as
                    compiler->ar
                    as->obj_file
                    obj_file->linker [label="*.obj"]
                    obj_file->ar[label="*.o"]
                    ar->a_file[label="*.a"]
                    obj_file->nm[label="*.o"]
                    ld_file->linker [label="*.ld"]
                    cmd_file->linker[label="*.cmd"]
                    a_file->linker[label="*.a"]
                    linker->elf_file[label="*.elf"]
                    linker->map_file[label="*.map"]
                    elf_file->addr2line[label="*.elf"]
                    addr2line->eclipse[label=".txt"]
                    elf_file -> objcopy
                    objcopy->bin_file
                    objcopy->hex_file
                    elf_file->readelf[label="*.elf"]
                    elf_file->GDB[label="*.elf"]
                    GDB-> JLinkGDBServer[dir="both"][label="port:2331"]
                    bin_file->hexdump[label="*.bin"]
                    hexdump->txt_file[label="*.txt"]
                    mk_file->make[label="*.mk"]
                    MakeFile->make[label="MakeFile"]
                    make->cpp_3
                    cpp_3 -> pp_file
                    hex_file->nrfjprog

        }




      subgraph cluster_BuildDoc {
                    style=filled;
              color=beige;
                    label = "Build Documentation";
                    doti_file->cpp_dot
                    cpp_dot->dot_file
                    dot_file->dot
                    dot->svg_file[label="*.svg"]
                    svg_file->browser[label="*.svg"]
                    svg_file->inkscape[label="*.svg"]
        }
                    clang_format->c_file[label="*.c"][dir="both"]
                    clang_format->h_file[label="*.h"][dir="both"]
                    h_file->Cppcheck[label="*.h"]
                    c_file->Cppcheck[label="*.c"]

                browser->jenkins[label="8080"]



            }

    }

    eclipse->Monitor
    nrfjprog->HOST_USB
    JLinkGDBServer->HOST_USB
    subgraph cluster_Board {
            style=filled;
            color=lightblue;
            label = "Board";
            USB_CONNECTOR_BOARD
            Programmator
            TargetMcu

    }

}

Вывод.
Как видите синергия препроцессора cpp и языка разметки Dot может оказаться очень полезна и эффективна в разработке софта и документации. Это позволяет высвободить тонну времени от ручной перерисовки. Можно также генерировать схемы электрических цепочек, графы задач из task traker(а), нейронные сети, конечные автоматы, архитектуры систем на чипе SoC. Да всё, что только угодно, что имеет графо образную природу.

Язык Dot настолько хорошо и универсален, что его следовало бы включить в университетскую программу обучения технических факультетов в качестве одной лабораторной работы по компьютерным технологиям.

Особенно советую обратить внимание на связку сpp/dot/make тем кто работает техническими писателями и схемотехниками. Это тот случай, когда программирование им тоже может быть полезно.

Ссылки про язык Dot

https://habr.com/ru/post/682346/

https://habr.com/ru/post/499170/

https://habr.com/ru/post/337078/

https://habr.com/ru/post/662561/

https://habr.com/ru/post/258295/

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Вы пользовались языком Dot?
100% да 2
0% нет 0
Проголосовали 2 пользователя. Воздержавшихся нет.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Вы составляли схемы ToolChain(а)?
50% да 1
50% нет 1
Проголосовали 2 пользователя. Воздержавшихся нет.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Вы собирали код из-под Zephyr project?
50% да 1
50% нет 1
Проголосовали 2 пользователя. Воздержавшихся нет.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Вы собирали код из-под Ninja?
100% да 2
0% нет 0
Проголосовали 2 пользователя. Воздержавшихся нет.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Вы собирали код из-под Makefile(ов)?
100% да 2
0% нет 0
Проголосовали 2 пользователя. Воздержавшихся нет.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Вы собираете документацию из кода?
100% да 2
0% нет 0
Проголосовали 2 пользователя. Воздержавшихся нет.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Вы пользовались языком Dot в связке с препроцессором cpp?
100% да 1
0% нет 0
Проголосовал 1 пользователь. Воздержавшихся нет.
Теги:
Хабы:
Рейтинг 0
Просмотры 95
Комментарии 0
Комментарии Комментировать