14.1.1.4. Laiteohjelmiston virheenjäljitys¶
Laitteistotason virheenjäljitys tarkoittaa suorittimen pysäyttämistä, keskeytyspisteiden asettamista C-lähdekoodiin, askeltamista ja muuttujien, muistin, rekisterien sekä oheislaitteiden tarkastelua – suoraan VS Coden sisältä. Tähän tarvitaan kolme asiaa: virheenjäljityskäännös, SWD-virheenjäljitysanturi (Segger J-Link) ja Cortex-Debug-laajennus, joka ohjaa arm-none-eabi-gdb-työkalua J-Linkin GDB-palvelinta vasten.
14.1.1.4.1. Käännös virheenjäljitystä varten¶
Käännä kohde aina uudelleen asetuksella DEBUG=1
make -j$(nproc) TARGET=<TARGET> DEBUG=1
Julkaisukäännös (DEBUG=0) käännetään asetuksella -O2; virheenjäljittimessä monille muuttujille näkyy <optimized out>, sisäänliitetyt funktiot sulautuvat kutsujiinsa ja askellus hyppii arvaamattomasti. DEBUG=1 kääntää asetuksilla -Og -ggdb3, mikä on jäljitettävissä mutta käynnistyy silti kamerassa. ELF-tiedosto, johon osoitat virheenjäljittimen, on:
build/<TARGET>/bin/firmware.elf
(Alif AE3:lla jäljitä build/OPENMV_AE3/bin/firmware_M55_HP.elf – suorituskykyydin.)
14.1.1.4.2. Laitteisto: J-Link SWD:n yli¶
Kytke Segger J-Link kameran SWD-nastoihin (SWDIO, SWCLK, GND ja kohteen VCC referenssiksi; kamera saa virtansa USB:n kautta kuten tavallisesti). J-Link EDU / Base / Pro toimivat kaikki. Virheenjäljitysnastojen sijainti vaihtelee kameroittain – monilla korteilla on oma JTAG/SWD-liitin, toiset tuovat SWD:n esiin I/O-rimassa tai testitassuissa – joten tarkista kyseisen kortin nastakaavio ja kytkentäkaavio OpenMV-laitteistodokumentaatiosta sen selvittämiseksi, mitkä nastat kytketään. Asenna J-Link Software and Documentation Pack osoitteesta segger.com koneeseen, johon anturi on fyysisesti kytketty. Pidä se kohtuullisen ajantasaisena – vanhempi J-Link-ohjelmisto ei tunne uudempia laitenimiä (STM32N6, MIMXRT, Alif).
Jokainen MCU tarvitsee tarkan J-Link device-nimensä, jotta anturi lataa oikean flash-latainin ja muistikartan:
Kamera ( |
MCU |
J-Link |
|---|---|---|
|
STM32F427 |
|
|
STM32F765 |
|
|
STM32H743 |
|
|
STM32N657 |
|
|
MIMXRT1062 |
|
|
Alif Ensemble (M55-HP) |
|
|
STM32H747 |
|
14.1.1.4.3. VS Code Cortex-Debug -asetukset¶
Luo .vscode/launch.json repositorioon. Yksinkertaisin tapaus – VS Code, J-Link ja käännös ovat kaikki samassa Linux- / macOS-koneessa – käyttää asetusta servertype: "jlink", jolloin Cortex-Debug käynnistää itse J-Linkin GDB-palvelimen:
{
"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"
}
]
}
Vaihda kortillesi sopivat executable ja device (katso yllä oleva taulukko). Paina F5 kääntääksesi, ohjelmoidaksesi ja suorittaaksesi pisteeseen main ja pysähtyäksesi siihen.
Vihje
Jotta uudelleenkäännös tapahtuu automaattisesti aina kun aloitat virheenjäljityksen, lisää käännöstehtävä tiedostoon .vscode/tasks.json ja viittaa siihen käynnistyskonfiguraatiosta asetuksella "preLaunchTask". Esimerkiksi tehtävä, joka ajaa make -j$(nproc) TARGET=OPENMV4 DEBUG=1 ja jolle on annettu nimi "build-firmware", sekä "preLaunchTask": "build-firmware" yllä olevassa konfiguraatiossa, jolloin F5 kääntää uudelleen, ohjelmoi ja käynnistää virheenjäljittimen yhdellä askeleella.
Varoitus
Cortex-Debug tarvitsee arm-none-eabi-gdb-työkalun. Se toimitetaan SDK:ssa polussa ~/openmv-sdk-<version>/gcc/bin mutta ei ole oletuksena PATH-muuttujassa, joten virheenjäljitys epäonnistuu viestillä ”GDB executable ’arm-none-eabi-gdb’ was not found”. Korjaa se joko asettamalla armToolchainPath / gdbPath kuten yllä on esitetty, tai lisäämällä ~/openmv-sdk-<version>/gcc/bin PATH-muuttujaan (printenv PATH listaa sen tällöin).
14.1.1.4.4. Oheislaiterekisterien näkymä (SVD)¶
Osoita Cortex-Debug CMSIS SVD-tiedostoon saadaksesi puretun oheislaiterekisterinäkymän (ajastimet, DMA, kameraliitäntä jne.) nimen ja bittikentän mukaan:
"svdFile": "/path/to/STM32H743.svd"
STM32:lle ja MIMXRT:lle hanki SVD ST:n / NXP:n CMSIS-paketeista tai Cortex-Debugin SVD-rekisteristä. Alifin SVD:t toimitetaan laiteohjelmistorepositorion mukana polussa lib/micropython/lib/alif_ensemble-cmsis-dfp/Debug/SVD/ (käytä tiedostoa ..._CM55_HP_View.svd AE3:n HP-ytimelle).
14.1.1.4.5. Windows: WSL ↔ Windows J-Link -silta¶
WSL 2 ei näe J-Linkin USB-laitetta suoraan, joten jako on seuraava: Windows tarjoilee anturin (johon se on kytketty) ja VS Code + gdb ajetaan WSL:ssä ja tavoittavat sen TCP:n yli.
Windowsissa asenna Segger J-Link -paketti ja kytke J-Link Windowsin USB-porttiin.
Windowsissa käynnistä J-Link Remote Server (se toimitetaan J-Link-paketin mukana): käynnistä se J-Link kytkettynä ja napsauta OK. Salli se Windowsin palomuurin läpi pyydettäessä. Ikkuna näyttää IP-osoitteen, jossa se tarjoilee anturia – merkitse se muistiin.
WSL:ssä käännä
DEBUG=1ja varmista, ettäarm-none-eabi-gdbon tavoitettavissa (asetaarmToolchainPathkuten yllä).WSL:n VS Codessa pidä
servertype: "jlink"– GDB-palvelin ajetaan WSL:ssä ja tavoittaa anturin Remote Serverin kautta – ja lisääserverpath+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" }
Aseta
ipAddressosoitteeksi, jonka Remote Server -ikkuna näyttää. Siinä on koko silta.
Vihje
Vaihtoehto GDB-palvelinsillalle: usbipd-win. Sen sijaan että ajaisit palvelinta Windowsissa, voit liittää J-Linkin USB-laitteen suoraan WSL:ään työkalulla usbipd-win. Järjestelmänvalvojan PowerShellistä:
winget install usbipd
usbipd list
usbipd bind --busid <busid>
usbipd attach --wsl --busid <busid>
(<busid> on J-Linkin väyläntunnus komennon usbipd list tuloksesta.) Anturi ilmestyy tällöin WSL:n sisälle, ja käytät tavallista saman koneen servertype: "jlink" -konfiguraatiota kohdasta VS Code Cortex-Debug setup ilman IP-osoitetta ja ilman erillistä Windows-palvelinta. GDB-palvelinsilta vaatii vähemmän asetuksia satunnaiseen käyttöön; usbipd-win on kätevämpi rutiininomaiseen kehitykseen.
Vihje
Käytä "request": "attach" jäljittääksesi laiteohjelmistoa sen jo ollessa käynnissä ilman nollausta tai uudelleenohjelmointia – ihanteellinen kentällä esiintyvän jumiutumisen nappaamiseen. Käytä "request": "launch" nollataksesi, ohjelmoidaksesi ELF:n ja aloittaaksesi puhtaalta pöydältä kohdassa runToEntryPoint.
14.1.1.4.6. Komentorivivirheenjäljitys gdbrunnerilla¶
GDB-istunnon pystyttäminen sulautettua kohdetta vasten käsin on viisivaiheinen tanssi: käynnistä J-Link- / ST-Link-GDB-palvelin yhdessä ikkunassa oikein laite-, portti- ja liitäntälipuilla; odota, että se tulostaa Waiting for GDB connection; aja arm-none-eabi-gdb toisessa ikkunassa; kirjoita target remote localhost:<port>; osoita gdb ELF-tiedostoon. Kun gdb-istunto päättyy, muista lopettaa palvelinikkuna. gdbrunner on pieni CLI, joka tiivistää kaiken tuon yhdeksi etualan komennoksi. Se toimitetaan OpenMV SDK:n Python-ympäristössä, joten mitään ei tarvitse asentaa; tavallinen aloituskohta on laiteohjelmistorepositorion make debug -kohde:
make -j$(nproc) TARGET=<TARGET> DEBUG=1 debug
Tämä ajaa gdbrunnerin kortin konfiguraatiosta saaduilla virheenjäljitysargumenteilla – J-Linkin laitenimellä ja tarvittaessa ST-Linkin ulkoisen flash-latainin kanssa – siten että SDK:n arm-none-eabi-gdb on jo PATH-muuttujassa. Oletustaustajärjestelmä on J-Link; make DEBUGGER=STLINK debug toimii sen sijaan ST-Link-anturin kanssa.
gdbrunner voidaan myös kutsua suoraan (SDK:n ulkopuolella, 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
Ensimmäinen sijaintiargumentti valitsee palvelimen taustajärjestelmän (jlink, stlink, qemu); loput välitetään kyseiselle taustajärjestelmälle oletuksilla, jotka toimivat OpenMV-kameroilla. gdbrunner --help listaa täydellisen taustajärjestelmäkohtaisen lippuluettelon; kunkin taustajärjestelmän argumenttitaulukko on JSON-ohjattu (src/gdbrunner/backends.json), joten uuden palvelimen lisääminen on konfiguraatiomuokkaus eikä koodimuutos.
Mitä gdbrunner tekee komentorivityöskentelyä varten:
Yksi prosessi, siisti elinkaari. Palvelin käynnistyy, gdb liittyy kun portti on auki, ja palvelin lopetetaan siististi gdb:n päättyessä. Ei istunnosta selviävää orpoa
JLinkGDBServer-prosessia, ei kahta hallittavaa päätettä.STM32CubeProgrammerin automaattinen löytäminen.
stlink-taustajärjestelmä etsii STM32CubeProgrammer-työkaluja tavanomaisista asennuspaikoista (~/STM32CubeProgrammer/,/opt/st/, STM32CubeIDE-lisäosapuu), joten pitkää--cube-prog-polkua ei tarvitse kirjoittaa joka kerta. SDK sisältää oman kopionsa polussa~/openmv-sdk-<version>/stcubeprog/bin– osoita--cube-progsinne, jos järjestelmäasennusta ei ole.Projektikohtainen gdbinit huomioidaan. Nykyhakemiston
.gdbinitladataan lipulla-ix– ohittaen käyttäjälaajuisen~/.gdbinit– joten projektikohtainen gdb-skriptaus (pretty-printerit, korttikohtaiset makrot, keskeytyspistejoukot) tulee käyttöön pelkästään olemalla työhakemistossa.make debugajetaan repositorion juuresta, joten siellä oleva.gdbiniton voimassa.Kuivaharjoitus.
--dryruntulostaa palvelinkomennon ajamatta sitä, mikä on hyödyllistä kutsun mukauttamiseen wrapper-skriptiin, sen kopioimiseen IDE:n käynnistyskonfiguraatioon tai vain sen tarkistamiseen, mitä argumentteja gdbrunner kokoaa.Palvelimen tuloste näkyvissä.
--show-outputpitää palvelimen stdout-/stderr-tulosteen näkyvissä. Oletus vaimentaa sen (jotta gdb:n käyttöliittymä pysyy siistinä); käännä lippu, kun palvelin itse on se, joka käyttäytyy huonosti.QEMU-taustajärjestelmä.
qemu-system-armjäljittää laiteohjelmistokäännöstä ilman, että korttia on kytkettynä.MPS2_AN500-kohde valitsee tämän taustajärjestelmän korttikonfiguraatiossaan, jotenmake TARGET=MPS2_AN500 DEBUG=1 debugkääntää QEMU:nmps2-an500-koneelle ja askeltaa alustariippumatonta koodia – kaikkea, mikä ei kosketa kamerakohtaisia oheislaitteita – lennossa. (qemu-system-armon isäntäasennus, ei osa SDK:ta.)
Lähdetason askellukseen keskeytyspistereunuksineen ja oheislaiterekisterinäkymineen yllä oleva VS Code Cortex-Debug -asetus on parempi työkalu; gdbrunner on oikea kaikkeen, mikä elää komentorivillä.
14.1.1.4.7. Virheenjäljittimen käyttö¶
Kun istunto on käynnissä (suoritin pysäytettynä kohdassa main):
Keskeytyspisteet – napsauta reunusta C-rivin vieressä, tai Debug Consolessa
break <file>:<line>/break <function>. Cortex-M-ytimillä on pieni määrä laitteistopohjaisia keskeytyspistevertailijoita (tyypillisesti 6–8 M7:llä / H7:llä, 8 M55:llä). Tämän ylittäminen flash-muistissa olevassa koodissa epäonnistuu hiljaisesti – pidä aktiivisten keskeytyspisteiden määrä maltillisena.Askellus – F10 askella yli (
next), F11 askella sisään (step), Shift+F11 askella ulos (finish), F5 jatka. Käskytason askellus onstepi/nextiDebug Consolessa.Muuttujat / vahti / kutsupino – Variables- ja Call Stack -ruudut näyttävät paikalliset muuttujat ja kutsupinon; lisää lausekkeita Watch-ruutuun. Vie hiiri muuttujan päälle lähdekoodissa nähdäksesi sen arvon. Kaikki, mikä näyttää
<optimized out>, tarkoittaa, ettet oleDEBUG=1-käännöksessä.Vahtipisteet (datakeskeytyspisteet) –
watch <expr>pysähtyy, kun muuttujaan kirjoitetaan,rwatchlukemisessa,awatchkummassakin. Cortex-M:n DWT-yksikkö tukee noin 4:ää laitteistopohjaista vahtipistettä – korvaamaton sen nappaamiseen, kuka turmeli muuttujan.Rekisterit ja oheislaitteet – Cortex Registers -näkymä näyttää ydinrekisterit; kun
svdFileon asetettu, Peripherals-näkymä purkaa jokaisen oheislaiterekisterin ja bittikentän (DMA, ajastimet, kamera- / CSI-liitäntä, XSPI jne.) – nopein tapa nähdä, miksi ajuri käyttäytyy huonosti.Muisti – käytä Cortex-Debugin muistinkatselinta tai gdb:n
x/-komentoa tarkastellaksesi kehyspuskureita, DMA-puskureita ja rakenteita suoraan.printf ilman pysäytystä (SWO/RTT) – ajoituksen suhteen herkkiin ongelmiin Seggerin RTT tai SWO antaa lähes nollakustannuksisen
printf-tulosteen kohteen ollessa käynnissä. Käännä asetuksellaDEBUG_PRINTF=1ja lisää Cortex-DebuginrttConfig(RTT) taiswoConfig(SWO, tarvitsee ydinkellon). Tämä on oikea työkalu silloin, kun keskeytyspiste muuttaisi ajoitusta, jota yrität tarkkailla.Yhteyden katkaiseminen – Stop
launch-istunnossa pysäyttää kohteen; Disconnectattach-istunnossa jättää kameran käyntiin. Käynnistä kamera virtakatkolla uudelleen palauttaaksesi sen normaaliin toimintaan jälkeenpäin.
14.1.1.4.8. Virheenjäljityksen sudenkuopat¶
Optimoidut pois -muuttujat. Kaikki näyttää
<optimized out>– käänsitDEBUG=0. Käännä uudelleen asetuksellaDEBUG=1.”GDB executable not found” – SDK:n
gcc/binei olePATH-muuttujassa; asetaarmToolchainPath/gdbPath.”Cannot connect” / väärä muistikartta – väärä tai puuttuva
device-nimi; käytä taulukon tarkkaa merkkijonoa.Keskeytyspisteisiin ei osuta hiljaisesti – liian monta laitteistopohjaista keskeytyspistettä flash-muistissa olevassa koodissa; vähennä niitä.
Lähdepolut eivät täsmää (Dockerissa käännetty ELF) – käännä Dockerin
build-firmware-dev-kohteella (sama absoluuttinen polku säiliön sisällä ja ulkona) tai aseta gdb:ssäset substitute-path.