Talaan ng mga Nilalaman:

Bahagi 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo: 16 Hakbang
Bahagi 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo: 16 Hakbang

Video: Bahagi 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo: 16 Hakbang

Video: Bahagi 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo: 16 Hakbang
Video: Part 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo 2024, Hulyo
Anonim
Image
Image

Ang pokus ng Instructable na ito ay ang STM32 Nucleo micro-controller. Ang pagganyak para dito upang makalikha ng isang proyekto sa pagpupulong mula sa mga walang buto. Tutulungan kami nitong malalim na maunawaan at maunawaan ang proyekto ng MSP432 Launchpad (ang TI-RSLK) na naging paksa ng maraming Mga Tagubilin na.

Walang masyadong tulong sa online upang lumikha ng isang proyekto na lamang sa pagpupulong para sa MSP432, gamit ang Code Composer Studio. Hanggang ngayon nakakopya lang kami / nag-paste mula sa isang paunang proyekto ng pagpupulong. Ang diskarte na ito ay nagsilbi sa amin ng maayos.

Gayunpaman, ngayon, para sa Lab 7, nagkakaroon kami ng kaunting problema. O kahit papaano isang pansamantalang sinok. Ipinakikilala ng Lab 7 ang mga finite-state-machine, at ang unang bagay na nakasalamuha namin ay ang pangangailangan na lumikha at gumamit ng isang hanay ng mga halaga. Dahil ang kurso na TI ay pangunahing gumagamit ng C programming - hindi ito isang problema. Ngunit ang mga Instructionable na ito ay nakatuon sa pagpupulong, hindi sa C.

Dagdag dito, dahil ang array ay mga read-only na halaga, mainam na ilagay ito sa flash memory, hindi sa RAM.

Tila mayroong higit na maraming tulong sa online para sa mga proyekto sa pagpupulong gamit ang STM32 MCU, sa gayon, nagsisimula kami sa Instructable na ito, na may layunin na gamitin ang natutunan, upang mag-apply sa MSP432 at sa Code Composer Studio.

Sa daan patungo sa layuning iyon, makakakuha rin kami ng karanasan sa isa pa, sikat na micro-controller.

Hakbang 1: Paunang Pagsubok ng Device

Paunang Pagsubok ng Device
Paunang Pagsubok ng Device
Paunang Pagsubok ng Device
Paunang Pagsubok ng Device
Paunang Pagsubok ng Device
Paunang Pagsubok ng Device

Muli, bakit pumili ng partikular sa STM32 Nucleo?

Sa totoo lang? Sapagkat naghahanap ako ng magagandang artikulo sa mga proyekto na walang koryenteng pagpupulong para sa mga tagokontrol ng ARM, at nahanap ko ang seryeng ito. At dahil din sa ang STM32 ay tila isang tanyag na MCU.

Gumawa ako ng ilang pagsasaliksik (maraming mga bersyon na mapagpipilian - tingnan ang imahe sa itaas), ngunit sa huli ito ay naging kung ano talaga ang makukuha ko, dahil gagamitin ko ang Amazon (sa U. S.).

Dumating ito sa isang simple ngunit propesyonal na pakete, na may ilang mga tagubilin sa pagsisimula. Ito ay medyo nakakatawa upang makita na ang demo ay sinunog sa controller ay halos eksakto kung ano ang nagawa natin sa nakaraang Instructables - isang LED flashes at binabago ang bilis ayon sa pagpindot ng isang pindutan.

Tila ang development board na ito ay halos kapareho sa MSP432 na mayroong 2 LEDs, at isang push-button ng gumagamit. Ang MSP432 ay may 2 mga user-button.

Tulad ng nakikita mo sa mga larawan, medyo nagulat ako na ang board ay may mini at hindi isang micro USB. Kailangang maubusan upang bumili ng isang kurdon.

Ang isa pang mahusay na pagsubok ay kapag ikinonekta mo ito sa iyong computer (Gumagamit ako ng isang kahon sa Linux), makikita ito sa aking file manager, bilang isang file system, na tinawag na "NODE_F303RE". Pagbubukas na nagsisiwalat ng dalawang mga file, isang HTML at isang teksto.

Iyon lang, ngunit hindi bababa sa sinabi din nito na ang pagkakakonekta ay tila medyo madali.

Ngayon handa na kaming magsimula.

Susubukan kong hindi ulitin ang anuman sa magagandang impormasyon mula sa serye ng artikulo ng IVONOMICON Bare Metal, ngunit palakihin ito.

Hakbang 2: Ang Mga Mahahalaga

Ang unang bagay na kailangan namin ay isang tagatala.

At pagkatapos, kailangan namin ng isang debugger:

devchu @ chubox: ~ $ sudo apt-get install gdb-arm-none-eabiPagbasa ng mga listahan ng package… Tapos na sa Paggawa ng puno ng dependency ng puno Pagbasa ng impormasyon sa estado… Tapos na Ang mga sumusunod na BAGONG pakete ay mai-install: gdb-arm-none-eabi 0 na-upgrade, 1 bagong naka-install, 0 upang alisin at 8 ay hindi na-upgrade. Kailangang makakuha ng 2, 722 kB ng mga archive. Matapos ang operasyon na ito, 7, 738 kB ng karagdagang disk space ang gagamitin. Kunin: 1 https://us.archive.ubuntu.com/ubuntu xenial / uniberso amd64 gdb-arm-none-eabi amd64 7.10-1ubuntu3 + 9 [2, 722 kB] Kinuha ang 2, 722 kB sa 1s (1, 988 kB / s) Ang pagpili ng dating hindi napiling package gdb-arm-none-eabi. (Pagbasa ng database … 262428 mga file at direktoryo na kasalukuyang naka-install.) Paghahanda upang i-unpack … / gdb-arm-none-eabi_7.10-1ubuntu3 + 9_amd64.deb… Inaalis ang gdb-arm-none-eabi (7.10-1ubuntu3 + 9)… Pagproseso nag-trigger para sa man-db (2.7.5-1)… Pagse-set up ng gdb-arm-none-eabi (7.10-1ubuntu3 + 9)…

Hakbang 3: Ang Mga Mahahalaga - Windows

Ipinapalagay ng hakbang sa itaas na gumagamit kami ng Linux. Paano kung gumagamit kami ng Windows?

Maaari kang pumunta sa site ng arm Developer, at maraming magagamit na mga pagpipilian sa pag-download. Gumagamit ako ng isang makina ng Windows 8.

Sa panahon ng pag-install, pinili ko upang mai-install ito sa root na "C: \" drive sa halip na Program Files dahil lamang sa gumagamit ako ng cygwin, at mas madaling lumikha ng isang link mula sa aking lokal na bin sa isang root C: folder kaysa sa lahat ng gulo sa landas sa Program Files (na may mga puwang, atbp).

Kaya, ang aking kapaligiran sa cygwin at landas, atbp, ay ganito ang hitsura:

C: / cygwin64 / home / bin / arm-none-eabi-gcc, kung saan ang arm-none-eabi-gcc ay isang link sa C: / GNUToolsArmEmbedded / 7.2018.q2.update / bin / arm-none-eabi- gcc

Lumikha ako pagkatapos ng isang "dev" folder sa ilalim ng cygwin home, at doon ko inilagay ang core. S file at pinatakbo ang command ng compiler. (tingnan ang karagdagang ibaba sa ibaba para sa mga bagay-bagay sa compiler).

Ginawa ko ang eksaktong parehong bagay para sa gdb (arm-none-eabi-gdb).

Hakbang 4: Ano ang Mga Mahahalaga

Kaya ano ang "gcc-arm-none-eabi"?

Ang gnu compiler (GCC) ay mag-iipon ng mga wika ng programa (tulad ng C) sa katutubong code para sa makina na tumatakbo ito. Halimbawa, kung magsusulat ka ng ilang C code gamit ang GCC sa iyong Windows machine, itatayo ito upang tumakbo sa Windows machine. Ang nabuong naisakatuparan ay hindi (karaniwang) tatakbo sa ARM micro-controller.

Kaya, upang makabuo ng mga program na mai-download at masunog sa micro-controller ng ARM (sa kasalukuyan naming kaso na ang STM32 Nucelo), kailangan naming bigyan ang GCC ng iba pa: ang kakayahang "mag-cross-compile". Iyon ay, ang kakayahang makabuo ng isang maipapatupad, hindi para sa katutubong system (at processor), ngunit para sa target na system (ang ARM micro-controller). Doon nag-play ang "gcc-arm-none-eabi".

Kaya kung ano ano ang "gdb-arm-none-eabi"?

Kapag na-download at nasunog na (na-flash) namin ang bagong napatupad na maipapatupad sa micro-controller, malamang na gugustuhin naming i-debug ito - hakbang-hakbang sa pamamagitan ng linya ng code. Ang GDB ay ang gnu debugger, at ito rin, ay nangangailangan ng isang paraan upang magawa ang trabaho nito, ngunit ang pag-target sa ibang system.

Kaya, gdb-arm-none-eabi ay sa GDB, kung ano ang gcc-arm-none-eabi sa GCC.

Ang isa pang iminungkahing pag-install ng package ay ang "libnewlib-arm-none-eabi". Ano yun

Ang Newlib ay isang C library at library ng matematika na inilaan para magamit sa mga naka-embed na system. Ito ay isang pagsasama-sama ng maraming mga bahagi ng silid-aklatan, lahat sa ilalim ng mga libreng lisensya ng software na ginagawang madali silang magamit sa mga naka-embed na produkto.

At sa wakas, ang package na "libstdc ++ - arm-none-eabi". Halatang halata ng isang iyon; ito ay C ++ library para sa cross-compiler; para sa naka-embed na mga micro-Controller ng ARM.

Hakbang 5: Ang File ng Linker

Ang File ng Linker
Ang File ng Linker
Ang File ng Linker
Ang File ng Linker

Lumikha tayo ng isang script ng linker.

Ang isang pangunahing bahagi o bloke sa file na ito ay ang utos na MEMORY.

--- mula sa sourceware.org:

Pinapayagan ng default na pagsasaayos ng linker ang paglalaan ng lahat ng magagamit na memorya. Maaari mo itong i-override sa pamamagitan ng paggamit ng MEMORY command. Inilalarawan ng utos ng MEMORY ang lokasyon at laki ng mga bloke ng memorya sa target. Maaari mo itong gamitin upang ilarawan kung aling mga rehiyon ng memorya ang maaaring magamit ng linker, at kung aling mga rehiyon ng memorya ang dapat na iwasan. Maaari mo nang italaga ang mga seksyon sa mga partikular na rehiyon ng memorya. Itatakda ng linker ang mga address ng seksyon batay sa mga rehiyon ng memorya, at babalaan tungkol sa mga rehiyon na masyadong napuno. Ang linker ay hindi magbabago ng mga seksyon sa paligid upang magkasya sa mga magagamit na rehiyon. Ang isang linker script ay maaaring maglaman ng maraming mga paggamit ng utos ng MEMORY, gayunpaman, ang lahat ng mga bloke ng memorya na tinukoy ay itinuturing na parang tinukoy sa loob ng isang solong utos ng MEMORY. Ang syntax para sa MEMORY ay:

MEMORY

{pangalan [(attr)]: ORIGIN = pinagmulan, LENGTH = len…}

Ang halimbawa sa artikulo:

/ * Tukuyin ang pagtatapos ng RAM at limitasyon ng memorya ng stack * // * (4KB SRAM sa linya ng STM32F031x6, 4096 = 0x1000) * / / * (Ang RAM ay nagsisimula sa address na 0x20000000) _estack = 0x20001000;

MEMORY

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

Kaya kailangan nating malaman kung magkano ang FLASH (para sa aming programa at mga pare-pareho, atbp) at kung magkano ang RAM (para magamit ng programa; magbunton at mag-stack, atbp) para sa aming partikular na lupon. Medyo nakakainteres ito.

Ang magandang maliit na kard na kasama ng Nucleo ay nagsasabi na mayroon itong memorya ng flash ay 512 Kbytes, at ang SRAM ay 80 Kbytes. Gayunpaman, sa pagkonekta nito sa USB, nakakabit ito bilang isang file system na may dalawang mga file, at kapwa ang file manager at GParted ay nagpapahiwatig na mayroon itong higit sa 540+ Kbytes ng puwang. (RAM?).

NGUNIT, ang pagtatangka na tanggalin ang dalawang mga file gamit ang file manager, pagdidiskonekta pagkatapos ay muling pagkonekta sa aparato, ipinapakita pa rin ang dalawang mga file. (at may kinilala ang file manager dahil mayroong isang maliit na "lock" na icon sa bawat file.

Kaya't sumabay tayo sa mga numero sa card. Kaya ngayon kinukuha namin ang halimbawa sa itaas at nai-convert ito sa aming tukoy na board.

Maaaring gusto mong gumamit ng isang bagay tulad ng online memory converter na ito, upang pumunta mula sa pangkalahatang KB hanggang sa tukoy na bilang ng mga byte.

Pagkatapos ay baka gusto mong gumamit ng isang online decimal to hex converter.

/ * Tukuyin ang pagtatapos ng RAM at limitasyon ng memorya ng stack * /

/ * (4KB SRAM sa linya ng STM32F031x6, 4096 = 0x1000) * // * ang halimbawa * /

/ * hakbang 1: (80KB SRAM sa STM32F303RE, 81920 = 0x14000) * // * aming board * /

/ * hakbang 2, idagdag ang laki ng hex sa hex simula ng address (sa ibaba). * /

/ * (Nagsisimula ang RAM sa address na 0x20000000) * /

_estack = 0x20001000; /* ang halimbawa */

_estack = 0x20014000; / * aming board * /

MEMORY {

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

RAM (rxw): ORIGIN = 0x20000000, LENGTH = 80K

}

Tawagin natin ang file sa itaas na "linker.script.ld".

Hakbang 6: Ang Talaan ng Vector

Ang Talaan ng Vector
Ang Talaan ng Vector

Ngayon ay lilikha kami ng isang maliit na file ng pagpupulong (na may mga direktiba) upang makagawa ng napakahalagang paghawak sa paggambala. Susundan namin ang halimbawa ng artikulo at lilikha ng file na pinangalanang "core. S".

Muli, narito ang halimbawang mga nilalaman ng file, ngunit gumawa ako ng pagbabago para sa aming tukoy na board:

// Ang mga tagubiling ito ay tumutukoy sa mga katangian ng aming chip at

// ang wika ng pagpupulong na gagamitin namin:.syntax pinag-isa / * Tingnan sa ibaba pagkatapos ng area ng code na ito * / /*.cpu cortex-m0 * / / * bigyan ng puna ang linyang ito ng halimbawa * /.cpu cortex-m4 / * idagdag sa halip ang cortex ng aming board. tingnan ang imahe sa itaas sa hakbang na ito * / /*.fpu softvfp * / / * bigyan ng puna ang linyang ito ng halimbawa * /.fpu vfpv4 / * idagdag sa halip ang aming board; mayroon itong FPU * /.thumb // Mga pandaigdigang lokasyon ng memorya..global vtable.global reset_handler / * * Ang aktwal na talahanayan ng vector. * Ang laki lamang ng RAM at handler na 'reset' ang * kasama, para sa pagiging simple. * /.type vtable,% object vtable:.word _estack.word reset_handler.size vtable,.-vtable

Hmm.. Hindi '.align' Directive

Gayunpaman, hindi iyon kritikal. Higit pa sa na (siguro) sa paglaon.

Pinag-isang.syntax

.syntax [pinag-isa | hinati]

Itinatakda ng direktiba na ito ang Syntax ng Pagtuturo ng Pagtuturo tulad ng inilarawan sa seksyon ng ARM-Instruction-Set

9.4.2.1 Itakda ng Tagubilin sa Syntax Dalawang bahagyang magkakaibang mga syntax ang sinusuportahan para sa mga tagubilin sa ARM at THUMB. Ang default, nahahati, ay gumagamit ng lumang istilo kung saan ang mga tagubilin sa ARM at THUMB ay nagkaroon ng kanilang sariling, magkahiwalay na mga syntax. Ang bago, pinag-isang syntax, na maaaring mapili sa pamamagitan ng direksyong.syntax.

.fpu vfpv4

Ang tagatala ng GCC ay maaaring makabuo ng mga binary na may maraming mga pagpipilian tungkol sa lumulutang point: malambot - angkop para sa pagtakbo sa mga CPU na walang FPU - ang mga kalkulasyon ay ginagawa sa software ng bumubuo ng softfp ng compiler - angkop para sa pagtakbo sa CPU na mayroon o walang FPU - ay gagamit ng isang FPU kung mayroon. Para sa aming tukoy na kaso (kailangan mong gawin ang iyong sariling pagsasaliksik), ang FPU ng partikular na lupon na ito ay umaayon sa vfpv4. Maaari kang maglaro dito. O kahit iwanan ito sa softfp.

.thumb (kumpara sa.arm)

Ang mga ARM microcontroller na ito ay talagang may isang halo ng mga hanay ng pagtuturo. Ang isa ay ARM, isa pa ang THUMB. Ang isang pagkakaiba ay 16-bit na tagubilin kumpara sa 32-bit na mga tagubilin. Kaya, sinasabi ng direktiba na ito sa tagatala na gamutin ang kasunod na mga tagubilin bilang alinman sa THUMB o ARM.

Dadalhin na lamang namin ang natitirang file tulad ng mayroon dahil ang mga Instructionable na ito ay hindi pa nakaganyak sa pag-program ng interrupt-driven na pagpupulong.

Hakbang 7: Ang Bersyon ng Assembly ng isang 'Hello World' Program

Ang sumusunod ay maaari ring mapunta sa dati nang nilikha na "core. S" na file. Ito, muli, ay mula sa halimbawa sa artikulo.

/ * * Ang Handler ng Reset. Tinawag sa pag-reset. * /.type reset_handler,% function reset_handler: // Itakda ang stack pointer sa dulo ng stack. // Ang halagang '_estack' ay tinukoy sa aming script ng linker. LDR r0, = _estack MOV sp, r0

// Magtakda ng ilang mga halaga ng dummy. Kapag nakita natin ang mga halagang ito

// sa aming debugger, malalaman namin na ang aming programa // ay na-load sa maliit na tilad at gumagana. LDR r7, = 0xDEADBEEF MOVS r0, # 0 main_loop: // Magdagdag ng 1 upang irehistro ang 'r0'. ADDS r0, r0, # 1 // Loop back. B main_loop.sa laki ng reset_handler,.-Reset_handler

Kaya, ang tulak ng programa sa itaas ay upang mai-load ang isang makikilala na pattern sa isang pangunahing rehistro ng MCU (sa kasong ito R7), at isang pagtaas ng halaga na nagsisimula sa zero sa isa pang pangunahing rehistro ng MCU (sa kasong ito R0). Kung susundan namin ang pagpapatupad ng code, dapat nating makita ang pagtaas ng data ng R0.

Kung sumusunod ka kasama ang Mga Tagubilin hinggil sa MSP432 at kurso / lab na TI-RSLK, kung gayon halos lahat ng nabanggit na programa ay dapat pamilyar sa iyo.

Ang isang bagong bagay na nakikita ko ay ang paggamit ng "=" kapag naglo-load ng "DEADBEEF" sa pagrehistro ng R7. Hindi namin nagamit iyon.

Ang file na "core. S" na nakakabit dito ay naglalaman ng kumpletong mapagkukunan.

Hakbang 8: Pagbuo ng Code

Panahon na upang gumawa ng ilang mga bagay na command-line. Isang bagay na totoo, sa wakas.

Gayunpaman, hindi kami masyadong doon. Muli nating kailangang baguhin ang utos na ibinigay sa artikulo, at baguhin ito sa aming sariling sitwasyon.

Narito ang halimbawa ng code:

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

Kung pupunta kami sa site ng gnu.org para sa GCC, (sa kasong ito bersyon 7.3),

x

Ang -x ay upang tukuyin ang wika. Kung hindi man kung walang -x, susubukan ng tagatala na hulaan sa pamamagitan ng paggamit ng extension ng file. (sa aming kaso, *. S).

Ang halimbawa sa itaas mula sa artikulo ay tumutukoy sa assembler-with-cpp, ngunit maaari lamang kaming assembler.

c

Sinasabi ng -c na sumulat ngunit huwag mag-link.

O0

Ang -O ay upang itakda ang antas ng pag-optimize. Ang paggamit ng -O0 (oh-zero) ay nagsabing "bawasan ang oras ng pag-ipon at gawin ang pag-debug na magawa ang inaasahang mga resulta. Ito ang default".

mcpu = cortex-m0

Tinutukoy ng -mcpu ang pangalan ng target na processor. Sa aming kaso, ito ay magiging cortex-m4.

mthumb

Tinutukoy ng -mthumb ang pagpili sa pagitan ng pagbuo ng code na nagpapatupad ng mga estado ng ARM at THUMB.

Wall

Ang -Wall ay syempre napaka-pangkaraniwan at kilalang-kilala. Binuksan nito ang lahat ng mga watawat ng babala.

Sa wakas, sa pagtatapos ng utos mayroon kaming input file core. S at ang output file core.o.

Narito ang nagresultang bagong linya ng utos upang magkasya sa aming tukoy na kaso.

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

At pinagsama iyon.

Hakbang 9: Pag-uugnay sa Program

Direkta mula sa halimbawa sa artikulo, mayroon kami nito:

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

Karamihan sa nabanggit na nakita mo. Nasa ibaba ang bago.

-specs = nosys.specs

Ang isang ito ay medyo nakakalito upang ipaliwanag.

Ito ay may kinalaman sa "semihosting" at "retargeting", at ito ay may kinalaman sa input / output. Ito rin ay may kinalaman sa mga tawag sa system at aklatan.

Kadalasan, ang mga naka-embed na system ay hindi nagbibigay ng karaniwang mga aparato ng pag-input / output. Maaapektuhan nito ang mga tawag sa system o library (halimbawa: printf ()).

Ang ibig sabihin ng Semihosting ay ang debugger (tingnan ang Hakbang 11 na imahe na may bahagi ng debugger na bilugan sa pula) ay may isang espesyal na channel at ginagamit ang semihosting na protokol, at makikita mo ang output ng printf () sa host machine (sa pamamagitan ng debugger).

Ang retarget, sa kabilang banda, ay nangangahulugang ang magkatulad na mga tawag sa system o library na iyon ay nangangahulugang iba pa. Ginagawa nila ang iba pa, na may katuturan para sa naka-embed na system. Sa isang katuturan, sabihin para sa printf (), mayroong isang bagong pagpapatupad, isang retargeted pagpapatupad ng pagpapaandar na iyon.

Nasabi na ang lahat ng iyon, ang --specs = nosys.specs ay nangangahulugang hindi kami magiging semihosting. Karaniwan nang nangangahulugang nangangahulugan kami ng muling pag-target. Dadalhin tayo nito sa susunod na watawat.

nostdlib

Ang pagpipilian ng linker -nostdlib ay ginagamit upang mai-link ang isang programa na inilaan upang magpatakbo ng standalone. -Nostdlib nagpapahiwatig ng mga indibidwal na pagpipilian -nodefaultlibs at -nostartfiles. Sa ibaba tinatalakay namin ang dalawang mga pagpipilian nang magkahiwalay, ngunit ang pinaka-karaniwang paggamit ay nostdlib lamang para sa one-stop shopping. Kapag nag-uugnay sa isang naka-host na programa, ang mga karaniwang system library na tulad ng libc ay na-link sa pamamagitan ng default, na nagbibigay sa pag-access ng programa sa lahat ng mga karaniwang pag-andar (printf, strlen at mga kaibigan). Ang pagpipilian ng linker -nodefaultlibs ay hindi pinagana ang pag-link sa mga default na aklatan; ang naka-link lamang na mga aklatan ay eksaktong mga malinaw mong pangalan sa linker gamit ang -l flag.

lgcc

ang libgcc.a ay isang pamantayang aklatan na nagbibigay ng panloob na mga subroutine upang mapagtagumpayan ang mga pagkukulang ng mga partikular na makina. Halimbawa, ang ARM processor ay hindi nagsasama ng isang tagubilin sa dibisyon. Ang bersyon ng ARM ng libgcc.a ay nagsasama ng isang pag-andar ng dibisyon at ang tagatala ay nagpapalabas ng mga tawag sa pagpapaandar na iyon kung kinakailangan.

T

Ito ay isang paraan lamang upang masabihan ang linker na gamitin ang file na ito bilang script ng linker. Sa aming kaso, ang pangalan ng file ay linker.script.ld.

o main.elf

Sa wakas, sinabi namin sa linker kung ano ang magiging pangalan ng pangwakas na file ng imahe ng output na susunugin / mai-flash sa aming aparato.

Narito ang aming bersyon ng kumpletong linya ng utos, binago para sa aming tukoy na sitwasyon:

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

Tinitiyak namin na ang file ng script, at ang file ng core.o, ay pareho sa parehong direktoryo, kung saan tatakbo namin ang linya ng utos sa itaas.

At nag-uugnay ito nang walang mga problema.

Isang Suriin

Pagkatapos ay tumakbo kami:

arm-none-eabi-nm main.elf

at nakukuha namin:

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

Mukhang okay. Ang utos ng arm-none-eabi-nm ay isang paraan upang ilista ang mga simbolo sa loob ng mga file ng object.

Hakbang 10: Pagsubok ng Koneksyon sa STM32 Nucleo-64

Pagsubok Koneksyon sa STM32 Nucleo-64
Pagsubok Koneksyon sa STM32 Nucleo-64
Pagsubok Koneksyon sa STM32 Nucleo-64
Pagsubok Koneksyon sa STM32 Nucleo-64

Ang iyong unang misyon, kung pipiliin mong tanggapin ito, ay upang makita ang iyong system na makita ang iyong development board.

Paggamit ng Windows

Para sa Windows, nagpasya akong i-install ang TrueSTUDIO mula sa Atollic (libreng bersyon). Ito ay isang walang sakit na pag-install at awtomatiko nitong na-install ang driver upang magamit ko ang st-link upang subukan ang koneksyon. Kapag na-install ko ang TrueSTUDIO at nakita ng manager ng aparato ang aparato, na-download ko ang mga tool ng texan / stlink na iminungkahi ng artikulong Bare Metal na sinusundan namin. Inilagay ko muli ang folder nang direkta sa ilalim ng "C: \", at muling lumikha ng ilang mga link mula sa aking lokal na cygwin home bin sa mga utos.

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

Bilang isang paunang pagsubok upang makita kung maaari ba kaming makipag-usap sa aparato, tumakbo ako:

st-info --probe

At nakabalik:

Natagpuan ang 1 stlink programmer

Kaya ngayon alam namin na maaari naming makipag-usap / magtanong sa aming development board.

Gamit ang Linux

Para sa linux, hindi mo talaga kailangan ng driver. Ngunit para kay Debian, kakailanganin mong buuin ang mga tool mula sa mapagkukunan.

git clone

Tiyaking mayroon kang naka-install na libusb-1.0-0-dev.

apt na listahan | grep -E "* libusb. * dev *"

Dapat mong makita ang:

libusb-1.0-0-dev / xenial, ngayon 2: 1.0.20-1 amd64 [na-install]

o isang bagay na tulad nito

Upang mai-install ito:

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

Tandaan na ang nasa itaas ay hindi pareho ng:

sudo apt-get install libusb-dev

Ang tamang nawawalang libusb dev ay maaaring maging sanhi ng pagkakaroon ng mga isyu sa cmake.

CMake Error: Ang mga sumusunod na variable ay ginagamit sa proyektong ito, ngunit itinakda ito sa NOTFOUND. Mangyaring itakda ang mga ito o tiyakin na ang mga ito ay naitakda at nasubok nang tama sa mga file ng CMake: LIBUSB_INCLUDE_DIR (ADVANCED)

Baguhin ang direktoryo ng ugat ng proyekto (… blah / blah / stlink). Gumawa ng isang "make release".

Pagkatapos na magtayo, ang mga tool ay dapat na nasa ilalim ng ".. / build / Release".

Maaari mo nang patakbuhin ang "st-info --probe". Narito ang output sa konektado sa Nucleo, pagkatapos ay hindi.

devchu @ chubox: ~ / Development / stlink $./ build/Release/st-info --probeFound 1 mga programmer ng stlink na serial: 303636414646353034393535363537 openocd: "\ x30 / x36 / x36 / x41 / x46 / x46 / x35 / x30 / x34 / x39 / x35 / x35 / x36 / x35 / x37 "flash: 524288 (pagesize: 2048) sram: 65536 chipid: 0x0446 describes: F303 high density device devchu @ chubox: ~ / Development / stlink $./ build/Release/st- impormasyon --probe Natagpuan 0 stlink programmer devchu @ chubox: ~ / Development / stlink $

Hakbang 11: Gumamit Tayo ng GDB Sa Linux

Gumamit Tayo ng GDB Sa Linux
Gumamit Tayo ng GDB Sa Linux
Gumamit Tayo ng GDB Sa Linux
Gumamit Tayo ng GDB Sa Linux

Kung sinusubukan mo ang lahat ng ito, at nakakuha ka ng hanggang dito - mahusay! Napakahusay Medyo masaya tayo ngayon.

Kapag binili mo ang mga ARM development board na ito, maging ang MSP432 Launchpad mula sa Texas Instruments, o ang isang ito na tinatalakay natin ngayon, ang Nucleo-F303 (STM32 Nucleo-64), karaniwang dumating sila na na-flash na may isang tumatakbo na programa, karaniwang ilang mga blinky na programa na nagsasama rin ng pagpindot sa isang switch upang baguhin ang rate kung saan ang (mga) flash ng LED.

Bago tayo masyadong mabilis na labis na maisulat iyon, tingnan natin kung ano ang dapat makita at gawin.

Sa Linux, buksan ang isang terminal, baguhin ang direktoryo ng proyekto ng stlink git na itinayo lamang namin, at hanapin ang tool na st-util.

devchu @ chubox: ~ / Development / stlink $ find. -pangalan ng st-util

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

Patakbuhin ang tool na iyon. Dahil nasubukan na namin dati ang aming koneksyon sa st-info --probe, dapat kaming makakuha ng ilang output tulad nito:

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

st-util 1.4.0-50-g7fafee2 2018-10-20T18: 33: 23 INFO common.c: Naglo-load ang mga parameter ng aparato…. 2018-10-20T18: 33: 23 INFO karaniwang.c: Ang aparato ay konektado ay: F303 mataas na density na aparato, id 0x10036446 2018-10-20T18: 33: 23 INFO karaniwang.c: Laki ng SRAM: 0x10000 bytes (64 KiB), Flash: 0x80000 bytes (512 KiB) sa mga pahina ng 2048 bytes 2018-10-20T18: 33: 23 INFO gdb-server.c: Ang Chip ID ay 00000446, ang Core ID ay 2ba01477. 2018-10-20T18: 33: 23 INFO gdb-server.c: Pakikinig sa *: 4242…

Iyon ang GDB server na tumatakbo ngayon, at nakikita nito ang aming development board, at higit sa lahat, nakikinig ito sa port 4242 (ang default port).

Handa na kaming sunugin ang kliyente ng GDB.

Sa Linux, buksan ang ibang terminal, ipasok ito:

arm-none-eabi-gdb -tui

Katulad lamang iyon ng pagpapatakbo ng gdb mahigpit na command-line, subalit gumagawa ito ng isang terminal na batay sa teksto (ang hula ko ay gumagamit ito ng mga sumpa).

Mayroon kaming tatakbo na GDB client at GDB server. Gayunpaman, ang client ay hindi konektado sa server. Sa ngayon wala itong nalalaman tungkol sa aming Nucleo (o board na iyong pinili). Kailangan nating sabihin ito. Sa terminal, ang iyong prompt ay dapat na ngayon ang "(gdb)". Ipasok:

target ng tulong

Bibigyan ka nito ng isang listahan. Pansinin na ang nais namin ay target na pinalawig-remote - Gumamit ng isang remote computer sa pamamagitan ng isang serial line.

Ngunit kailangan din nating bigyan ito ng lokasyon. Kaya, sa prompt (gdb), ipasok ang:

(gdb) target na pinalawig-remote na localhost: 4242

Dapat kang makakuha ng isang tugon tulad nito:

(gdb) target na pinalawig-remote na localhost: 4242

Remote na pag-debug gamit ang localhost: 4242 0x080028e4 sa ?? ()

Samantala, sa terminal na nagpapatakbo ng st-util gdbserver, nakuha namin ito:

2018-10-20T18: 42: 30 INFO gdb-server.c: Natagpuan 6 na rehistro ng breakpoint

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

Hakbang 12: Ulitin Natin, Sa Windows at Flash Ang aming Program

Ulitin Natin, Sa Windows at Flash Ang aming Program
Ulitin Natin, Sa Windows at Flash Ang aming Program
Ulitin Natin, Sa Windows at Flash Ang aming Program
Ulitin Natin, Sa Windows at Flash Ang aming Program
Ulitin Natin, Sa Windows at Flash Ang aming Program
Ulitin Natin, Sa Windows at Flash Ang aming Program

Ang mga hakbang sa pagpapatakbo ng st-util gdbserver, at ang arm-none-eabi-gdb client ay mahalagang katulad ng ginawa namin noong nakaraang Hakbang. Buksan mo ang dalawang mga terminal (cygwin, DOS cmd, o Windows Powershell), hanapin ang lokasyon ng st-util, patakbuhin ito. Sa kabilang terminal, patakbuhin ang arm-none-eabi-gdb client. Ang pagkakaiba lamang ay ang mode na -tui (view ng teksto batay sa terminal) na malamang na hindi suportado.

Kung ang nasa itaas ay nagtrabaho sa Windows, malamang na kailangan mong ihinto (ang kliyente lamang). Sa puntong ito, kahit papaano kakailanganin mong patakbuhin ang GDB client kung saan ang iyong build file ay ("core.out"), o idagdag ang buong landas sa file na iyon bilang isang argument sa GDB client.

Pinasimple ko ang aking buhay sa pamamagitan ng paggamit ng cygwin at paglikha ng mga link mula sa aking lokal na $ HOME // bin direktoryo kung saan naninirahan ang parehong mga tool na iyon.

Ok, pinagsama-sama at na-link namin tulad ng dati, at mayroon kaming pangunahing file. Handa kaming mai-flash.

Mayroon kaming st-util na tumatakbo sa isang window. Sinimulan namin muli ang kliyente ng GDB, sa pagkakataong ito ay ginagawa namin:

arm-none-eabi-gdb main.elf

Hinahayaan namin itong magsimula, maghintay para sa prompt (gdb), gawin ang aming parehong utos ng koneksyon sa GDB server (st-util), at handa kaming i-flash ang maipapatupad. Napaka-anti-klimatiko:

(gdb) load

Tumatakbo sa mga terminal ng cygwin, mayroong isang kilalang isyu na may mga oras na mga utos ng console na hindi lumabas. Kaya't sa aming kaso, ang window na tumatakbo sa server ay tahimik na tuluyan. Ang nagpapatakbo ng kliyente, kung saan pinatakbo namin ang pagkarga, i-output ito:

Naglo-load ang seksyon.text, laki 0x1c lma 0x8000000Simulan ang address 0x8000000, laki ng pag-load 28 Rate ng paglipat: 1 KB / sec, 28 bytes / magsulat.

Hakbang 13: Flashing Sa Linux - Higit na Gantimpala: D

Flashing With Linux - Higit na Gantimpala: D
Flashing With Linux - Higit na Gantimpala: D

Hakbang 14: Sumisid Tayo ng Mas Malalim

Kung nakarating ka dito, mahusay. Ituloy na natin.

Bakit hindi tumingin sa loob ng main.elf na file, ang maipapatupad? Patakbuhin ang sumusunod:

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

Dapat mong makita ang isang output ng isang bagay tulad nito:

main.elf: format ng file elf32-littlearm

Pag-disassemble ng seksyon.text:

08000000:

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

08000008:

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

08000010:

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

Anong maliliit na nugget ang maaari nating makuha mula sa output sa itaas?

Kung naalala mo pabalik kapag tinatalakay namin at nilikha ang linker.script.ld file, nakasaad namin na ang mga ARM device na ito ay may RAM na nagsisimula sa 0x20000000, at ang memorya ng FLASH ay nagsisimula sa 0x08000000.

Kaya, maaari nating makita na sa katunayan ang programa ay tulad ng lahat ng ito ay naninirahan sa memorya ng FLASH.

Pagkatapos, sa itaas, ngunit sa paglaon ng Hakbang, nang pinag-uusapan namin ang bahaging "Hello World", mayroong isang pahayag kung saan naglo-load kami ng isang agaran, pare-pareho, literal na halaga ("0xDEADBEEF") sa isang pangunahing rehistro ng MCU ("R7").

Ang pahayag ay:

LDR R7, = 0xDEADBEEF

Sa aming code, iyon lamang ang lugar kung saan binabanggit namin ang DEADBEEF. Wala saan pa. Gayunpaman, kung titingnan mo ang nasa itaas na disassembled / reconstructed na mga tagubilin, atbp, mas maraming nauugnay doon sa DEADBEEF kaysa sa naisip namin na ginawa namin.

Kaya, nagpasya ang tagatala / linker na permanenteng i-flash ang halaga ng DEADBEEF sa isang FLASH address, sa lokasyon na 0x8000018. At pagkatapos, binago ng tagatala ang aming tagubilin sa itaas ng LDR na:

LDR R7, [PC, # 8]

Bumuo pa ito ng isang komento para sa amin. Magaling. At sinasabi nito sa amin na kunin ang kasalukuyang halaga ng counter ng programa (ang pagrehistro sa PC), idagdag ang 0x8 sa halagang iyon, at doon nasunog ang DEADBEEF, at kunin ang halagang iyon at ilagay ito sa R7.

Kaya't nangangahulugan din ito na ang program counter (PC) ay tumuturo sa address na 0x8000010, na kung saan ay ang simula ng main_loop, at ang halaga ng DEADBEEF ay nakaupo sa dalawang mga address pagkatapos ng pagtatapos ng main_loop.

Hakbang 15: Panghuli, isang Maikling Pagtingin sa Pagpapatakbo ng Program

Kahit na umalis ka sa GDB, muling ipasok ang utos. Hindi mo rin kailangang bigyan ito ng anumang file; hindi na kami kumikislap, tumatakbo lang ito.

Kapag nakakonekta mo ulit ang GDB client sa GDB server, sa prompt ng (gdb) na utos:

(gdb) mga rehistro ng impormasyon

Dapat mong makita ang isang bagay tulad nito:

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 429800678x 0x0ff 0x0ff 429800678x 0

Ngunit pagkatapos, sa (gdb) prompt, ipasok ang:

(gdb) magpatuloy

At napakabilis na tumama sa CTRL-C. Dapat i-pause iyon sa programa. Ipasok muli ang utos na "mga rehistro ng impormasyon."

Sa oras na ito, iba ang hitsura nito:

(gdb) rehistro ng impormasyon

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 r12 0x0 0ffxxff 0x200ff 16777216

Anong nangyari? Eksakto kung ano ang gusto namin. Ang DEADBEEF ay na-load sa R7, at ang R0 ay (napakabilis) na nagdaragdag. Kung uulitin, makikita mo muli ang R0 na may isa pang halaga.

Hakbang 16: Nais naming Lumikha ng isang Read-Only Array sa Flash

Ang isang paraan upang likhain ang katumbas ng isang array na gumagamit ng pagpupulong at mga direktiba, ay ang mga sumusunod:

.type myarray,% object // ang pangalan o label na 'myarray' ay tinukoy bilang isang uri ng object.

myarray: // ito ang simula ng pagdedeklara ng 'myarray' // (kung ano ang lalagyan nito)..word 0x11111111 // ang unang kasapi o halagang nilalaman sa 'myarray'..word 0x22222222 // ang pangalawang halaga (magkadikit na mga address)..word 0x33333333 // at iba pa..size myarray,.-myarray // alam ng tagatala / assembler ngayon kung saan ang katapusan o // hangganan ng 'myarray'.

Ngayon na na-set up namin ito sa memorya ng FLASH, maaari natin itong magamit sa programa. Nasa ibaba ang isang bahagi:

Ang LDR R1, myarray // naglo-load ang data na nilalaman sa unang lokasyon ng 'myarray'. ' // hindi ito ang gusto namin.

LDR R1, = myarray // na-load ang mismong halaga ng lokasyon (ang ika-1 address), // not the data.. // IT IS what we want.

Ang MOV R2, # 0 // R2 ay magpapanatili ng bilang upang matiyak na hindi kami naglalakad

// pagtatapos ng array. Ang LDR R3, = myarrsize // R3 ay magiging katumbas ng 'myarrsize'.

// Hawak ng R0 ang aming data

main_loop:

LDR R0, [R1] // I-load ang data na itinuro ni R1 ('myarray') sa R0. CMP R2, R3 // Nasa limitasyon ba tayo ng array? BEQ main_loop // Kung tayo ay tapos na, kaya't loop na lang tayo magpakailanman.

ADD R2, # 1 // Kung hindi man, mapapanatili natin ang pag-ulit sa pamamagitan ng array.

ADD R1, # 4 // Magdagdag ng 4 upang irehistro ang R1, kaya't tumuturo ito nang tama sa susunod

// address..

B main_loop // Loop back.

Dumaan ang video sa lahat ng ito, at mayroong isang bug dito. Mabuti ito; ipinapakita nito na mahalaga ang run at debug code. Ipinapakita nito ang isang klasikong kaso ng paglalakad sa dulo ng isang array.

Inirerekumendang: