Obsah:

Část 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab Lab 7 STM32 Nucleo: 16 Steps
Část 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab Lab 7 STM32 Nucleo: 16 Steps

Video: Část 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab Lab 7 STM32 Nucleo: 16 Steps

Video: Část 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab Lab 7 STM32 Nucleo: 16 Steps
Video: Part 3 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Array FLASH Memory 2024, Listopad
Anonim
Image
Image

Tento návod je zaměřen na mikrořadič STM32 Nucleo. Motivace k tomu, abychom mohli vytvořit montážní projekt z holých kostí. To nám pomůže ponořit se hlouběji a porozumět projektu MSP432 Launchpad (TI-RSLK), který byl již tématem několika Instructables.

K vytvoření projektu pouze pro sestavení pro MSP432 pomocí Code Composer Studio moc online pomoci není. Až dosud jsme pouze kopírovali/vkládali z již existujícího projektu montáže. Tento přístup nám dobře sloužil.

Nyní jsme však pro laboratoř 7 narazili na trochu problém. Nebo alespoň dočasná škytavka. Lab 7 představuje stroje s konečným stavem a první, s čím se setkáváme, je potřeba vytvořit a použít řadu hodnot. Vzhledem k tomu, že kurz TI využívá hlavně programování C - není to problém. Ale tyto Instructables se zaměřily na montáž, ne C.

Dále, protože pole má hodnoty pouze pro čtení, bylo by dobré jej umístit do paměti flash, nikoli do paměti RAM.

Zdá se, že online je mnohem více nápovědy pro montážní projekty pomocí MCU STM32, takže začneme tímto Instructable, s cílem použít to, co jsme se naučili, a poté použít na MSP432 a Code Composer Studio.

Na cestě k tomuto cíli získáme také zkušenosti s dalším, populárním mikrořadičem.

Krok 1: Počáteční test zařízení

Počáteční test zařízení
Počáteční test zařízení
Počáteční test zařízení
Počáteční test zařízení
Počáteční test zařízení
Počáteční test zařízení

Opět, proč si vybrat konkrétně STM32 Nucleo?

Upřímně řečeno? Protože jsem hledal dobré články o projektech montáže holých kovů pro řadiče ARM a narazil jsem na tuto sérii. A také proto, že se zdá, že STM32 je populární MCU.

Udělal jsem nějaký průzkum (na výběr je spousta verzí - viz obrázek výše), ale nakonec se ukázalo, co vlastně můžu získat, protože jsem používal Amazon (v USA).

Dodává se v jednoduchém, ale profesionálním balení s několika pokyny pro spuštění. Bylo trochu zábavné sledovat, že demo vypálené do ovladače bylo téměř přesně to, co jsme udělali v minulých Instructables - LED bliká a mění rychlost podle stisknutí tlačítka.

Zdá se, že tato vývojová deska je velmi podobná MSP432 v tom, že jsou zde 2 LED diody a jedno uživatelské tlačítko. MSP432 má 2 uživatelská tlačítka.

Jak vidíte na fotkách, trochu mě zarazilo, že deska má mini a ne micro USB. Musel dojít koupit kabel.

Dalším dobrým testem je, že když jej připojíte k počítači (používám Linux), zobrazí se v mém správci souborů jako souborový systém s názvem „NODE_F303RE“. Otevření, které odhalí dva soubory, jeden HTML a jeden text.

To je ono, ale alespoň to také říká, že konektivita se zdá být docela snadná.

Nyní jsme připraveni začít.

Pokusím se neopakovat žádné dobré informace ze série článků IVONOMICON Bare Metal, ale spíše je rozšířit.

Krok 2: Základní informace

První věc, kterou potřebujeme, je kompilátor.

A pak potřebujeme debugger:

devchu@chubox: ~ $ sudo apt-get install gdb-arm-none-eabiČtení seznamů balíčků … Hotovo Budování stromu závislostí Čtení informací o stavu … Hotovo Budou nainstalovány následující NOVÉ balíčky: gdb-arm-none-eabi 0 upgradováno, 1 nově nainstalováno, 0 k odebrání a 8 není aktualizováno. Potřebujete získat 2 722 kB archivů. Po této operaci bude použito 7 738 kB dalšího místa na disku. Získejte: 1 https://us.archive.ubuntu.com/ubuntu xenial/universe amd64 gdb-arm-none-eabi amd64 7.10-1ubuntu3+9 [2, 722 kB] Načteno 2, 722 kB za 1 s (1, 988 kB/s) Výběr dříve nevybraného balíčku gdb-arm-none-eabi. (Čtení databáze… aktuálně nainstalováno 262428 souborů a adresářů.) Příprava na rozbalení…/gdb-arm-none-eabi_7.10-1ubuntu3+9_amd64.deb… Rozbalení gdb-arm-none-eabi (7.10-1ubuntu3+9)… zpracování spouští pro man-db (2.7.5-1)… Nastavení gdb-arm-none-eabi (7.10-1ubuntu3+9)…

Krok 3: The Essentials - Windows

Výše uvedený krok předpokládal, že používáme Linux. Co když používáme Windows?

Můžete přejít na web Arm Developer a je k dispozici několik možností stahování. Používám počítač s Windows 8.

Během instalace jsem se rozhodl nainstalovat ji na kořenovou jednotku „C: \“místo na Program Files pouze proto, že také používám cygwin, a bylo snazší vytvořit odkaz z mého místního koše na kořenovou složku C: než všechny nepořádek v cestě k programovým souborům (s mezerami atd.).

Moje prostředí a cesta cygwin atd. Tedy vypadá takto:

C: / cygwin64 / home / bin / arm-none-eabi-gcc, kde arm-none-eabi-gcc je odkaz na C: / GNUToolsArmEmbedded / 7.2018.q2.update / bin / arm-none-eabi- gcc.

Poté jsem vytvořil složku „dev“pod domovskou stránkou cygwin, a tam jsem umístil soubor core. S a spustil příkaz kompilátoru. (viz dále níže o kompilátoru).

Přesně to samé jsem udělal pro gdb (arm-none-eabi-gdb).

Krok 4: Jaké jsou základy

Co je tedy „gcc-arm-none-eabi“?

Kompilátor GNU (GCC) zkompiluje programovací jazyky (jako C) do nativního kódu pro stroj, na kterém běží. Pokud byste například zkompilovali nějaký kód C pomocí GCC na počítači se systémem Windows, byl by postaven tak, aby fungoval na počítači se systémem Windows. Vygenerovaný spustitelný soubor nebude (obvykle) spuštěn na mikrokontroléru ARM.

Abychom tedy mohli vytvářet programy ke stažení a vypálení do mikrokontroléru ARM (v našem současném případě by to byl STM32 Nucelo), musíme dát GCC něco jiného: schopnost „cross-compile“. To znamená schopnost generovat spustitelný soubor, nikoli pro jeho nativní systém (a procesor), ale pro cílový systém (mikrokontrolér ARM). Tam vstupuje do hry „gcc-arm-none-eabi“.

Co je tedy „gdb-arm-none-eabi“?

Jakmile stáhneme a vypálíme (flashujeme) nově generovaný spustitelný soubor do mikrořadiče, pravděpodobně ho budeme chtít ladit-procházet řádek po řádku kódu. GDB je gnu debugger a také potřebuje způsob, jak dělat svou práci, ale cílení na jiný systém.

Gdb-arm-none-eabi je tedy pro GDB, co je gcc-arm-none-eabi pro GCC.

Další doporučenou instalací balíčku bylo „libnewlib-arm-none-eabi“. Co je to?

Newlib je knihovna C a matematická knihovna určená pro použití ve vestavěných systémech. Je to konglomerace několika knihovních částí, vše pod licencemi svobodného softwaru, které je činí snadno použitelnými na vestavěných produktech.

A nakonec balíček „libstdc ++-arm-none-eabi“. Ten je docela zřejmý; je to knihovna C ++ pro křížový překladač; pro vestavěné mikrokontroléry ARM.

Krok 5: Soubor Linker

Soubor Linker
Soubor Linker
Soubor Linker
Soubor Linker

Pojďme vytvořit skript linkeru.

Jednou klíčovou částí nebo blokem v tomto souboru by byl příkaz MEMORY.

--- ze sourceware.org:

Výchozí konfigurace linkeru umožňuje přidělení veškeré dostupné paměti. Toto můžete přepsat pomocí příkazu MEMORY. Příkaz MEMORY popisuje umístění a velikost bloků paměti v cíli. Můžete jej použít k popisu, které oblasti paměti může linker použít a kterým oblastem paměti se musí vyhnout. Poté můžete přiřadit sekce konkrétním oblastem paměti. Linker nastaví adresy sekcí na základě oblastí paměti a upozorní na oblasti, které jsou příliš plné. Linker nebude míchat sekce, aby se vešel do dostupných oblastí. Skript linkeru může obsahovat mnoho použití příkazu MEMORY, ale se všemi definovanými bloky paměti se zachází, jako by byly zadány v rámci jednoho příkazu MEMORY. Syntaxe pro MEMORY je:

PAMĚŤ

{name [(attr)]: ORIGIN = origin, LENGTH = len…}

Příklad v článku:

/* Definujte konec RAM a limit zásobníku paměti* //* (4KB SRAM na řádku STM32F031x6, 4096 = 0x1000)*//* (RAM začíná na adrese 0x20000000) _estack = 0x20001000;

PAMĚŤ

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

Musíme tedy zjistit, kolik FLASH (pro náš program a konstanty atd.) A kolik RAM (pro použití programem; halda a zásobník atd.) Pro naši konkrétní desku. Tohle začíná být trochu zajímavé.

Pěkná malá karta, která je součástí Nucleo, říká, že má flash paměť 512 kB a SRAM je 80 kB. Po připojení k USB se však připojí jako souborový systém se dvěma soubory a správce souborů i GParted naznačují, že má více než 540+ kB prostoru. (RAM?).

ALE, pokus o odstranění dvou souborů pomocí správce souborů, odpojení a opětovné připojení zařízení, stále zobrazuje dva soubory. (a správce souborů něco rozpoznal, protože na každém souboru je malá ikona „zámku“.

Pojďme tedy k obrázkům na kartě. Nyní tedy vezmeme výše uvedený příklad a převedeme jej na naši konkrétní desku.

Chcete -li přejít z obecné KB na konkrétní počet bajtů, můžete použít něco jako tento online převaděč paměti.

Pak možná budete chtít použít online převodník desetinných míst na hex.

/ * Definujte konec RAM a limit zásobníku paměti */

/* (4KB SRAM na řádku STM32F031x6, 4096 = 0x1000)* //* příklad*/

/ * krok 1: (80 kB SRAM na STM32F303RE, 81920 = 0x14000) * // * naše deska */

/* krok 2, přidejte hexadecimální velikost na hexadecimální počáteční adresu (níže). */

/ * (RAM začíná na adrese 0x20000000) */

_estack = 0x20001000; /* příklad */

_estack = 0x20014000; / * naše rada */

PAMĚŤ {

FLASH (rx): PŮVOD = 0x08000000, DÉLKA = 512K

RAM (rxw): PŮVOD = 0x20000000, DÉLKA = 80K

}

Nazvěme výše uvedený soubor „linker.script.ld“.

Krok 6: Vektorová tabulka

Vektorový stůl
Vektorový stůl

Nyní vytvoříme malý soubor sestavy (se směrnicemi), abychom provedli některé velmi základní zpracování přerušení. Budeme následovat příklad článku a vytvoříme soubor s názvem „core. S“.

Opět zde je příklad obsahu souboru, ale provedl jsem změnu pro naši konkrétní desku:

// Tyto pokyny definují atributy našeho čipu a

// jazyk sestavení, který použijeme:.syntax sjednocený /*Viz níže za touto oblastí kódu* //*.cpu cortex-m0* / /*okomentujte tento řádek příkladu* /.cpu cortex-m4 /* místo toho přidejte kůru naší desky. viz výše uvedený obrázek v tomto kroku * / /*.fpu softwarfp * / / *okomentujte tento řádek příkladu * /.fpu vfpv4 / *přidejte místo toho naši desku; má FPU */.thumb // umístění globální paměti..global vtable.global reset_handler / * * Skutečná vektorová tabulka. * Pro jednoduchost je zahrnuta pouze velikost paměti RAM a obslužný program pro reset. */.typ vtable, %objekt vtable:.word _estack.word reset_handler.size vtable,.-vtable

Hmm.. Žádná směrnice „.align“

To však není kritické. Více o tom (možná) později.

.syntax sjednocený

.syntax [jednotný | rozdělený]

Tato směrnice nastavuje syntaxi instrukční sady, jak je popsáno v části ARM-instrukční sada

9.4.2.1 Syntaxe instrukční sady Pro instrukce ARM a THUMB jsou podporovány dvě mírně odlišné syntaxe. Výchozí, rozdělený, používá starý styl, kde instrukce ARM a THUMB měly své vlastní, oddělené syntaxe. Nová, sjednocená syntaxe, kterou lze vybrat pomocí směrnice.syntax.

.fpu vfpv4

Kompilátor GCC může vytvářet binární soubory s několika možnostmi, které se týkají plovoucí desetinné čárky: soft - vhodné pro běh na CPU bez FPU - výpočty se provádějí v softwaru pomocí kompilátoru generovaného softfp - vhodné pro běh na CPU s FPU nebo bez FPU - bude používat FPU, pokud je k dispozici. Pro náš konkrétní případ (budete si muset udělat vlastní průzkum), FPU této konkrétní desky odpovídá vfpv4. Možná si s tím budete muset pohrát. Nebo to dokonce nechte na softfp.

.thumb (vs..arm)

Tyto mikrokontroléry ARM ve skutečnosti obsahují kombinaci instrukčních sad. Jedním z nich je ARM, druhým je PALEC. Jedním rozdílem jsou 16bitové instrukce a 32bitové instrukce. Tato směrnice tedy říká kompilátoru, aby s následnými instrukcemi zacházel jako s THUMB nebo ARM.

Vezmeme zbytek souboru tak, jak je, protože tyto Instructables se ještě neponořily do programování sestavování řízeného přerušením.

Krok 7: Verze sestavení programu „Hello World“

Do dříve vytvořeného souboru „core. S“lze také přejít. To je opět z příkladu v článku.

/ * * Obsluha resetování. Voláno při resetu. */.type reset_handler, %funkce reset_handler: // Nastaví ukazatel zásobníku na konec zásobníku. // Hodnota '_estack' je definována v našem skriptu linkeru. LDR r0, = _estack MOV sp, r0

// Nastavte nějaké hodnoty figuríny. Když vidíme tyto hodnoty

// v našem debuggeru budeme vědět, že náš program // je načten na čipu a funguje. LDR r7, = 0xDEADBEEF MOVS r0, #0 main_loop: // Přidejte 1 k registraci 'r0'. PŘIDÁ r0, r0, #1 // Smyčka zpět. B main_loop.size reset_handler,.-Reset_handler

Tahem výše uvedeného programu je načíst rozpoznatelný vzor do jednoho jádrového registru MCU (v tomto případě R7) a přírůstkovou hodnotu začínající na nule do jiného jádrového registru MCU (v tomto případě R0). Pokud projdeme prováděcím kódem, měli bychom vidět přírůstek dat R0.

Pokud jste sledovali instrukce týkající se kurzů/laboratoří MSP432 a TI-RSLK, pak by vám měl být známý téměř celý výše uvedený program.

Jedna nová věc, kterou vidím, je použití "=" při načítání "DEADBEEF" do registru R7. To jsme nepoužili.

Zde připojený soubor "core. S" nyní obsahuje kompletní zdroj.

Krok 8: Kompilace kódu

Je čas udělat nějaké věci z příkazového řádku. Konečně něco skutečného.

Nejsme tam však úplně. Znovu musíme vyladit příkaz uvedený v článku a upravit ho podle vlastní situace.

Zde je ukázkový kód:

arm -none -eabi -gcc -x assembler -with -cpp -c -O0 -mcpu = cortex -m0 -mthumb -Wall core. S -o core.o

Pokud přejdeme na web gnu.org pro GCC (v tomto případě verze 7.3),

X

-X je určit jazyk. Jinak pokud ne -x, kompilátor se pokusí uhodnout pomocí přípony souboru. (v našem případě *. S).

Výše uvedený příklad z článku určuje assembler-with-cpp, ale mohli bychom jen provést assembler.

C

-C říká „zkompilovat, ale nepropojit.

O0

-O je nastavení úrovně optimalizace. Použití -O0 (oh -nula) říká "zkrátit čas kompilace a zajistit, aby ladění přineslo očekávané výsledky. Toto je výchozí nastavení".

mcpu = kůra-m0

-Mcpu určuje název cílového procesoru. V našem případě by to byl cortex-m4.

mumbál

-Mthumb Určuje výběr mezi generováním kódu, který spouští stavy ARM a THUMB.

Stěna

-Stěna je samozřejmě velmi běžná a známá. Zapne všechny varovné příznaky.

Nakonec na konci příkazu máme vstupní soubor core. S a výstupní soubor core.o.

Zde je výsledný nový příkazový řádek, který odpovídá našemu konkrétnímu případu.

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

A to sestaveno.

Krok 9: Propojení programu

Přímo z příkladu v článku máme toto:

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

Většinu z výše uvedených jste viděli. Níže je uvedeno, co je nového.

specs = nosys.specs

Tohle je trochu složité vysvětlit.

Souvisí to s „semihostingem“a „retargetingem“a souvisí to se vstupem / výstupem. Souvisí to také se systémovými voláními a knihovnami.

Integrované systémy obvykle neposkytují standardní vstupní/výstupní zařízení. To by ovlivnilo volání systému nebo knihovny (příklad: printf ()).

Semihosting znamená, že debugger (viz obrázek kroku 11 s částí ladicího programu zakroužkovanou červeně) má speciální kanál a používá semihostingový protokol a výstup printf () můžete vidět na hostitelském počítači (prostřednictvím debuggeru).

Retargeting na druhé straně znamená, že stejná volání systému nebo knihovny znamenají něco jiného. Dělají něco jiného, což má pro vestavěný systém smysl. V jistém smyslu, řekněme pro printf (), existuje nová implementace, retargeted implementace této funkce.

Když jsme to všechno řekli, --specs = nosys.specs znamená, že nebudeme semihosting. To by normálně znamenalo, že se znovu zaměříme. Tím se dostáváme k další vlajce.

nostdlib

Volba linkeru -nostdlib slouží k propojení programu určeného ke spuštění samostatně. -nostdlib implikuje jednotlivé možnosti -nodefaultlibs a -nostartfiles. Níže diskutujeme dvě možnosti samostatně, ale nejtypičtějším použitím je pouze nostdlib pro nákupy na jednom místě. Při propojení hostovaného programu jsou standardně propojeny standardní systémové knihovny, jako je libc, což programu poskytuje přístup ke všem standardním funkcím (printf, strlen a přátelé). Volba linkeru -nodefaultlibs zakáže propojení s těmito výchozími knihovnami; jediné propojené knihovny jsou přesně ty, které explicitně pojmenujete pomocí linkeru -l.

lgcc

libgcc.a je standardní knihovna, která poskytuje interní podprogramy k překonání nedostatků konkrétních strojů. Procesor ARM například neobsahuje instrukci rozdělení. ARM verze libgcc.a obsahuje funkci rozdělení a kompilátor v případě potřeby vysílá volání této funkce.

T

Toto je jen způsob, jak říct linkeru, aby použil tento soubor jako skript linkeru. V našem případě je název souboru linker.script.ld.

o main.elf

Nakonec řekneme linkeru, jaký bude název konečného výstupního obrazového souboru, který bude vypálen/flashován do našeho zařízení.

Zde je naše verze kompletního příkazového řádku, upravená pro naši konkrétní situaci:

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

Zajistíme, aby soubor skriptu a soubor core.o byly ve stejném adresáři, kde spustíme výše uvedený příkazový řádek.

A propojuje se bez problémů.

Kontrola

Poté spustíme:

arm-none-eabi-nm main.elf

a získáme:

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

Vypadá dobře. Příkaz arm-none-eabi-nm je způsob, jak vypsat symboly v souborech objektů.

Krok 10: Testování připojení k STM32 Nucleo-64

TestingConnection k STM32 Nucleo-64
TestingConnection k STM32 Nucleo-64
TestingConnection k STM32 Nucleo-64
TestingConnection k STM32 Nucleo-64

Vaše první mise, pokud se ji rozhodnete přijmout, je přimět váš systém, aby viděl vaši vývojovou desku.

Používání systému Windows

Pro Windows jsem se rozhodl nainstalovat TrueSTUDIO z Atollic (bezplatná verze). Byla to bezbolestná instalace a automaticky nainstaloval ovladač, takže jsem mohl použít st-link k testování připojení. Jakmile jsem nainstaloval TrueSTUDIO a správce zařízení viděl zařízení, stáhl jsem si nástroje texan/stlink navržené v článku Bare Metal, který jsme sledovali. Složku jsem znovu umístil přímo pod „C: \“a znovu vytvořil několik odkazů z mého místního domovského koše cygwin na příkazy.

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

Jako počáteční test, abychom zjistili, zda můžeme se zařízením skutečně komunikovat, jsem spustil:

st-info-sonda

A vrátil se:

Nalezeno 1 stlink programátorů

Takže teď víme, že můžeme mluvit/dotazovat se na naši vývojovou desku.

Používání Linuxu

U linuxu ovladač opravdu nepotřebujete. Ale pro Debian budete muset vytvořit první nástroje ze zdroje.

klon git

Ujistěte se, že máte nainstalované libusb-1.0-0-dev.

výstižný seznam | grep -E "*libusb.*dev*"

Měl bys vidět:

libusb-1.0-0-dev/xenial, nyní 2: 1.0.20-1 amd64 [nainstalováno]

nebo něco takového.

Chcete -li jej nainstalovat:

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

Všimněte si, že výše uvedené není stejné jako:

sudo apt-get install libusb-dev

Správně chybějící libusb dev může způsobit problémy s cmake.

Chyba CMake: V tomto projektu jsou použity následující proměnné, ale jsou nastaveny na NOTFOUND. Nastavte je prosím nebo se ujistěte, že jsou správně nastaveny a testovány v souborech CMake: LIBUSB_INCLUDE_DIR (ADVANCED)

Přejděte do kořenového adresáře projektu (… blah /blah /stlink). Proveďte „uvolnění“.

Poté, co se vytvoří, by nástroje měly být pod „.. /build /Release“.

Poté můžete spustit „st-info --probe“. Zde je výstup s připojeným Nucleo, pak ne.

devchu@chubox: ~/Development/stlink $./build/Release/st-info --probeFound 1 stlink programmers serial: 303636414646353034393535363537 openocd: "\ x30 / x36 / x36 / x41 / x46 / x46 / x35 / x30 / x34 / x39 / x35 / x35 / x36 / x35 / x37 "flash: 524288 (velikost stránky: 2048) sram: 65536 chipid: 0x0446 descr: F303 zařízení s vysokou hustotou devchu@chubox: ~/Development/stlink $./build/Release/st- info --probe Found 0 stlink programmers devchu@chubox: ~/Development/stlink $

Krok 11: Pojďme použít GDB s Linuxem

Pojďme použít GDB s Linuxem
Pojďme použít GDB s Linuxem
Pojďme použít GDB s Linuxem
Pojďme použít GDB s Linuxem

Pokud jste to všechno zkoušeli a dostali jste se tak daleko - skvělé! Vynikající. Pojďme se teď trochu pobavit.

Když si koupíte tyto vývojové desky ARM, ať už jsou to MSP432 Launchpad od Texas Instruments, nebo tento, o kterém nyní diskutujeme, Nucleo-F303 (STM32 Nucleo-64), obvykle dorazí již s běžícím programem, obvykle nějaký blinky program, který také zahrnuje stisknutí spínače pro změnu rychlosti, jakou LED (y) blikají.

Než to tak rychle přepíšeme, pojďme se podívat, co je k vidění a dělat.

V systému Linux otevřete terminál, změňte adresář projektu stlink git, který jsme právě vytvořili, a najděte nástroj st-util.

devchu@chubox: ~/Development/stlink $ find. -název st-util

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

Spusťte ten nástroj. Protože jsme již dříve testovali naše spojení se st-info --probe, měli bychom získat nějaký výstup takto:

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

st-util 1.4.0-50-g7fafee2 2018-10-20T18: 33: 23 INFO společné.c: Načítání parametrů zařízení…. 2018-10-20T18: 33: 23 INFO common.c: Připojené zařízení je: F303 zařízení s vysokou hustotou, id 0x10036446 2018-10-20T18: 33: 23 INFO common.c: Velikost SRAM: 0x10000 bytů (64 KiB), Flash: 0x80000 bytů (512 KiB) na stránkách 2048 bytů 2018-10-20T18: 33: 23 INFO gdb-server.c: ID čipu je 00000446, ID jádra je 2ba01477. 2018-10-20T18: 33: 23 INFO gdb-server.c: Poslech v *: 4242…

To je nyní spuštěný server GDB, který vidí naši vývojovou desku, a co je důležitější, poslouchá na portu 4242 (výchozí port).

Nyní jsme připraveni spustit klienta GDB.

V Linuxu otevřete jiný terminál a zadejte toto:

arm-none-eabi-gdb -tui

To je stejné jako běh příkazového řádku gdb, ale místo toho produkuje textový terminál (hádám, že používá kletby).

Máme spuštěného klienta GDB a server GDB. Klient však není připojen k serveru. V tuto chvíli neví nic o našem Nucleu (nebo desce podle vašeho výběru). Musíme to říct. V terminálu by nyní měla být vaše výzva „(gdb)“. Zadejte:

pomocný cíl

Poskytne vám seznam. Všimněte si, že ten, který chceme, je target extended -remote - Použijte vzdálený počítač přes sériovou linku.

Musíme mu ale také určit umístění. Na výzvu (gdb) tedy zadejte:

(gdb) cíl rozšířený vzdálený localhost: 4242

Měli byste dostat zpět odpověď asi takto:

(gdb) cíl rozšířený vzdálený localhost: 4242

Vzdálené ladění pomocí localhost: 4242 0x080028e4 in ?? ()

Mezitím jsme na terminálu, na kterém běží std-util gdbserver, dostali toto:

2018-10-20T18: 42: 30 INFO gdb-server.c: Nalezeno 6 registrů zarážek hw

2018-10-20T18: 42: 30 INFO gdb-server.c: GDB připojeno.

Krok 12: Opakujme, s Windows a Flash náš program

Zopakujme si, s Windows a Flash náš program
Zopakujme si, s Windows a Flash náš program
Zopakujme si, s Windows a Flash náš program
Zopakujme si, s Windows a Flash náš program
Zopakujme si, s Windows a Flash náš program
Zopakujme si, s Windows a Flash náš program

Kroky ke spuštění serveru st-util gdbserver a klienta arm-none-eabi-gdb jsou v podstatě stejné jako v předchozím kroku. Otevřete dva terminály (cygwin, DOS cmd nebo Windows Powershell), najděte umístění st-util a spusťte jej. Na druhém terminálu spusťte klienta arm-none-eabi-gdb. Jediným rozdílem je, že režim -tui (zobrazení textu založené na terminálu) s největší pravděpodobností není podporován.

Pokud výše uvedené fungovalo v systému Windows, pravděpodobně budete muset přestat (pouze klient). V tomto okamžiku nějak budete muset spustit klienta GDB, kde je váš soubor sestavení („core.out“), nebo přidat celou cestu k tomuto souboru jako argument pro klienta GDB.

Zjednodušil jsem si život pomocí cygwin a vytvářením odkazů z místního adresáře $ HOME // bin, kde oba tyto nástroje sídlí.

Dobře, zkompilovali jsme a propojili stejně jako dříve a máme soubor main.elf připraven k použití.

V jednom okně běží st-util. Znovu spustíme klienta GDB, tentokrát děláme:

arm-none-eabi-gdb main.elf

Necháme jej spustit, počkáme na výzvu (gdb), provedeme stejný příkaz připojení k serveru GDB (st-util) a jsme připraveni spustit spustitelný soubor. Je to velmi protiklimatické:

(gdb) zatížení

Při běhu s terminály cygwin existuje známý problém s tím, že se příkazy konzoly někdy nezobrazují. V našem případě tedy bylo okno běžící na serveru zcela tiché. Ten, na kterém je spuštěn klient, kde jsme spustili zatížení, vydá toto:

Načítání sekce.text, velikost 0x1c lma 0x8000000 Startovní adresa 0x8000000, velikost načtení 28 Přenosová rychlost: 1 KB/s, 28 bajtů/zápis.

Krok 13: Bliká s Linuxem - více odměn: D

Bliká s Linuxem - více odměn: D
Bliká s Linuxem - více odměn: D

Krok 14: Ponořme se trochu hlouběji

Pokud jste se dostali až sem, skvělé. Pokračujme.

Proč se nepodíváte dovnitř spustitelného souboru main.elf? Spusťte následující:

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

Měli byste vidět výstup něco takového:

main.elf: formát souboru elf32-littlearm

Demontáž oddílu.text:

08000000:

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

08000008:

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

08000010:

8000010: 3001 přidá r0, #1 8000012: e7fd b.n 8000010 8000014: 20014000.word 0x20014000 8000018: mrtvé hovězí maso.word 0xdeadbeef

Jaké malé nugety můžeme získat z výše uvedeného výstupu?

Pokud si pamatujete, když jsme diskutovali a vytvářeli soubor linker.script.ld, uvedli jsme, že tato zařízení ARM mají RAM od 0x20000000 a že paměť FLASH začíná od 0x08000000.

Můžeme tedy vidět, že program je skutečně takový, že je celý umístěn v paměti FLASH.

Poté, nahoře, ale v pozdějším kroku, když jsme rozebírali část „Hello World“, došlo k prohlášení, kde jsme do registru jádra MCU („R7“) nahráli okamžitou, konstantní, doslovnou hodnotu („0xDEADBEEF“).

Prohlášení bylo:

LDR R7, = 0xDEADBEEF

V našem kódu je to jediné místo, kde dokonce zmiňujeme DEADBEEF. Nikde jinde. A přesto, když se podíváte na výše uvedené rozebrané/zrekonstruované pokyny atd., Tam je toho souvisejícího s DEADBEEF víc, než jsme si mysleli.

Kompilátor/linker se tedy nějak rozhodl trvale blikat hodnotou DEADBEEF na adresu FLASH v místě 0x8000018. A poté kompilátor změnil naši výše uvedenou instrukci LDR na:

LDR R7, [PC, #8]

Dokonce nám to vygenerovalo komentář. Jak milé. A říká nám, abychom vzali aktuální hodnotu čítače programu (registr PC), přičetli k této hodnotě 0x8, a to je místo, kde byl vypálen DEADBEEF, abychom tuto hodnotu získali a nacpali do R7.

To tedy také znamená, že programový čítač (PC) směřoval na adresu 0x8000010, což je začátek main_loop, a že hodnota DEADBEEF sedí na dvou adresách po skončení main_loop.

Krok 15: Nakonec se krátce podívejte na spuštěný program

I když ukončíte GDB, zadejte příkaz znovu. Dokonce mu nemusíte dávat žádný soubor; už neblikáme, jen to spouštíme.

Jakmile znovu připojíte klienta GDB k serveru GDB, na příkazovém řádku (gdb):

(gdb) informační registry

Měli byste vidět něco takového:

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 0x90008000

Ale pak na výzvu (gdb) zadejte:

(gdb) pokračovat

A velmi rychle stiskněte CTRL-C. To by mělo pozastavit program. Znovu zadejte příkaz „informační registry“.

Tentokrát to vypadá jinak:

(gdb) informační registry

r0 0x350ffa 3477498 r1 0x0 0 r2 0x0 0r0 0ff 16777216

Co se stalo? Přesně to, co jsme chtěli. DEADBEEF byl načten do R7 a R0 se (extrémně rychle) zvyšoval. Pokud budete opakovat, uvidíte znovu R0 s jinou hodnotou.

Krok 16: Chtěli jsme ve Flashi vytvořit pole jen pro čtení

Jeden způsob, jak vytvořit ekvivalent pole pomocí sestavení a směrnic, je následující:

.type myarray, %object // název nebo popisek 'myarray' je definován jako typ objektu.

myarray: // toto je začátek deklarace 'myarray' // (z čeho se bude skládat)..word 0x11111111 // první člen nebo hodnota obsažená v 'myarray'..word 0x22222222 // druhá hodnota (souvislé adresy)..word 0x33333333 // a tak dále..size myarray,.-myarray // kompilátor/assembler nyní ví, kde je konec nebo // hranice 'myarray'.

Nyní, když jsme jej nastavili v paměti FLASH, můžeme jej použít v programu. Níže je část:

LDR R1, myarray // načte data obsažená v 1. místě 'myarray'. ' // tohle nechceme.

LDR R1, = myarray // toto načte samotnou hodnotu umístění (1. adresa), // ne data.. // toto JE TO, co chceme.

MOV R2, #0 // R2 bude počítat, abychom se ujistili, že neodejdeme

// konec pole. LDR R3, = myarrsize // R3 bude ekvivalentem 'myarrsize'.

// R0 bude uchovávat naše data

hlavní_smyčka:

LDR R0, [R1] // Načtěte data, na která ukazuje R1 ('myarray'), do R0. CMP R2, R3 // Jsme na hranici pole? BEQ main_loop // Pokud jsme, skončili jsme, takže se budeme navždy opakovat.

ADD R2, #1 // Jinak můžeme iterovat přes pole.

PŘIDAT R1, #4 // Přidejte 4 pro registraci R1, aby správně směřovalo na další

// adresa..

B main_loop // Smyčka zpět.

Video tím vším prochází a je v něm chyba. Je to dobré; ukazuje, že je důležité spustit a ladit kód. Ukazuje klasický případ odchodu z konce pole.

Doporučuje: