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

Как же понять и разобраться в новой схемотехнике очередной навороченной платы?

Как понять с какой стороны подходить к печатной плате?

Как понять куда подавать питание, куда подключать программатор, а куда отладочный UART?

Ответ прост. Нужен Helicopter View или, проще говоря, подробная блок схема устройства. Надо четко себе представлять аппаратную платформу платы на системном уровне.

Как же создать блок-схему сложнецкой платы? Как не ошибиться с разводкой топологии блок схемы?

По поводу важности составления блок схем печатных плат у меня есть отдельный пост https://habr.com/ru/post/667030/

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

Проделаем этот путь на примере малоизвестной отладочной платы nRF5340-DK. Эту плату nRF5340-DK можно метафорично назвать железнодорожным вокзалом, так как количество мультиплексоров на этой PCB просто зашкаливает, подобно тому как на ж/д станциях полно рельсовых стрелок. Попробуем разобраться с этим всем прибегнув к хипстерскому языку Dot.

Вот Dot код описывающий плату nRF5340-DK. Dot язык очень простой и код пишется прямо по схемотехнике из *.pdf. Copy->Paste. Всего 440 строк.

digraph graphname {
 rankdir=LR;
 ranksep=0.5;
 IF_OFF[shape="point"][color=darkgreen]
 VBUS[shape="point"]
 USB2[shape="point"]
 USB3[shape="point"]
 RESET[shape="point"]
 VDD_nRF_SENSE[shape="point"]
 TRACE[shape="point"]
 VDD_nRF_DASH[shape="point"]
 I2C[shape="point"]
 SWD[shape="point"][color=blue]
 IMCU_RESET[shape="point"]
 SWD0[shape="point"][color=blue]
 SWD3[shape="point"][color=blue]
 UART_1[shape="point"][color=magenta]
 UART_2[shape="point"][color=magenta]
 VBOOST_SRC[shape="point"]
 GND[shape="point"]
 VREG[shape="point"]
 BOOT_RESET[shape="point"]
 VREG_EN_INV[shape="point"]
 VEXT_EN[shape="point"]
 VSENSE_SW_OUT[shape="point"]
 VSUPPLY[shape="point"]
 VEXT_EN_INV[shape="point"]
VBOOST_SRC_DASH[shape="point"]
 VBUS_IMCU[shape="point"]
V5V[shape="point"]
VDD[shape="point"][fillcolor=grey, style=red]
 J1[shape="box",label="J1 ANT 1pin "] 
 
 U1[shape="box"][label="U1 MCU"][fillcolor=grey, style=filled][height=8] [width=3]
 U2[shape="box"][fillcolor=grey, style=filled][height=4][width=3][label="U2 If MCU"]
J2[shape="box",label="J2 5pin"][height=2][width=1]
J3[shape="box",label="J3 USB 5pin"][height=2][width=1]
J4[shape="box",label="J4 10pin"][height=3][width=1]
J5[shape="box",label="J5 NFC 5pin"][height=2][width=1]
J6[shape="box",label="J6 Li-Po 2pin"][height=1][width=1]
P1[shape="box",label="P1 8pin"][height=2][width=1]
P2[shape="box",label="P2 6pin"][height=1.5][width=1]
P3[shape="box",label="P3 8pin"][height=2][width=1]
P4[shape="box",label="P4 10pin"][height=3][width=1]
P5[shape="box",label="P5 6pin"][height=1.5][width=1]
P6[shape="box",label="P6 8pin"][height=2][width=1]
P7[shape="box",label="P7 16pin"][height=4] [width=1]
P8[shape="box",label="P8 12pin"][height=3][width=1]
P9[shape="box",label="P9 DebugOut 8pin"][height=2]
P10[shape="box",label="P10 20pin"][height=5][width=1]
P11[shape="box",label="P11 6pin"][height=2] [width=1]
P12[shape="box",label="P12 16pin"][height=4] [width=1]
P13[shape="box",label="P13 16pin"][height=4] [width=1]
P14[shape="box",label="P14 12pin"][height=3] [width=1]
P15[shape="box",label="P15 16pin"] [height=4] [width=1]
P16[shape="box",label="P16 20pin"][height=5][width=1]
P17[shape="box",label="P17 16pin"][height=4] [width=1]
P18[shape="box",label="P18 DebugIN 10pin"][height=3][width=1]
P19[shape="box",label="P19 DebugOUT 10pin"][height=3][width=1]
P20[shape="box",label="P20 13pin"][height=3.25][width=1]
P21[shape="box",label="P21 2pin"][height=1][width=1]
P22[shape="box",label="P22 current 2pin"] [width=1]
P23[shape="box",label="P23 2pin"][height=1][width=1]
P24[shape="box",label="P24 20pin"][height=5][width=1]
P25[shape="box",label="P25 Trace 20pin"][height=5][width=1]
P26[shape="box",label="P26 13pin"][height=3.25][width=1]
P27[shape="box",label="P27 Li-Po 2pin"][height=1][width=1]
 D7[shape="triangle"]
 U25_12[shape="box"][fillcolor=grey, style=filled]
 U11[shape="box"][fillcolor=grey, style=filled]
 U3_34[shape="box"][fillcolor=grey, style=filled]
 Q10B[shape="box"]
 U18[shape="box",label="U18 AND" ][fillcolor=grey, style=filled]
P28[shape="box",label="P28 Op-amp 3pin"][height=0.75][width=1]
 U10[shape="box"][fillcolor=grey, style=filled]
 U21[shape="box"][fillcolor=grey, style=filled]
 U24[shape="box"][fillcolor=grey, style=filled]
  U4[label="U4 4pin"][shape="box"][fillcolor=darkslategray1, style=filled]
 U12[label="U12 4pin"][shape="box"][fillcolor=darkslategray1, style=filled]
 U13[label="U13 4pin"][shape="box"][fillcolor=darkslategray1, style=filled]
 U14[label="U14 4pin"][shape="box"][fillcolor=darkslategray1, style=filled]
 U15[label="U15 4pin"][shape="box"][fillcolor=darkslategray1, style=filled]
 U17[label="U17 4pin"][shape="box"][fillcolor=darkslategray1, style=filled]
 U20[label="U20 4pin"][shape="box"][fillcolor=darkslategray1, style=filled]
 U19[label="U19 4pin"][shape="box"][fillcolor=darkslategray1, style=filled]
 U22[label="U22 4pin"][shape="box"][fillcolor=darkslategray1, style=filled]
 U23[label="U23 4pin"][shape="box"][fillcolor=darkslategray1, style=filled]
 U16[shape="box"][fillcolor=grey, style=filled]
 U5[shape="box"][fillcolor=grey, style=filled]
 SW7A[shape="box"][fillcolor=bisque, style=filled]
 SW7B[shape="box"][fillcolor=bisque, style=filled]
 
 D3[shape="triangle"]
 D5[shape="triangle"]
 D6[shape="triangle"]
 U7[shape="box",label="U7 Flash"][fillcolor=grey, style=filled]
 SW1[shape="box"][fillcolor=bisque, style=filled];
 SW2[shape="box"][fillcolor=bisque, style=filled];
 SW3[shape="box"][fillcolor=bisque, style=filled];
 SW4[shape="box"][fillcolor=bisque, style=filled];
 SW5[shape="box"][fillcolor=bisque, style=filled]
 LED1[shape="box"];
 LED2[shape="box"];
 LED3[shape="box"];
 
 Q10A[shape="box"];
 Q10B[shape="box"];
 LED4[shape="box"];
 
 U19->U2[label="VDD_IMCU"]
 SW1->U1[label="P0.23"] 
 SW2->U1[label="P0.24"] 
 SW3->U1[label="P0.08"] 
 IMCU_RESET->U2[label="IMCU_RESET"] 
 SW4->U1[label="P0.09"] 
 U2->U25_34->U1;
 U2->U3_12->U1;
 U7->U1[label="QSPI"] 
 U6_12->RESET
 U1->P18
 RESET->U1[label="RESET"]
 RESET->P18[label="RESET"] 
 RESET->P19[label="RESET"] 
 RESET->P20[label="RESET"] 
 RESET->U1[label="RESET"] 
 RESET->P25[label="RESET"] 
 U2->U5->U1
 U1->P2
 U1->P8
 U1->P14
 SW5->BOOT_RESET
 P8->P2->P14
 VBUS_IMCU->U2 [label="VBUS_IMCU"] 
 Bat1->U17[label="VBAT"] 
 U17->Q10B
 Q5B->SW6A[label="USB_DETECT"] 
 GND->SW6A
 U1->P4
 U1->P16
 P4->P10->P16
 U22->VBUS_IMCU
 U1->P6
 P12->P6->P17
 U1->P3
 U1->P9
 U1->P12
 P9->P3->P15
 U2->SWD3->U5 [label="SWD3"] [color=blue]
 U5->SWD [label="SWD"] [color=blue]
 X3->U2[label="32MHz"] 
 U25_34->UART_1->U1[label="UART_1"][color=magenta]
 U2->U25_34[label="VCOM_0"]
 U1->P10
 P7->P1->P13
 U3_34->UART_2->U1[label="UART_2"][color=magenta]
 IF_OFF->U3_34[label="IF_OFF"][color=darkgreen]
 U2->U3_34[label="VCOM_2"]
 J4->U2
 U2->Q1
 Q1->LED5
 U2->U3_34->U1
 VREG_EN_INV->U21[label="VREG_EN_INV"] 
 VEXT_EN_INV->U21[label="VEXT_EN_INV"] 
 Q10A->Q10B[label="Gate"] 
 VSUPPLY->U21[label="VSUPPLY"][color=pink] 
 U21->Q10A[label="Gate"]
 SWD->U1[label="SWD"] [color=blue]
 P18->SWD [label="SWD"] [color=blue]
 J3->USB3->U1[label="USB"] 
 P19->SWD0->U2[label="SWD0"] [color=blue]
 UART_1->P3[label="UART_1"] [color=magenta]
 UART_2->P24[label="UART_2"] [color=magenta]
 P1->RESET[label="RESET"] 
 J4->IMCU_RESET[label="IMCU_RESET"]
 P11->P5
 U1->P11
 U1->P5
 V5V->P13[label="V5V"][color=orange] 
 U1->P24
 U1->P17
 U1->P14
 U1->P12
 U1->P15
 U1->I2C
 I2C->P16 [label="I2C"] 
 J2->U22->U2
 J2->Q5A
 BOOT_RESET->U6_12[label="BOOT/RESET"]


 U2->U6_12[label="IMCU_BOOT"] 
 SW8A->U6_34 [label="SHIELD_DETECT"]
 I2C->U6_34 [label="I2C"]
 SW8A->VDD[label="VDD"][color=red]
 VDD->U6_34[label="VDD"][color=red]
  Q5A[shape="box"]
 Q5B[shape="box"]
 //subgraph clusterQ5 { Q5A  Q5B }
 X1->U1[label="32MHz"] 
 X2->U1[label="32kHz"] 
 U10->V5V
 U1->J5[label="NFC"] 
 SW7A->U3_12[label="UART2_FC_OFF"] [color=green]
 GND->SW7A
 IF_OFF->SW7A[label="IF_OFF"][color=darkgreen][fontcolor=darkgreen]
 SW7B->U25_12[label="UART1_FC_OFF"] [color=green]
 GND->SW7B
 IF_OFF->SW7B[label="IF_OFF"][color=darkgreen][fontcolor=darkgreen]
 IF_OFF->U22[label="IF_OFF"][color=darkgreen][fontcolor=darkgreen]
 VBUS_IMCU->LED5[label="VBUS_IMCU"]
 J4->VBUS->U22 [label="VBUS"][color=gold]
 J2->VBUS->U22 [label="VBUS"][color=gold]
 J2->USB2->U2[label="USB"]
 GND->SW6B
 SW9B->VDD->SW6B [label="VDD"][color=red]
 
 //SW9B->Q10B[label="VDD"][color=red] 
 VDD->Q10B[label="VDD"][color=red] 
 U12->VSENSE_SW_OUT
 U14->VSENSE_SW_OUT
 Q10B->VSUPPLY
 VSENSE_SW_OUT->SW8A[label="VSENSE_SW_OUT"]
 U18->U17 [label="VBAT_EN"] 
 VSUPPLY->U14[label="VSUPPLY"][color=pink]
 U13->VSUPPLY[label="VSUPPLY"][color=pink] 
 V5V->U12[label="V5V"][color=orange] 
 V5V->U11 [label="V5V"][color=orange] 
 U11->VREG[label="VREG"] 
 VREG->U13 [label="VREG"] 
 X1[fillcolor=yellow, style=filled]
 X2[fillcolor=yellow, style=filled]
 X3[fillcolor=yellow, style=filled]
 LED1[fillcolor=green, style=filled]
 LED2[fillcolor=green, style=filled]
 LED3[fillcolor=green, style=filled]
 LED4[fillcolor=green, style=filled]
 LED5[fillcolor=green, style=filled]
 U1->LED1[label="P0.28/AIN7"]
 U1->LED2[label="P0.29"]
 U1->LED3[label="P0.30"]
 U1->LED4[label="P0.31"]
 IF_OFF->U5[label="IF_OFF"][color=darkgreen][fontcolor=darkgreen]
 IF_OFF->U3_34[label="IF_OFF"][color=darkgreen][fontcolor=darkgreen]
 IF_OFF->U6_12[label="IF_OFF"][color=darkgreen][fontcolor=darkgreen]
 SW8A->U6_34[label="SHIELD_DETECT/VDD"]
 IF_OFF->U25_34[label="IF_OFF"][color=darkgreen][fontcolor=darkgreen]
 U23->SW10B [label="VEXT"]
 VSUPPLY->U23[label="VSUPPLY"][color=pink]
 SW10B->P21
 SW9A->SW10A[label="VSRC_NRF"]
 U1->J1

         U25_34[shape="box"][fillcolor=grey, style=filled]
 
 U2->U25_12[label="VCOM0_CRTL"]
 U25_12->U1[label="UART_1_CRTL"][color=magenta]
 
 U2->U3_12[label="VCOM2_CRTL"]
 U3_12->U1[label="UART_2_CRTL"][color=magenta]
 SW8B->VBOOST_SRC
 
  U9A[shape="box"][fillcolor=grey, style=filled]
 U9B[shape="box"][fillcolor=grey, style=filled]
 SW10A[shape="box"][fillcolor=bisque, style=filled];
 SW10B[shape="box"][fillcolor=bisque, style=filled];
// subgraph clusterSW10 { SW10A SW10B }
 VolDiv [label="1/2.74"] [shape="box"] 
    Bat1[label="Bat1 2pin"][shape="box"]
  Q8A[shape="box"];
 Q8B[shape="box"];
 SW8A[shape="box"][fillcolor=bisque, style=filled];
 SW8B[shape="box"][fillcolor=bisque, style=filled];
 SW9A[shape="box"][fillcolor=bisque, style=filled];
 SW9B[shape="box"][fillcolor=bisque, style=filled];
     SW8B->Q6[label="Gate"] 
     U16->U13 [label="CTRL"] 
 SW6A[shape="box"][fillcolor=bisque, style=filled];
 SW6B[shape="box"][fillcolor=bisque, style=filled];
 VBOOST_SRC->U10
 SW9B->U15[label="out"]
 VDD->U15[label="VDD"][color=red]
 VSUPPLY->U16[label="VSUPPLY"][color=pink]
 VolDiv->U16[label="VREG_EN"]
 U17->VSUPPLY->U18[label="VSUPPLY"][color=pink]
 Q8A->VREG_EN_INV
 VREG_EN_INV->U18[label="VREG_EN_INV"]
 U24->VEXT_EN
 VEXT_EN->Q8B [label="VEXT_EN"] 
 VEXT_EN->U23 [label="VEXT_EN"] 
 GND->Q5A
 
 VDD_nRF_DASH->P20[label="VDD_nRF'"]
 VDD_nRF_DASH->P26[label="VDD_nRF'"]
 VDD_nRF_DASH->P22[label="VDD_nRF'"]
 SW9A->VDD_nRF_DASH[label="VDD_nRF'"]
 SW9A->VDD_nRF_SENSE[label="VDD_nRF_SENSE"] 
 VREG_EN_INV->U24[label="VREG_EN_INV"] 
 
 Q8B->VEXT_EN_INV
 VEXT_EN_INV->U18[label="VEXT_EN_INV"]
 SW6A->IF_OFF[color=darkgreen][fontcolor=darkgreen]
 IF_OFF->U19[label="IF_OFF"][color=darkgreen][fontcolor=darkgreen]
 VDD->U19[label="VDD"][color=red]
 
 U15->P23[label="VDD_HV'"]
 VDD_nRF_SENSE->Q9[label="VDD_nRF_SENSE(Gate)"]
 Q9->U16[label="VSUPPLY_EN"]
 
 V5V->VolDiv [label="V5V"][color=orange]
 VolDiv -> Q8A [label="VREG_EN"] 
 D3->VBOOST_SRC_DASH[label="VBOOST_SRC'"] [color=turquoise1][fontcolor=turquoise1]
 D5->VBOOST_SRC_DASH[label="VBOOST_SRC'"] [color=turquoise1][fontcolor=turquoise1]
 D6->VBOOST_SRC_DASH[label="VBOOST_SRC'"] [color=turquoise1][fontcolor=turquoise1]
 D7->VBOOST_SRC_DASH[label="VBOOST_SRC'"] [color=turquoise1][fontcolor=turquoise1]
 VBOOST_SRC_DASH->SW8B[label="VBOOST_SRC'"] [color=turquoise1][fontcolor=turquoise1]
 J3->D5
 V5V->VolDiv
 
 Q5A->Q5B[label="Gate"]
 J2->VBUS->Q5A [label="VBUS"][color=gold]
 U19->J4[label="VDD_IMCU"]

 D3->VBOOST_SRC_DASH[label="VBOOST_SRC'"] [color=turquoise1][fontcolor=turquoise1]
 D5->VBOOST_SRC_DASH[label="VBOOST_SRC'"] [color=turquoise1][fontcolor=turquoise1]
 D6->VBOOST_SRC_DASH[label="VBOOST_SRC'"] [color=turquoise1][fontcolor=turquoise1]
 D7->VBOOST_SRC_DASH[label="VBOOST_SRC'"] [color=turquoise1][fontcolor=turquoise1]
 
 U20->U1[label="VBUS_nRF"] 
 J4->VBUS->D3[label="VBUS"][color=gold] 
 J2->VBUS->D3[label="VBUS"][color=gold] 
 J3->U20[label="VBUS_nRF'"] 
 
 VDD->SW10A
 VDD->U20[label="VDD"][color=red] 
 VDD->U20[label="VDD"][color=red] 
 
 
 J3->D5[label="VBUS_nRF'"] 
 D6->SW9B[label="VLi-Ion"] 
 J3->SW9B[label="VBUS_nRF'"] 
 P22->SW9B[label="VDD_nRF"] 
 //P27->D6[label="VLi-Ion"] 
 J6->D6[label="VLi-Ion"] 
 P20->D7[label="VIN3-5V"] 
 P26->D7[label="VIN3-5V"] 
 P25->SWD[label="SWD"] [color=blue]
 P25->TRACE->U1[label="TRACE"] 
 VDD->U3_34[label="VDD"][color=red] 
 VDD->U25_34[label="VDD"][color=red] 
 VDD->U5[label="VDD"][color=red] 
 VDD->U6_12[label="VDD"][color=red]
 VDD->U6_34[label="VDD"][color=red]
 VDD->U4[label="VDD"][color=red] 
 SW6B->U4 [label="nRF_ONLY"]
 U4->LED1
 U4->LED2
 U4->LED3
 U4->LED4
 J6->P27[label="VLi-Ion"]
 VDD->SW6B[label="VDD"][color=red] 
 VDD->Q5B[label="VDD"][color=red] 
 VDD_nRF_SENSE->U12[label="VDD_nRF_SENSE"] 
 Q7->U12
 U9A->Q7[label="Gate"] 
 VDD_nRF_SENSE->U9A[label="VDD_nRF_SENSE"] 
 V5V->P11[label="V5V"][color=orange] 
 P28->U9B
 U9B->P28



 // { rank=same;U3_34 U25 U25_34 U5 U6 U6_12 U6_34}

          U3_12[shape="box"][fillcolor=grey, style=filled];
         U3_34[shape="box"][fillcolor=grey, style=filled];
                  U6_12[shape="box"][fillcolor=grey, style=filled]
         U6_34[shape="box"][fillcolor=grey, style=filled]
         SW10A->P21
         V5V->Q6 [label="V5V"][color=orange] 
         

  //{ rank=same; U7 U1 }
 subgraph clusterDIR {
     
     color=transparent
     subgraph clusterPower {
         color=transparent
         subgraph clusterP7_1_13 { color=transparent P7 P1 P13  }
         subgraph clusterRect { P20 P26 color=transparent} 
         VSENSE_SW_OUT SW8A Bat1 VBOOST_SRC U10 U11 U15 Q7 Q9   P28 U12  J6 P27 P22 P23 VREG U13 U14 U16 U17 U19 VREG_EN_INV U18 U20 U21 VEXT_EN U23 VSUPPLY Q6 P21  VBOOST_SRC_DASH V5V VDD U24 SW10A VolDiv  SW8B Q8A Q8B Q10A Q10B U9A  U9B VDD_nRF_SENSE  SW9A VDD_nRF_DASH D3 D5 D6 D7
         subgraph clusterP21_SW10_B { P21  SW10B }
         //{ rank=same; U12 U14 } 
        // { rank=same; U10 U20 U15}
        // { rank=same; D3 D5 D6 D7 }
        // { rank=same; U18 U21 U24}
       //  { rank=same; J6 P22 P23   }
         //{ rank=same; U23 Q10B U13 }
        // { rank=same; VolDiv U24 }
          subgraph clusterJ6_P27 { J6  P27 }
        
     }
     subgraph clusterSystem {
         SW5 Q5A Q5B  RESET GND 
         color=transparent
         //subgraph clusterQ5 { Q5A Q5B  }
         subgraph clusterProg { VBUS IMCU_RESET U2 X3 J2 USB2 J4 LED5 Q1 P19 U22 VBUS_IMCU SWD3 SWD0}
         subgraph clusterMUX_GL {
             color=transparent
             SW7B SW7A  SW6A SW6B IF_OFF
             subgraph clusterMUX {
                 color=transparent
                 U5  U3_12    U3_34 U25_12 U25_34 BOOT_RESET U6_12 U6_34 
                 //subgraph clusterU3 {  U3_12    U3_34 }
                 //subgraph clusterU25 {  U25_12 U25_34 }
                 //subgraph clusterU6 {  U6_12 U6_34 }
                   
             }
         }
         subgraph clusterMCU {
             color=transparent
             subgraph clusterP11_5 { P11 P5  }
             subgraph clusterP12_6_17 { P12 P6 P17  }
             subgraph clusterP8_2_14 { P8 P2 P14  }
             subgraph clusterP9_3_15 { P9 P3 P15  }
             subgraph clusterP10_4_16 { P10 P4 P16  }
             J1  U4 J3 USB3 P6 P3 P4 P2 P1 P24 J5  UART_1 UART_2 I2C SWD TRACE
             subgraph clusterArduino { P1 P2  P3 P4 }
             subgraph clusterLED { LED1 LED2 LED3 LED4 }
             subgraph clusterSW { SW1 SW2 SW3 SW4 }
             subgraph clusterMem {color=transparent U1 U7 
             //{ rank=same; U7 U1 }
             }
             subgraph clusterClc {color=transparent X1 X2   }
             //subgraph clusterNFC { U1 J5   }
             subgraph clusterSWDMCU {color=transparent P18 P25   }
             //{ rank=same; LED1 LED2 LED3 LED4 J1}
         }
     }
 }
 //{ rank=same;    VBOOST_SRC_DASH  SW8B    }
}

Этот Dot код нужен только для того, чтобы утилита dot.exe отрисовала граф и сама расставила ранги узлов. Так как иначе понять правильный путь электрического сигнала ни разу не очевидно. Теперь надо сгенерировать сам граф электрической цепи в виде *.svg файла прямо по исходнику из *.dot. Вот *.bat скрипт авто генерации графа электрической цепи в виде *.svg файла.

cls
"C:\Program Files\Graphviz\bin\dot.exe" -v -Tsvg nRF5340.dot -o nRF5340_generated.svg
start chrome -open %cd%/nRF5340_generated.svg

или даже лучше собрать артефакт *.svg makefile(ом)


CC=dot
RENDER=chrome
CURRENT_DIR = $(shell pwd)

SOURCES_DOT += $(CURRENT_DIR)/nRF5340.dot
SOURCES_DOT := $(subst /c/,C:/, $(SOURCES_DOT))
ART_SVG := $(subst dot,svg, $(SOURCES_DOT))

OPT +=-Tsvg

all:  print_svg

clean:
	rm nRF5340.svg

print_svg:$(ART_SVG)
	$(RENDER) -open $(ART_SVG)

$(ART_SVG): $(SOURCES_DOT)  
	$(CC) $(OPT) $(SOURCES_DOT) -o $(ART_SVG)

А это как раз сгенерированный граф принципиальной схемы электрической цепи для nRF5340-DK.

Далее, глядя на граф можно перерисовать цепь аккуратнее в утилите inkscape.

Успех! Теперь всё как на ладони. Оказывается схемотехника nRF5340-DK ни разу не сложная.

Вывод

Благодаря языку разметки dot можно очень легко чисто механически представлять и изучать новые сложные аппаратные платформы, составлять блок схемы и документацию (Doc Food). Правда для этого придется вручную накропать несколько сот строк исходника *.dot файла для конкретной платы по схемотехнике в *.pdf(ке). Но это чистая механика и копи-паста. Таким образом язык Dot можно смело использовать как hardware description language. Эта технология может пригодится техническим писателям, схемотехникам, программистам прошивок.

А вы пользовались языком Dot? Если да, то для чего вы применяли язык Dot?

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


  1. VT100
    13.08.2022 21:12
    +2

    "Не всё так однозначно". И в опросах маловато вариантов.
    Я использовал Dot для составления блок-схемы алгоритма. Правда — post factum, для документирования.


  1. iggr63
    13.08.2022 22:48
    +3

    Dot трудно назвать языком разметки, а dot диаграмма выше выглядит как электронная плата с проводными соединениями между компонентами:)


  1. kest007
    13.08.2022 22:52
    +3

    Может кто знает, есть ли «рисовальщик» дот’ов, который в зависимости от весовых коэффициентов (или других атрибутов), расположилы бы шейпы сверху вниз (или слева направо)? Очень напряжно «перерисовать цепь аккуратнее» для нескольких тысяч связей (пусть будет, например, связь сотрудников в AD).


    1. Karlson_rwa
      13.08.2022 23:03
      +3

      Есть редактор yEd, он умеет структурировать накиданные схемы. Очень удобная штука. Посмотрите, может туда можно втянуть эту лапшу из дота.


    1. Karlson_rwa
      13.08.2022 23:45
      +1

      Кстати, вот: yed.yworks.com/support/qa/73/import-of-dot-files
      Это возможно.


    1. VT100
      14.08.2022 12:31
      +1

      Веса есть и в самом dot. Но я недопонял, как ими пользоваться.


      1. DmitriiPisarenko
        14.08.2022 16:55
        +1

        На странице про веса есть ссылка Edit in Playground. Там можно поиграться с весами и посмотреть на результат.


    1. DmitriiPisarenko
      14.08.2022 16:51

      Для этого может быть полезно свойство графа rankdir. У него может одно из двух значений:

      • сверху вниз (TB) и

      • слево направо (LR).

      Пример графа с расположением сверху вниз

      Код

      digraph {
          rankdir="TB"
          a -> b -> c;
      }
      

      Диаграмма

      Пример графа с расположением слево направо

      Код

      digraph {
          rankdir="LR"
          a -> b -> c;
      }
      

      Диаграмма


  1. Karlson_rwa
    13.08.2022 23:02
    +2

    Вам не нужна такая блок-схема (это, кстати, не она, вы так и не узнали, как называются подобные схемы), чтобы разобраться, как работает плата. Вам нужна общая структурная схема и некоторые частные функциональные схемы. Всё равно вы плату в любом случае будете разбирать поблочно, а не целиком сразу. И будете смотреть, на что завязан каждый отдельный блок.
    Говорю по своему опыту перерисовывания схемотехники под себя для олвиннеровского H3.

    Опять же, у вас тут овал:

    Любая принципиальная схема это, в сущности, граф.
    А тут уже сова:
    Вот Dot код описывающий плату nRF5340-DK.
    Где промежуточный этап, Карл? Или вы хотите сказать, что пишете этот код вручную, глядя на pdf-ку? Тогда этому коду грош цена.


    1. aabzel Автор
      14.08.2022 00:02
      +1

       Или вы хотите сказать, что пишете этот код вручную, глядя на pdf-ку?

      да.
      Этот Dot код нужен для того, чтобы утилита dot.exe отрисовала граф и сама расставила ранги узлов. Так как иначе понять правильный путь электрического сигнала не очевидно.


      1. Karlson_rwa
        14.08.2022 00:13
        +1

        да.
        рукалицо.jpg
        А просто пристально, вдумчиво поизучать схему не вариант вообще? По-моему вы мартышкиным трудом с этим описанием занимаетесь. Сколько времени у вас ушло на составление приведенного описания? Полученная схема в виде графа абсолютно нечитаема. Сколько времени вы потратили на то, чтобы привести её в более компактный нечитаемый вид? По-моему это время можно было провести с чуть большей пользой, поблочно разрисовав всё сразу вручную в том же yEd, если вам настолько не хватает структурной схемы готовой борды.


        1. aabzel Автор
          14.08.2022 00:16
          -3

          По поводу важности составления блок схем печатных плат у меня есть отдельный пост
          https://habr.com/ru/post/667030/

          Сколько времени у вас ушло на составление приведенного описания?

          пара часов, параллельно просматривая YouTube


          1. Karlson_rwa
            14.08.2022 00:19
            +3

            Спасибо, я помню ту статью и своё мнение о ней. А вы мой комментарий, похоже, не очень.


        1. aabzel Автор
          14.08.2022 01:15
          +1

          А просто пристальновдумчиво поизучать схему не вариант вообще?

          Pdf(ки) со схемотехникой от Vendor(a) иногда настолько циклопические (45--100 страниц), что подвисают при обычном Ctrl+F.


      1. VT100
        14.08.2022 13:02
        +1

        Если есть исходный проект отладочной платы, то, может быть, следовало бы поискать по "parsing netlist to DOT"? Что-то вроде этого?


  1. weirded
    14.08.2022 06:34
    +1

    Я dot в качестве таскера использую, в сочетании с overlap=prism оно рисует дела на день-неделю-месяц в очень наглядном виде.
    Пример с небольшой обфускацией в кракозябры.
    Потихоньку обрастаю вебкой и отправкой на почту повестки дня утром.


    1. tzlom
      14.08.2022 10:09
      -2

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


    1. vassabi
      14.08.2022 12:58
      +1

      ладно кракозяблы, так ведь и стрелочки еще "невидимым серым"!

      PS: вроде там можно настроить ему, чтобы он квадратнее группы\субгруппы делал, не?


  1. peacemakerv
    14.08.2022 15:55
    +1

    Я когда-то в стародревние времена писал реверс-инжиниринговую программку-вьюер печатной платы (pcbcomparer), просмотр одновременно с двух сторон (две фотки).
    Создание пинов (контактных площадок), цепей меж ними и ... генерация netlist-а для CAD-ов.

    Набор компонент на плате использовался очень ограниченный: резистор, конденсатор, дроссель, транзистор, контактный вывод и многополюсник-черный-ящик - с соответствующими библиотечными элементами

    Кроме net-list-а программа создавала файл печатной платы в самом первом старинном текстовом формате Protel (сейчас уже общеизвестный Altium).
    И, если мне не изменяет память, процесс реверс-инжиниринга выглядел так:

    • файл .pcb открывался в Protel'99

    • в него импортировался NetList

    • в интерфейсе Protel создавался новый файл принципиальной схемы .sch

    • и ... делалась синхронизация: т.е. перенос компонент и цепей в схему с платы, силами Protel-а.

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

    Но странное дело - я уже даже и не помню, что пошло не так, и почему разработка программы не пошла далее. Вероятнее всего потому, что я продолжал создавать схемы с нуля, без использования реверс-инжиниринга :)



  1. HEXFFFFFFFF
    15.08.2022 17:54
    +2

    С nrf и их отладочными платами имел дело. В упор не понял при чем тут дот, графы и вообще нафига это все нужно. Разобраться с платой можно по описанию, и это не сложнее чем научится пользоватся посудомойкой или материнкой компа. Другое дело что у нордика достаточно специфичный подход к отладочным платам. Они там скорее не отладочные а демонстрационные , да еще и за дикие деньги. Для nrf9160 пришлось заказывать свой девкит т.к. их ни куда не годится, на плате налеплена куча ненужной ппреферии которая тупо мешает подключить свою. Половина ножек на ружу не выведена, в общем как отладочная плата это мало применимо.