14.1.1.4. Otklanjanje pogrešaka u ugrađenom programu (firmware)¶
Otklanjanje pogrešaka na sklopovlju znači zaustavljanje procesora, postavljanje točaka prekida u C izvornom kodu, izvođenje korak po korak te pregledavanje varijabli, memorije, registara i periferije – sve iz unutrašnjosti VS Code-a. Za to su potrebne tri stvari: debug build, SWD debug sonda (Segger J-Link) i ekstenzija Cortex-Debug koja upravlja programom arm-none-eabi-gdb spojenim na J-Link GDB poslužitelj.
14.1.1.4.1. Izgradnja za otklanjanje pogrešaka¶
Ciljni program uvijek ponovno izgradite s DEBUG=1
make -j$(nproc) TARGET=<TARGET> DEBUG=1
Release (DEBUG=0) slika prevodi se s -O2; u debuggeru ćete za mnoge varijable vidjeti <optimized out>, ugrađene (inline) funkcije stapaju se sa svojim pozivateljima, a izvođenje korak po korak nepredvidivo skače. DEBUG=1 gradi s -Og -ggdb3, što je pogodno za otklanjanje pogrešaka uz zadržanu mogućnost pokretanja na kameri. ELF na koji usmjeravate debugger je:
build/<TARGET>/bin/firmware.elf
(Za Alif AE3 otklanjajte pogreške u build/OPENMV_AE3/bin/firmware_M55_HP.elf – visokoučinkovita jezgra.)
14.1.1.4.2. Sklopovlje: J-Link preko SWD-a¶
Spojite Segger J-Link na SWD pinove kamere (SWDIO, SWCLK, GND te ciljni VCC za referencu; kamera se napaja preko USB-a kao i obično). J-Link EDU / Base / Pro svi rade. Mjesto na kojem se debug pinovi pojavljuju razlikuje se po kameri – mnoge pločice imaju namjenski JTAG/SWD priključak, druge izlažu SWD na I/O konektoru ili na test pločicama – pa provjerite dijagram rasporeda pinova i shemu te pločice u OpenMV dokumentaciji sklopovlja kako biste znali koje pinove ožičiti. Instalirajte J-Link Software and Documentation Pack sa stranice segger.com na računalu na koje je sonda fizički priključena. Održavajte ga razumno aktualnim – starije J-Link verzije neće prepoznati novije nazive uređaja (STM32N6, MIMXRT, Alif).
Svaki MCU treba svoj točan J-Link naziv uređaja kako bi sonda učitala ispravan flash loader i memorijsku mapu:
Kamera ( |
MCU |
J-Link |
|---|---|---|
|
STM32F427 |
|
|
STM32F765 |
|
|
STM32H743 |
|
|
STM32N657 |
|
|
MIMXRT1062 |
|
|
Alif Ensemble (M55-HP) |
|
|
STM32H747 |
|
14.1.1.4.3. Postavljanje VS Code Cortex-Debug¶
Stvorite .vscode/launch.json u repozitoriju. Najjednostavniji slučaj – VS Code, J-Link i build svi su na istom Linux / macOS računalu – koristi servertype: "jlink", čime Cortex-Debug sam pokreće J-Link GDB poslužitelj:
{
"version": "0.2.0",
"configurations": [
{
"name": "OpenMV J-Link",
"type": "cortex-debug",
"request": "launch",
"cwd": "${workspaceFolder}",
"executable": "${workspaceFolder}/build/OPENMV4/bin/firmware.elf",
"servertype": "jlink",
"device": "STM32H743VI",
"interface": "swd",
"runToEntryPoint": "main",
"armToolchainPath": "${env:HOME}/openmv-sdk-1.6.0/gcc/bin",
"gdbPath": "${env:HOME}/openmv-sdk-1.6.0/gcc/bin/arm-none-eabi-gdb"
}
]
}
Promijenite executable i device prema svojoj pločici (vidi tablicu iznad). Pritisnite F5 za izgradnju, flashanje i pokretanje do main te zaustavljanje na tom mjestu.
Savjet
Za automatsku ponovnu izgradnju svaki put kad pokrenete otklanjanje pogrešaka, dodajte zadatak izgradnje u .vscode/tasks.json i referencirajte ga iz konfiguracije pokretanja pomoću "preLaunchTask". Na primjer zadatak koji izvodi make -j$(nproc) TARGET=OPENMV4 DEBUG=1, nazvan "build-firmware", te "preLaunchTask": "build-firmware" u gornjoj konfiguraciji, tako da F5 u jednom koraku ponovno izgradi, flasha i pokrene debugger.
Upozorenje
Cortex-Debug treba arm-none-eabi-gdb. Isporučuje se u SDK-u na lokaciji ~/openmv-sdk-<version>/gcc/bin, ali nije prema zadanim postavkama na PATH, pa otklanjanje pogrešaka ne uspijeva s porukom „GDB executable ‘arm-none-eabi-gdb’ was not found”. Riješite to bilo postavljanjem armToolchainPath / gdbPath kao što je prikazano iznad, bilo dodavanjem ~/openmv-sdk-<version>/gcc/bin u svoj PATH (printenv PATH bi ga tada trebao prikazati).
14.1.1.4.4. Pregled registara periferije (SVD)¶
Usmjerite Cortex-Debug na CMSIS SVD datoteku kako biste dobili dekodirani pregled registara periferije (mjerači vremena, DMA, sučelje kamere itd.) po nazivu i bitnom polju:
"svdFile": "/path/to/STM32H743.svd"
Za STM32 i MIMXRT nabavite SVD iz ST / NXP CMSIS paketa ili iz Cortex-Debug SVD registra. Alif SVD-ovi uključeni su u repozitorij ugrađenog programa na lib/micropython/lib/alif_ensemble-cmsis-dfp/Debug/SVD/ (koristite ..._CM55_HP_View.svd za AE3 HP jezgru).
14.1.1.4.5. Windows: WSL ↔ Windows J-Link most¶
WSL 2 ne može izravno vidjeti J-Link-ov USB uređaj, pa je podjela ovakva: Windows poslužuje sondu (gdje je priključena), a VS Code + gdb rade u WSL-u i dosežu ju preko TCP-a.
Na Windowsu instalirajte Segger J-Link paket i priključite J-Link u Windows USB priključak.
Na Windowsu pokrenite J-Link Remote Server (isporučuje se s J-Link paketom): pokrenite ga uz priključen J-Link i kliknite OK. Dopustite mu prolaz kroz Windows vatrozid kada se to zatraži. Prozor prikazuje IP adresu na kojoj poslužuje sondu – zabilježite je.
U WSL-u izgradite
DEBUG=1i provjerite je liarm-none-eabi-gdbdostupan (postavitearmToolchainPathkao gore).U WSL VS Code-u zadržite
servertype: "jlink"– GDB poslužitelj radi u WSL-u i doseže sondu preko Remote Servera – te dodajteserverpath+ipAddress{ "name": "OpenMV J-Link (Windows host)", "type": "cortex-debug", "request": "launch", "cwd": "${workspaceFolder}", "executable": "${workspaceFolder}/build/OPENMV4/bin/firmware.elf", "servertype": "jlink", "serverpath": "/opt/SEGGER/JLink/JLinkGDBServer", "ipAddress": "192.168.x.x", "device": "STM32H743VI", "interface": "swd", "runToEntryPoint": "main", "armToolchainPath": "${env:HOME}/openmv-sdk-1.6.0/gcc/bin" }
Postavite
ipAddressna adresu koju prikazuje prozor Remote Servera. To je cijeli most.
Savjet
Alternativa GDB-server mostu: usbipd-win. Umjesto pokretanja poslužitelja na Windowsu možete pričvrstiti J-Link-ov USB uređaj izravno u WSL pomoću usbipd-win. Iz administratorskog PowerShell-a:
winget install usbipd
usbipd list
usbipd bind --busid <busid>
usbipd attach --wsl --busid <busid>
(<busid> je J-Link-ov bus ID iz usbipd list.) Sonda se zatim pojavljuje unutar WSL-a, a koristite običnu konfiguraciju za isto računalo servertype: "jlink" iz VS Code Cortex-Debug setup bez IP adrese i bez zasebnog Windows poslužitelja. GDB-server most zahtijeva manje postavljanja za povremenu upotrebu; usbipd-win je prikladniji za redovit razvoj.
Savjet
Koristite "request": "attach" za otklanjanje pogrešaka u ugrađenom programu dok već radi, bez resetiranja ili ponovnog flashanja – idealno za hvatanje zastoja na terenu. Koristite "request": "launch" za resetiranje, flashanje ELF-a i kreće od početka na runToEntryPoint.
14.1.1.4.6. Otklanjanje pogrešaka iz naredbenog retka pomoću gdbrunner¶
Ručno postavljanje GDB sesije prema ugrađenom ciljnom uređaju peterostruki je ples: pokrenite J-Link / ST-Link GDB poslužitelj u jednom prozoru s ispravnim uređajem, portom i zastavicama sučelja; pričekajte da ispiše Waiting for GDB connection; pokrenite arm-none-eabi-gdb u drugom prozoru; upišite target remote localhost:<port>; usmjerite gdb na ELF. Kada gdb sesija završi, ne zaboravite ugasiti prozor poslužitelja. gdbrunner je mali CLI koji sve to sažima u jednu naredbu u prednjem planu. Isporučuje se u Python okruženju OpenMV SDK-a, pa nema ništa za instalirati; uobičajena ulazna točka je cilj make debug repozitorija ugrađenog programa:
make -j$(nproc) TARGET=<TARGET> DEBUG=1 debug
Ovo pokreće gdbrunner s argumentima debuggera iz konfiguracije pločice – J-Link nazivom uređaja i, gdje je potrebno, ST-Link vanjskim flash loaderom – uz SDK-ov arm-none-eabi-gdb koji je već na PATH. Zadana pozadina je J-Link; make DEBUGGER=STLINK debug umjesto toga radi s ST-Link sondom.
gdbrunner se može pozvati i izravno (izvan SDK-a, pip install gdbrunner):
gdbrunner jlink --device STM32H743VI build/OPENMV4/bin/firmware.elf
gdbrunner stlink build/OPENMV4/bin/firmware.elf
gdbrunner qemu --machine mps2-an500 build/MPS2_AN500/bin/firmware.elf
Prvi pozicijski argument bira pozadinu poslužitelja (jlink, stlink, qemu); ostatak se prosljeđuje toj pozadini, sa zadanim vrijednostima koje rade za OpenMV kamere. gdbrunner --help ispisuje cijeli popis zastavica po pozadini; tablica argumenata svake pozadine vođena je JSON-om (src/gdbrunner/backends.json), pa je dodavanje novog poslužitelja izmjena konfiguracije, a ne koda.
Što gdbrunner radi za rad iz naredbenog retka:
Jedan proces, čist životni ciklus. Poslužitelj se pokreće, gdb se pričvršćuje kada je port otvoren, a poslužitelj se uredno gasi kada gdb izađe. Nema zaostalog
JLinkGDBServerkoji preživljava sesiju, nema dva terminala za upravljanje.STM32CubeProgrammer automatsko otkrivanje. Pozadina
stlinkpretražuje uobičajene lokacije instalacije (~/STM32CubeProgrammer/,/opt/st/, stablo dodataka STM32CubeIDE) za STM32CubeProgrammer alate, tako da se duga putanja--cube-progne mora upisivati svaki put. SDK uključuje vlastitu kopiju na~/openmv-sdk-<version>/stcubeprog/bin– usmjerite--cube-progtamo ako nema instalacije na sustavu.Poštivanje gdbinit-a po projektu.
.gdbinitu trenutnom direktoriju učitava se s-ix– nadjačavajući korisnički~/.gdbinit– tako da se gdb skriptiranje po projektu (pretty-printeri, makroi specifični za pločicu, skupovi točaka prekida) uključuje samim svojim postojanjem u radnom direktoriju.make debugizvodi se iz korijena repozitorija, pa se primjenjuje.gdbinittamo.Suho pokretanje.
--dryrunispisuje naredbu poslužitelja bez pokretanja, korisno za prilagodbu poziva omotač skripti, kopiranje u konfiguraciju IDE pokretača ili jednostavno provjeru koje argumente gdbrunner sastavlja.Vidljiv izlaz poslužitelja.
--show-outputzadržava stdout / stderr poslužitelja vidljivim. Zadana postavka ga potiskuje (kako bi gdb-ovo sučelje ostalo čisto); preokrenite zastavicu kada se sam poslužitelj loše ponaša.QEMU pozadina.
qemu-system-armotklanja pogreške u izgrađenom ugrađenom programu bez priključene pločice. CiljMPS2_AN500bira ovu pozadinu u svojoj konfiguraciji pločice, pamake TARGET=MPS2_AN500 DEBUG=1 debuggradi za QEMU-ov strojmps2-an500i prolazi kroz kod neovisan o platformi – sve što ne dotiče periferiju specifičnu za kameru – u letu. (qemu-system-armje instalacija na hostu, nije dio SDK-a.)
Za izvođenje korak po korak na razini izvornog koda s prikazom točaka prekida na rubu i pregledom registara periferije, gornje VS Code Cortex-Debug postavljanje bolji je alat; gdbrunner je pravi za sve što živi u naredbenom retku.
14.1.1.4.7. Korištenje debuggera¶
Kada sesija radi (procesor zaustavljen na main):
Točke prekida – kliknite rub uz C redak ili u Debug Console upišite
break <file>:<line>/break <function>. Cortex-M jezgre imaju malen broj hardverskih komparatora točaka prekida (obično 6–8 na M7 / H7, 8 na M55). Premašivanje tog broja na kodu u flash memoriji tiho ne uspijeva – održavajte broj aktivnih točaka prekida umjerenim.Izvođenje korak po korak – F10 korak preko (
next), F11 korak u (step), Shift+F11 korak van (finish), F5 nastavi. Izvođenje na razini instrukcija jestepi/nextiu Debug Console.Varijable / watch / poziv stog – okna Variables i Call Stack prikazuju lokalne varijable i trag poziva; dodajte izraze u Watch. Zadržite pokazivač iznad varijable u izvornom kodu da vidite njezinu vrijednost. Sve što prikazuje
<optimized out>znači da niste naDEBUG=1buildu.Watchpointi (podatkovne točke prekida) –
watch <expr>zaustavlja kada se u varijablu piše,rwatchpri čitanju,awatchpri oboje. Cortex-M DWT jedinica podržava ~4 hardverska watchpointa – neprocjenjivo za hvatanje tko je oštetio varijablu.Registri i periferija – pregled Cortex Registers prikazuje registre jezgre; uz postavljen
svdFile, pregled Peripherals dekodira svaki registar periferije i bitno polje (DMA, mjerači vremena, sučelje kamere / CSI, XSPI itd.) – najbrži način da vidite zašto se upravljački program loše ponaša.Memorija – koristite Cortex-Debug preglednik memorije ili gdb
x/za izravan pregled međuspremnika slika, DMA međuspremnika i struktura.printf bez zaustavljanja (SWO/RTT) – za probleme osjetljive na vremenske odnose, Segger RTT ili SWO daje
printfs gotovo nultim opterećenjem dok ciljni uređaj radi. Izgradite sDEBUG_PRINTF=1i dodajte Cortex-Debug-ovrttConfig(RTT) iliswoConfig(SWO, treba takt jezgre). Ovo je pravi alat kada bi točka prekida promijenila vremenske odnose koje pokušavate promatrati.Odspajanje – Stop na
launchsesiji zaustavlja ciljni uređaj; Disconnect naattachsesiji ostavlja kameru u radu. Nakon toga ponovno uključite napajanje kamere da je vratite u normalan rad.
14.1.1.4.8. Zamke pri otklanjanju pogrešaka¶
Optimizacijom uklonjene varijable. Sve prikazuje
<optimized out>– izgradili steDEBUG=0. Ponovno izgradite sDEBUG=1.„GDB executable not found” – SDK-ov
gcc/binnije naPATH; postavitearmToolchainPath/gdbPath.„Cannot connect” / pogrešna memorijska mapa – pogrešan ili nedostajeći
devicenaziv; koristite točan niz iz tablice.Točke prekida tiho se ne pogađaju – previše hardverskih točaka prekida na kodu koji se nalazi u flash memoriji; smanjite ih.
Putanje izvornog koda se ne podudaraju (ELF izgrađen Dockerom) – gradite s Docker ciljem
build-firmware-dev(ista apsolutna putanja unutar i izvan kontejnera) ili postavite gdbset substitute-path.