Innholdsfortegnelse:

Del 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo: 16 trinn
Del 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo: 16 trinn

Video: Del 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo: 16 trinn

Video: Del 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo: 16 trinn
Video: TI-RSLK Lab 7-1 Finite State Machine example 2024, Juli
Anonim
Image
Image

Fokuset for denne Instructable er STM32 Nucleo mikrokontroller. Motivasjonen for dette for å kunne lage et monteringsprosjekt fra bare bein. Dette vil hjelpe oss med å dykke dypere og forstå MSP432 Launchpad-prosjektet (TI-RSLK) som allerede har vært tema for flere instrukser.

Det er ikke veldig mye hjelp online for å lage et prosjekt som bare er for montering for MSP432, ved hjelp av Code Composer Studio. Hittil har vi bare kopiert/limt inn fra et eksisterende monteringsprosjekt. Denne tilnærmingen har tjent oss godt.

Men nå, for Lab 7, har vi støtt på et lite problem. Eller i det minste en midlertidig hikke. Lab 7 introduserer finite-state-maskiner, og det første vi møter er behovet for å lage og bruke en rekke verdier. Siden TI -kurset hovedsakelig bruker C -programmering - er dette ikke et problem. Men disse instruksjonene har fokusert på montering, ikke C.

Siden matrisen er av skrivebeskyttede verdier, ville det være bra å sette den i flash-minne, ikke RAM.

Det ser ut til å være mye mer hjelp online for monteringsprosjekter som bruker STM32 MCU, og derfor begynner vi med denne instruksen, med målet om å bruke det som er lært, for deretter å søke på MSP432 og Code Composer Studio.

På veien mot målet har vi også fått erfaring med enda en populær mikrokontroller.

Trinn 1: Første test av enheten

Første test av enheten
Første test av enheten
Første test av enheten
Første test av enheten
Første test av enheten
Første test av enheten

Igjen, hvorfor velge STM32 Nucleo spesielt?

Ærlig talt? Fordi jeg søkte etter gode artikler om bare metallmonteringsprosjekter for ARM-kontrollere, og jeg kom over denne serien. Og også fordi STM32 ser ut til å være en populær MCU.

Jeg gjorde noen undersøkelser (det er mange versjoner å velge mellom - se bildet ovenfor), men til slutt ble det hva jeg faktisk kan få, siden jeg skulle bruke Amazon (i USA).

Den kommer i en enkel, men profesjonell pakke, med noen oppstartsinstruksjoner. Det var litt morsomt å se at demoen som brant seg inn i kontrolleren var nesten akkurat det vi har gjort tidligere Instructables - en LED blinker og endrer hastigheten i henhold til et tastetrykk.

Det ser ut til at dette utviklingsbordet er veldig likt MSP432 ved at det er 2 lysdioder og en bruker-trykknapp. MSP432 har 2 brukerknapper.

Som du kan se på bildene, ble jeg litt overrasket over at brettet har en mini og ikke en mikro -USB. Måtte løpe ut for å kjøpe en ledning.

En annen god test er at når du kobler den til datamaskinen din (jeg bruker en Linux -boks), vises den i filbehandleren min, som et filsystem, kalt "NODE_F303RE". Åpning som avslører to filer, en HTML og en tekst.

Det er det, men i det minste sier det også at tilkobling virker ganske enkelt.

Nå er vi klare til å begynne.

Jeg skal prøve å ikke gjenta noe av den gode informasjonen fra IVONOMICON Bare Metal -artikkelserien, men heller øke den.

Trinn 2: Essentials

Det første vi trenger er en kompilator.

Og så trenger vi en feilsøkingsprogram:

devchu@chubox: ~ $ sudo apt-get install gdb-arm-none-eabiLesende pakkelister … Ferdig Bygge avhengighetstreet Lese statlig informasjon … Ferdig Følgende NYE pakker blir installert: gdb-arm-none-eabi 0 oppgradert, 1 nylig installert, 0 for å fjerne og 8 ikke oppgradert. Trenger å få 2, 722 kB arkiver. Etter denne operasjonen vil 7, 738 kB ekstra diskplass brukes. Få: 1 https://us.archive.ubuntu.com/ubuntu xenial/universe amd64 gdb-arm-none-eabi amd64 7.10-1ubuntu3+9 [2, 722 kB] Hentet 2, 722 kB på 1 sekund (1, 988 kB/s) Velge pakke som ikke er valgt tidligere gdb-arm-none-eabi. (Lese databasen … 262428 filer og kataloger som er installert for øyeblikket.) Forbereder å pakke ut …/gdb-arm-none-eabi_7.10-1ubuntu3+9_amd64.deb… Pakke ut gdb-arm-none-eabi (7.10-1ubuntu3+9)… Behandler utløsere for man-db (2.7.5-1) … Sette opp gdb-arm-none-eabi (7.10-1ubuntu3+9) …

Trinn 3: The Essentials - Windows

Trinnet ovenfor antok at vi bruker Linux. Hva om vi bruker Windows?

Du kan gå til armen Developer -området, og det er flere nedlastingsalternativer tilgjengelig. Jeg bruker en Windows 8 -maskin.

Under installasjonen valgte jeg å installere den på roten "C: \" i stedet for programfiler bare fordi jeg også bruker cygwin, og det var lettere å opprette en lenke fra min lokale bin til en rot C: mappe enn alle rot i banen til programfiler (med mellomrom osv.).

Dermed ser mitt cygwin -miljø og banen, osv. Slik ut:

C: / cygwin64 / home / bin / arm-none-eabi-gcc, der arm-none-eabi-gcc er en lenke til C: / GNUToolsArmEmbedded / 7.2018.q2.update / bin / arm-none-eabi- gcc.

Jeg opprettet deretter en "dev" -mappe under cygwin home, og det var der jeg plasserte core. S -filen og kjørte kompilatorkommandoen. (se ytterligere nedenfor for kompilator -ting).

Jeg gjorde akkurat det samme for gdb (arm-none-eabi-gdb).

Trinn 4: Hva er det viktigste

Så hva er "gcc-arm-none-eabi"?

GNU -kompilatoren (GCC) vil kompilere programmeringsspråk (som C) til innfødt kode for maskinen den kjører på. For eksempel, hvis du skulle kompilere noen C -kode ved hjelp av GCC på Windows -maskinen din, ville den være bygget for å kjøre på Windows -maskinen. Den genererte kjørbare filen vil (vanligvis) ikke kjøre på ARM-mikrokontrolleren.

Så for å bygge programmer som skal lastes ned og brennes inn i ARM-mikrokontrolleren (i vårt nåværende tilfelle ville det være STM32 Nucelo), må vi gi GCC noe annet: muligheten til å "kryss-kompilere". Det vil si muligheten til å generere en kjørbar, ikke for det opprinnelige systemet (og prosessoren), men for målsystemet (ARM-mikrokontrolleren). Det er der "gcc-arm-none-eabi" spiller inn.

Så hva er "gdb-arm-none-eabi"?

Når vi har lastet ned og brent (blinket) den nylig genererte kjørbare filen til mikrokontrolleren, vil vi sannsynligvis feilsøke den-gå gjennom linje for linje i koden. GDB er gnu debugger, og den trenger også en måte å gjøre jobben sin på, men målrettet mot et annet system.

Således er gdb-arm-none-eabi for GDB, hva gcc-arm-none-eabi er for GCC.

En annen foreslått pakkeinstallasjon var "libnewlib-arm-none-eabi". Hva er den?

Newlib er et C -bibliotek og mattebibliotek beregnet for bruk på innebygde systemer. Det er et konglomerasjon av flere biblioteksdeler, alt under gratis programvarelisenser som gjør dem lett brukbare på innebygde produkter.

Og til slutt pakken "libstdc ++-arm-none-eabi". Den er ganske åpenbar; det er C ++-bibliotek for krysskompilatoren; for innebygde ARM mikrokontroller.

Trinn 5: Linker -filen

Linker -filen
Linker -filen
Linker -filen
Linker -filen

La oss lage et linkerskript.

En nøkkeldel eller blokk i denne filen vil være MEMORY -kommandoen.

--- fra sourceware.org:

Linkerens standardkonfigurasjon tillater allokering av alt tilgjengelig minne. Du kan overstyre dette ved å bruke MEMORY -kommandoen. MEMORY -kommandoen beskriver plasseringen og størrelsen på minneblokker i målet. Du kan bruke den til å beskrive hvilke minneområder som kan brukes av linkeren, og hvilke minneområder den må unngå. Du kan deretter tilordne seksjoner til bestemte minneområder. Linkeren angir seksjonsadresser basert på minneområdene, og vil advare om områder som blir for fulle. Linkeren vil ikke blande seksjoner rundt for å passe inn i de tilgjengelige områdene. Et linker -script kan inneholde mange bruksområder for MEMORY -kommandoen, men alle definerte minneblokker behandles som om de var spesifisert inne i en enkelt MEMORY -kommando. Syntaksen for MEMORY er:

HUKOMMELSE

{navn [(attr)]: ORIGIN = opprinnelse, LENGDE = len…}

Eksemplet i artikkelen:

/* Definer slutten på RAM og grensen for stackminne* //* (4KB SRAM på linjen STM32F031x6, 4096 = 0x1000)*//* (RAM starter på adressen 0x20000000) _estack = 0x20001000;

HUKOMMELSE

{FLASH (rx): ORIGIN = 0x08000000, LENGDE = 32K RAM (rxw): ORIGIN = 0x20000000, LENGTH = 4K}

Så vi må finne ut hvor mye FLASH (for vårt program og konstanter, osv.) Og hvor mye RAM (for bruk av programmet; haug og stabling, osv.) For vårt bestemte brett. Dette blir litt interessant.

Det fine lille kortet som følger med Nucleo sier at det har flashminne er 512 Kbytes, og SRAM er 80 Kbytes. Når du kobler den til USB, blir den imidlertid montert som et filsystem med to filer, og både filbehandleren og GParted indikerer at den har over 540+ Kbytes plass. (RAM?).

MEN, forsøk på å slette de to filene ved hjelp av filbehandleren, koble fra og deretter koble til enheten på nytt, viser fremdeles de to filene. (og filbehandleren gjenkjente noe fordi det er et lite "lås" -ikon på hver fil.

Så la oss gå med tallene på kortet. Så nå tar vi eksemplet ovenfor og konverterer det til vårt spesifikke bord.

Det kan være lurt å bruke noe som denne online minnekonverteren, for å gå fra den generelle KB til et bestemt antall byte.

Da kan det være lurt å bruke en online desimal til hex -omformer.

/ * Definer slutten på RAM og grensen for stakkminne */

/* (4KB SRAM på linjen STM32F031x6, 4096 = 0x1000)* //* eksemplet*/

/ * trinn 1: (80KB SRAM på STM32F303RE, 81920 = 0x14000) * // * vårt bord */

/* trinn 2, legg til hex -størrelsen til hex -startadressen (nedenfor). */

/ * (RAM starter på adressen 0x20000000) */

_stack = 0x20001000; /* eksempelet */

_stack = 0x20014000; / * vårt styre */

MINNE {

FLASH (rx): ORIGIN = 0x08000000, LENGDE = 512K

RAM (rxb): ORIGIN = 0x20000000, LENGDE = 80K

}

La oss kalle filen ovenfor "linker.script.ld".

Trinn 6: Vektortabellen

Vektortabellen
Vektortabellen

Nå skal vi lage en liten monteringsfil (med direktiver) for å gjøre noen helt grunnleggende avbruddshåndtering. Vi vil følge artikkelens eksempel og lage en fil som heter "core. S".

Igjen, her er eksempelfilinnholdet, men jeg gjorde en endring for vårt spesifikke bord:

// Disse instruksjonene definerer attributtene til brikken vår og

// samlingsspråket vi vil bruke:.syntax unified /*Se nedenfor etter dette kodeområdet* //*.cpu cortex-m0* / /*kommenter denne linjen i eksemplet* /.cpu cortex-m4 /* legg i stedet til styrets cortex. se bildet ovenfor i dette trinnet * / /*.fpu softvfp * / / *kommenter denne linjen i eksemplet * /.fpu vfpv4 / *legg i stedet til styrets; den har en FPU */.thumb // Global minnesteder..global vtable.global reset_handler / * * Den faktiske vektortabellen. * Bare størrelsen på RAM og 'reset' handler er * inkludert, for enkelhets skyld. */.type vtable, %object vtable:.word _estack.word reset_handler.størrelse vtable,.-vtable

Hmm.. Nei '.align' direktiv

Det er imidlertid ikke kritisk. Mer om det (kanskje) senere.

.syntax forenet

.syntax [samlet | delt]

Dette direktivet angir Syntaks for instruksjonssett som beskrevet i delen ARM-instruksjonssett

9.4.2.1 Syntaks for instruksjonssett To litt forskjellige syntakser støtter ARM- og THUMB -instruksjoner. Standarden, delt, bruker den gamle stilen der ARM og THUMB -instruksjoner hadde sine egne, separate syntakser. Den nye, enhetlige syntaksen, som kan velges via.syntax -direktivet.

.fpu vfpv4

GCC -kompilatoren kan produsere binære filer med flere alternativer angående flytende punkt: myk - egnet for kjøring på CPUer uten FPU - beregninger utføres i programvare av kompilatorgenerert softfp - egnet for kjøring på CPU -er med eller uten FPU - vil bruke en FPU hvis den er tilstede. For vår spesifikke sak (du må gjøre din egen forskning), er dette brettets FPU i samsvar med vfpv4. Du må kanskje leke med dette. Eller til og med la den stå på softfp.

.tommel (vs.arm)

Disse ARM -mikrokontroller har faktisk en blanding av instruksjonssett. Den ene er ARM, den andre er TOMMEL. En forskjell er 16-biters instruksjoner vs 32-biters instruksjoner. Dermed ber dette direktivet kompilatoren om å behandle påfølgende instruksjoner som enten TOMMEL eller ARM.

Vi kommer til å bare ta resten av filen slik den er siden disse instruksjonene ennå ikke har fordypet seg i avbruddsdrevet montering.

Trinn 7: Monteringsversjonen av et Hello World -program

Følgende kan også gå inn i den tidligere opprettet "core. S" -filen. Dette, igjen, er fra eksemplet i artikkelen.

/ * * Reset handler. Ringte ved tilbakestilling. */.type reset_handler, %function reset_handler: // Sett stabelpekeren til slutten av stabelen. // Verdien '_estack' er definert i vårt linkerskript. LDR r0, = _stack MOV sp, r0

// Angi noen dummy -verdier. Når vi ser disse verdiene

// i debuggeren vet vi at programmet vårt // er lastet på brikken og fungerer. LDR r7, = 0xDEADBEEF MOVS r0, #0 main_loop: // Legg til 1 for å registrere 'r0'. ADDS r0, r0, #1 // Sløyfe tilbake. B main_loop.size reset_handler,.-Reset_handler

Så, kraften i programmet ovenfor er å laste inn et gjenkjennelig mønster i ett kjerne -MCU -register (i dette tilfellet R7), og en økende verdi som starter ved null til et annet kjerne -MCU -register (i dette tilfellet R0). Hvis vi går gjennom kjøringskoden, bør vi se R0s datastigning.

Hvis du har fulgt sammen med instruksjonene angående MSP432 og TI-RSLK-kurset/laboratoriene, bør stort sett alle de ovennevnte programmene være kjent for deg.

Den nye tingen jeg kan se er bruk av "=" når du laster inn "DEADBEEF" for å registrere R7. Det hadde vi ikke brukt.

"Core. S" -filen som er vedlagt her inneholder nå hele kilden.

Trinn 8: Kompilering av koden

Det er på tide å gjøre noen kommandolinje-ting. Noe ekte, endelig.

Vi er imidlertid ikke helt der. Vi må igjen justere kommandoen i artikkelen, og endre den til vår egen situasjon.

Her er eksempelkoden:

arm -none -eabi -gcc -x assembler -with -cpp -c -O0 -mcpu = cortex -m0 -tommel -Veggkjerne. S -o kjerne.o

Hvis vi går til gnu.org -nettstedet for GCC, (i dette tilfellet versjon 7.3),

x

-X er å angi språket. Ellers hvis nei -x, vil kompilatoren prøve å gjette ved å bruke filtypen. (i vårt tilfelle, *. S).

Eksemplet ovenfor fra artikkelen spesifiserer assembler-with-cpp, men vi kan bare gjøre assembler.

c

-C sier kompiler, men ikke lenke.

O0

-O er å angi optimaliseringsnivået. Bruk av -O0 (oh -zero) sier "reduser kompileringstiden og få feilsøking til å gi de forventede resultatene. Dette er standard".

mcpu = cortex-m0

-Mcpu angir navnet på målprosessoren. I vårt tilfelle ville det være cortex-m4.

tommelen

The -mthumb spesifiserer å velge mellom generering av kode som kjører ARM- og THUMB -tilstander.

Vegg

The -Wall er selvfølgelig veldig vanlig og kjent. Det slår på alle advarselsflagg.

Til slutt, på slutten av kommandoen har vi inndatafilen core. S og output filen core.o.

Her er den nye kommandolinjen som passer til vårt spesifikke tilfelle.

arm -none -eabi -gcc -x assembler -c -O0 -mcpu = cortex -m4 -tommelen -Wall core. S -o core.o

Og det ble samlet.

Trinn 9: Koble programmet

Direkte fra eksemplet i artikkelen har vi dette:

arm -none -eabi -gcc core.o -mcpu = cortex -m0 -mthumb -Wall --specs = nosys.specs -nostdlib -lgcc -T./STM32F031K6T6.ld -o main.elf

De fleste av de ovennevnte har du sett. Nedenfor er det som er nytt.

specs = nosys.specs

Denne er litt vanskelig å forklare.

Det har å gjøre med "semihosting" og "retargeting", og det har å gjøre med input / output. Det har også å gjøre med systemanrop og biblioteker.

Vanligvis gir innebygde systemer ikke standard inndata/utgangsenheter. Dette vil påvirke system- eller bibliotekanrop (eksempel: printf ()).

Semihosting betyr at feilsøkingsprogrammet (se trinn 11 -bilde med feilsøkingsdel sirklet i rødt) har en spesiell kanal og bruker semihosting -protokollen, og du kan se utskriften av printf () på vertsmaskinen (via feilsøkingsprogrammet).

Retargeting, derimot, betyr at de samme system- eller bibliotekanropene betyr noe annet. De gjør noe annet, som gir mening for det innebygde systemet. På en måte, si for printf (), det er en ny implementering, en målrettet implementering av den funksjonen.

Når alt dette er sagt, betyr --specs = nosys.specs at vi ikke kommer til å være semihosting. Det vil normalt bety at vi målretter. Det bringer oss til neste flagg.

nostdlib

Linkeralternativet -nostdlib brukes til å koble et program som er ment å kjøre frittstående. -nostdlib innebærer de individuelle alternativene -nodefaultlibs og -nostartfiles. Nedenfor diskuterer vi de to alternativene hver for seg, men den mest typiske bruken er bare nostdlib for one-stop shopping. Når du kobler et hostet program, er standard systembiblioteker som libc koblet som standard, noe som gir programmet tilgang til alle standardfunksjoner (printf, strlen og venner). Linkeralternativet -nodefaultlibs deaktiverer kobling til disse standardbibliotekene; de eneste bibliotekene som er koblet, er akkurat de som du eksplisitt navngir til linkeren ved å bruke -l -flagget.

lgcc

libgcc.a er et standardbibliotek som gir interne subrutiner for å overvinne mangler ved bestemte maskiner. For eksempel inkluderer ARM -prosessoren ikke en divisjonsinstruksjon. ARM -versjonen av libgcc.a inkluderer en divisjonsfunksjon, og kompilatoren sender ut samtaler til den funksjonen der det er nødvendig.

T

Dette er bare en måte å fortelle linkeren om å bruke denne filen som linker -script. I vårt tilfelle er filnavnet linker.script.ld.

o main.elf

Til slutt forteller vi linkeren hva navnet på den endelige utdatafilen vil bli brent/blinket inn i enheten vår.

Her er vår versjon av den komplette kommandolinjen, modifisert for vår spesifikke situasjon:

arm -none -eabi -gcc core.o -mcpu = cortex -m4 -mthumb -Wall --specs = nosys.specs -nostdlib -lgcc -T./linker.script.ld -o main.elf

Vi sørger for at skriptfilen og core.o-filen begge er i samme katalog, hvor vi kjører kommandolinjen ovenfor.

Og den kobles uten problemer.

En sjekk

Vi kjører da:

arm-none-eabi-nm main.elf

og vi får:

devchu@chubox: ~/Development/Atollic/TrueSTUDIO/STM32_workspace_9.1 $ arm-none-eabi-nm main.elf 20014000 A _estack 08000010 t main_loop 08000008 T reset_handler 08000000 T vtable

Ser bra ut. Arm-none-eabi-nm-kommandoen er en måte å vise symboler på i objektfiler.

Trinn 10: TestingTilkobling til STM32 Nucleo-64

TestingTilkobling til STM32 Nucleo-64
TestingTilkobling til STM32 Nucleo-64
TestingTilkobling til STM32 Nucleo-64
TestingTilkobling til STM32 Nucleo-64

Ditt første oppdrag, hvis du velger å godta det, er å få systemet til å se utviklingsbordet ditt.

Bruke Windows

For Windows bestemte jeg meg for å installere TrueSTUDIO fra Atollic (gratisversjon). Det var en smertefri installasjon og den installerte driveren automatisk, slik at jeg kunne bruke st-link for å teste tilkoblingen. Når jeg installerte TrueSTUDIO og enhetsbehandleren så enheten, lastet jeg ned texan/stlink -verktøyene som ble foreslått av Bare Metal -artikkelen vi har fulgt. Jeg plasserte mappen igjen direkte under "C: \", og opprettet igjen noen koblinger fra min lokale cygwin -søppelbøtte til kommandoene.

ln -s /c/STM32. MCU/stlink-1.3.0-win64/bin/st-info.exe ~/bin/st-info

Som en første test for å se om vi virkelig kan kommunisere med enheten, løp jeg:

st-info --probe

Og kom tilbake:

Fant 1 stlink programmerere

Så nå vet vi at vi kan snakke/spørre utviklingsstyret vårt.

Bruker Linux

For linux trenger du egentlig ikke en driver. Men for Debian må du bygge verktøyene fra kilden.

git -klon

Pass på at du har libusb-1.0-0-dev installert.

passende liste | grep -E "*libusb.*dev*"

Du bør se:

libusb-1.0-0-dev/xenial, nå 2: 1.0.20-1 amd64 [installert]

eller noe sånt.

Slik installerer du det:

sudo apt-get install libusb-1.0-0-dev

Vær oppmerksom på at ovenstående ikke er det samme som:

sudo apt-get install libusb-dev

Den riktige manglende libusb -dev kan føre til at cmake får problemer.

CMake -feil: Følgende variabler brukes i dette prosjektet, men de er satt til NOTFOUND. Vennligst sett dem eller sørg for at de er angitt og testet riktig i CMake -filene: LIBUSB_INCLUDE_DIR (ADVANCED)

Bytt til prosjektets rotkatalog (… bla /bla /stlink). Gjør en "make release".

Etter at det er bygget, skal verktøyene være under ".. /build /Release".

Du kan deretter kjøre "st-info --probe". Her er utgangen med Nucleo tilkoblet, så ikke.

devchu@chubox: ~/Development/stlink $./build/Release/st-info --probeFunnet 1 stlink programmerere serie: 303636414646353034393535363537 openocd: "\ x30 / x36 / x36 / x41 / x46 / x46 / x35 / x30 / x34 / x39 / x35 / x35 / x36 / x35 / x37 "blits: 524288 (sidestørrelse: 2048) sram: 65536 chipid: 0x0446 descr: F303 enhet med høy tetthet devchu@chubox: ~/Development/stlink $./build/Release/st- info --probe Fant 0 stlink programmerere devchu@chubox: ~/Development/stlink $

Trinn 11: La oss bruke GDB med Linux

La oss bruke GDB med Linux
La oss bruke GDB med Linux
La oss bruke GDB med Linux
La oss bruke GDB med Linux

Hvis du har prøvd alt dette, og du har kommet så langt - flott! Utmerket. La oss ha det litt moro nå.

Når du kjøper disse ARM-utviklingstavlene, enten de er MSP432 Launchpad fra Texas Instruments, eller denne vi diskuterer nå, Nucleo-F303 (STM32 Nucleo-64), kommer de vanligvis allerede blinket med et program som kjører, vanligvis noe blinkende program som også inkluderer å trykke på en bryter for å endre hastigheten som LED -lampene (e) blinker med.

Før vi er så raske til å overskrive det, la oss se hva det er å se og gjøre.

Med Linux, åpne en terminal, endre katalogen for stlink git-prosjektet som vi nettopp bygde, og finn st-util-verktøyet.

devchu@chubox: ~/Development/stlink $ finn. -navn st-util

./build/Release/src/gdbserver/st-util

Kjør det verktøyet. Siden vi allerede tidligere har testet forbindelsen vår med st-info --probe, bør vi få litt output slik:

devchu@chubox: ~/Development/stlink $./build/Release/src/gdbserver/st-util

st-util 1.4.0-50-g7fafee2 2018-10-20T18: 33: 23 INFO felles. c: Laster inn enhetsparametere…. 2018-10-20T18: 33: 23 INFO common.c: Tilkoblet enhet er: F303 enhet med høy tetthet, id 0x10036446 2018-10-20T18: 33: 23 INFO common.c: SRAM-størrelse: 0x10000 byte (64 KiB), Flash: 0x80000 byte (512 KiB) på sider med 2048 byte 2018-10-20T18: 33: 23 INFO gdb-server.c: Chip-ID er 00000446, kjerne-ID er 2ba01477. 2018-10-20T18: 33: 23 INFO gdb-server.c: Lytter på *: 4242 …

Det er GDB -serveren som kjører nå, og den ser vårt utviklingstavle, og enda viktigere, den lytter på port 4242 (standardporten).

Nå er vi klare til å fyre opp GDB -klienten.

I Linux, åpne en annen terminal, skriv inn denne:

arm-none-eabi-gdb -tui

Det er akkurat det samme som å kjøre gdb strengt kommandolinje, men det produserer i stedet en tekstbasert terminal (jeg antar at den bruker forbannelser).

Vi har GDB -klienten og GDB -serveren i gang. Klienten er imidlertid ikke koblet til serveren. For øyeblikket vet den ingenting om Nucleo (eller brettet du ønsker). Vi må fortelle det. I terminalen skal meldingen din nå være "(gdb)". Tast inn:

hjelp mål

Det vil gi deg en liste. Legg merke til at den vi ønsker er target extended -remote - Bruk en ekstern datamaskin via en seriell linje.

Men vi må også gi den plasseringen. Så, ved (gdb) ledeteksten, skriv inn:

(gdb) mål utvidet ekstern lokal vert: 4242

Du bør få tilbake et svar slik:

(gdb) mål utvidet ekstern lokal vert: 4242

Ekstern feilsøking ved hjelp av localhost: 4242 0x080028e4 in ?? ()

I mellomtiden, på terminalen som kjører st-util gdbserver, fikk vi dette:

2018-10-20T18: 42: 30 INFO gdb-server.c: Fant 6 hw breakpoint-registre

2018-10-20T18: 42: 30 INFO gdb-server.c: GDB tilkoblet.

Trinn 12: La oss gjenta, med Windows og Flash vårt program

La oss gjenta, med Windows og Flash vårt program
La oss gjenta, med Windows og Flash vårt program
La oss gjenta, med Windows og Flash vårt program
La oss gjenta, med Windows og Flash vårt program
La oss gjenta, med Windows og Flash vårt program
La oss gjenta, med Windows og Flash vårt program

Trinnene for å kjøre st-util gdbserver og arm-none-eabi-gdb-klienten er i hovedsak de samme som vi gjorde under forrige trinn. Du åpner to terminaler (cygwin, DOS cmd eller Windows Powershell), finn plasseringen til st-util, kjør den. I den andre terminalen kjører du arm-none-eabi-gdb-klienten. Den eneste forskjellen er at -tui (terminalbasert tekstvisning) -modus sannsynligvis ikke støttes.

Hvis det ovennevnte fungerte i Windows, må du sannsynligvis stoppe (bare klienten). På dette tidspunktet må du på en eller annen måte kjøre GDB -klienten der build -filen din er ("core.out"), eller legge til hele banen til filen som et argument for GDB -klienten.

Jeg forenklet livet mitt ved å bruke cygwin og lage koblinger fra min lokale $ HOME // bin -katalog til hvor begge disse verktøyene ligger.

Ok, vi har samlet og lenket akkurat som før, og vi har filen main.elf klar til å bli blinket.

Vi har st-util som kjører i ett vindu. Vi starter GDB-klienten på nytt, denne gangen gjør vi:

arm-none-eabi-gdb main.elf

Vi lar den starte opp, venter på (gdb) ledeteksten, gjør den samme tilkoblingskommandoen til GDB-serveren (st-util), og vi er klare til å blinke den kjørbare filen. Det er veldig antiklimatisk:

(gdb) belastning

Når det kjøres med cygwin -terminaler, er det et kjent problem med at konsoller ikke kommer ut noen ganger. Så i vårt tilfelle var vinduet som kjørte serveren helt stille. Den som kjører klienten, der vi kjørte lasten, send ut denne:

Lasteseksjon. Tekst, størrelse 0x1c lma 0x8000000 Startadresse 0x8000000, laststørrelse 28 Overføringshastighet: 1 KB/sek, 28 byte/skrive.

Trinn 13: Blinker med Linux - Mer belønning: D

Blinker med Linux - mer belønning: D
Blinker med Linux - mer belønning: D

Trinn 14: La oss dykke litt dypere

Hvis du kom hit, utmerket. La oss gå videre.

Hvorfor ikke se på innsiden av main.elf -filen, den kjørbare filen? Kjør følgende:

arm-none-eabi-objdump -d main.elf

Du bør se en utgang omtrent slik:

main.elf: filformat elf32-littlearm

Demontering av seksjon.tekst:

08000000:

8000000: 00 40 01 20 09 00 00 08.@. ….

08000008:

8000008: 4802 ldr r0, [stk, #8]; (8000014) 800000a: 4685 mov sp, r0 800000c: 4f02 ldr r7, [stk, #8]; (8000018) 800000e: 2000 movs r0, #0

08000010:

8000010: 3001 legger til r0, #1 8000012: e7fd b.n 8000010 8000014: 20014000.word 0x20014000 8000018: deadbeef.word 0xdeadbeef

Hvilke små nuggets kan vi få fra utdataene ovenfor?

Hvis du husker tilbake da vi diskuterte og opprettet linker.script.ld -filen, uttalte vi at disse ARM -enhetene har RAM som starter på 0x20000000, og at FLASH -minnet starter på 0x08000000.

Dermed kan vi se at programmet faktisk er slik at det hele ligger i FLASH -minne.

Så, ovenfor, men et senere trinn, da vi diskuterte "Hello World" -delen, var det en uttalelse der vi laster inn en umiddelbar, konstant, bokstavelig verdi ("0xDEADBEEF") i et MCU -kjerneregister ("R7").

Uttalelsen var:

LDR R7, = 0xDEADBEEF

I koden vår er det det eneste stedet hvor vi til og med nevner DEADBEEF. Ingen andre steder. Og likevel, hvis du ser på de demonterte/rekonstruerte instruksjonene ovenfor, er det mer relatert til DEADBEEF enn vi trodde vi gjorde.

Så kompilatoren/linkeren bestemte seg på en eller annen måte for å permanent blinke verdien av DEADBEEF til en FLASH -adresse, på stedet 0x8000018. Og så endret kompilatoren vår ovennevnte LDR -instruksjon til å være:

LDR R7, [PC, #8]

Det genererte til og med en kommentar for oss. Så fint. Og det forteller oss å ta gjeldende programtellerverdi (PC -registeret), legge til 0x8 til den verdien, og det er der DEADBEEF har blitt brent, og få den verdien og fylle den i R7.

Så det betyr også at programtelleren (PC) pekte på adressen 0x8000010, som er starten på main_loop, og at DEADBEEF -verdien sitter på to adresser etter slutten av main_loop.

Trinn 15: Til slutt, en kort titt på programkjøringen

Selv om du avslutter GDB, er det bare å skrive inn kommandoen på nytt. Du trenger ikke engang å gi den noen filer; vi blinker ikke lenger, bare kjører det.

Når du har koblet GDB-klienten til GDB-serveren på nytt, ved (gdb) ledeteksten:

(gdb) inforegistre

Du bør se noe slikt:

r0 0x0 0

r1 0x0 0 r2 0x0 0 r3 0x0 0 r4 0x0 0 r5 0x0 0 r6 0x0 0 r7 0x0 0 r8 0x0 0 r9 0x0 0 r10 0x0 0 r11 0x0 0 r12 0x0 0 sp 0x20014000 0x20014000 lr 0xffffffff 4294967295

Men så, ved (gdb) ledeteksten, skriv inn:

(gdb) fortsett

Og slo veldig raskt CTRL-C. Det bør stoppe programmet. Skriv inn "inforegister" -kommandoen igjen.

Denne gangen ser det annerledes ut:

(gdb) inforegistre

r0 0x350ffa 3477498 r1 0x0 0 r2 0x0 0 r3 0x0 0 r4 0x0 0 r5 0x0 0 r6 0x0 0 r7 0xdeadbeef 3735928559 r8 0x0 0 r9 0x0 0 r10 0x0 0 r11 0x0 0 r10 01010 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 16777216

Hva skjedde? Akkurat det vi ønsket. DEADBEEF ble lastet inn i R7, og R0 har steget (ekstremt raskt). Hvis du gjentar, ser du R0 igjen med en annen verdi.

Trinn 16: Vi ønsket å lage en skrivebeskyttet matrise i Flash

En måte å lage ekvivalenten til en matrise ved hjelp av samling og direktiver, er som følger:

.type myarray, %object // navnet eller etiketten 'myarray' er definert som en objekttype.

myarray: // dette er starten på erklæringen om 'myarray' // (hva den vil bestå av)..word 0x11111111 // det første medlemmet eller verdien i 'myarray'..word 0x22222222 // den andre verdien (sammenhengende adresser)..word 0x33333333 // og så videre..størrelse myarray,.-myarray // kompilatoren/montøren vet nå hvor slutten eller // grensen til 'myarray'.

Nå som vi har satt det opp i FLASH -minne, kan vi bruke det i programmet. Nedenfor er en del:

LDR R1, myarray // dette laster inn data som finnes på første plassering av 'myarray'. ' // dette er ikke det vi ønsker.

LDR R1, = myarray // dette laster inn selve plasseringsverdien (den første adressen), // ikke dataene.. // dette er det vi ønsker.

MOV R2, #0 // R2 holder en telling for å sikre at vi ikke går av

// slutten av matrisen. LDR R3, = myarrsize // R3 vil være ekvivalent med 'myarrsize'.

// R0 vil lagre dataene våre

main_loop:

LDR R0, [R1] // Last dataene pekt med R1 ('myarray') i R0. CMP R2, R3 // Er vi på grensen til matrisen? BEQ main_loop // Hvis vi er det, er vi ferdige, så vi vil bare sløyfe for alltid.

ADD R2, #1 // Ellers kan vi fortsette å gjenta gjennom array.

LEGG TIL R1, #4 // Legg til 4 for å registrere R1, så det peker riktig til neste

// adresse..

B main_loop // Sløyfe tilbake.

Videoen går gjennom alt dette, og det er en feil i den. Det er bra; det viser at det er viktig kjøre- og feilsøkingskode. Det viser et klassisk tilfelle av å gå utenfor enden av en matrise.

Anbefalt: