Sulautettu reaaliaikakäyttöjärjestelmä¶
Osaamistavoitteet: RTOS ja ohjelman alustus SensorTag-laitteessa.
Aloitamme sulauttujen laitteiden ohjelmointiin perehtymisen käymällä ensin läpi ohjelman rakenteen SensorTag-laitteessa. Valmistaja tarjoaa laitteen ohjelmointia helpottavan reaaliaikakäyttöjärjestelmän (TI-RTOS), jonka kirjastoja ja palveluita käytämme harjoitteluun ja lopuksi harjoitustyön toteuttamiseen. Tässä materiaalissa esitetään laitteelle ohjelmointiesimerkkejä, mutta parhaiten asioita oppii tietysti itse kokeilemalla ja tekemällä. Aluksi muutama aiheeseen liittyviä käsite..
Käyttöjärjestelmä on tietokoneen sovelluksia pyörittävä ohjelmisto, jolla on kaksi pääasiallista tehtävää. Se tarjoaa suoritusympäristön sovelluksille ja hallinnoi tietokoneen resursseja sekä käyttöoikeuksia. Käyttöjärjestelmä tarjoaa palveluita yhtenäisen rajapinnan ja kirjastojen kautta sovelluksille resussien käyttöön, mm. muistihallintaan, tiedostojärjestelmän, oheislaitteiden käyttöön ja ulkoiseen tiedonsiirtoon. Käyttöjärjestelmä myös kontrolloi sovellusten suoritusta, jakaen prosessori(e)n suoritusaikaa ja muistia sovellusten kesken. Tarkemmin käyttöjärjestelmiä käsitellään Käyttöjärjestelmät-kurssilla, joten ohitamme tässä kattavan esityksen.
Reaaliaikakäyttöjärjestelmä (engl. Real-time Operating System, RTOS) taas tarjoaa suoritusympäristön sulautettujen järjestelmien sovelluksille. Reaaliaikaisuus tässä yhteydessä tarkoittaa sitä, että käyttöjärjestelmä takaa toiminnallisuuksille tietyn vasteajan, esimerkiksi johonkin tapahtumaan reagoidaan varmasti yhden millisekunnin sisällä. RTOS itsessään voi olla hyvin kevyesti toteutettu, se voi esimerkiksi vain jakaa prosessoriaikaa sovellusten kesken. Kevyt toteutus tukee myös osaltaan sovelluksia, joissa on tiukat reaaliaikavaatimukset, koska käyttöjärjestelmän omien rutiinien suoritukseen ei kulu aikaa. RTOS:n palvelut ja tarjottu toiminnallisuus vaikuttavat siis merkittävästi sulautetun ohjelman suunnitteluun, toteutukseen ja ylläpitoon.
(Kuten aiemmin esitettiin, sulautettuja järjestelmiä on toki mahdollista ohjelmoida ilman käyttöjärjestelmää ja/tai laiteohjelmistoa, mutta tällöin ohjelmoija on vastuussa laitteen komponenttien kytkemisestä MCU:hun ohjelmallisesti ja sovelluksen tarvitsemien palveluiden toteuttamisesta.)
Terveisiä laitevalmistajilta¶
Kuten aiemmassa C-kielen materiaalissa todettiin, tietokoneohjelmien toteuttamisessa modulaarisesti on hyvinkin paljon järkeä. Tietysti nyt myös sulautetun ohjelman kokonaisuus on järkevää jakaa modulaarisesti tehtäviin, joiden toiminnallisuus voidaan loogisesti kapseloida eli erottaa toisistaan. Näin sitten suunnittelun toiminnallisuuden toteuttavat tehtävät voidaan toteuttaa omina funktioinaan, vaikkapa nyt C/C++-kielillä.
Esimerkiksi, SensorTag-laitteessa tehtäviä voisi olla sensoridatan lukeminen, näytön päivitys tai langaton tiedonsiirto. Nyt RTOS osaa huolehtia niiden rinnakkaisesta suorittamisesta laitteessa, yrittäen ottaa huomioon ohjelmoijan asettamat vaatimukset. Tämä ilman, että ohjelmoida esimerkiksi toteuttaisi esimerkiksi eri tehtävien prioriteettien mukaisen suorituksen! Työelämässä sulautettujen ohjelmointi onkin tässä suhteessa oma taiteenlajinsa, kun päästään tekemään esim oheislaiteajureita tai jopa omaa käyttöjärjestelmää.
Valitettavasti, erityisesti sulautetuissa laitteissa ohjelmoija voi omalla koodaustyylillään jopa vaikeuttaa RTOS:n toimintaa! Esimerkiksi, jos SensorTagille tehdään koodia Arduino-tyyliin yksittäiseen jättimäiseen while-loopiin ja samalla kadotetaan modulaarisuuden hyödyt. Tässä, jos jossain, on paras uskoa laitevalmistajia..
TI-RTOS:n esittely¶
Kuvassa lohkokaavio TI-RTOS:n, firmiksen ja laiteajurien tarjoamista valmiista toiminnallisuuksista SensorTag-laitteeslle. RTOS tarjoaa ohjelmoijalle rajapintoja (kuvassa punainen alue), jotka piilottavat alemman tason toteutuksen yksityiskohdat, kuten laite-ja komponenttiajurit, reaaliaika-ominaisuudet ja tiedonsiirron detaljit. Tällä kurssilla meitä kiinnostaa sovellustaso, jossa käytämme erilaisia kirjastoja rajapintojen kautta (engl. application programming interface, API). Kurssilla pysymme punaisen alueen sisällä, jota syvemmälle laitteen toiminnassa ei tarvitse mennä.
Mainitsemme joitakin näistä kirjastoista jo nyt, mutta niiden käyttöön ohjelmissa perehdymme yksityiskohtaisesti myöhemmin luentomateriaalissa.
(Kiinnostuneille: Osa RTOS:n lähdekoodista tulee CCS:n asennuspaketin mukana. Niistä voi löytyä paljon muutakin mielenkiintoista, johon ei tässä materiaalissa perehdytä).
Palvelut ja kirjastot¶
Seuraavia kirjastoja tulemme käyttämään ohjelmien toteuttamisessa. Ao. terminologia käydään tulevassa materiaalissa kyllä läpi.
- Pin Kirjasto mikrokontrollerin I/O-pinnien hallintaan. Sensortagin painonappeja ja ledejä ohjataan tätä kautta. Myös GPIO-kirjastolla voidaan ohjata yleisiä I/O-pinnejä.
- driverlib Laiterekisterit ja bittimaskit.
- I2C Kirjasto i2c-tiedonsiirtoväylän käyttämiseen. Moniin SensorTagin antureihin päästään käsiksi tällä kirjastolla.
- Display Kirjasto tekstin ja grafiikan tuottamiseen LCD-näytölle.
- wireless_lib Kurssin henkilökunnan toteuttama kirjasto langattomaan tiedonsiirtoon 6LoWPAN-radioteknologialla.
- (PWM Kirjasto Pulssinleveysmodulaation (PWM) tuottamiseen SensorTagin I/O-pinneillä. PWM:llä voidaan digitaalipinnistä syöttää analogista jännitettä tietyllä taajuudella vaikkapa ledin kirkkauden säätämiseen.)
- (UART Sarjaliikenneprotokolla oheislaitteiden kanssa kommunikointiin. Esimerkiksi PC:lle voidaan lähettää dataa tai laitteelle lähettää komentoja PC:ltä tällä kirjastolla.)
(Kiinnostuneille: Tarkempaa tietoa kirjastosta löytyy TI-RTOS Kernel User Guide:sta ja TI RTOS User's Guide:sta.)
Ohjelman toiminta¶
SensorTag:lle RTOS:ia käyttävät C-kieliset ohjelmat kirjoitetaan lähdekoodimoduleina, ihan samoja periaatteita noudattaen kuin mitkä tahansa C-kieliset ohjelmat. SensorTagin RTOS:n ja kirjastojen syntaksi voi alkuun vaikuttaa kryptiseltä, koska käytetään niin paljon valmista tavaraa. Mutta tässä auttaa koodiin perehtyminen ja miettiminen, että mitä siinä oikeastaan tapahtuu.
Jokaisella ohjelmalla on yksi main-funktio, josta ohjelman suoritus lähtee. Ok, RTOS tekee ensin omiaan piilossa taustalla ennen main-funktion suoritusta, mutat emme murehdi siitä tällä kurssilla.
Alla esimerkki SensorTag-ohjelman
main
-funktiosta:// SensorTagin kirjastot mukaan
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/drivers/I2C.h>
// Globaalit muuttujat aihan samoin alkuun
// Nyt niitä ei esimerkissä ole, mutta malttakaa hetki..
int main(void) {
// Hox! Tästä funktion alusta on jätetty muuttujien esittely pois
...
// Alustetaan laite
Board_initGeneral();
Board_initI2C(); // i2c-väylä käyttöön
// Mahdolliset I/O-määritykset,
// joilla otetaan oheislaitteita käyttöön: pinnit, ym
hLed = PIN_open(&sLed, cLed);
if(!hLed) {
System_abort("Error initializing LED pin\n");
}
...
// Alustetaan sovelluksen eri tehtävät,
// jotka toteutamme itse funktioina
Task_Params_init(&taskParams);
taskParams.stackSize = STACKSIZE;
taskParams.stack = &taskStack;
taskParams.priority=2;
task = Task_create((Task_FuncPtr)taskFxn, &taskParams, NULL);
if (task == NULL) {
System_abort("Task create failed!");
}
// Muita tarvittavia alustuksia, esim. keskeytykset, ajastimet, ym
...
// Lopuksi kerrotaan ohjelmoijalle, että alustus onnistui
System_printf("Hello world!\n");
System_flush();
// Käynnistetään BIOS/RTOS, jolloin tehtävät lähtevät
// suoritukseen
BIOS_start();
return 0;
}
Tarvittavat kirjastot tulee tietenkin esitellä ohjelmaamme esikääntäjän
#include
-lauseella. Sen, mitä ja missä olevia kirjastoja meidän tulee koodissa käyttää, selviää luentomateriaalista, ja yleisesti laitteen ja ohjelmointiympäristön manuaaleista. Sitten ajurikirjastojen kautta käytettävät oheislaitteet tulee alustaa sisäisesti. Pureudutaanpas main-funktion toimintaan hiukan. Kuten huomataan, alussa ensin alustetaan itse laite
Board_initGeneral
-funktiolla. Tämä tarkoittaa sitä, että RTOS:lle ja ohjelmallemme kerrotaan, että se ajaa nyt itseään SensorTag-laitteessa. Jolloin se osaa ottaa huomioon laitteen resurssit, sähköiset kytkennät ja laitekohtaiset I/O-määrittelyt. Lisäksi, tässä esimerkissä haluamme käyttää I2C-kirjastoa kommunikointiin oheislaitteen kanssa, joten se alustetaan kutsulla Board_initI2C
. Oheislaitteiden alustamisen jälkeen alustetaan ohjelmoijalle näkyvä I/O, eli käytettävät I/O-pinnit ja -portit, kuten painonapit tai ledit, ja muut I/O-liitännät oheislaitteisiin. Näistä lisää myöhemmin.
Seuraavaksi alustetaan varsinaisen ohjelman toiminta. RTOS:n kantava ajatus on, että ohjelma jaetaan modulaarisesti tehtäviin (eng. process / task), joita suoritetaan rinnakkain (No, oikeasti peräkkäin yksi kerrallaan käyttöjärjestelmän päättämässä järjestyksessä). Jokainen SensorTagin tehtävä on C-kielinen funktio ja niiden kirjoittamiseen ja käyttöön pätee (varauksin) samat säännöt kuin C-kielen funktioiden yleensä.
Sitten olisi main-funktiossa tilaa tehdä mahdollisia muita alustuksia ohjelman toiminnan ohjaamiseen. Esimerkiksi, jos käytämme ajastimia ohjaamaan taskien suoritusta, ne voidaan alustaa tässä.
Tämän jälkeen on hyvä lähettää terveisiä kehitysympäristön konsoli-ikkunalle, jotta näemme, että laitteen alustus on onnistunut. Konsoli-ikkunaan voidaan kirjoittaa
System_printf
-funktiolla, joka toimii (pienin poikkeuksin) samoin kuin C:n standardikirjaston printf-funktio. Itseasiassa System_printf kerää tulostukset puskuriin, joka tyhjennetään vasta kun ohjelmassa kutsutaan System_flush
-funktiota. Tässä on pieni säädön paikka ohjelmoijalla. Syy tähän käyttäytymiseen on se, että itseasiassa kirjoitus konsolille on laitteemme kannalta erittäin hidas operaatio, joten näin ohjelmoija voi valita sopivan paikan aikaavievää viestien tulostusta varten! Eli, ei kirjoiteta ruudulle silloin kun laite on tekemässä jotain muuta aikakriittistä. Viimeiseksi, funktiossa käynnistetään taskien suoritus kutsulla
BIOS_start
. Sitten, joskun kaikki taskit on suoritettu loppuun, palataan main-funktioon ja suoritetaan se loppuun. Tietenkin nyt sulautettujen tapauksessa tällä arvolla ei ole juuri merkitystä, koska ohjelma pyörii aiemmin mainitussa ikuisessa silmukassa, josta lisää hetken päästä. Tässä tulikin nyt lyhyesti kuvattua SensorTagin main-funktion perusrakenne, joka pätee mille tahansa kirjoitettavalle C-kieliselle ohjelmalle. Huomatkaa, että koodissa käytetään paljon alustuksien jälkeisiä tarkistuksia varmistamaan, että alustut menivät oikein. Nämä tarvitaan juuri siitä syystä, että sulautettuja ohjelmoidessa meillä on rajoitettu näkymä laitteen sisäiseen toimintaan..
Lopuksi¶
Näin olemme tutustuneet ohjelmien suorittamisen perusteisiin RTOS:ssa. Opettelemme RTOS:n käyttöä syvemmin kurssin laboratorioharjoituksessa.
Esimerkkikoodi yllä saattaa vaikuttaa kryptiseltä, aiemman selkeän C-kielen jälkeen, mutta kuten perehtymällä nähdään niin SensorTag-koodissa käytetään paljon valmiita kirjastoja, niiden funktiokutsuja, joilla on oma nimeämiskäytäntönsä, valmiita tietorakenteita, osoittimia ja vakioita. Lähemmin tarkastellen kuitenkin kyse on ihan samasta C-kielestä..
Anna palautetta
Kommentteja materiaalista?