sobota 29. června 2019

Raspberry Pi ladění

Jak jsem ji psal v předchozím příspěvku, Raspberry Pi má snadno dostupný JTAG a díky tomu je možné kód na něm pohodlně ladit. Jako převodník jsem použil čínský klon J-Linku a již dříve popsané OpenOCD.

openocd -f ..\scripts\interface\jlink.cfg -f ..\scripts\target\raspberry3.cfg

GNU MCU Eclipse OpenOCD, 64-bitOpen On-Chip Debugger 0.10.0+dev-00593-g23ad80df4 (2019-04-22-20:25)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
trst_and_srst separate srst_gates_jtag trst_push_pull srst_open_drain connect_deassert_srst
adapter speed: 1000 kHz
jtag_ntrst_delay: 500
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : J-Link ARM V8 compiled Nov 28 2014 13:44:46
Info : Hardware version: 8.00
Info : VTarget = 3.306 V
Info : clock speed 1000 kHz
Info : JTAG tap: rpi3.tap tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x4)
Info : rpi3.a53.0: hardware has 6 breakpoints, 4 watchpoints
Info : rpi3.a53.1: hardware has 6 breakpoints, 4 watchpoints
Info : rpi3.a53.2: hardware has 6 breakpoints, 4 watchpoints
Info : rpi3.a53.3: hardware has 6 breakpoints, 4 watchpoints
Info : Listening on port 3333 for gdb connections
Info : Listening on port 3334 for gdb connections
Info : Listening on port 3335 for gdb connections
Info : Listening on port 3336 for gdb connections

po připojení telnetem (port 4444) se zobrazí toto:
Open On-Chip Debugger
> targets
    TargetName         Type       Endian TapName            State
--  ------------------ ---------- ------ ------------------ ------------
 0  rpi3.a53.0         aarch64    little rpi3.tap           running
 1  rpi3.a53.1         aarch64    little rpi3.tap           running
 2  rpi3.a53.2         aarch64    little rpi3.tap           running
 3* rpi3.a53.3         aarch64    little rpi3.tap           running
> halt
cannot read system control register in this mode
in procedure 'target'
> targets
    TargetName         Type       Endian TapName            State
--  ------------------ ---------- ------ ------------------ ------------
 0  rpi3.a53.0         aarch64    little rpi3.tap           running
 1  rpi3.a53.1         aarch64    little rpi3.tap           running
 2  rpi3.a53.2         aarch64    little rpi3.tap           running
 3* rpi3.a53.3         aarch64    little rpi3.tap           halted
> mww 0x3f200004 0x40240
> mdw 0x3f200000 0x50
0x3f200000: 00000000 00040240 086db6c0 00000009 3f200924 00000fff 00000000 6770696f
0x3f200020: 6770696f 6770696f 6770696f 6770696f 6770696f 1349c1ff 003efcff 00000000
0x3f200040: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x3f200060: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x3f200080: 00000000 00000000 00000000 00000000 00000000 00000002 00000000 00000000
0x3f2000a0: 00000000 ffffffff 003fffff 6770696f 00000000 6770696f 6770696f 6770696f
0x3f2000c0: 00000000 00000000 00000000 00000000 6770696f 6770696f 6770696f 6770696f
0x3f2000e0: 6770696f 6770696f 6770696f 6770696f 6770696f 6770696f 6770696f 6770696f
0x3f200100: 6770696f 6770696f 6770696f 6770696f 6770696f 6770696f 6770696f 6770696f
0x3f200120: 6770696f 6770696f 6770696f 6770696f 6770696f 6770696f 6770696f 6770696f

mdb u Raspberry Pi nefunguje, protože CPU umožňuje číst jen po 32 bitech
> mdb 0x3f200000
Opcode 0x1001e4d0, DSCR.ERR=1, DSCR.EL=2

stejně tak nebude fungovat s jinou adresou než dělitelnou čtyřkou (word)
> mdw 0x3f200001
Opcode 0x1004e490, DSCR.ERR=1, DSCR.EL=2

zapnutí LEDek (nastavení směru pro GPIO12,13 a 16)
mww 0x3f200004 0x40240

Stažení image (kernel7.img je po startu nakopírován GPU od adresy 0x8000):
> dump_image flash.bin 0x8000 0x1000
dumped 4096 bytes in 0.097825s (40.889 KiB/s)

Nyní ještě k jádrům, to je novinka oproti klasickým STM32F1, které mají jádro jen jedno. Napadlo vás někdy jak to vlastně funguje, když máme procesory třeba čtyři? Jak je třeba psát program pro čtyř jádrový procesor? Pokud napíšeme program, tak jak jsem to udělal v předchozím příspěvku, nulté jádro ho vykonává ale ostatní jadérka se nám "flákají".

nahrajeme program do RAM paměti
load_image "D:/vyvoj/GPIO_jinak/main.bin" 0x90000 bin

a spustíme
resume 0x90000

Zapojení pinů:

JTAG Pin
J-Link Pin
SoC Pin
Raspberry Pi pin
Vref
1

1
nRST
3
GPIO22
15
GND
4

6
TDI
5
GPIO26
37
TMS
7
GPIO27
13
TCK
9
GPIO25
22
RTCK
11
GPIO23
16
TDO
13
GPIO24
18