Avtor: dr. Simon Vavpotič
2017_256_36
Microchip Harmony je zagotovo najpomembnejši programski okvir za vse, ki se navdušujemo nad mikrokontrolerji in digitalnimi procesorji podjetja Microchip. Je tudi pomemben vgradni del razvojnega okolja MPLAB X IDE, ki nekajkrat pohitri in poenostavi delo programerjev.
V preteklem nadaljevanju smo spoznali osnove datotečnega sistema in strežnika za spletne storitve. Microchipov primer je spletnega strežnika je kompleksen in omogoča implementacijo veliko spletnih storitev. Tokrat nas bo bolj zanimal sam datotečni sistem.
Microchip Harmony podpira datotečna sistema FAT in MCFS. Izbira datotečnega sistema je mogoča z ustrezno izbiro nastavitve v Harmony Configuratorju. Potrebno je izbrati tudi ustrezen gonilnik. Podporo delovanju datotečnega sistema sicer zagotavlja tudi opravila, ki se morajo neprestano izvajati in smo jih omenili že v 7. delu. V našem primeru smo potrebovali SYS_FS_Tasks in DRV_SDCARD_Tasks. To pa zato, ker smo uporabili datotečni sistem na kartici SD.
Ta vsebina je samo za naročnike
Dostop do datotek
Do datotek dostopamo na enak način kot pri Linuxu. Zavedati se moramo, le, da podatke beremo ali pišemo v EEPROM mikrokontrolerja. Vendar so pomnilnik mikrokontrolerjev izjemno majhni in lahko shranijo zgolj izjemno majhne količine podatkov, kar seveda ni primerno za shranjevanje drugega kot nastavitvenih datotek, ki omogočajo lažje upravljanje delovanja.
Prvi korak se navadno izvede ob zagonu mikrokontrolerja. Nato najprej datoteko opremo in vanjo pišemo ali iz nje beremo podatke. Po zaključku bralne ali pisalne operacije datoteko zapremo. Ukazi imajo kljub podobnosti z Linuxom nekatere specifike.
Poglejmo, kako izvedemo osnovi dostop do datotek: V prvem koraku moramo namestiti podatkovni pogon (SYS_FS_Mount) , nato lahko dostopamo do datotečnega sistema na klasičen način, z ukazi odpri datoteko (SYS_FS_FileOpen), beri datoteko (SYS_FS_FileRead) (ali piši datoteko, SYS_FS_FileWrite) in zapri datoteko (SYS_FS_FileClose).
Za namestitev podatkovnega nosilca moramo podati naslednje parametre: ime naprave (devName), ime pogona (mountName), tip datotečnega sistema (filesystemtype), zastavice za namestitev (mountflags) in dodatne podatke (data) v kolikor so potrebni. Primer ukaza, ki vključuje tudi preverjanje uspešnosti namestitve podatkovnega pogona, je vzet iz programske knjižnice Microchip Harmony, glej program 1.
Naslednji ukaz je odpiranje datoteke, pri katerem podamo pot, vključno z imenom datoteke ter način branja in/ali pisanja datoteke. Kot rezultat operacije dobimo datotečno ročico (file handle), s katero dostopamo do datoteke s pomočjo ukazov FileRead in/ali FileWrite. Primer ukaza je naslednji, glej program 2.
Poznamo več načinov odpiranja datoteke. V našem primeru smo odprli datoteko za branje. Poleg tega podatka moramo kot prvi parameter vnesti le še pot, vključno z imenom datoteke.
Sledi ukaz za branje vsebine datoteke, ki vsebuje kazalec na podatkovno strukturo v pomnilniku mikrokontrolerja, kamor bomo brali podatke in največjo dolžino branja. Po izvajanju operacije prejmemo odgovor o dejanski količini prebranih podatkov v bajtih. Primer ukaza je naslednji, glej program 3.
V primeru, da želimo podatke pisati, uporabimo ukaz, glej program 4, ki deluje podobno, le da podatke shrani v pomnilnik. Microchipovi mikrokontrolerji imajo največ 2 MB EEPROM-a.
Dostop do datoteke končamo z ukazom SYS_FS_FileClose, kot prikazuje naslednji primer:
SYS_FS_FileClose(appData.fileHandle1).
Praktični napotki
V primerjavi z osebnimi računalniki je podpora za datotečni sistem pri mikrokontrolerjih zgolj bazična in ni namenjena hrambi velikih količin podatkov. Lahko pa si iz majhnih datotek izdelamo tudi preprosto spletno stran, ki služi za upravljanje mikrokontrolerja. Po drugi strani, velike datoteke uporabljamo predvsem zaradi lažje izmenjave podatkov z osebnim računalnikom in pri njihovem shranjevanju neposredno v zunanji pomnilnik, kot je kartica SD. Pogosto bi sicer podatke enostavneje shranili v obliki pomnilniških polj.
Zanimiv primer uporabe datotečnega sistema je, na primer, snemalnik ali predvajalnik zvoka. Za predvajanje stisnjenih glasbenih datotek (npr. v zapisu MP3), potrebujemo ustrezen programski kodek, ki je pogosto plačljiv, lastni razvoj pa zahteva veliko programiranja. Zato se pri domačih aplikacijah stiskanju zvoka pogosto raje izognemo, kar ima za posledico potrebo po zunanjem pomnilniku v obliki kartice SD. Ustrezen vmesnik za povezavo slednje s poljubnim Microchipovim mikrokontrolerjem najdemo v spletni trgovini Microchip Direct.
Kako se lotiti programiranja? Začeti se splača s primerom komunikacije mikrokontrolerja s kartico SD, ki mu dodamo še potrebne funkcionalnosti za predvajanje in/ali snemanje zvoka preko pretvornika A/D.
Velja opozoriti, da potrebujemo za snemanje zvoke iz mikrofona še ustrezen predojačevalnik. Bolj smeli programerji lahko poskusijo zajemati zvok tudi prek spletne kamere ali mikrofona, ki delujeta preko priključka USB. Vendar poudarimo, da slednje ni najbolj preprosto, saj je komunikacijski protokol USB dokaj zapleten. Zato bomo izbrali enostavnejšo možnost z uporabo pretvorbe A/D, pri čemer bomo predpostavili, da je vhodni signal že ustrezno prilagojen za vhod A/D pretvornika. Še namig: Za test lahko uporabimo signal iz izhoda za slušalke pri avdio ojačevalniku, ki ga na A/D pretvornik pripeljemo preko kondenzatorja in ustreznega uporovnega delilnika. Čeprav je vezje sorazmerno enostavno, velja poudariti, da na vhod A/D pretvornika ne sme priti negativni signal (manjši od -0,3 V). Zato mora biti uporovni delilnik pravilno skonstruiran.
Programska koda
Kot smo že vajeni, se večopravilnosti pri povezovanju različnih funkcijskih enot znotraj mikrokontrolerja in posledično različnih zunanjih naprav, ne moremo izogniti. Večopravilnost se lahko lotimo tako, da jo preko programskih korakov vgradimo v glavno programsko zanko mikrokontrolerja, ali pa uporabimo večopravilnost, ki jo s pomočjo prekinitev omogočajo razni enostavni operacijski sistemu za PIC32. Vendar je pri večini primerov v sklopu Harmony uporabljena prva možnost. Ker smo začeli na osnovi primera za povezavo kartice SD z mikrokontrolerjem, smo jo izbrali tudi mi.
Kako deluje?
Snemanje zvoka je zahtevnejše od predvajanja zato smo se osredotočili predvsem nanj. Za zvezno snemanje zvoka moramo uporabiti prekinitve in sistem več izravnalnikov. Medtem, ko se trenutni delovni izravnalnik polni, mikrokontroler dodaja vsebino že napolnjenih izravnalnikov v datoteko na kartici SD. Izbrali smo datotečni sistem FAT32. Zato lahko po snemanju vsebino kartice brez težav preberemo z namiznim osebnim računalnikom, ki ima vgrajen ustrezen bralnik kartic, ali notesnikom.
Poglejmo, kako deluje glavna programska zanka za zapisovanje zvoka v datoteko SND.bin na kartici SD, glej sliko program 1. Program 1 prikazuje glavno zanko, ki posnet zvok iz izravnalnikov prenaša v datoteko na kartici SD. Vidimo lahko, kako je preko več korakov implicitno realizirana večopravilnost. Podprogram APP_Task mora namreč delovati pretočno, tako da se mikrokontroler med čakanjem na dostop so kartice SD ali datoteke na njej nikoli ne vrti v neskončni zanki. Ne smemo pozabiti, da mora vzporedno potekati tudi vzorčenje zvoka preko A/D pretvornika. Slednjega ne bomo prikazali, saj smo ga spoznali že v seriji o programiranju PIC32. Kljub temu povejmo, da najdemo celoten primer za PIC32MZ EC Starter Kit na spletni strani https://sites.google.com/site/pcusbprojects
Naslednjič
Ste vedeli, da lahko PIC32 deluje tudi kot gostitelj naprav USB, spletni spojnik (HUB), ali pa kot večpredstavna periferna enota, denimo mikrofon USB? Prihodnjič se lotimo implementacije večpredstavnih naprav s pomočjo PIC32, kot tudi njihove uporabe.
www.svet-el.si
Harmonija razvoja in programiranja (7)
Harmonija razvoja in programiranja (6)
Harmonija razvoja in programiranja (5)
Harmonija razvoja in programiranja (4)
Harmonija razvoja in programiranja (3)
Harmonija razvoja in programiranja (2)
Harmonija razvoja in programiranja (1)
program 1 if(SYS_FS_Mount("/dev/mmcblka1", "/mnt/myDrive", FAT, 0, NULL) != SYS_FS_RES_SUCCESS)
program 2 appData.fileHandle1 = SYS_FS_FileOpen("/mnt/myDrive2/abc.txt", (SYS_FS_FILE_OPEN_READ));
program 3 if(SYS_FS_FileRead(appData.fileHandle1, (void *)appData.data, 13) == -1)
program 4 bytes_written = SYS_FS_FileWrite(fd, (const void *)buf, nbytes);