9. Ohjelmistotyö. 9.1 Johdanto

Samankaltaiset tiedostot
9. Luento: Ohjelmistotyö. Tommi Mikkonen,

Arto Salminen,

Ohjelmiston testaus ja laatu. Ohjelmistotekniikka elinkaarimallit

Concurrency - Rinnakkaisuus. Group: 9 Joni Laine Juho Vähätalo

OHJ-4301 Sulautettu Ohjelmointi

ELM GROUP 04. Teemu Laakso Henrik Talarmo

Soveltuvuustutkimus Lifebelt-ohjelman ideologian käytettävyydestä olioorientoituneeseen

Ohjelmiston testaus ja laatu. Testaustasot

Automaattinen yksikkötestaus

Kontrollipolkujen määrä

Ohjelmointi 1. Kumppanit

Ohjelmistojen mallintaminen. Luento 11, 7.12.

Arkkitehtuurikuvaus. Ratkaisu ohjelmistotuotelinjan monikielisyyden hallintaan Innofactor Oy. Ryhmä 14

Simulaattoriavusteinen ohjelmistotestaus työkoneympäristössä. Simo Tauriainen

Ohjelmoinnin perusteet Y Python

Sulautettujen järjestelmien skaala on niin laaja, että on erittäin vaikea antaa yleispätevää kuvausta siitä millainen on sulautettu järjestelmä.

Convergence of messaging

Ongelma(t): Miten mikro-ohjelmoitavaa tietokonetta voisi ohjelmoida kirjoittamatta binääristä (mikro)koodia? Voisiko samalla algoritmin esitystavalla

Ongelma(t): Miten tietokoneen käyttöjärjestelmä toimii sisäisesti, jotta resurssit saadaan tehokkaaseen käyttöön?

CT60A4150 OHJELMISTOTESTAUKSEN PERUSTEET. Jussi Kasurinen Kevät 2016

Palomuurit. Palomuuri. Teoriaa. Pakettitason palomuuri. Sovellustason palomuuri

TIE Ohjelmistojen testaus 2015 Harjoitustyö Vaiheet 1 ja 2. Antti Jääskeläinen Matti Vuori

Testaussuunnitelma. Koskelo. Helsinki Ohjelmistotuotantoprojekti. HELSINGIN YLIOPISTO Tietojenkäsittelytieteen laitos

5. Luento: Rinnakkaisuus ja reaaliaika. Tommi Mikkonen,

AS C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin

Virtualisointiympäristössä on kolme pääosaa: isäntä (host), virtualisointikerros ja vieras (guest).

SEPA diary. Dokumentti: SEPA_diary_PK_HS.doc Päiväys: Projekti: AgileElephant Versio: V0.3

Ohjelmistojen virheistä

Harjoitustyön testaus. Juha Taina

Rekursiolause. Laskennan teorian opintopiiri. Sebastian Björkqvist. 23. helmikuuta Tiivistelmä

11/20: Konepelti auki

ohjelman arkkitehtuurista.

Ohjelmiston toteutussuunnitelma

TKT224 KOODIN KOON OPTIMOINTI

58160 Ohjelmoinnin harjoitustyö

Onnistunut Vaatimuspohjainen Testaus

TIE Tietorakenteet ja algoritmit 1. TIE Tietorakenteet ja algoritmit

Agenda. Johdanto Ominaispiirteitä Kokonaisjärjestelmän määrittely Eri alojen edustajien roolit Sulautetut järjestelmät ja sulautettu ohjelmointi

PRINCIPLES OF PROGRAMMING LANGUAGES - DEBUGGER

dokumentin aihe Dokumentti: Testausraportti_I1.doc Päiväys: Projekti : AgileElephant

Testauksen tuki nopealle tuotekehitykselle. Antti Jääskeläinen Matti Vuori

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. FT Ari Viinikainen

Test-Driven Development

C-ohjelmoinnin peruskurssi. Pasi Sarolahti

Älysopimusten kehittäminen. Sopimus suuntautunut ohjelmointi

Ohjelmoinnin perusteet, syksy 2006

Testaustyökalut. Luento 11 Antti-Pekka Tuovinen. Faculty of Science Department of Computer Science

S11-09 Control System for an. Autonomous Household Robot Platform

Ohjelmoinnin perusteet Y Python

Testauksen hallinta Testaustyökalut Luento 7 Antti-Pekka Tuovinen

UML -mallinnus TILAKAAVIO

S14 09 Sisäpeltorobotti AS Automaatio ja systeemitekniikan projektityöt. Antti Kulpakko, Mikko Ikonen

UCOT-Sovellusprojekti. Testausraportti

TTY TKT-1110 Mikroprosessorit TKT. HEW-ohjeet ver 1.0

Ohjelmoinnin peruskurssi Y1

Test-Driven Development

Versio Päiväys Tekijä Kuvaus Tikkanen varsinainen versio

TIES530 TIES530. Moniprosessorijärjestelmät. Moniprosessorijärjestelmät. Miksi moniprosessorijärjestelmä?

Uudelleenkäytön jako kahteen

Ohjelmiston testaus ja laatu. Testausmenetelmiä

Ohjelmointi 1 / syksy /20: IDE

Yksikkötestaus. import org.junit.test; public class LaskinTest public void testlaskimenluonti() { Laskin laskin = new Laskin(); } }

BlueJ ohjelman pitäisi löytyä Development valikon alta mikroluokkien koneista. Muissa koneissa BlueJ voi löytyä esim. omana ikonina työpöydältä

KONEAUTOMAATION LAATU JA TURVALLISUUS Marko Varpunen

12. Javan toistorakenteet 12.1

T Testiraportti - integraatiotestaus

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. Assembly ja konekieli

TOIMINNALLINEN MÄÄRITTELY MS

Liite 1: KualiKSB skenaariot ja PoC tulokset. 1. Palvelun kehittäjän näkökulma. KualiKSB. Sivu 1. Tilanne Vaatimus Ongelma jos vaatimus ei toteudu

Vaatimusmäärittely Ohjelma-ajanvälitys komponentti

S Elektroniikan häiriökysymykset. Laboratoriotyö, kevät 2010

TT00AA Ohjelmoinnin jatko (TT10S1ECD)

Onnistunut SAP-projekti laadunvarmistuksen keinoin

4. Lausekielinen ohjelmointi 4.1

Virtualisointi Kankaanpään kaupungissa. Tietohallintopäällikkö Jukka Ehto

Web-palvelu voidaan ajatella jaettavaksi kahteen erilliseen kokonaisuuteen: itse palvelun toiminnallisuuden toteuttava osa ja osa, joka mahdollistaa k

Ohjelmoinnin peruskurssi Y1

Oleelliset vaikeudet OT:ssa 1/2

Enterprise SOA. Nyt. Systeemi-integraattorin näkökulma

Onnittelut PC SpeedCAT perheeseen liittymisestä

TAMPEREEN TEKNILLINEN YLIOPISTO Digitaali- ja tietokonetekniikan laitos. Harjoitustyö 4: Cache, osa 2

T Testiraportti - järjestelmätestaus

Simulaattorin asennus- ja käyttöohje

Testausdokumentti. Kivireki. Helsinki Ohjelmistotuotantoprojekti HELSINGIN YLIOPISTO Tietojenkäsittelytieteen laitos

Tutoriaaliläsnäoloista

Algoritmit. Ohjelman tekemisen hahmottamisessa käytetään

PC-LAITTEEN TESTAAMINEN

4. Luento: Prosessit ja säikeets. Tommi Mikkonen,

2 Konekieli, aliohjelmat, keskeytykset

12. Javan toistorakenteet 12.1

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit

5. HelloWorld-ohjelma 5.1

PC-LAITTEEN TESTAAMINEN

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

Ohjelmoinnin peruskurssi Y1

GIS-automatisointi ja ohjelmointi/skriptaus. Harri Antikainen

Automaattinen regressiotestaus ilman testitapauksia. Pekka Aho, VTT Matias Suarez, F-Secure

Tik Tietojenkäsittelyopin ohjelmatyö Tietotekniikan osasto Teknillinen korkeakoulu. LiKe Liiketoiminnan kehityksen tukiprojekti

TIETOKONE JA TIETOVERKOT TYÖVÄLINEENÄ

Pong-peli, vaihe Aliohjelman tekeminen. Muilla kielillä: English Suomi. Tämä on Pong-pelin tutoriaalin osa 3/7. Tämän vaiheen aikana

Transkriptio:

148 Sulautettu ohjelmointi 9. Ohjelmistotyö Vaikka sulautettujen järjestelmien ohjelmointi sinänsä ei periaatteessa juurikaan eroa muusta ohjelmoinnista, on joitakin erityispiirteitä, jotka ovat voimakkaammin läsnä sulautettujen järjestelmien suunnittelussa ja toteutuksessa. Käymme seuraavassa läpi joitakin tällaisia ominaisuuksia. Lisäksi esittelemme myös jonkin verran hyväksi osoittautuneita käytäntöjä. 9.1 Johdanto Sulautettujen järjestelmien erityispiirteitä ovat se, että kehitystyö, ja usein myös mahdollisuuksien mukaan testaus, suoritetaan eri ympäristössä kuin missä ohjelmaa tullaan lopulta suorittamaan. Muita erityispiirteitä ovat paitsi ohjelmiston testaus myös laitteiston toiminnan oikeellisuuden varmentaminen, sekä tarpeen mukaan myös ajossa olevan ohjelmiston päivittäminen, joskus jopa siten, että käyttökatkot eivät ole sallittuja. Oman haasteensa tuo mukanaan se, että monet järjestelmät on rakennettava käyttäen varsin harvinaisia ja erikoislaatuisia perustyökaluja, kuten esimerkiksi kääntäjiä, joihin voi liittyä erilaisia ongelmia. Tästä syystä on usein aiheellista testata myös kehitysympäristö rakentamalla minimaalinen versio ohjelmistosta, joka kuitenkin on mahdollista käynnistää aidossa kohdeympäristössä. Koska rajapintaerojen lisäksi sulautetussa järjestelmässä on usein sellaisia laitteita, joita ei kehitysympäristössä ole käytettävissä, ei lopullista testausta voida tehdä kuin vasta kohdekoneessa. Jotta kohdekoneella tehtävää testausta olisi mahdollisimman vähän, käytetään apuna testiympäristöjä. Tällainen testiympäristö on kehityskoneessa toimiva ohjelmisto, joka toteuttaa kohdekoneen ominaisuudet mahdollisimman tarkkaan ja simuloi niitä osia, joita ei voida muulla tavalla toteuttaa.

Ohjelmistotyö 149 Käytännössä kehitysympäristö voi olla hyvinkin monimutkainen, varsinkin, jos sama ohjelmisto on yhtä aikaa käytössä eri kohdekoneissa. Ohjelmointiympäristönä voi toimia työntekijän työasema, ristikäännöskoneena toinen, verkossa oleva kone ja testausympäristönä kolmas työasematyyppinen kone. Neljäs kone on sitten se varsinainen kohdekone tai -laite, jolle ohjelmisto siirretään tuotantokäyttöä ja -testejä varten. Tällaisessa ympäristössä ohjelmoijalta vaaditaan harvinaisen tiukkaa itsekuria, jotta ohjelmistojen siirrettävyys ympäristöstä toiseen olisi mahdollisimman helppoa ja ympäristökohtaiset erityistarpeet pieniä. Yleisin ohjelmointikieli sulautetuissa järjestelmissä on C, jonka osuus on yli 60 % 20. C++:n osuus on yli 20 %. Itse asiassa C:n osuus kasvanut viime vuosina; keväällä 2010 se ohitti Javan yleisimpänä käytettynä kielenä (Tiobe 2010). Pääohjelmointikielestä riippumatta tietyt järjestelmän osat vaativat edelleen assemblyn käyttöä, varsinkin kaikkein suorituskykykriittisimmissä ja laitteistonläheisimmissä tilanteissa. On tosin myös todettava, että joidenkin suoritinten käskykannat ovat niin monimutkaisia, että ei ole enää aivan selvää, tarjoaako assemblyn käyttö merkittävää suorituskyvyn lisäystä. Sulautetuissa järjestelmissä tyypillisten laitteistojen tapauksessa näin kuitenkin yleensä on edelleen, johtuen ehkä siitä, että kaikkein uusimpia ja erikoisimpia laitteita ei yleensä oteta käyttöön sulautetussa ympäristössä. 9.2 Ristikehitys Ristikehityksellä tarkoitetaan sitä, että ohjelmat kirjoitetaan ja käännetään eri arkkitehtuurin tai käyttöjärjestelmän koneella kuin missä niitä tullaan käyttämään. Sulautetuissa järjestelmissä kohdekone on yleensä sellainen, että normaali ohjelmankehitys siinä on mahdotonta. Toisaalta, vaikka kehittäminen olisikin periaatteessa mahdollista, sitä ei aina kannata tehdä kohdekoneessa, koska sen ominaisuudet eivät välttämättä toimi hyvin kehitysympäristönä. Yksinkertaisimmillaan ristikehityksessä ohjelmat kirjoitetaan ja käännetään toisella koneella ja siirretään sitten ajettavaksi lopulliseen ympäristöön (kuva 9.1). Tällöin ristikehitys on vain ohjelmoinnin alusta, eikä esimerkiksi auta testausta lainkaan. 20. Michel Barr: Real men program in C, http://embedded.com/columns/barrcode/218600142?printable=true, 1.8.2009.

150 Sulautettu ohjelmointi Kehitystyöasema Laite Lähdekoodi ristikäännös Laitteelle käännetty siirto Laitteessa suoritettava Kuva 9.1 Ristikäännös Usein ristikehityksessä on käytettävissä kääntäjä, joka tuottaa koodia ristikehityskoneelle. Tällöin voidaan ainakin osa moduulitestausta tehdä tavanmukaisin menetelmin ristikehitysympäristössä. Mahdollinen riski tässä on muun muassa siinä, että kohdekoneen kääntäjä toimii hieman eri tavalla, jolloin "oikeaksi" testattu ohjelmisto ei toimikaan kohdekoneessa oikein. Kääntäjän virhettä suurempi ongelma on se, jos käytössä olevien käyttöjärjestelmien rajapinnat ovat erilaiset. Tällaiset rajapintaongelmat voidaan kiertää tekemällä oma rajapintamoduuli, jonka toteutus on kehitys- ja kohdeympäristössä erilainen, mutta jonka rajapinta ei muutu ympäristöstä toiseen. Luonnoillisesti tässä ratkaisussa ongelmaksi tulee tämän rajapinnan yhtenevä toteutus kummassakin ympäristössä. Laite, johon ohjelmisto asennetaan, saattaa myös vaatia jotain erikoistoimenpiteitä, ennen kuin ohjelmiston suoritus on mahdollista. Esimerkiksi moniin matkapuhelimiin pitää uudet sovellukset tuoda asennuspaketteina, joihin on mahdollista liittää erilaisia varmenteita. Näiden varmenteiden avulla voidaan myöhemmin varmentaa, kuka sovelluksen on toteuttanut. Tällaiset varmenteet ovat kuitenkin verraten harvinaisia, ja useimmiten ohjelmoijalle riittää ohjelmiston siirtäminen oikeaan paikkaan laitteessa, josta se käynnistyy automaattisesti, kun laitteeseen kytketään virta päälle. 9.3 Testaus ja virheiden jäljitys yleensä Virheiden jäljittäminen on sulautetuissa järjestelmissä hankalampaa kuin tavallisesti, koska ohjelmaa ei ainakaan kokonaan voi testata samassa ympäristössä kuin missä sitä tehdään. Tämä tarkoittaa sitä, että normaaleja jäljitysohjelmia (debug) ei voida käyttää, eikä tavallisesti käytössä olevia testausohjelmiakaan ainakaan koko ohjelmiston osalta. Lisäongelmista mainittakoon se, että pienetkin muutokset ohjelmistossa esimerkiksi ajoitusongelmien etsimiseksi saattavat peittää itse on-

Ohjelmistotyö 151 gelman, eikä varsinkaan aloitusvaiheessa ole varmuutta siitä, testataanko laitteistoa vai ohjelmistoa tai ainakaan siitä, kummassa mahdollinen vika on. Itse asiassa havaitut ongelmat voivat johtua jopa laitteiston ja ohjelmiston yhteistoiminnasta jossakin tietyssä ääritilanteessa. Tietenkin haaveena on täysin virheetön järjestelmä, mutta siihen on käytännössä hyvin vaikea ellei mahdoton päästä. Ratkaisuja on yritetty löytää hyvin erilaisista lähtökohdista lähtien, toiset lähtien työn organisoinnista, toiset formaaleista menetelmistä. Myös niin sanottu Cleanroom-ideologia, jossa lähtökohtaisesti pyritään estämään virheiden syntyminen joka kohdassa prosessia jo tehtyjen virheiden korjaamisen sijaan, on mahdollinen lähestymistapa, varsinkin silloin, kun ollaan tekemisissä ajastuksiin liittyvien yksityiskohtien kanssa. 9.3.1 Virheen paikantaminen Kun virhe on havaittu, sen paikantaminen ohjelmasta voi olla melkoinen ongelma, sillä mitä monimutkaisempi ohjelma, sitä hankalampi on tunnistaa virheen alkuperä. Virhe kun on voinut syntyä aivan eri puolella ohjelmistoa, kuin missä se havaitaan. Monen prosessin (säikeen) ympäristössä vika on voinut tulla toisesta prosessista, jolloin vikaa etsitään aluksi aivan väärästä paikasta, tai olla peräisin vaikkapa oheislaitteen virheellisestä toiminnasta. Hankalimmat viat johtuvat ajoituksen pettämisestä: tällöin järjestelmä voi toimia melkein aina, mutta sekoaa ennalta aavistamattomasti silloin tällöin. Yhdistelmä, joka aiheuttaa vian, voi olla niin harvinainen, ettei mikään testausjärjestelmä voi sitä varmasti havaita. Mikäli vika on todella harvinainen, sitä ei välttämättä tarvitse edes korjata, koska laitteen elinikä tai laitteistotason vikojen väliaika voi olla lyhyempi kuin vian ilmenemisfrekvenssi. Toisaalta, jos laite on tarpeeksi kriittinen, vika on tällaisessakin tapauksessa löydettävä ja korjattava. Koska ajoitusvirheet ovat erittäin hankalia havaita, tulisi järjestelmän ajastukset suunnitella etukäteen aivan vedenpitäviksi, jotta niitä ei myöhemmin tarvitsisi edes epäillä ongelmien syyksi. Omat ongelmansa tähän tuo tietenkin ylläpito, jonka seurauksena aiemmat oletukset saattavat osoittautua vääriksi esimerkiksi uuden, tehokkaamman laitteiston myötä. Myös dynaaminen muisti voi aiheuttaa hankalia ongelmia. Tämä sen takia, että sekä jäänneviittaus että roskaantuminen voivat ilmetä aivan eri kohdassa kuin missä itse virhe on. Tämän takia dynaamista

152 Sulautettu ohjelmointi muistinkäyttöä pyritään välttämään sulautetuissa järjestelmissä, kuten jo aiemminkin todettiin. Edellä oletettiin, että virhe on jotenkin havaittu. Kun virhe on havaittu, puolet ongelmasta on ohi: tarvitsee vain löytää se virhe ohjelmasta. Havaitsemattoman virheen löytäminen vasta vaikeaa onkin, sillä sitä etsiessä ei voi olla varma sen olemassaolosta, jolloin etsimisen varmaa lopetusehtoa ei ole olemassa. Testauksessa pyritään siihen, että mahdollisimman suuri osa virheistä havaitaan, paikannetaan ja korjataan. Yleisesti käytössä olevia testaustapoja ovat muun muassa testipedit ja pöytätestaus, joita käsittelemme seuraavassa. Näiden lisäksi tutustumme lyhyesti myös profilointiin, jonka käyttöön sulautetussa ympäristössä liittyy kuitenkin joitakin käytännön ongelmia. 9.3.2 Pöytätestaus Pöytätestauksesta on kaksi versiota, josta kevyempi tarkoittaa sitä, että ohjelman tekijä selittää toiselle ohjelmoijalle, mitä ohjelman pitäisi tehdä. Menetelmän kummallisuus on siinä, että kuuntelijan ei tarvitse edes ymmärtää, riittää, kun hän kuuntelee ja tekee välillä kysymyksiä. Usein näennäisesti tyhmimmät kysymykset ovat parhaita, sillä juuri itsestäänselvyyksien kohdalla syntyy eniten virheitä. Menetelmän teho lienee siinä, että voidakseen selittää toiminnan toiselle ohjelmoijalle alkuperäisen tekijän on selitettävä se paremmin kuin koskaan sen itsellensä tekisi. Raskaampi versio pöytätestauksesta on sitä, että ohjelmaa käydään läpi rivi riviltä, ja toiminta tarkistetaan ikään kuin suorittamalla käskyt käsin. Tällä menetelmällä pitäisi löytyä myös siirrettävyyteen vaikuttavia ongelmia, kuten sijoituskäsky mallia i = i++; joka on syntaksiltaan kunnossa, mutta semantiikaltaan määrittelemätön. Tästä esimerkistä voi edelleen johtaa sen, että C ei ole edes sulautettujen järjestelmien tekemiseen paras mahdollinen kieli, vaikka sitä paljon toteutustyössä käytetäänkin. Toisaalta C:llä on myös hyvät puolensa, sillä C-kääntäjiä on saatavilla useisiin eri laiteympäristöihin. Lisäksi tavallisimmat C-kirjastot siis ne, jotka tarjoavat funktioita kuten itoa, fopen tai printf ovat niin yksinkertaisia, että ne voidaan tarvittaessa toteuttaa osana omaa sovellusta, jos niitä ei syystä tai toisesta ole valmiina saatavilla kyseiseen ympäristöön. Sen sijaan esimerkiksi C++:n kirjastot, kuten vaikkapa Standard Template Library (STL), ovat jo niin mon-

Ohjelmistotyö 153 imutkaisia, että niiden siirto ympäristöstä toiseen vaatii yleensä merkittävää siirtotyötä. 9.3.3 Testipedit Testipeti on ohjelmisto, jolla testattavan järjestelmän moduuleita voidaan testata joko interaktiivisesti käyttäjän ohjaamana tai eräajotyyppisesti suorittamalla etukäteen tallennetut käskyt ja vertaamalla tulosta odotettuun. Aina, kun ohjelmaan tehdään muutos, oli se sitten korjaus tai uuden ominaisuuden lisääminen, tulee testiaineisto ajaa uudelleen järjestelmän läpi sen varmistamiseksi, että muutos ei ole vaikuttanut vanhoihin, toimiviin ominaisuuksiin (niin sanottu regressiotestaus). Testausaineiston tekeminen riippuu siitä, miten paljon ohjelman toteutuksesta tiedetään. Kokonaisjärjestelmästä vastuussa oleva yritys voi varmistaa alihankkijalta saatua koodia testaamalla sen vielä itse. Tällöin on kyseessä "musta laatikko" -testaus, koska testi perustuu vain järjestelmän rajapintaan ja toiminnalliseen määrittelyyn. "Valkoinen laatikko" tai paremminkin läpinäkyvä laatikko tarkoittaa sitä, että moduulin toteutustapa tunnetaan ainakin pääpiirteissään, jolloin testit pyritään tekemään niin, että mahdollisimman suuri osa ohjelmasta saadaan testattua. Testin kattavuus on siis hyvä, joskaan vähänkään monimutkaisemmassa ympäristössä harvoin täysi sata prosenttia. Testipeti on valmisohjelmisto, johon testattava ohjelmisto tai sen osa voidaan liittää. Voidaan tehdä myös niin, että kirjoitetaan erillisiä testaus(pää)ohjelmia moduulien testaukseen. Laajasti jälkimmäistä menetelmää ei kannata käyttää, mutta pienessä mittakaavassa tämäkin toimii. 9.3.4 Profilointi Profilointia ei aina mainita testauksen yhteydessä. Profiloinnilla pyritään löytämään ne ohjelman osat, joissa ohjelma viipyy pisimpään. Tarkoituksena on tunnistaa ne ohjelman osat, jotka mahdollisissa ajoitusongelmissa on ensisijaisesti pyrittävä optimoimaan. Koska optimointiin ei pidä ryhtyä missään järjestelmässä, jos se ilman sitäkin täyttää järjestelmälle annetut vaatimukset, profiloinnin merkitys ei tavallisesti ole iso. Toisaalta pahimmillaan sulautettu järjestelmä on samaan aikaan sekä reaktiivinen että reaaliaikainen, jolloin profilointia voidaan hyvinkin tarvita, varsinkin, jos järjestelmässä on vaikeasti saavutettavissa olevia kovia reaaliaikavaatimuksia.

154 Sulautettu ohjelmointi Profilointi tehdään yleensä kehitysympäristössä. Niinpä siihen liittyy kehitysympäristötestauksen yleiset ongelmat, koska kohdekoneen arkkitehtuuri voi olla niin erilainen, että tulos ei välttämättä paljasta oikeaa pullonkaulaa. Lisäksi profiloinnin aikana suoritettavat toimenpiteet, kuten profilointitiedon kerääminen ja tallettaminen esimerkiksi tiedostoon voivat vaikuttaa siihen, missä pullonkaula on. Yleensä näissäkin tilanteissa profilointi pystyy kuitenkin osoittamaan oikean ohjelman osan kohtalaisen hyvällä tarkkuudella. Siksi sen harkittua käyttöä voi perustella sulautetussa ympäristössä mahdollisista ongelmista huolimatta. 9.4 Testaus ja jäljitys kehitysympäristössä Vaikka koko sulautetun järjestelmän toimintaa ei voi testata kuin lopullisessa kohdelaitteessa, voidaan ainakin osa testauksesta tehdä myös järjestelmän kehitys- eli ohjelmointiympäristössä. Toisin sanoen osa moduulitestauksesta voidaan tehdä kehitysympäristössä. 9.4.1 Testaaminen ja jäljitys kehitysympäristön työkaluilla Kehitysympäristössä testaamisessa on montakin hyötyä: testaukseen ja virheiden jäljitykseen on käytettävässä laajemmat ja monipuolisemmat työkalut ja työskentely on nopeampaa. Lisäksi suoritettavaa sovellusta ei tarvitse siirtää kohdelaitteelle, vaan sitä voidaan ajaa suoraan kehitysympäristössä. Kehitysympäristön käytössä on myös ongelmansa: mikäli käyttöjärjestelmä tai suoritin on eri kuin kohdejärjestelmässä, voi jokin kutsu tai ohjelma toimia kehitysympäristössä, mutta ei kohdejärjestelmässä. Samallakin käyttöjärjestelmällä voi olla eroja sulautetussa ytimessä ja yleisessä joskin nämä erot eivät yleensä ole tarkoituksellisia. Eri suoritin johtaa myös eri kääntäjän käyttämiseen, jolloin mahdolliset kääntäjän virheet ovat erilaisia. Tämä voi tulla vastaan samallakin suorittimella, jos kehitysympäristön ja kohdeympäristön käyttöjärjestelmä on eri. Testaus eri kääntäjällä voi tuottaa toimivan tuloksen, mutta varsinaisen kohdekoneen kääntäjän virhe aiheuttaakin sitten yllätyksen, kun ohjelma siirretään lopulliseen kohteeseensa. Edellä olleista ongelmista huolimatta kehitysympäristössä testaaminen kannattaa aina, sillä sen avulla saadaan looginen toiminta oikeaksi. Parhaassa tapauksessa voidaan testata jopa kokonainen osajärjestelmä ja testaus on mahdollista tehdä kattavammaksi kuin kohde-

Ohjelmistotyö 155 järjestelmässä. Tämä kehitysympäristössä tapahtuva testaus ei kuitenkaan vapauta testauksesta lopullisessa järjestelmässä. 9.4.2 Järjestelmän simulointi Järjestelmän simuloinnissa varsinainen ohjelma käännetään kohdekoneen ymmärtämään muotoon, mutta sen sijaan, että ohjelmaa ajettaisiin kohdeympäristössä, sitä ajetaankin simulaattorin avulla kehitysympäristössä. Tässä ratkaisussa simulaattori tulkitsee kohdekoneen konekieltä ja toimii sen mukaan. Simulaattoriin on voitu kuvata myös järjestelmän oheislaitteet, joten tällä tavalla voidaan testata ja jäljittää virheitä myös oheislaitteita ohjaavista ohjelman osista, mikä pelkillä kehitysympäristön työkaluilla ei ole mahdollista. Simulaattorin avulla voidaan löytää myös kohdekoneen kääntäjän virheitä. Simulaattorin ongelmana on se, että oheislaitteiden toimintaa myös simuloidaan. Jos ohjattavana on monimutkainen kokonaisuus, ei simulointiympäristö pysty tuottamaan aitoja reaktioita järjestelmän tekemiin ohjauksiin. Tarpeeksi yksinkertaisissa tapauksissa reaktiot voivat olla lähes oikean kaltaisia, mutta koskaan ne eivät täydellisesti vastaa aidon järjestelmän vastineita. Simulaattorin avulla voidaan kuitenkin tehdä perustestaus ennen kuin ohjelmaa aletaan testata kohdelaitteessa, sillä aidossa ympäristössä testaaminen on oikeastaan aina merkittävästi hitaampaa ja kalliimpaa kuin simulaattoriympäristössä. Markkinoilla on simulaattoreita useimmille yleisille suorittimille, osa näistä on jopa ilmaisia mikä kyllä valitettavasti näkyy myös ominaisuuksien määrässä ja joskus myös toteutuksen laadussa (ja sitä myötä myös käyttökelpoisuudessa ohjelmistokehityksessä). 9.4.3 Virtualisointi Simuloinnin lisäksi on kohdejärjestelmä mahdollista myös virtualisoida. Tällöin saavutetaan yleensä dynaamisempi joukko suorituksia, olettaen, että virtualisointi on mahdollista ulottaa niin pitkälle, että simuloitujen laitteiden sijaan voidaan käyttää jotain todellista järjestelmää, joka toimii samaan tapaan kuin mitä kohdejärjestelmä. Toinen virtualisoinnin tarjoama etu simulointiin verrattuna on, että mikäli valitaan laitteistot sopivasti, voidaan virtualisoitua järjestelmää käyttää kehitysympäristönä. Tämä on osoittautunut käytännössä

156 Sulautettu ohjelmointi käteväksi ratkaisuksi esimerkiksi silloin, kun kehitetään ohjelmistoja sulautettuun Linux-ympäristöön. Joissakin tapauksissa kokonaisia virtualisointi-imageja 21 voi olla saatavilla. Tällöin yleensä riittää imagen asentaminen oman virtualisointiympäristön avulla, joskin esimerkiksi näppäimistöasetusten ja muiden pienten käytännön yksityiskohtien kanssa voidaan törmätä ongelmiin, sillä imagen tekijä on voinut käyttää erilaista kokoonpanoa, kuin mitä kehittäjällä on käytettävissään. Samoin kuin simulaattoreita, myös virtualisointiympäristöjä on saatavilla useita, ja jopa ilmaiset ympäristöt ovat usein varsin käyttökelpoisia ainakin pienimuotoiseen ohjelmistokehitykseen. 9.5 Testaus ja jäljitys kohdejärjestelmässä Lopullinen testaus tehdään aina kohdejärjestelmässä. Koska usein laitteistoa tehdään yhtä aikaa ohjelmiston kanssa, tähän vaiheeseen päästään suhteellisen myöhään. Onkin sanottu, että sulautetun järjestelmän testaus alkaa siitä, mihin tavallisen ohjelmiston testaus loppuu. 9.5.1 Johdanto Tavallisen peräkkäisohjelman jäljittäminen (debug) on suhteellisen helppoa, sillä toiminta on aina vain lähtötietojen funktio. Suhteellinen helppous ei silti tee jäljityksestä varsinaisesti helppoa. Mikäli ohjelma jakautuu säikeisiin, tulee jäljityksestä tavallisessakin ympäristössä todella hankalaa. Sulautetuissa järjestelmissä jäljitys on vaikeampaa, koska normaali jäljitintekniikka ei pure, ja ohjelmiston rakenne on usein säikeisiin perustuva. Apuna käytetään emulaattoreita, logiikka-analysaattoreita, laitteeseen lisättyjä seurannan apuliittymiä tai näiden yhdistelmiä. Mikäli laitteessa on jokin monitorilaite, ohjelmat voivat välittää tilastaan tietoja tälle. Erityisiä apulaitteita ovat esimerkiksi merkkivaloina toimivat ledit. Näille voidaan ohjata suorittimen tila (esimerkiksi idle-tila), ajossa olevan prosessin numero (jos ledejä on tarpeeksi monta), tilatieto siitä, onko suoritin tekemässä keskeytyskäsittelyä, keskeytyskielto voimassa, vai onko suoritus kriittisellä alueella. Ledi voisi myös palaa monisuoritinkoneessa aktiivisen odotussilmukan (spin-lock) suorituksen ajan. 21. image ohjelman "kuva", sen binaarikoodi.

Ohjelmistotyö 157 Mitä tietoja ledien annetaan ilmoittaa on kiinni siitä, mikä kuvitellaan tai tiedetään järjestelmässä tärkeäksi. Esimerkiksi keskeytyskieltoledin ei pitäisi palaa jatkuvasti. Ledien sijaan tai niiden rinnalla voidaan tila siirtää myös toiselle koneelle tai logiikka-analysaattorille analysoitavaksi. 9.5.2 Logiikka-analysaattori Logiikka-analysaattoreilla voidaan tutkia normaalinopeudella toimivan suorittimen tai väylän liikennettä. Laitteella voidaan muun muassa ottaa vauhdissa kopio väyläliikenteestä ja tulkita siitä jälkeenpäin askel askeleelta, mitä laite on tehnyt. Hyvä analysaattori osaakin muuttaa bittivirran symboliseen konekoodimuotoon, jolloin ohjelmaa on helpompi seurata. Jos käytettävissä on muistikartta, jopa aliohjelmien ja staattisten muuttujien nimet saadaan selväkielisiksi. Koska yleensä ollaan kiinnostuneita jostain tietystä tapahtumasta, eikä kaikkea liikennettä voida tallettaa pitkältä ajalta, logiikkaanalysaattoreilla voidaan asettaa kopion teon alkamiselle ehto. Laukaisuehto voi esimerkiksi olla viittaaminen johonkin tiettyyn osoitteeseen tai jonkin signaalin tilamuutos. Logiikka-analysaattori pystyy laskemaan aliohjelmille tunnuslukuja, joita voidaan käyttää huoltotoiminnassa testaamaan, onko toiminta normaalia vai ei. Ideana on siis laittaa huoltokirjaan erilaisia laukaisuehtoja vastaavia tunnuslukuja, joiden avulla vikaa voidaan yrittää paikantaa. Niin kuin monessa muussakin vastaavassa tilanteessa, välimuistien käyttö pilaa hyvän yrityksen. Koska logiikka-analysaattori seuraa väylän liikennettä, välimuistin toiminta kätkee suuren osan todellisesta liikenteestä analysaattorilta. Tämän takia logiikka-analysaattori on käyttökelpoinen vain harvoissa tapauksissa, ja tämän tason testausta varten sopii paremmin emulointi. 9.5.3 Emulointi Emuloinnissa suorittimen paikalle laitetaan välikannan tai muu sellainen avulla piirikortti, joka pystyy tekemään suorittimen työt. Tyypillisesti emulaattorin avulla voidaan ajaa ohjelmaa askel kerrallaan, tarkastella muuttujien arvoja ja asetella niitä. On myös mahdollista ajaa ohjelmaa sen normaalilla nopeudella. Tässäkin tapauksessa ohjelman suoritus voidaan pysäyttää ennalta määrätyssä tilanteessa (viittaus tiettyyn muuttujaan, hyppy mielenkiintoiseen aliohjelmaan). Parhaimmilla em-

158 Sulautettu ohjelmointi ulaattoreilla työskentely vastaakin tavallisen järjestelmän debuggerilla työskentelyä. Joissakin suorittimissa on erityisiä järjestelmiä emuloinnin helpottamiseksi. Tällaisia ovat muun muassa ulkoinen kello, jonka saa hidastaa nollaan asti tai normaalin toiminnan kannalta turhia lisäliityntöjä, joiden avulla suoritin saadaan johonkin erikoistilaan. Vaikka emulaattorilla pystytäänkin tekemään paljon, sekään ei pysty kaikkeen. Esimerkiksi, jos vika on ajoituksessa, pienikin muutos nopeuksissa voi hävittää vian täysin. Mitenkään tavatonta ei "tavallisessakaan" ympäristössä ole se, että ohjelma toimii, kun aputulostuksia on, mutta ei toimi, kun niitä ei ole. Toinen esimerkkiongelma liittyy muisteihin: emulaattorissa on usein enemmän muistia kuin todellisessa järjestelmässä, jolloin kaikki viat eivät näy. Toisaalta ohjelma saattaa toimia kohdelaitteessa oikein (tai ainakin näennäisesti oikein), mutta se ei toimi lainkaan emulaattorissa. Tällainen tilanne voi tulla siitä, että ohjelma kirjoittaa lukumuistiin, joka kohdelaitteistossa ei vaikuta mitään, mutta saattaa emulaattorissa sekoittaa sen toiminnan, koska lukumuistin paikalla onkin luku kirjoitusmuistia. (Kirjoitus on väärin joka tapauksessa, mutta se ei ilmene kohdejärjestelmässä.) 9.5.4 Erillinen testijärjestelmä Toteutettaessa kalliita sulautettuja järjestelmiä, joita ei voida helposti testata niiden normaalissa käyttöympäristössä, on joskus mahdollista rakentaa erillinen testiympäristö, jossa ohjelma osana kokonaisjärjestelmää voidaan testata niin lähellä todellista ympäristöä kuin mahdollista. Tällöin kyseeseen tulevat lähinnä avaruus- ja ilmailualan järjestelmät, joiden testaaminen voisi muuten olla mahdotonta. Erillisen testijärjestelmän joka sekin on mitä todennäköisimmin sulautettu järjestelmä rakentaminen lienee tällaisessa tapauksessa oma projektinsa, ja sitä tekemään valjastetaan oma projektiorganisaationsa. Periaate muistuttaa vähän ohjelmistotestauksen V-mallia, jossa ohjelmiston määrittelyä vastaa hyväksymistestaus, suunnitelmaa integrointitestaus, ja yksityiskohtaista suunnittelua moduulitestaus. Tässä tapauksessa malliin lisätään yksi taso, jossa lähtökohdaksi otetaan koko järjestelmän vaatimukset, ja rakennetaan niitä vastaava testiympäristö. Lienee ilmeistä, että erillisen testijärjestelmän rakentaminen on merkittävästi kalliimpaa kuin yleiskäyttöisten testijärjestelmien käyttö.

Ohjelmistotyö 159 9.5.5 Tiedon siirto toiselle koneelle analysoitavaksi Mikäli järjestelmässä on käytettävissä joko erityinen liityntä tapahtumatietojen siirtämiseksi toiselle koneelle tai merkittävä osa järjestelmän tiedoista kulkee jotain väylää pitkin, voidaan tapahtumatietoja siirtää toiselle koneelle analysoitavaksi. Analysointi voi tapahtua joko välittömästi tai jälkikäteen. Jos tapahtumatiedot kaapataan normaalitoimintatilanteessa sisäiseltä väylältä, kaappaaminen ei vaikuta järjestelmän muihin ominaisuuksiin, ja saatu loki vastaa todellista toimintaa. Ongelma tässä on usein siinä, että sisäisellä väylällä ei välttämättä liiku tarpeeksi tietoa varsinaista analysointia varten. Jos sitten tuotetaan seurantaa varten lisäviestejä, nämä lisäviestit voivat vaikuttaa järjestelmän toimintaan erityisesti ajoitustasolla. Tuloksia käsiteltäessä tulee tämä ottaa huomioon. Jos tapahtumatietoja varten on tehty oma liittymänsä, voidaan tapahtumatiedot lähettää sitä pitkin toiselle koneelle. Tapahtumailmoitusten generointi aiheuttaa tässä tapauksessa aina ylimääräistä työtä, joka edelleen voi häiritä järjestelmän ajoituksia. Tapahtumien generoinnissa on se ongelma, että kaikkia tapahtumia ei varmasti pystytä tallentamaan. Tämän takia joudutaan valitsemaan ne tapahtumat, joista loki tehdään. Tyypillisesti tällöin on tiedossa jokin ongelmatilanne, jota yritetään paikallistaa, ja yleisellä ohjelmiston tuntemuksella valitaan ne viestit, joiden odotetaan paljastavan ongelman lähteen. Tapahtumien generointi voidaan toteuttaa ehdollisen kääntämisen avulla. Näin voidaan lopullisesta ohjelmasta poistaa ylimääräinen jäljitykseen tarvittava koodi. Varjopuolena tässä on se, että lopullinen ohjelma ei ole identtinen testatun kanssa, ja jotkin (harvinaiset) kääntäjän virheet saattavat aiheuttaa virhetoiminnan lopullisessa tuotteessa. 9.6 Laitteiston testaus Edellä olevat kohdat koskivat lähinnä ohjelmiston testausta tai tarkemmin joitain erityistoimia, joita sulautetun järjestelmän testauksessa tulee harkittavaksi käyttää. Edellä mainittiin ongelmana se, että aina ei tiedetä, onko vika laitteistossa vai ohjelmistossa. Tämän takia pitää olla olemassa erilliset laitteistontestausohjelmat. Laitteiston testaamisessa on tunnettava tyypilliset laitteistoviat. Näitä ovat muun muassa huonot kontaktit, oikosulut, katkenneet johdot,

160 Sulautettu ohjelmointi sähkömagneettisesta induktiosta johtuvat signaalin ylikuulumiset, väärät signaalitasot ja ajoitusvirheet. Tyypillisesti näitä vikoja etsitään sähköisillä mittalaitteilla, esimerkiksi oskilloskoopilla. Mutta osa laitteistonkin vioista on sellaisia, joita voidaan löytää ohjelmallisesti. Muistin testaaminen on tyypillinen ohjelmallinen testi. Muistitestit ajetaan usein aina järjestelmää käynnistettäessä. 9.6.1 Muistien testaaminen Lukumuistin testaus tehdään käymällä lukumuistin kaikki muistipaikat läpi ja laskemalla niistä jollain menetelmällä tarkistussumma. Tämä sama tarkistussumma on talletettu itse lukumuistiin, ja tulosta verrataan tähän talletettuun arvoon. Tuloksena on yksinkertainen kyllä ei-tyyppinen tieto siitä, toimiiko muisti vai onko siinä jokin vika. Koska vian luonnetta ei voi tällä selvittää, muistissa olevaa tietoa ei voi käyttää turvallisesti. Luku kirjoitusmuisti testataan kirjoittamalla muistiin merkkejä ja sitten lukemalla ne sieltä. Mikäli luettu merkki poikkeaa kirjoitetusta, muistissa on vikaa. Tyypillisesti muisti kirjoitetaan täyteen lukua 5555 16 ja tämän jälkeen lukua AAAA 16 (olettaen, että muistiväylä on 16-bittinen). Nämä bittikuviot asettavat jokaisen muistin bitin ykköseksi ja nollaksi. Koska rinnakkaiset bitit ovat aina eri arvossa, pitäisi testin paljastaa, jos dataväylän vierekkäiseltä johdolta tapahtuu ylikuulumista toiseen johtoon. Testi ei kuitenkaan takaa, että muisti toimisi. Nythän voi olla niin, että osoiteväylällä on vikaa (esimerkiksi oikosulku), ja suuri osa viittauksista osuu yhteen ja samaan muistipaikkaan. Edellä kuvattu testi ei paljastaisi tätä. Tämä ongelma voidaan havaita siten, että edellisen testin lisäksi kirjoitetaan jokaiseen muistipaikkaan sen oma osoite tai osoitteesta johdettu luku, jos osoite ei mahdu muistipaikkaan kokonaisena. Talletettua arvoa ei saa testata heti, vaan kaikki muistipaikat kirjoitetaan ensin, jonka jälkeen vasta tarkistetaan talletettu arvo. Mikäli arvo olisi luettu heti, edellä mainittu osoiteväylän vika ei tulisi ilmi. Mikäli laitteen väylien johdotus on tavallisuudesta poikkeava, on syytä miettiä sellaisia testiarvoja, joilla havaitaan mahdolliset ylikuulumiset tai oikosulut signaaleissa. Yleisesti ottaen on varmistuttava siitä, että testi testaa sitä mitä pitääkin. Kokonaisuutena muistit testaavien testien tulee paljastaa mahdolliset katkot, oikosulut ja ylikuulumiset väylillä.

Ohjelmistotyö 161 Huomattakoon, että välimuistin käyttö muistia testattaessa tulee kieltää, sillä muuten voi käydä niin, että testi testaa vain välimuistin toimintaa. 9.6.2 Oheislaitteiden testaus Varsinkin monimutkaisimmissa oheislaitteissa voi olla erityisiä testitiloja. Esimerkiksi tietoliikennepiiri voi itse vastaanottaa lähettämänsä tiedon lähettämättä sitä kuitenkaan varsinaiselle siirtotielle. Yksinkertaisimmissa piireissä ei tällaisia ominaisuuksia ole, mutta niitäkin voi testata lukemalla tilarekistereitä, kokeilemalla, pystyykö piiri keskeyttämään ja niin edelleen. Suuri osa oheislaitteista voidaan testata ohjelmallisesti vain osittain. Tämä osittainen testi tehdään yleensä aina käynnistyksen osana. Kattavampi testi voi tarvita ulkoisia apulaitteita tai erityisen testipedin. Tämäntyyppinen kattava testi tehdään tavallisesti valmistuksen päätteeksi ja mahdollisesti osana huoltotoimenpiteitä. Näitä samoja testejä voidaan käyttää laitteen ensimmäisissä testeissä ennen kuin ohjelmiston varsinainen testaaminen alkaa. Tyypillisesti laitteistossa on joitain merkkiledejä tai vastaavia, jolla voidaan testin tulos ilmoittaa, mikäli laite ei pysty ilmoittamaan siitä jollain käyttäjäystävällisemmällä tavalla. Yleisesti ottaen jokaiselle oheislaitteelle tulee tehdä käynnistyksen aikainen perustesti ja mahdollisesti kattavampi huolto- ja valmistustesti. Joitakin laitetestejä voidaan suorittaa tarvittaessa myös ajoaikana, mutta tällainen on harvinaista. 9.7 Iteratiivisuudesta kehitystyössä Vaikka iteratiivinen kehitys onkin yhä yleisemmin käytetty tapa toteuttaa ohjelmistoja, ei iteratiivisuuden hyötyjä voi edelleenkään korostaa liikaa sulautettuja ohjelmistoja suunniteltaessa tai toteutettaessa. Vaikka kokonaisjärjestelmälle tehtäisiinkin perinteinen määrittely, on toteutustyössä silti otettava huomioon se, että kehitystyön tuloksena pitäisi syntyä yhteensopivat laitteisto ja ohjelmisto. Näiden yhteensovittaminen onnistuu harvoin ensimmäisellä yrittämällä johtuen useastakin eri syystä, mutta useimmiten siksi, että eri kehityspolkujen varrella on tehty erilaisia olettamuksia. Toinen iteratiivisuuden kehityksen käyttöä puoltava seikka on, että oikeastaan kaikki ohjelmistot sisältävät virheitä. Mitä suuremmasta kokonaisuudesta on kyse, sitä vaikeampaa niitä on yleensä löytää. Tästä

162 Sulautettu ohjelmointi syystä on usein eduksi sulautetussa ympäristössä, jos voidaan minimoida niiden ohjelman osien määrä, jotka ovat käytössä ensimmäistä kertaa, ja joiden toimintaa ei siksi ehkä olla voitu verifioida lainkaan. Itse asiassa voidaan jopa ajatella, että koko ohjelmistosuunnittelun perusta sulautetussa ympäristössä olisi ohjelmiston pilkkominen pieniin osiin, niiden iteratiiviseen toteuttamiseen, ja huolelliseen verifiointiin. Jotkut sulautetuista järjestelmistä ovat kuitenkin sellaisia, että niitä ei kerta kaikkiaan voi toteuttaa ja testata muuten kuin valmiina kokonaisuuksina. Näin ei kuitenkaan käy kovinkaan usein, vaan oikeanlaisella ohjelmistosuunnittelulla on lähes aina mahdollista löytää osia, jotka voidaan toteuttaa ja testata iteratiivisesti. Tämä puolestaan auttaa kasvattamaan luottamusta järjestelmän suunnitteluun ja etenemiseen, sillä järjestelmän osittaisenkin toiminnan havainnointi oikeassa laitteessa kerää yleensä huomiota järjestelmästä. Sitten kun tiedetään, että jotkut ominaisuudet toimivat, on helpompi edetä suunnittelussa ja toteutuksessa eteenpäin. Iteratiivisuuden mittakaavan suhteen on luonnollisesti mahdollista käyttää harkintaa ja ohjelmiston toteutuksen kannalta sopivaa osittamistrategiaa. Tämä saattaa joissain tilanteissa vaatia jonkun sopivan arkkitehtuurityylin valitsemista toteutuksen perustaksi, mutta pikemminkin kyse on ajattelutavasta ja suhtautumisesta ohjelmointiin: Toteutettavat ominaisuudet tulisi valita siten, että ne voidaan varmentaa edes jossakin testiympäristössä. Usein jo sulautetun laitteen henkiin herättäminen siten, että järjestelmä nousee hallittuun tilaan ja kykenee vastaamaan ulkomaailmasta tulevaan syötteeseen, on jo erinomainen ensimmäinen askel, jota voidaan ryhtyä laajentamaan sovelluskohtaisella toiminnalla. Joskus itse asiassa jo se, että pystyy asentamaan laitteistoon jotakin, on merkittävä askel eteenpäin. Iteratiivisen kehityksen kannalta hedelmällisiä kohteita ovat myös ne osat ohjelmaa, jotka testaavat laitteiston toimintaa. Siksi ne kannattaa toteuttaa omana kokonaisuuksinaan, jolloin laitteiston toiminta voidaan verifioida jo aikaisessa vaiheessa kehitystyötä. Lisäksi monimutkaisten algoritmien suunnittelu kannattaa mahdollisuuksien mukaan tehdä omana iteraationaan, ja tarvittaessa vaikkapa käyttää ensin PC-ympäristöä, jossa algoritmin oikeellisuus voi olla nopeampaa ja helpompaa verifioida. Sitten kun toiminnallisuus on osoitettu oikeaksi, se voidaan siirtää osaksi sulautettua järjestelmää. Siirtotyössä täytyy luonnollisesti ottaa huomioon erilaiset suoritusnäkökohdat, muistinkulutus, sekä mahdolliset käännöstyökalu- ja kirjasto-

Ohjelmistotyö 163 eroavaisuudet. Toisaalta ilman algoritmin erillistä toteuttamista saattaa olla mahdotonta selvittää sen suorittamisessa tarvittavaa aikaa, mikä puolestaan saattaa olla järjestelmän aikakriittisten toimintojen kannalta oleellista. Tietysti tässäkin yhteydessä kannattaa pyrkiä käyttämään oikeaa laitteistoa mahdollisimman nopeasti, jotteivät kokeilu- ja tuotantolaitteiston mahdolliset suorituskykyerot hämärry. Vaikka iteratiivista kehitysmallia käytettäisiinkin, koskaan ei ohjelman toimiminen pidä perustua vain sen suorittamiseen, eikä sulautetuissa järjestelmissä ainakaan. Koska määrittelymenetelmät eivät voi koskaan taata virheettömyyttä, täytyy ohjelmat joka tapauksessa testata mahdollisimman hyvin. 9.8 Yhteenveto Kehitys- ja käyttöympäristöt ovat yleensä erilaiset; kehitysympäristöllä tehdään tyypillisesti ristikäännös, jonka tuotosta voidaan suorittaa. Suuri joukko erilaisia avustavia työkaluja, kuten emulaattorit ja simulaattorit, on usein tarjolla, mutta ne eivät kuitenkaan voi kokonaan korvata oikean laitteen käyttöä kehityksen aikana. Laitteiston testaus on toteutettava ohjelmiston osanana. Iteratiivinen kehitystyyli lähes välttämätöntä ohjelmistotyössä.