1. marec, 2019

O dihanju in izvajanju v realnem času

microchip 300x74 - O dihanju in izvajanju v realnem časuMicrochip Technology Inc
Avtor: Lucio Di Jasio
2019_272_43

Pred kratkim sem se udeležil praktične delavnice, katere namen je bil skupini »tisočletij«, ki je že poznala osnove računalništva, predstaviti umetnost ugnezdenega programiranja. Kot običajno je bil eden izmed prvih primerov projekt pregovorni “Hello (Embedded) World”, kar v svetu mikrokontrolerjev seveda pomeni klasični prvi korak: utripanje svetleče diode (LED)

272 43 01 254x300 - O dihanju in izvajanju v realnem času

Slika 1: Okno za izbiro virov v MCC projektu

Inštruktor je naredil izjemno dobro delo in se uspel spretno se izogniti številnim podrobnostim in skušnjavam. Razred je vodil k vzpostavitvi preprostih vhodno-izhodnih vrat neposredno na najpreprostejšo možno rešitvijo. To je prikazal s parom blokirnih (čakajočih) zank in dvema nalogama, ki jih je pameten C-prevajalnik, kot je pojasnil, pretvoril v en sam mikrokontrolerski ukaz (postavljanje in brisanje bita). Kmalu je bila soba napolnjena z občasno svetlobo mnogih rdečih LED, vendar je bil predavatelj kar nekoliko razočaran, saj množica udeležencev delavnice nad rezultatom ni bila videti najbolj navdušena. Z ozadja sobe sem slišal posamezne pritožbe in kmalu sem ugotovil tudi vir nezadovoljstva skupine: obstaja utripanje, poznamo pa tudi pulziranje ali dihanje, kot radi imenujemo tisto, kar počnejo mnogi sodobni prenosniki in mobilni telefoni, ko se nahajajo v stanju pripravljenosti. Kot se pogosto dogaja, je šlo tu za vprašanje nepravilno ocenjenih pričakovanj.

Tek na MIPS
Potem pa je na razredu prišlo do nepričakovanega obrata, ko je voditelj poskušal vsaj delno zadovoljiti občinstvo in začel s tangento, da bi jih seznanil z relativno kompleksnostjo, ki jo je prinesla nova naloga. Uvedel se je časovnik, s katerim je bilo mogoče izvajati pulzno-širinsko modulacijo (PWM) za prilagoditev vidne svetlobe krmiljene LED s krmiljenjem razmerij v obratovalnem ciklu. Sledila je razlaga, kako je treba to razmerje spreminjati postopoma, z zaporedjem korakov navzgor in navzdol po neki krivulji, ki je definirana s konkretnimi vrednostmi (točkami) v tabeli. Trajanje vsakega koraka je bilo izvedeno s še enim (počasnejšim) časovnikom, ki je povzročil prekinitev. Mikrokontroler se je na prekinitev odzval tako, da je izračunal (ali prebral iz vpogledne tabele) novo vrednost dolžine delovnega cikla za PWM.

To pa je bilo že malce preveč za občinstvo, ki je prvič prestopilo prag v ugnezdeni svet, vendar so se stvari samo še poslabšale, ko jih je predavatelj poskušal navdušiti s hitro predstavitvijo formule za izračun te krivulje.

272 43 02 300x120 - O dihanju in izvajanju v realnem času

Slika 2: Okno za konfiguracijo MCC sistema, podrobnosti v zvezi z notranjim oscilatorjem

Tukaj je vsa potrebna matematika, ki se je spomnim:

  • Izbrana PWM frekvenca naj bi bila dovolj visoka, da lahko računamo na učinek vztrajnosti človeškega očesa, nekje med 30 in 120Hz.
  • To vrednost nato pomnožimo, da zagotovimo nemoten učinek zatemnitve z recimo 256 koraki. To skupaj daje frekvenco okrog 32kHz. Torej, v tem trenutku nam kaže dokaj dobro! V vsakem PIC® mikrokontrolerju je na voljo notranji oscilator z izredno nizko porabo, ki deluje prav na tej frekvenci!
  • Če želimo zdaj ustvariti najenostavnejši dihalni učinek (s pomočjo trikotnega profila) s skupnim časom od ½ sekunde do 2 sekund, bomo morali za vsako obdobje naraščati navzgor in upadati navzdol v 512 (skupno) korakih.
  • To v grobem pomeni, da je treba PWM posodobiti približno vsako milisekundo. Če se izrazimo v ciklih izvajanja ukazov, bi pri taktu 32kHz dobili eno prekinitev na vsakih osem ciklov izvajanja strojnega programa.

Tudi najbolj izkušenemu oblikovalcu bi ta rešitev zvenela praktično neizvedljiva. Takt procesorja je bilo treba povečati ali z drugimi besedami: zmanjkalo je MIPS-ov!

272 43 03 236x300 - O dihanju in izvajanju v realnem času

Slika 3: Okno za konfiguracijo PWM6

Za nekatere udeležence je bilo to precej kruto spoznanje, saj so prvič razumeli, da ima izraz hitrost izvajanja (izraženo v MIPS in MHz) v tem kontekstu čisto drugačen pomen. Mikrokontroler smo morali “naviti” k najhitrejšemu možnemu izvajanju programa, čeprav nismo niti poskušali narediti kakšnih izračunov, temveč smo se morali le pravočasno odzvati na prekinitveni dogodek!
To je bilo njihovo prvo srečanje s konceptom delovanja v realnem času.

Začutiti utrip
Ta vaja je tudi name naredila velik vtis, zaradi česar tukaj tudi berete o njej. Poskusil sem najti enostavnejše načine za prikaz omejitev mikrokontrolerjev v ugnezdenih aplikacijah s tradicionalnim pristopom, osredotočenim na delovanje v procesnem jedru. V današnjem času, ko smo nekako obsedeni s procesno zmogljivostjo, MIP, megaherci in megabajti, vendar se pri izbiri pogosto osredotočimo na napačno vrsto zmogljivosti. Takrat, ko sem sedel v tisti učilnici. mi je to postalo kristalno jasno.

Včasih nam lahko le en korak, ki ga naredimo nazaj, odkrije pogled na isti problem iz čisto novega zornega kota in pri tem razkrije do takrat skrito, veliko bolj elegantno in največkrat tudi bolj uravnoteženo rešitev. Ko se na primer lotite takšnega primera, kot je zgoraj opisani problem z “dihajočimi” LED, si vzemite minuto časa in poskusite osvoboditi svoj um od okovov tradicionalne kulture na procesno jedro mikrokontrolerjev vezanega razmišljanja izvajanja in pri tem za nekaj trenutkov prenehajte razmišljati tudi o prekinitvah in vpoglednih tabelah.

Če se osredotočite na prvotne zahteve problema, za trenutek zamižite in si predstavljajte signal kvadratne oblike, kateremu se delovni cikel postopoma spreminja, boste morda opazili presenetljivo podobnost s pojavom, ki ga pogosto doživljamo kot akustični učinek, ki ga povzroča »trk« dveh signalov podobne frekvence, ki se ob združitvi ojačita ali medsebojno izničita. Vsota obeh signalov, ki doseže naša ušesa, je z ovojnico, ki je takšne frekvence, da jo lahko zazna tudi uho in je enaka razliki frekvenc obeh signalov. Tega res ni težko izvesti s samo nekaj logičnimi vrati in čisto lahko jo izvedemo tudi v mikrokontrolerju, ki ima logična vrata vgrajena v naboru perifernih naprav.

Od procesnega jedra neodvisna rešitev

272 43 04 300x144 - O dihanju in izvajanju v realnem času

Slika 4: Konfiguracijsko okno za TMR6

Prva stvar, ki jo pri tem potrebujemo, je najti način za generiranje dveh periodičnih signalov (kvadratni signali so čisto v redu), vendar bi morala biti njihova frekvenca samo 0,5 do 2Hz narazen. Za ustvarjanje dveh signalov lahko uporabite par digitalnih časovnikov z registrom za ponovno nalaganje (z drugimi besedami dve osnovni PWM periferni enoti). Previdno bomo morali izbrati dve takšni vrednosti za ponovno nalaganje, da si bosta dovolj blizu, vendar kljub temu toliko različni, da se ustvari želena frekvenca utripanja. Če bi na primer uporabili PIC mikrokontroler s frekvenco takta 32kHz, dvema 8-bitnim časovnikoma in priključenima PWM moduloma, lahko na izhodu ustvarimo dva signala s frekvencama 60,5 Hz in 61,5 Hz. Nato pa za izvedbo IN logične funkcije med obema signaloma lahko uporabimo katero od konfiguracijskih logičnih celic (CLC), ki so majhni programirljivi logični bloki, podobni FPGA/PLD makro blokom. Poleg tega lahko kot neposredni izhod določimo katerikoli vhodno-izhodni fizični priključek mikrokontrolerja, na katerega bo LED dejansko priključena.

272 43 05 235x300 - O dihanju in izvajanju v realnem času

Slika 5: Konfiguracijsko okno PWM7

To nam bo dalo vizualni učinek dihanja s frekvenco 1 Hz. Hitrejše dihanje bo doseženo s povečanjem razlike med obema frekvencama (zaradi česar je drugo obdobje PWM krajše) in obratno, počasnejše dihanje bo doseženo z zmanjšanjem razlike med obema frekvencama do 0,1 Hz, ko je razlika vrednosti v obeh registrih le za eno narazen.

Konfigurabilna logična celica pa je samo ena izmed tistih čisto osnovnih iz palete od procesnega jedra neodvisnih perifernih naprav (CIP), ki jih lahko danes najdemo v modernih (PIC) mikrokontrolerjih, za dokončno rešitev pa smo potem uporabili le še standardne časovnike in PWM generatorje.

Morda se po vsem tem zdaj marsikdo med vami sprašuje, če s tem člankom pravzaprav nismo imeli namena predstaviti več o možnosti uporabe samega mikrokontrolerja? Jedro mikrokontrolerja bo dejansko zaposleno s funkcijo LED dihanja le ob inicializaciji za konfiguracijo perifernih naprav. Morda je še večja zanimivost pri vsem tem dejstvo, da smo našo rešitev izvedli z uporabo oscilatorja z izjemno nizko porabo energije, poleg tega pa imamo še vedno na voljo vseh 100% zmogljivosti mikrokontrolerja (v MIPS ali MHz, neodvisno od tega, kako jo merimo), ki je v celoti na voljo »drugemu« (bistvenemu) delu izvajanja funkcij v naši aplikaciji.

Poglej, dihajoča LED brez programske kode!
Če vas je vse prej opisano pritegnilo, boste najbrž še bolj veseli, ko boste izvedeli, da vam za praktično uporabo ni potrebno napisati niti ene same vrstice programske kode, niti vam ne bo treba iskati kakršnih koli informacij iz podatkovnega lista! Če spadate med tiste, ki morajo videti, da verjamejo, vas vabim, da mi sledite.

272 43 06 300x153 - O dihanju in izvajanju v realnem času

Slika 6: Konfiguracijsko okno za TMR4

Za poenostavitev bom uporabil kar eno izmed cenovno ugodnih razvojnih plošč z oznako MPLAB® Xpress. Na njej bom uporabil mikrokontroler PIC16F18855, ki je že vgrajen na tej ploščici, čeprav bi bilo mogoče uporabiti katerega koli od novejših mikrokontrolerjev iz družinePIC16F1, ki podpirajo CIP (od procesnega jedra neodvisna periferija).

Začnimo kar s čarovnikom za nov projekt v integriranem razvojnem okolju (IDE) MPLAB X, s katerim ustvarimo nov projekt z izbranim PIC mikrokontrolerjem. Uporabili bomo tudi konfigurator kode MPLAB (MCC), brezplačen vtičnik MPLAB X IDE, ki nam bo pomagal inicializirati in povezati vse vgrajene periferne naprave. Lahko jih preprosto izberemo s seznama »Device Resources« z dvoklikom na njihova imena. V našem primeru lahko dvokliknemo na TMR4, TMR6, PWM6, PWM7 in en CLC modul, za ta primer sem izbral CLC1.
V zgornjem oknu, kjer so navedeni »projektni viri«, ki smo jih za svoj projekt izbrali (glejte sliko 1), lahko zdaj kliknemo na vsakega izmed njih in nadaljujemo z vpogledom v njuni konfiguracijski pogovorni okni. Tu lahko pravzaprav izvemo prav vse o možnostih glede nastavitev, ki so na voljo za vsako periferno enoto.

Na vrhu seznama virov projekta je tudi skupina »System«. Sistemski modul predstavlja predvsem bistvene elemente izbranega mikrokontrolerja, kot sta na primer izbira oscilatorja in nastavitev konfiguracijskih bitov.

272 43 07 300x211 - O dihanju in izvajanju v realnem času

Slika 7: Konfiguracijsko okno CLC1 modula

Oscilator nastavite za delovanje v načinu “31kHz_LF” (izmed vseh možnosti najnižja poraba), kot je prikazano na sliki 2.

Nato kliknite na vir PWM6 (glejte sliko 3) in izberite časovnik Timer 6 za njegovo časovno osnovo. Vse ostale možnosti so že privzeto nastavljene in vključujejo 50% delovni cikel (razmerje signal-pavza) in neobrnjeno polariteto izhodnega signala.

S klikom na TMR6 (slika 4) se nam še enkrat prikažejo številni parametri, ki že imajo svoje privzete vrednosti, za čas trajanja ene periode pa vpišemo 16,2 ms.

Sedaj kliknite PWM7 (na sliki 5) in nastavite kot vir za časovno bazo časovnik Timer 4, s čimer bomo imeli možnost nastavitve drugačnega trajanja ene periode, kot smo ga nastavili pri časovniku TMR6.

Zdaj kliknite TMR4 in spremenite vrednost obdobja 16ms kot je prikazano na sliki 6.

Na koncu kliknite še na modul CLC1 in nastavite prva dva vhodna signala, ki ju želite priključiti na izhod PWM6 in PWM7 (glejte sliko 7). Povežite jih z GATE1 in GATE2 in zagotovite, da bo izbrana funkcija “AND-OR” (IN-ALI).

Nato uporabite okno za nastavitev mreže svoje logike »Pin Manager: Grid« prek katere lahko dostopate do mreže za konfiguracijo vhodno-izhodnih priključkov, kjer boste morali CLC1 izhodu dodeliti en ali več fizičnih priključkov. Zahvaljujoč funkciji za prosto izbiro perifernega priključka, lahko CLC izhod hkrati poganja tudi več kot eno samo LED. V našem primeru izberemo priključke RA0-2 (Port A, zeleno obarvano), ki so fizično priključeni na štiri LEDice razvojne plošče MPLAB XPRESS (slika 8).

Če se vrnemo nazaj na skupino sistemskih virov, lahko izberemo “Pin modul” in v njegovem oknu za konfiguracijo preverimo, ali so vsi uporabljeni vhodno-izhodni priključki pravilno nastavljeni (slika 9).

272 43 08 300x127 - O dihanju in izvajanju v realnem času

Slika 8: Okno mreže upravljalnika pinov MCC

S pritiskom na gumb »Generiraj kodo« bo MCC sprožil postopek, v katerem nastane skupina šestih manjših datotek z izvorno kodo (napisanih v C), ki zagotavljajo vso potrebno programsko kodo za inicializacijo periferije. MCC bo prav tako samodejno ustvaril glavno datoteko. Z veseljem bomo najbrž sprejeli ponudbo, da se ustvarjena koda doda glavni datoteki z imenom “main.c”, ki vsebuje klice na inicializacijo periferije in prazno glavno programsko zanko, kamor bomo kasneje umestili programsko kodo za ostale funkcije, ki jih bo izvajal mikrokontroler s podporo procesnega jedra.

Marsikomu se bo zdelo neverjetno, vendar od te točke naprej MPLAB X IDE le še preprosto ukažete, da zgradi projekt in sprogramira Curiosity ploščico in to z enim samim zadnjim klikom na gumb “Make and Program”. Po nekaj sekundah bo ustvarjanje strojne kode za mikrokontroler končano in ko bo tudi programator opravil svoje delo, boste najbrž presenečeni opazili, da so začele majhne LED na preizkusni ploščici MPLAB XPRESS nenadoma “dihati”!

Programka koda v manj kot 10 (binarnih) vrsticah
Morda vam bo zanimivo tudi to, da sem pred kratkim napisal knjigo z naslovom »Z desetimi vrsticami programske kode« (“In 10 lines of code”), v kateri je predstavljen ta projekt skupaj s še dvajsetimi podobnimi projekti, je pa res, da v tem, ki sem ga tu opisal, ni bilo potrebno ročno zapisati ene same vrstice! Z združitvijo posameznih vgrajenih CIP perifernih enot mikrokontrolerja nam je uspelo ustvariti “funkcijo dihanja”, s čimer smo dosegli svoj cilj, za samo aplikacijo pa nam je ostalo na voljo vseh 100% zmogljivosti našega izbranega mikrokontrolerja.

272 43 09 300x115 - O dihanju in izvajanju v realnem času

Slika 9: Okno za konfiguracijo “Pin modul”

Projekt, ki vsebuje konfiguracijo MCC in celotno kodo, ki je bila ustvarjena za ta članek, boste našli v knjižnici na GitHubu na naslovu https://github.com/luciodj/In10LinesOfCode.

Morda je pri tem zanimivo tudi to, da sem že od začetka objavljanja teh preprostih kratkih praktičnih primerov opazil, da so tako kot dijaki višjih letnikov, kot tudi izkušeni razvijalci presenečeni zaradi izboljšanja zmogljivosti delovanja »v realnem času«, ki ga lahko dosežejo z uporabo CIP, od procesnega jedra neodvisne periferije. Njihova uporaba sicer zahteva preskok razmišljanja iz udobja zakoreninjene navezanosti na “izvajanje v procesnem jedru”, ko pa vam ta preskok enkrat uspe, ne bo več povratka!

Avtor članka je Lucio Di Jasio, vodja poslovnega razvoja za Microchip Technology MCU8 Division

Opomba: Ime in logotip Microchip sta registrirani blagovni znamki podjetja Microchip Technology Incorporated v ZDA in drugih državah. Vse druge blagovne znamke, ki so morda tu omenjene, so last njihovih podjetij.

www.microchip.com
Tags: