Mbed IDE je veliko lažje uporabljati s paleto ARM MCU-jev (vključno z ARM-napravami podjetja STM) kot STM32CubeIDE. Mbed IDE vsebuje podporne pakete ugnezdene programske opreme, torej knjižnice, ki jih je napisal (ali za) Mbed. Ti paketi ugnezdene programske opreme so prilagojeni delu z eno od razvojnih plošč, ki jih podpira Mbed. Te podporne knjižnice so do neke mere pregledne (in skrite) končnemu uporabniku. Ko delate na Mbed projektu, boste videli ikono zobnika z zeleno krožno puščico v njem. V tej mapi ni izvornih datotek. Namesto tega je bila ta ugnezdena programska oprema vnaprej pripravljena za vas, Mbed pa nudi dokumentacijo o njihovem API-ju, ki obravnava vse različne funkcije.
To je glavna podporna programska oprema za ploščo, ki ste jo določili. Poleg tega lahko v svoj projekt uvozite tudi dodatne knjižnice – samo z desno miškino tipko kliknite svoj projekt in izberite »Uvozi knjižnico« -> »iz čarovnika za uvoz«. Tam lahko določite knjižnice po imenu (tj. “ADS1015” za uporabo ADS1015 ADC Analog Devices). Lahko vnesete tudi »BSP«, ki bo prikazal različne »pakete za podporo plošče« za podprte MCU-je. Za izbrane STM Discovery plošče, ki vsebujejo TFT zaslone občutljive na dotik, obstajata tudi knjižnici “LCD” in “TS”, ki ju lahko najdemo z uporabo teh oznak. Kombinacija takih knjižnic bo včasih vse, kar boste potrebovali. Vendar bi vas moral opozoriti, da bo povsem možno, da bodo takšne knjižnice in z njimi povezani primeri delovali samostojno, vendar ne, če jih kombinirate z drugimi knjižnicami / primeri, zasnovanimi za druge periferne bloke, ki jih vsebuje isti MCU.
Ta vsebina je samo za naročnike
V preteklem članku sem na kratko opisal, kako deluje CubeMX orodje. V ta namen lahko CubeMX orodju naročite, da nastavi vse zunanje naprave na privzeto konfiguracijo. Če to storite, potem uporabite zavihek Pinout (v modrem meniju Pins and Configuration) in izberite možnost “clear pinouts”. To vam bo omogočilo, da izberete samo periferne bloke, ki jih želite konfigurirati, in ne da bi vam orodje za generiranje kode konfiguriralo vse vgrajene periferne naprave, saj bo to ustvarilo veliko dodatne kode.
Rad bi opisal datoteke, ki jih CubeMX orodje ustvari po končani konfiguraciji želenih zunanjih blokov. Najprej je treba omeniti, da je ustvarjenih več različnih datotek, nekaterih pa ne bi nujno odkrili sami. Pričakovali bi, da bo nekaj te konfiguracijske kode postavljene v datoteko main.c. Na koncu “main.c” boste našli rutine, ki vsebujejo imena funkcij, kot sledi:
MX_XXXX_Init (void), kjer je XXXX zunanja oprema, kot so GPIO, TIM, UART itd. To konfiguracijsko kodo bi morali za vsako zunanjo napravo, ki ste jo konfigurirali, postaviti na konec “main.c” datoteke. Prav tako potrebujete stavek prototipa funkcije na vrhu datoteke “main.c” v razdelku programa “/ * Zasebni prototipi funkcij —— * /”.Koda v teh konfiguracijskih rutinah je v dveh oblikah:
- čista koda, ki nastavi konfiguracijo dejanskega registra,
- Definicija strukture, kjer je opredeljenih veliko perifernih parametrov. Dejanska konfiguracija fizičnega registra je narejena drugje, z uporabo “ročaja” (angl. »handle«) te strukture.
Če želite uporabiti te rutine, ki jih izvajate, morate v “main.c” datoteko vključiti stavek v istem odseku kode, kjer deklarirate svoje spremenljivke. Primer tega bi za SPI blok bil videti tako:
SPI_HandleTypeDef hspi2; // tukaj konfiguriram SPI2
V STM32 kodi predpona »h« imena spremenljivke na splošno pomeni, da gre za »ročaj«. Morda mislite, da bi zgoraj opisana Init rutina zadostovala za konfiguracijo izbranega perifernega bloka. Ni tako! Obstaja še ena, ki je v obliki:
HAL_XXX_MspInit( *handle)
kjer je XXX zamenjan imenom periferije, kot SPI.
“* Ročaj” je, kjer se uporablja zgoraj omenjena hspi2 spremenljivka ročaja (in jo je treba v zgornji rutini vnesti kot “& hspi2”). “Ročaj” kaže na strukturo, ki definira vse potrebne periferne parametre (kot tudi na rutino, ki te parametre naloži v MCU registre).
“HAL_XXX_Mspinit” funkcije generira CubeMX orodjein se ne nahajajo v “main.c” datoteki, ki jo generira (kjer se ostale inicializacijske datoteke nahajajo). Namesto tega boste te “Mspinit” funkcije našli v “stm32F4xx_hal_msp.c” datoteki (ali F7, če uporabljate MCU ARM7). Ko pa te funkcije prenesete v Mbed, jih lahko postavite v “main.c” skupaj z drugimi funkcijami inicializacije.
Smo že končali? Ne, ne še. Vse zunanje naprave uporabljajo vhodno / izhodne priključke in vsak priključek GPIO vrat mora biti posebej konfiguriran za pripadajoči periferni blok. GPIO vrata zahtevajo tudi uro. Zato morate vključiti inicializacijsko rutino za reševanje teh dveh težav. To funkcijo najdete v “main.c” datoteki, ki jo ustvari CubeMX orodje, imenovano:
MX_GPIO_Init(void)
Torej bi to funkcijo skupaj z vsemi ostalimi dodali proti koncu “main.c” datoteke vašega Mbed programa. Ne pozabite, da potrebujete izjavo prototipa funkcije, kot je navedeno zgoraj. Seznam 1 prikazuje primer rutine – ta konfigurira samo 2 GPIO priključka!
In končno, če ste katerokoli periferno napravo konfigurirali tako, da ima sposobnost generiranja prekinitev, bodo generirane »škrbine« (angl. »stubs«) oziroma prazne rutine za tako imenovane prekinitvene rutine (ISR – interrupt service routine), ki jim v C programskem jeziku rečemo rutine povratnih klicev (angl. »Callback«). Nahajale se bodo v »stm32f7xx_it.c datoteki (f7 se nanaša na ARM družino mikrokontrolerjev, ki sem jo uporabljal). Ko omogočite funkcijo prekinitve za periferno enoto, CubeMX generira vektorsko tabelo prekinitev s kazalci na te »škrbine« v “stm32f7xx_it.c” datoteki.
Na začetku kode morate poklicati dve inicializacijski rutini za vsako zunanjo napravo, ki ste jo konfigurirali, plus GPIO inicializacijsko rutino, ki jo je ustvaril CubeMX. HAL sem omenil v eni od rutin. HAL pomeni Hardware Abstraction Layer in je nekaj, kar STM uporablja v knjižnicah gonilnikov za vse svoje ARM MCU-je. Pomen tega je, da so vse zgoraj omenjene rutinske konfiguracijske zasnove zasnovane tako, da delujejo z obsežnim naborom gonilnih rutin, ki jih STM dobavlja v HAL formatu.
Preprosto povedano, pisanje HAL gonilnika pomeni, da ga razbijete na dva dela:
- Odsek, ki posebej deluje s strojno opremo, ki jo najdete v določenem MCU.
- Odsek, ki dejanje, ki ga poskušate izvesti, pretvori v generično obliko, ki jo lahko vnesete v zgornji odsek 1).
Prednost uporabe arhitekture HAL je, da lahko na splošno napišete en odsek 2) za celo družino MCU-jev in morate prilagoditi le odsek 1) za vsak določen MCU. To STM-u prihrani veliko časa za pisanje gonilnikov za vse njihove številne ARM MCU-je. Glavna pomanjkljivost gonilnikov, ki temeljijo na HAL, je ta, da se običajno izvajajo počasneje kot gonilniki, ki so posebej napisani za določen MCU.
Mbed IDE deluje z gonilniki, ki temeljijo na HM STM, zato lahko pri konfiguriranju zunanjega bloka s CubeMX orodjem pokličete STM HAL API rutine za delo s to določeno zunanjo napravo. Pravzaprav večina Mbed API-jev sama pokliče STM-ove HAL rutine.
Omeniti moram, da STM ponuja tudi drugačen nabor rutin za gonilnike – tiste nizko nivojske (LL) namreč. Te rutine neposredno vplivajo na ARM MCU registre, ne da bi uvedli plast abstrakcije strojne opreme. Kot rezultat bi ponavadi to pomenilo hitrejše rutine, vendar so veliko bolj povezani z arhitekturo določenega MCU, za katerega so bile napisane. To pomeni, da niste mogli sprejeti takšne knjižnične rutine, ki je bila napisana za MCU F4, in pričakovati, da bo delovala z MCU F7.
Zadnja oblika Mbed knjižnic, ki jo bom omenil, so BSP knjižnice. BSP je kratica za Board Support Package. Na primer, za ‘F746NG-Discovery ploščo je na voljo BSP_DISCO_F746NG paket. Ta knjižnična mapa bo na splošno vsebovala gonilnike za različne zunanje naprave, ki so na plošči, ne pa tudi v samih MCU-jih. V primeru ‘F746 Discovery plošče obstajajo gonilniki za kodek, QSPI Flash, krmilnik, ki se nahaja na LCD zaslonu, in krmilnik zaslona občutljivega na dotik. Najboljši način za pridobitev teh BSP knjižnic je, da z desno miškino tipko kliknete svoj projekt, izberete “import library-> from import wizard” in v iskalno polje vnesete “BSP”. Nato izberite tiste, ki se uporabljajo. Tu je bolje, da plošče ne navedete v iskalnem polju, saj iskalnik ni podoben Googlu – na primer ne bo našel ničesar, če vnesete nekaj posebnega, kot je »F746 BSP«.
Morda mislite, da so BSP knjižnice, značilne za to ploščo, najobsežnejše knjižnice, ki so vam na voljo v Mbedu, vendar ni tako. Poleg tega obstajata knjižnici z oznakama LCD_DISCO_F746NG in TS_DISCO_F746NG za obdelavo rutin na višjem nivoju za LCD in zaslon na dotik. Obstajajo tudi knjižnice za obdelavo rutin na višji ravni za dve različni Codek napravi na ‘F746 in’ F469 ploščah, na katere se sklicujem v tej seriji člankov (na primer F746_SAI_IO). Tudi tu je bolje, da v iskalno polje “čarovnika za uvoz -> iz čarovnika za uvoz” vnesete široko definicijo, namesto da bi poskušali zožiti iskanje na svojo ploščo, saj bolje ločite, kaj želite od generičnega iskanja, kot ga ponudi Mbed iskalnik, če zožite iskalne kriterije. Preveč se navajamo na odlične Googlove rezultate iskanja, se vam ne zdi?
Prikaz Bitmap-ovin 16 Mbyte QSPI Flash pomnilnik
Oglejmo si nekaj, kar bi vas utegnilo zanimati pri uporabi ene od dveh Discovery plošč, omenjenih v tej seriji člankov. Ker sem jih kupil z zaslonom občutljivim na dotik, je ena od očitnih zahtev lahko tudi uporaba bitnih slik kot dela grafičnega uporabniškega vmesnika (GUI).
Še nikoli prej nisem uporabljal razvojne plošče, ki bi imela toliko pomnilnika (RAM in Flash). ST32F469NI-Disco razvojna plošča vsebuje 128 MB Flash NOR pomnilnika, kar pomeni 16 megabajtov x 8 bitov. Gre za QSPI napravo – uporablja SPI serijski protokol, vendar ima podatkovno vodilo s širino 4 bite. Zato je kar hitra. Prvič sem jo poskusil uporabiti, ko sem se ukvarjal z bitnimi slikami za zaslon občutljiv na dotik. Ločljivost zaslona 800 x 480 slikovnih pik in dejstvo, da podpira 24-bitno barvno globino pomeni, da bo bitna slika katere koli velikosti zavzela veliko pomnilnika. Kvadratna bitna slika s stranico 10 mm na primer zasede približno 30 K Flash pomnilnika. Takšne bitne slike lahko shranite na nekaj različnih načinov:
- V polju konstant (const array) v C programskem jeziku, ki je vključeno v vaš program.
- Shranjeno v QSPI Flash pomnilniku.
- Na uSD kartici, priključeni na vtičnico na obeh ploščah.
Ko sem začel delati z bitnimi slikami za ta zaslon, sem najprej preizkusil 1. način. Zaslon razvojne plošče F469 uporablja 24-bitno barvno globino, zato sem moral najti bitno sliko, ki je bila v tem formatu. STM-ov paket ugnezdene programske opreme za CubeF4 vsebuje veliko primerov / demo programov in hitro iskanje .BMP datotek v tej mapi je dalo nekaj primernih bitnih slik. Nato morate BMP datoteko, ki je binarna datoteka, pretvoriti v dolg seznam šestnajstiških vrednosti, da se sestavi “C” matrika. Uporabil sem spletni pretvornik na naslednji spletni strani:
https://littlevgl.com/image-to-c-array
Nastala izhodna datoteka bo vsebovala nekaj informacij o glavi, ki jih morate izbrisati, ter nekaj vrstic na koncu, ki jih je treba odstraniti. Nato morate pred dolg seznam šestnajstiških števil postaviti naslednje:
const uint8_t Image [] = {
in
}; v zadnjo vrstico.
V tem primeru je ime spremenljivke polja »Image«, vendar je to lahko kar koli želite. Ko uporabljate spletno Mbed razvojno orodje, je te podatke najlažje dodati v program tako, da z desno miškino tipko kliknete mapo programa in izberete »dodaj datoteko«. Dajte mu smiselno ime (ki se ujema z zgornjo vrstico glave) in uporabite razširitev “.h”. Nato kopirajte matriko, ki ste jo pravkar pripravili, v odložišče in jo prilepite v to prazno datoteko. Na koncu morate na začetek programa dodati #include “filename.h” (pri čemer je ime datoteke tisto ime, ki ste ga dali tej matriki .h).
Ob predpostavki, da že imate kodo za konfiguracijo LCD zaslona in lahko počistite zaslon, napišete besedilo itd., vse kar potrebujete za prikaz bitne slike, bi uporabili naslednji ukaz:
lcd.DrawBitmap(500,100,(uint8_t *)Image); // prikažeBMP datoteko ST metulja
Po preizkusu te metode sem se nato odločil, da poskusim shraniti bitno sliko v QSPI Flash pomnilnik. Sprva sem mislil, da bi bil najboljši način nalaganje BMP slik na uSD kartico in nato branje teh datotek z Mbed knjižnico SD kartic. Uspešno sem že bral SD kartice s pomočjo ‘F469 Discovery plošče in Mbed prevajalnika. Na tej plošči je konektor za uSD kartico priključen na SDIO MCU vrata. Če imate veliko izkušenj s SD karticami, boste vedeli, da podpirajo dva ločena protokola:
- SDIO protokol, ki je nekaj podobnega QSPI protokolu, saj je serijski, vendar prenaša podatke po 4 bite naenkrat.
- SPI protokol, ki je počasnejši, vendar je praviloma to protokol, ki se uporablja pri povezovanju SD kartic z mikrokontrolerji, saj imajo vsi SPI vrata.
Precej časa sem poskušal najti Mbed knjižnico za SD kartice, ki bi delovala z SD F469 konektorjem za SD kartico. Nisem mogel najti nobenega, ki bi bil sestavljen za „F469 dev. oziroma če se je prevedel, ni deloval. Uspelo mi je najti knjižnico SD kartic, ki bi delovala, ko sem na SPI F469 vrata (z uporabo Arduino SPI priključkov) ločeno priklopil konektor za SD kartice.
Ker je treba določiti, kateri vhodno/izhodni (I/O) pini se uporabljajo za SPI vrata, sem mislil, da bom morda lahko le prestavil SPI vrata pinom SDIO vrat, ki jih uporablja vtičnica SD kartice na plošči. To mi ni uspelo in tako sem odkril nekaj zares nenavadnega v načinu delovanja razvojnega sistema Mbed.
V sodobnih ARM MCU-jih je normalno, da lahko preslikate notranje periferne bloke na različne GPIO priključke z uporabo notranjih multiplekserjev. Na splošno lahko izbirate med podskupinami GPIO priključkov – vsekakor pa ne med vsemi. Lahko bi preučevali tehnični referenčni priročnik s 1000+ stranmi za določen MCU, vendar pa običajno knjižnične rutine vsebujejo smernice, ki preverjajo veljavnost vaših izbir GPIO-jev in izdajo sporočilo o napaki prevajalnika, če izberete GPIO priključke, ki jih ni mogoče dodeliti tej zunanji napravi.
Mbed ne deluje na ta način. Z veseljem vam bo na primer omogočil, da izberete neveljavne GPIO priključke za SPI vrata. Ko naložite in zaženete program, seveda ne bo deloval. Tu pa stvari postanejo zanimive. Zelena LED na plošči ‘F469 bo utripala v določenem vzorcu. Nisem našel nobene dokumentacije, ki bi prikazovala, kako dešifrirati ta utripajoči vzorec, toda ko vidite zeleno lučko, ki utripa na ta način, v računalniku zaženite program serijskega terminala in prikazalo se bo sporočilo o napaki, kot je prikazano na sliki 1.
V tem primeru bo sporočilo navedlo, da je prišlo do napake »pinmap not found for periferal«. To vam pove, da ste izbrali priključke, ki ne bodo delovali za eno od zunanjih funkcij. Ne bo vam povedalo, katera zunanja naprava ima napako, vendar boste to na vedeli, če postopoma spreminjate kodo. Dokumentacija Mbed o tem odpravljanju napak med izvajanjem je redka, vendar jo imenujejo “Lights of Death”!
Zato sem bil omejen na uporabo konektorje zunanje SD kartice z delujočo knjižnico SD datotečnega sistema na osnovi SPI. Tudi ta rešitev ni bila idealna. Ugotovil sem, da je knjižnica SD kartic sama po sebi delovala dobro, takoj ko sem želel uporabiti zaslon na dotik, so stvari propadle. Za uporabo zaslona na dotik za GUI sem moral dodati različne mape knjižnice:
BSP_DISCO_F469NI F469 GUI LCD_DISCO_F469NI TS_DISCO_F469NI
Ko so bili ti vključeni v program, je prišlo do konfliktov med temi knjižnicami in knjižnico SD kartic (ki temelji na SPI), ki sem jo uporabljal. Tega še nisem mogel rešiti. Lahko naložim program, ki bere bitne slike iz SD kartice in jih shrani na QSPI Flash, če pa želim uporabljati zaslon na dotik, ne morem vključiti nobenih funkcij SD kartice. Vendar pa na F746 Discovery plošči razpoložljiva knjižnica SD kartic na osnovi SDIO deluje v redu z ostalimi knjižnicami, ki jih uporabljam.
Preden se lotim kakršnih koli podrobnosti programiranja QSPI Flash čipa, se mi zdi koristno omeniti STM-ov ST-LINK pripomoček.
ST-Link program
Preden sem naročil svojo STM32F469NI -DISCO ploščo, sem že prenesel STM-ov STM32CUBE razvojni paket. Ko pa so plošče prispele, sem zelo težko razumel / uporabil in se odločil, da nadaljujem z Mbed IDE. Vendar je bil del STM32CUBE paketa tudi program pomožnega programa ST-LINK. ST-LINK je lastniška programska oprema / razhroščevalna oprema podjetja STM, ki se uporablja za programiranje / odpravljanje napak STM32 MCU-jev pri uporabi STM32Cube programske opreme.
Če razvijate z F469 ali F746 -DISCO ploščami znotraj Mbed, sploh ne uporabljate nobenega programatorja. Namesto tega .BIN datoteko vašega programa preprosto povlečete na USB pogon, ki se prikaže v upravitelju datotek, takoj ko Discovery ploščo priključite v računalnik. Zato sem v bistvu ignoriral ST-LINK Utility program, dokler se nisem spomnil, da sem prebral, kje se lahko neposredno programira QSPI Flash, nameščen na različnih STM32 razvojnih ploščah. To je lep trik – QSPI Flash je povezan samo s ciljnim ARM MCU, ne pa tudi z ločeno napravo za odpravljanje napak / programiranje ST-LINK, ki se nahaja na razvojni plošči. Nekako jim to uspe. Ko zaženete pomožni ST-Link program in ko prvič izberete element menija »Zunanji nalagalnik« se na vrhu ne bo pojavil noben meni. Uporabite ukaz Add loader in izberite vnos N25Q128A_STM32469I-DISCO. Ko je ta nalagalnik dodan, boste lahko izbirali med Mass Erase, Sector Erase, Program in Read. Slika 2 prikazuje zaslon po branju Flash QSPI pomnilnika od začetka (= 0x900000000 v naslovnem prostoru ‘F469 MCU).
Pripomoček ST-LINK je zelo priročen, ko razvijate kodo za QSPI Flash. Iz lastne kode lahko napišete blok podatkov in nato s pripomočkom preverite, ali je bil pravilno shranjen, ali po potrebi izbrišete sektorje ali celotno napravo. Ko sem »odkril« ta pripomoček, sem mislil, da bi bil to odličen način za nalaganje več bitnih slik v QSPI. To pomeni, da datoteko najprej naložite iz menija »Datoteka«, nato odprete External Loader orodje, izberete mesto za shranjevanje v QSPI pomnilniku in nato programirate. Nato bi prešli na naslednjo datoteko.
To pa žal ne bo delovalo, ker ukaz Program ne izbriše samo sektorjev, ki jih potrebuje za shranjevanje naložene datoteke, temveč tudi v celoti briše vse datoteke v napravi. Zdi se, da tudi ideja, da najprej naložite vse bitne slike v pripomoček in nato naredite en sam programski ukaz, ni možnost. Ko naložite datoteko, vam ne dovoli, da ji določite zamik v spominski lokaciji, zato pred izvajanjem funkcije programa ne morete pripraviti večbitne pomnilniške matrike. Vendar pa bi ta pripomoček dobro deloval, če želite v QSPI Flash naložiti samo eno datoteko.
Kasneje sem dobil STM32F746-Discovery ploščo. Med drugimi razlikami naj omenim, da ST-LINK External Loader rutina deluje drugače, kot pri pri F746 Discovery plošči. V tem primeru lahko izvaja samo Sector Erase in Program funkciji. Ne more prebrati vsebine QSPI Flash. To je tisto, kar sem iskal, zato mi zunanji nalagalnik F746 na tej plošči ni bil preveč koristen.
Napačno sem mislil, da bo zunanji nalagalnik, ki sem ga prej dodal v ST-Link pripomoček (za ‘F469 ploščo), deloval tudi za ploščo ‘F746. Ni res – moral sem odstraniti nalagalnik „F469“ plošče in nato dodati nalagalnik „F746“, da so stvari pravilno delovale. To je še en primer dveh podobnih Discovery plošč, ki imata na plošči zunanje naprave, ki opravljajo enako funkcijo, sicer pa niso združljive niti pri uporabi lastnih STM knjižnic itd..
QSPI funkcije programiranja
Po preučitvi ST-LINK pripomočka in po njegovih omejitvah se vrnimo k programiranju QSPI Flash z lastno kodo. Različne funkcije, ki so na voljo, najdete v “stm32469i_discovery_qspi.h” datoteki:
uint8_t BSP_QSPI_Init (void); uint8_t BSP_QSPI_DeInit (void); uint8_t BSP_QSPI_Read (uint8_t* pData, uint32_t ReadAddr, uint32_t Size); uint8_t BSP_QSPI_Write (uint8_t* pData, uint32_t WriteAddr, uint32_t Size); uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress); uint8_t BSP_QSPI_Erase_Chip (void); uint8_t BSP_QSPI_GetStatus (void); uint8_t BSP_QSPI_GetInfo (QSPI_InfoTypeDef* pInfo); uint8_t BSP_QSPI_EnableMemoryMappedMode(void);
Preden kar koli naredite s QSPI Flash, morate poklicati BSP_QSPI_Init () funkcijo – če bo uspešna, bo vrnila vrednost »QSPI_OK«. Branje naprave je preprosto, preprosto pokličete BSP_QSPI_Read () funkcijo, ki ji da kazalec na vmesni pomnilnik, kamor želite, da se shranijo podatki, QSPI naslov, iz katerega se bere, in velikost bloka. V tem primeru se QSPI naslov, s katerega berete, začne pri “0” za prvo mesto v napravi (ne 0x900000000, kjer je naprava preslikana v pomnilnik).
Pisanje bloka v napravo ni veliko težje – le da morate najprej izbrisati blok, v katerega želite zapisovati, s BSP_QSPI_Erase_Block () funkcijo. Če zaženete naslednjo kodo:
QSPI_InfoTypeDef pQSPI_Info; BSP_QSPI_GetInfo(&pQSPI_Info); uint32_t t= pQSPI_Info.EraseSectorSize; printf("QSPI Erase sector size = %d nr",t);
boste videli, da je velikost sektorja za brisanje 4096 bajtov. Zato, ko želite podatke shraniti v QSPI, morate upoštevati velikost podatkov in vnaprej izbrisati ustrezno število sektorjev.
Obstaja ena lepa lastnost QSPI Flash pomnilnika, ki jo moram omeniti. Če imate na splošno SPI (ali I2C) pomnilnik, bodisi SRAM ali Flash, je edini način dostopa do njega z uporabo rutin branja in pisanja v pripadajoči knjižnici. Z drugimi besedami, ta serijski pomnilnik ni nikjer mapiran v MCU. Tako QSPI Flash na ‘F469 dev. plošči deluje privzeto. V BSP_QSPI knjižnici pa obstaja funkcija:
uint8_t BSP_QSPI_EnableMemoryMappedMode(void);
Če je to storilo tisto, kar naj bi, je bilo videti, kot da bi lahko prebrali Flash QSPI pomnilnik tako, da ga preprosto naslovite na njegov naslov v pomnilniku ‘F469, ki se začne na 0x900000000. To sem preizkusil tako, da sem funkciji lcd.DrawBitmap () posredoval 0x900000000 (kjer je bila bitna slika naložena v QSPI Flash) in je delovalo v redu.
To se mi je zdelo čarobno. Preveril sem tehnični referenčni priročnik za „F469 MCU“ in ugotovil, da vsebuje blok fleksibilnega krmilnika pomnilnika (FMC), ki lahko obvladuje QSPI NOR Flash pomnilnik, pa tudi PSRAM in SDRAM. FMC je dovolj dovršen, da dostop do pomnilnika v MCU pomnilniškem prostoru pretvori v ustrezne strojne ukaze za serijsko pridobivanje pravilnih podatkov prek QSPI vmesnika. Ugotovil sem tudi, da ko omogočite način preslikave QSPI pomnilnika, QSPI_Read () funkcije ne morete več uporabljati – QSPI_Write () funkcije v teh okoliščinah še nisem preizkusil.
Ko sem začel uporabljati ‘F746-Discovery ploščo, sem ugotovil, da obstaja knjižnica za obdelavo vgrajenega QSPI Flash z imenom »QSPI_DISCO_F746NG.h «. Za razliko od QSPI F469 knjižnice le-ta uporablja QSPI funkcije kot razred, zato je koda, ki jo morate napisati za dostop do nje, nekoliko drugačna.
Razhroščevanje s pomočjo printf funkcije z STM32CUBE integriranim razvojnim okoljem
Medtem ko sem se odločil, da bom večino svojega projektnega dela opravil z uporabo Mbed IDE, sem veliko časa namenil preizkusu STM32CubeIDE. Upal sem, da bom lahko pridobil dovolj izkušenj z STM ARM napravami iz številnih primerov, ki jih STM ponuja v svojih CubeFW podpornih paketih. Ne da bi se spuščali v podrobnosti, povejmo samo, da sem bil razočaran, da orodje za konfiguracijo CubeMX ni bilo mogoče uporabiti za noben primer. Zato je bilo težko razviti programe po meri z uporabo teh primerov, saj CubeMX orodja ni bilo mogoče zlahka uporabiti. Vendar, medtem ko sem ga uporabljal, sem si zaželel preprostega odpravljanja napak z uporabo tistega, kar bi v Arduino okolju bilo metoda »Serial.println ()« razhroščevanja.
Čeprav imate na voljo ST-Link razhroščevalnik strojne opreme, ko uporabljate STM32CubeIDE, je v nekaterih primerih uporaba preprostih ukazov Serial.println (Arduino IDE) ali printf (Mbed IDE) hitrejša in bolj informativna. Ko uporabljate STM32Cube ID IDE na ‘F469 ploščah ali ‘ F746 ni vnaprej konfiguriranega serijskega razreda za UART vrata. To pomeni, da če želite uporabiti USB COM navidezna vrata (priključena na USART3) ali USART6 (pritrjena na CN12 (Arduino) konektor), boste morali sami konfigurirati ustrezni UART in napisati nekaj kode gonilnika za to. Poglejmo korake, potrebne za to.
Za začetek morate uporabiti MX konfiguracijsko orodje. Verjetno ste s tem orodjem že konfigurirali MCU za svoj projekt, in če je tako, boste na dnu seznama datotek vašega projekta v raziskovalcu projektov videli vnos datoteke z modro ikono z oznako “MX” in »Ioc« ekstenzijo. Dvokliknite ta vnos, da odprete orodje za konfiguracijo MX. Videli boste nekaj podobnega, kot kaže slika 3.
Vsem USART-om, ki jih vsebuje MCU F469, so lahko njihovi Rx, Tx priključki dodeljeni različnim GPIO priključkom. Če si ogledate shematski diagram za ‘F469 Discovery ploščo boste ugotovili, da so UART3 dodelili priključkom Port B10 (Rx) in Port B11 Tx. Ta dva priključka sta povezana z UART vrati znotraj U3, čipom ST-Link, ki nato omogoča povezavo UART-USB z vašim računalnikom. Na sliki 4 lahko vidite iskalno okno, kamor lahko vnesete te oznake priključkov vrat, in pripadajoči priključek na sliki čipa bo utripal vklop / izklop. Kliknite vsakega od priključkov PB10, PB11 in nastavite priključek PB10 za USART3 Rx in PB11 za Tx.
Naslednji je pogled na levi strani zaslona, kjer je seznam različnih IO funkcij, razdeljenih na široke kategorije. Izberite Povezljivost in izberite USART3. Konfiguracijo pinov, ki ste jo pravkar izvedli, bi morali videti na zavihku z GPIO nastavitvami. V razdelku Nastavitve parametrov lahko izberete različne USART parametre, na primer hitrost prenosa itd.. Privzete vrednosti so v redu (115.200 baudov itd.).
Če ste to MX orodje že zagnali, da lahko sploh konfigurirate svoj projekt, je to vse, kar morate tukaj narediti. Ko naredite Datoteka -> Shrani, vas bo vprašal, ali želite ustvariti kodo, ki jo ustvari konfiguracija, ki ste jo pravkar izvedli. Lahko pa v orodni vrstici kliknete ikono, ki je videti kot zobnik, iz katerega štrli gred.
Tega ne delajte, razen če se vsa programska koda, ki ste jo že napisali, nahaja znotraj »USER CODE BEGIN in USER CODE END« main.c različnih regij (in datoteke stm32f4xx_it.c, če ste opravili obdelavo kodo prekinitev). V nasprotnem primeru se vrnite in ustrezno uredite svoj program: ko MX orodje ustvari kodo, bo orodje izbrisalo vse, kar ste napisali zunaj teh regij.
Če želite, lahko nastavite PG6, PD4, PD5 ali PK3 kot izhod – to so 4 LED-ice na sprednji strani ‘F469 plošče. Naredil sem to in nato dodal nekaj kode za preklop ene od teh LED-ic, ki označuje, kdaj je bila za diagnostične namene poklicana moja USART3 rutina pošiljanja.
Nato lahko preizkusite delovanje USB COM navideznih vrat na naslednji način:
- Dodajte naslednje, da določite medpomnilnik za znake, ki bodo poslani, in vanj vstavite sporočilo.
uint8_t aTxBuffer[] = "**** UART_Transmitting **** rn";
- Če želite poslati sporočilo, dodajte naslednje, po možnosti v zanko:
HAL_UART_Transmit(&huart3, (uint8_t*) aTxBuffer, 32, 5000);
“32” je dolžina sporočila v bajtih, “5000” pa časovna omejitev v milisekundah. Če uporabljate Windows upravitelja naprav, lahko poiščete COM vrata, ki so bila dodeljena Discovery plošči. Slika 5 prikazuje Virtual COM vrata in ST-Link razhroščevalnik v mojem sistemu.
Zdaj, ko delujejo COM USB navidezna vrata, je naslednja stvar, da izhod funkcije printf preusmerite na ta COM vrata. To se doseže z dodajanjem naslednje kratke funkcije v vaš program:
void__io_putchar(uint8_t ch) { HAL_UART_Transmit(&huart3, (uint8_t*) &ch, 1, 5000); ITM_SendChar(ch); HAL_GPIO_TogglePin(GPIOD,LED2_Pin); // flash the Red LED so you know printf is using this routine to output to COM port }
To kodo sem postavil v odsek USER CODE BEGIN PFP – ne pozabite, kako bo orodje za konfiguracijo MX izbrisalo kodo zunaj teh določenih USER CODE regij. Upoštevajte, da morata biti v imenu funkcije 2 znaka za podčrtaj!
Morda se sprašujete, kaj počne vrstica, ki vsebuje ITM_SendChar. To nima nič skupnega s COM vrati, temveč je povezano z drugim načinom pošiljanja informacij iz Discovery plošče na računalnik. To je SVO Viewer metoda in to bom opisal v nadaljevanju.
Izhod razhroščevanja preko SVO Viewer
Druga značilnost ST-Link razhroščevalnika je njegova sposobnost obdelave SVO (Serial-Wire Viewer Output) sporočil. To so sporočila, ki jih ARM MCU-ji pošljejo v hitrem zaporednem formatu (UART) na določenem GPIO priključku. Na MCU F469 je to GPIO PB3. Ta priključek je povezan z U3, čipom za odpravljanje ST-Link napak. Ta SVO sporočila lahko pošljete s klicem na ITM_SendChar () rutino, ki je definirana v osnovi ARM CMSIS kode.
Ko ta sporočila prejme ST-Link razhroščevalnik, jih lahko posreduje v računalnik za ogled – z uporabo ST-Link Utility programa, ki sem ga omenil v 1. delu (glede programiranja F469 QSPI Flash s tem pripomočkom). Ko je ogled SVO nastavljen, je hitrejši in verjetno bolj priročen kot uporaba serijskega Terminal programa v računalniku za ogled sporočil, ki prihajajo iz navideznih COM vrat. Poglejmo natančno, kaj je treba storiti, da to deluje.
Preden se lotim kakršne koli namestitve programske opreme, je treba obravnavati eno pomembno podrobnost strojne opreme. SVO izhod iz PB3 na MCU Discovery plošče se privzeto ne poveže z ST-Link napravo!Za vzpostavitev te povezave je treba s spajkalnikom spojiti SB7 spajkalni mostiček. Na sliki 6 je prikazan detajl plošče PO TEM, ko sem spojil SB7 mostiček. Najprej mi ni uspelo, da bi SVO pregledovalnik začel delovati, in kar nekaj časa sem potreboval, da sem to odkril.
Na srečo sta za obe Discovery plošči, ki sem ju kupil, na voljo sheme od STM. Med odpravljanjem težav s SVO sem z osciloskopom izmeril izhod PB3 iz MCU F469. Ta signal lahko vidite na sliki 7. Kot vidite dejansko deluje na 2000 kHz, kot je določeno.
Med zagonom IDE STM32Cube z naloženim projektom nato kliknite meni Zaženi v orodni vrstici in izberite Konfiguracija razhroščevanja. Nato kliknite zavihek Debugger (zelena ikona hrošča). Pomembne nastavitve so:
- Vmesnik- SWD
- Serial Wire Viewer- omogočen
- SWO Clock 2000 kHz.
Kliknite »Apply« da shranite te nastavitve. Obstaja okno za Core Clock. Ko sem vnesel 168000000, to je tisto, kar sem nastavil za sistemsko uro, jo je sprejel, pozneje pa je pokazal 2147 MHz, ko sem ponovno vstopil v ta meni. Torej nisem prepričan, da je to pomembno, a številka 2000 kHz je pomembna.
Ko zaženete ST-Link pripomoček, kliknite ST-LINK in izberite printf prek SVO pregledovalnika (ne kliknite menija Target -> Connect, kot si morda mislite). Nato se prikaže okno, ki je videti kot slika 8. Na tej točki morate vnesti dejansko frekvenco ure, na kateri deluje ‘F469, in za vrata Stimulus izbrati “All”. Nato kliknite Start. Opazite, da »SWV Frequency« okno prikazuje 2000 kHz, tako kot ste nastavili v konfiguraciji razhroščevalnika.
Na tem mestu (če se vaš program izvaja in prikliče ITM_SendChar () rutino), bi morali videti ta sporočila, prikazana v oknu SVO pregledovalnika. Ta sporočila lahko prihajajo iz ITM_SendChar () stavkov, ki ste jih postavili v svoj program, ali pa iz katerega koli stavka printf, ki ga imate v programu. Slednja izjava je resnična SAMO, če ste ITM_SendChar () stavek vključili v
void__io_putchar(uint8_t ch)
funkcijo, kot sem prikazal proti koncu zadnjega odseka.
Zdaj imate tako strojno razhroščevanje kot tudi preprosto printf () razhroščevanje, ki ste ga imeli v Mbed IDE. Pomembno je vedeti, da lahko SVO Viewer uporabljate samo, kadar na Discovery plošči deluje program, ne pa, ko program izvajate v načinu za odpravljanje napak. Torej deluje eno ali drugo – bodisi je STM32Cube IDE povezan z ST-Link, bodisi je z njim povezana ST-Link Utility računalniška aplikacija. Ko končate z ogledom SVO sporočil, ne pozabite zapreti ST-Link Utility programa, sicer Discovery plošče ne boste mogli programirati ali razhroščevati napake znotraj IDE STM32Cube.
S tem se zaključi moj dvodelni članek z dvema STM32 ARM Discovery ploščama, s katerima sem delal, pa tudi moja prva izkušnja s ploščama STM32CubeIDE in Mbed. Kot sem omenil v 1. delu, sem zelo navdušen nad dvema STM Discovery ploščama, ki sem jih kupil in vsebujeta TFT LCD zaslone in kapacitivne zaslone na dotik. Če bralce revije Svet Elektronike ta tematika zanima, lahko napišem nekaj nadaljnjih člankov o tej temi.