Tilakoneen räjähtäminen ja kamelin kyttyrät
Pekka RitamäkiSulautettuilta järjestelmiltä vaaditaan liitäntöjä mekaniikkaan, nopeaa toimintaa, ikuisesti toimivaa ohjelmaa, pientä virrankulutusta, halpaa hintaa, pientä kokoa ja ohjelmaa ei voi koskaan päivittää. Miten sulautetun järjestelmän kehittäjä pystyy tähän pienitehoisilla, vähän muistia omaavilla prosessoreilla? Lisäksi sulautetun järjestelmän pitää kehittää käyttöjärjestelmä ja BIOS samaan aikaan kuin varsinainen sovelluskin. Kirjoituksessa esitetään tähän ratkaisumalli, jota on kehitetty 40 vuotta.
Miksi tilakone ?
Tilakone-mallia pidetään sulautettujen järjestelmien ylivoimaisesti parhaana ohjelmointimallina. Tilakoneella voidaan hallita monimutkaisia dynaamisia prosesseja ja tiedonsiirtoprotokollia etukäteen sovitulla ohjelmointimallilla. Tilakoneohjelmointia ei kuitenkaan opeteta kouluissa normaaleja PC-ohjelmointikieliä opetettaessa. Sulatetuissa järjestelmissä esiintyy monia rinnakkaisia prosesseja, niiden hallinta ilman tilakonetta on hankalaa ja monimutkaista. Lineaarisessa ohjelmoinnissa monimutkaisissa protokollassa eksytään helposti umpikujaan. Kokemattomat ohjelmoijat syyttävät erilaisia asioita ja useimmiten työ myöhästyy tai jää kesken. Perinteisin menetelmin kirjoitettujen ohjelmien tarkastus vaatii suurta keskittymistä ohjelmoijalta. Monimutkaisissa ohjelmissa toisen henkilön suorittama ohjelmatarkastus on vaikeaa ellei mahdotonta.
Ohjelman tarkastaminen on vaikeaa ilman lopullista toimintaympäristöä
USA ja Ronald Reganin aloitti 1980 alussa Tähtien sota hankkeen. Se kaatui ohjelmoinnin tarkistuksen hankaluuteen ilman avaruudessa tapahtuvaa atomisotaa. Vastapuoli lähti mukaan, mutta USA:n embargo esti tietokoneiden ja teknologian viennin näihin maihin ja koko ideologiajärjestelmä romahti vuosikymmenen lopulla.
Ranskan Arianne raketti räjähti vuonna 2000, koska aikaisemmin oikein toimineessa ohjelmassa 64-bittisen liukuvan pilkun luvun muunnos 16-bittiseen integer-lukuun vuosi ylitse. Ohjelmaa ei osattu tarkistaa uudella suuremmalla raketilla. Vika johtui suuremmista voimista uudessa raketissa. Turvaohjelmat räjäyttivät kalliin raketin.
Nasan mönkijää ei saatu alas ehjänä Marsin pinnalle 2000-luvun alussa, koska eräs anturi heilahti laskeutumisen aikana. Laskeutumisohjelma luuli päässeensä jo Marsin pinnalle ja sammutti laskeutumisoperaation. Ohjelma ei välittänyt muista tiedoista, joista olisi voinut päätellä laskeutumisaluksen olevan vielä korkealla Marsin pinnasta. Anturin heilahtamista ei osattu huomioida testeissä.
Sulatetuissa järjestelmissä pienikin virhe on katastrofi, mutta PC voidaan aina käynnistää uudestaan. Testiympäristön luominen pitäisi olla ohjelmoijan ensimmäinen asia, jos alkuperäistä kohdetta, kuten Marsia ei voi tuoda ohjelmoijan luokse. Kun teet sulutettuja järjestelmiä älä koskaan anna periksi tehdä ohjelmaa lopullisessa ympäristössä tai ainakin vaadi teettäjältä kirjallinen vakuutus, että kaikki ohjelmointivirheet ovat tällaisen vaatimuksen esittäjän syytä.
Tilakone auttaa rakentamaan tarkastettavia ohjelmia
Tilakoneen ohjelmointi ei ole helppoa, mutta sen avulla on mahdollista tehdä ohjelmia, joiden toimintaa voidaan etukäteen tarkastaa. Ohjelmien kuvaaminen on mahdollista kuvata siten, että muutkin ymmärtävät sen toiminnan. Tilakonemallissa on kerrallaan voimassa yksi tila. Tilasta toiseen päästään vain etukäteen sovituilla tavoilla. Kaikki muut toiminnat ovat kiellettyjä. Jos ohjelmalla ei ole mitään tärkeää tehtävää se on vapaalla (Idle). Rinnakkaisia prosesseja ei lähdetä käsittelemään samalla hetkellä kun ne tapahtuvat, vaan vasta niiden omilla vuoroillaan.
Ohjelman dokumentoinnista
Kaikki ohjelmien tilaajat vaativat hyvän ja yksityiskohtaisen kuvauksen ohjelman toiminnasta. En ole nähnyt yhtäkään sellaista. Missä opetetaan ohjelmien dokumentointia? Onko jossakin kirjastossa kirja, josta voi asiaa opetella? Oletteko nähneet hyvää Microsoftin dokumenttia?
Olin ulkopuolisena tarkastajana tarkastamassa erästä yksinkertaista tarjouslaskentaohjelmaa neljä vuotta, mutta sen dokumentointi jäi aina kesken. Ohjelmoija vaihtui noin vuoden välein. Arvaatte, että ohjelmakaan ei koskaan valmistunut. Tietokoneet, käyttöjärjestelmät ja tietokannat vaihtuivat nopeammin kuin ohjelmoijat. Ohjelmointiprojektia johti toimitusjohtaja, joka ei ollut ikinä ohjelmoinut yhtäkään riviä. Eräässä toisessa paikallisessa firmassa samantapaista asiaa yritettiin 10 vuotta.
Olen katsellut erään suomalaisen matkapuhelinyhtiön ohjelmadokumentteja. Ne käsittävät 50% lyhenneselityksiä, jotka on kopioitu aina edellisistä papereista. Satasivuisista papereista ei itse ohjelman toiminnasta saa minkäänlaista kuvaa. Ohjelmaa ei kuvata kuin yhdellä sivulla, siinäkin on muutama funktio nimi ja lopuksi maininta, että ohjelmaa ei ole vielä testattu.
Miten ohjelmoijat voisivat tehdä hyviä dokumentteja, jos opettajat eivät ole näyttäneet esimerkkiä?
Jos ohjelmoijalla ei ole selvää menetelmää miten hän on ohjelman tehnyt, ei hän osaa tehdä siitä dokumentointiakaan.
Tilakoneen avulla on pieni mahdollisuus kuvata ohjelman toiminta ihmisen ymmärtämällä tavalla.
Ohjelman lähdekoodi on tärkein dokumentti. Jokaisessa lähdekoodissa pitää mainita aikakin seuraavat asiat:
• Projektin nimi
• Tiedoston nimi
• Tekijän nimi
• Kenelle ohjelma on tehty
• Lyhyt laitteistokuvaus
• Ensimmäinen luontipäivä
• Kääntäjän merkki ja versio
• Kohdeprosessorin nimi ja malli
• Oskillaattoritaajuus
• Versiopäivämäärät ja selitys muutoksista
/*============GSMASTAM projekti=================
Projekti: GSMASTMA
Tiedosto: GSMASTMA.C
Toiminta: Pölypunkkien etähävitys
Laitteisto
PIC18F452-I/P, 10MHz resonaattori
UART ST232 RC6,RC7
RELE RB.1
LED RB.3
Buzzer RD.2
LM335z RA.0 ja RA.1 lämpötila-anturit
24LC256 EEPROM I2C muisti 32 kByteä
========
HARDWARE-asetus
Kaksi päätilaa : PC ja GSM-ohjaus, valinta kytkimellä
GSM-ohjaus tila
Odota SMS-viestiä RELE1=1
SMS-viestiä RELE1=0,lähetä kuittausviesti ( RELE=1)
Loggaus käynnistyy, RELE Päälle
Odota kunnes lämpötila menee 47C lähetä viesti
Odota SMS viestiä, lähetä kuittausviesti
Jos sanomaa ei tule, loggeri pyörii ympäri
PC asetustila
Odota kyselyä
-tulosta ASETUSTIEDOT ja lämpötila
-odote ASETUSSANOMAA
Pura sanoma EEPROM muistiin
=====================================*/
Jokaiseen ohjelman moduuliin kopioidaan sama alkuotsikko. Tarpeelliset tiedostonimet tietysti muutetaan.
Jokaiseen funktioon tehdään pieni kuvaus sen tehtävästä.
Kuvaus laitetaan C-kielen kommenttimerkkien sisälle /* */.
Funktion loppuun myös samanlainen kommenttirivi.
/* ================= Funktio xx loppu===========*/
Itse funktion sisällä olevat huomautukset laitetaan rivikommentteihin // Tässä rivikommentti.
Tämä helpottaa koko funktion väliaikaista poistamista.
Funktion alkukommentista poistetaan vain loppumerkit */ ja koko funktio on väliaikaisesti poissa.
Poistettuihin kohtiin voidaan laittaa sopivia merkkejä esim. DDDDD, jotka on helppo myöhemmin hakea tekstinkäsittelyohjelmalla.
/* ==========================
Alusta PIC18F452 hardware,
ajastimet , suuntarekisterit ja keskeytykset
Tämä tehdään vain kerran ohjelman alussa
============================*/
void HardwareInit ( void) {
setup_adc_ports(RA0_RA1_RA3_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
setup_psp(PSP_DISABLED);
setup_wdt(WDT_ON);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2|RTCC_8_BIT);
// ei esijakajaa, joten overflow = 9765Hz 10 MHz
/*========HardwareInit end =============*/
Vakiot
Vakiot kirjoitetaan isoilla kirjaimilla.
Vakioit kerätään yleensä yhteen paikkaan.
#define YKSI 1
#define KYMMPI 10
#define LUKU1 100
Mitä vikaa on edellisissä merkintätavoissa?
Jos ohjelmassa pitää muuttaa vakioita nuo käytetyt vakiot eivät ole enää voimassa.
Parempi on käyttää nimiä, jotka kuvaavat kohdetta.
Esim.:
#define IDLE_STATE 1
#define MAX_LEN 10
#define SMALLEST_NUMBER 100
Jos vakiota käytetään vain yhdessä moduulissa, sitä tuskin kannattaa siirtää yhteiseen tiedostoon, vaan pitää siinä missä sitä tarvitaan.
Kamelin kyttyrä muita tyylilajia
Nashville tyyli
Muuttujien merkintätyylejä on monia.
Nashville tyyli on sama kuin äänilevyjä tehdessä, ei ajatella mitään.
Tällä tyylillä luoduissa äänilevyissä ei ole miksaaja, joka koko ajan vääntelee nappeja vaan levystä tulee juuri sellainen kuin siitä sattuu tulemaan.
Esimerkkejä Nashville tyylistä:
int luku3, luku1;
long luku2;
string luku[10]={”luku”};
Vain huippuohjelmoijat pystyvät tekemään ohjelmia Nashville tyylillä.
Koeta sinä käyttää jotain muuta tyyliä.
Hungarian notation
Microsoftin pääohjelmoija unkarilainen Charles Simoni laittaa jokaisen objektin, funktion tai muuttujan nimen alkuun kirjaimia jotka antavat viitteitä sen määrittelystä. Etuliite erotetaan muuttujanimestä alaviitteellä.
Huomaa, että tämä on selväkielistä Simonille, mutta ei välttämättä meille muille.
Tätä tyyliä sanotaan unkarilaiseksi merkintätavaksi (Hungarian notation).
Esimerkkejä Simonin tyylistä:
HWD hwnd_Foo ; // kahva Windows ikkunaan
FAR char *lpsz_Bar ; // long osoitin nollaan loppuvaan merkkijonoon
int i_keskiarvo;
long li_ikasumma;
FAR String FS_etunimi;
float *ptr_f_laske_keskiarvo( int * ptr_d_ika_taulukko) ;
Simonin alaiset kehittivät Windowsin ja tyyli tuli tutuksi kaikille Windows sovellusohjelmoijille, jotka käyttivät Simonin tekemiä esimerkkejä.
Microsoftin uuden ohjelmointiympäristön .NET Framework ohjeissa ei suositella unkarilaista merkintätapaa, mutta ei sanota mikä on oikea tapa.
Kamelinkyttyrätyyli
Kamelinkyttyrätyyli hauska nimi muuttujien ja funktioiden merkintavalle, jossa muuttujat merkitään ilman alaviittavälejä. Sanojen erotus tehdään isoilla kirjaimilla. Isot kirjaimet merkinöissä näyttävät kamelin kyttyröiltä.
• int IntKeskiarvo;
• long LongIkiSumma;
• FAR String FarStringEtunimi;
• float *PointerToFloatLaskeKeskiarvo ( int * PointerTokaTaulukko) ;
• int8 bBusy : boolean
• int1 cApples : omenien määrä
• double dwLightYears ; //kaksinkertaisen tarkkuuden luku
• int1 fBusy : boolean (flag)
• int nSize : integer
• float fpPrice: floating-point
• double dbPi: double
• *char pFoo : pointer
• char szLastName[100] : zero-terminated string
Tamperelainen struktuurityyli
Mielestäni paras tyyli on struktuurityyli. Siinä kakki mahdolliset muuttujat ryhmitellään struktuuriin, jolloin niitä käytettäessä heti tiedetään mihinkä asiaan muuttuja kuuluu.
Tämän tyylin kanssa voidaan käyttää Simonin unkarilaista merkintätapaa tai kyttyrätyyliä.
struct message_struct {
int IntStartTosi;
char CharBuffer [MAXBUFF];
long LongtIntCounter ;
} message;
message. IntStartTosi =1;
message. CharBuffer [0]=0;
Kun muuttujat on ryhmitelty struktuureihin ,muuttujia ei voi ripotella pitkin ohjelmia vaan niiden luokka sanoo jo mihinkä asiaan muuttuja kuluu.
Eikö struktuuri kuluta enemmän muistia saatat kysyä.
Ei, kääntäjä käsittelee struktuurin muistipaikkoja aivan samoin kuin muitakin muuttujia.
Voit tarkastaa tämä oman kielesi debuggerilla.
C++ kuuluvat objektit eivät kuitenkaan kuulu sulautettuihin järjestelmiin.
Tämä menetelmä vaatii paljon muistia ja erityisesti pinomuistia, jota ei sulautetuissa järjestelmissä ole käytettävissä. Ainoa haitta on hieman pidemmät muuttujanimet, mutta kiintolevyn tila on tuskin rajoittava tekijä järjestelmiä kehitettäessä.
Reaaliaikainen toiminta
Jos tehtäviä ei suoriteta heti, eikö tilakone hidasta ohjelman nopeutta?
Ei, koska kaikki ohjelman vaatimat prosessit pitää joka tilanteessa pystyä käsittelemään täydellisesti
jokaisella perättäisellä aikaviipaleella.
Yhden tehtävän välitön käsittely ei nopeuta koko ohjelman suoritusnopeutta.
Kaikki ohjelman osat pitää tehdä sallitulla aikaviiveellä. Tätä tarkoittaa reaaliaikainen tietojenkäsittely.
Reaaliaikainen toiminta ei tarkoita mahdollisimman nopeata toimintaa, jossa joskus hoidetaan vain yhtä asiaa nopeasti.
PC:n Windows ja Linux-käyttöjärjestelmät ovat esimerkki tällaisesta epäreaaliaikaisesta toiminnasta. PC on periaatteessa nopea, mutta siitä puuttuu toimintoja joita on jokaisessa mikroprosessorissa. Miten nopeasti PC:llä luetaan yksinkertaisia pulsseja rinnakkaisportin avulla?
Kolmen gigahertsin PC pystyy tekemään miljoonia laskutoimituksia sekunnissa.
Kaikki normaalit DOS ja Windows käyttöjärjestelmät eivät pysty kuin 18.2Hz tapahtumaan sekunnissa!
Huonoinkin Microchipin PIC-sarjan prosessori pystyy 50 MHz pulssien laskentanopeuteen.
Jos tehtävä vaatii suurta ulkopuolisten pulssien mittausnopeutta PIC prosessori on ylivoimainen PC:n nähden.
Onko PC:si joskus jumiintunut lukemaan verkosta saapuvaa tietoa tai kovalevy alkanut tehdä tärkeää levyn kalibrointikäsittelyä kesken kirjoitusohjelman?
Silloin näppäimistön merkit tulevat näytölle viiveellä. Vaikka näitä asioita ei näyttäisi tapahtuvankaan, käyttöjärjestelmä vaati itselleen aikaa pienen siivun 18.2 kertaa sekunnissa.
Tänä aikana PC:tä on turha yrittää käskeä minkäänlaiseen järkevään työhön.
DOS-käyttöjärjestelmässä on tuo sama aikaväli käytössä.
DOSin toimintaa ohjelmoija pystyy muuttamaa asettamalla TIMER1 (8254) aika pidemmäksi, mutta Windows asettaa oman aikansa heti takaisin kun käyttöjärjestelmä seuraavan kerran käynnistyy.
Sulautetut prosessorit eivät pysty käsittelemään suuria tietomääriä valtavassa työmuistissa kuten PC, mutta niiden tehtävä suuremman prosessorin apulaitteena tulee hoidetuksi pienellä vaivalla.
Microchipin PIC tarkoittaa Periferial Interface Controller eli apulaiteprosessori.
Työstökoneen paikkaohjaus on hyvä esimerkki reaaliaikaisesta toiminnasta.
Työstökoneessa on useita akseleita, joiden pitää liikkua synkronisesti toisten akseleiden kanssa.
Yksi akseli ei voi jäädä touhuamaan kiintolevyn siivousta toisten akselien jyrsiessä pallopintaa. Laakereihin tulisi kuoppia, jos ohjaus tehtäisiin pelkällä PC:llä. Työstökoneen pitää liikkua jokaiseen pisteeseen reaaliaikaisesti muiden akselien kanssa.
Jokaisessa aikaviipaleessa pitää pystyä mittaamaan paikka, katsomaan uusi asetusarvo, laskea PID-asetukset, tehdä ohjaukset moottorille, hoitaa raja-arvojen tarkastus ja näyttää akselin tila käyttäjälle.
Reaaliaikainen toiminta voi olla myös hitaampaa, esim. pankkikortin käyttö pitää olla reaaliaikaista, jotta tilitapahtumilla ei pääsisi keinottelemaan. Aikavaste voi olla kuitenkin vaikka 10 sekuntia ilman, että ihminen hermostuu.
Miten tilakone toimii?
Perinteinen ohjausjärjestelmä ohjaa antoja ja tulosignaalien perusteella.
Jos ohjaus riippuu aikaisemmista tiloista ohjausta sanotaan sekvenssiohjaukseksi.
Yksinkertaisen hissin ohjaus riippuu aikaisemmista tapahtumista ja kerroskutsupainikkeista.
Katso kuvaa 2. Tulot ovat kutsupainikkeita ja kerrosilmaisimia. Hissin tilakoneen toiminta on tarkkaan määritelty tulojen avulla. Hissi voi olla myös kahden kerroksen välitilassa, joka pitää ottaa huomioon ohjelmassa.
Ohjelman logiikka määrittelee järjestelmän tilan muuttujalla, jonka nimi on tila tai state.
Muutos painonappien tiloissa tai hissin paikassa aiheuttaa toimenpiteitä moottorin ohjauksessa.
Täydellinen hissinohjaus on tietysti monimutkaisempi.
Jos laitteen anto Y on tosi vain kun kaikki kolme tuloa A, B ja C ovat tosia, mitään tilakonetta ei tarvita vaan yhtälö on helppo ratkaista
Kuva 4 Yksinkertainen tilakone
Y = A AND B AND C (Yhtälö 1)
Esimerkki2
Jos edelliseen esimerkkiin lisätään ehto, että anto voi olla tosi vain jos tulo A on tosi ennen tuloa B, tarvitaan sekvenssilogiikkaa.
Sekvenssilogiikan jalostuneempi muoto on tilakone. Ohjelmoitavat logiikat toimivat sekvenssilogiikan periaatteella.
Niissä luetaan aina ensin tulot muistipaikkoihin yhdellä kertaa. Tulojen, apumuistipaikkojen ja lähtöjen avulla käsitellään kaikki tehtävät yhdessä pitkässä ohjelmassa.
Ohjelmassa laitetaan lähtöjen tilat muistiin. Kun ohjelma on tehty, siirretään muistipaikat lähtöihin. Koska käyttäjä voi muuttaa ainoastaan tätä sekvenssiohjelmaa, ohjelma luominen on suoraviivaista ja helppoa.
Toisaalta myös rajoittunutta, varsinkin tietoliikennekäsittelyn osalta.
Samoin matematiikkafunktioita ei voi muuttaa.
Tämä on vähän sama kuin antaisi viisivuotiaalle legopalikkalaatikon.
Hetkessä syntyy hienoa auto tai laiva, mutta auto ei oikeasti toimi.
Dekooderit ja tilakoneet
Tilakonemalleja alettiin käyttää laitteistopohjaisissa ratkaisuissa 1970-luvulla. Toteutus tehtiin PAL-piireillä tai ROM-muisteilla ja myöhemmin EPROM-muisteilla. 1980-luvulla tutkin kotimaisen valmistajan FMS järjestelmää, jossa työstökappaleiden kuljetuksen ohjaus perusti suureen määrää tuloja. Osa tuloista oli saman ohjauksen laitteen lähtötiloja.
Varsinaista ohjelmaa ei ollut, vaan koko ohjaus piti tehdä EPROM-piirillä, jossa on kaikki mahdolliset tilat.
Tuon EEPROMin määrittely osoittautui mahdottomasi tehtäväksi.
Kaikkia tiloja ei yksinkertaisesti voinut tutkia etukäteen. Tehtävä oli paljon mahdottomampi kuin shakkipelin ratkaisu, jossa jokaiselle tilanteelle olisi mietitty etukäteen yksi ainoa ratkaisu.
FMS-ohjausongelma ratkaistiin ohjelmalla, jossa on tilakone ja siinä määriteltiin vain sallitut muutostilat.
Ohjelman taulukoiden täyttäminen oli suoraviivaista ja jokseenkin yksinkertainen tehtävä. Tämä menetelmä osoittautui toimivaksi.
Sattumanvarainen ohjelmointimenetelmä
Ohjelmointi on tullut mahdolliseksi yhä useammalle ihmiselle, mutta ongelmia ratkaistaan yhä edelleen sattumanvaraisilla menetelmillä.
Tämä onnistuu loistavilta ohjelmoijilta, mutta loistavien ohjelmoijien luonnonvara on rajallinen.
Useimpien yhtiöiden pitää tyytyä tavallisiin tai tavallista keskenkertaisempiin ohjelmoijiin.
Siksi meidän muiden pitää käyttää hallittuja menetelmiä.
Jokainen ymmärtää, että paperin tai matkapuhelimien valmistus on monimutkaista, mutta kun se tehdään suunnitelmallisesti ja tehtävät jaetaan tarpeeksi pieniin palasiin, niin nämä tehtävät onnistuvat tavallisilta ihmisiltä.
Samoin ohjelmointi pitää jakaa pieniin etukäteen suunniteltuihin palasiin.
Isot tehtävät syntyvät suurelta joukolta kuin liukuhihnalta, kunhan tehtävät ovat tarpeeksi pieniä ja jokainen suorittaa etukäteen sovittuja tehtäviä oikeilla työkaluilla.
Nokiallakin on suuri joukko keskinkertaisia ohjelmoijia ja kuitenkin puhelimia syntyy ja operaattorit saavat uusia ominaisuuksia hallintaohjelmiinsa.
Taustalla on kuitenkin loistavia ohjelmoijia ja organisaattoreita.
Amerikkalainen Charles Moore on loistava ohjelmoija, joka teki 1970-luvulla teleskooppien ohjausohjelmia.
Observatoriolla oli IBM-tietokone, jossa oli perinteinen editoi, käännä, linkitä ohjelmointimenetelmä.
Lopuksi yritettiin arvata mikä meni pieleen. Hänen mielestään yhden ohjelman tekeminen vuodessa ei ollut tarpeeksi tehokasta.
Moore keksi interaktiivisen FORT-kielen. Nimen piti olla oikeastaan neljännen sukupolven kieli eli Fourth, mutta sen aikainen IBM-käyttöjärjestelmä ei sallinut muuta kuin nelimerkkisiä tiedostonimiä.
Nyt Moore pystyi käyttämään helposti interaktiivista kieltä nopeasti testaukseen ja ohjelmia alkoi syntyä kuin liukuhihalta.
Itsekin käytin Fort-kieltä Tampereen Teatterin 65000 ledin näyttötaulussa vuonna 1985.
C-kieli kuitenkin voitti Fortin. Fortin käänteinen puolalainen logiikka oli ystävällinen integroidulle kääntäjälle, mutta ei tavallisten ohjelmoijien mielelle.
Fort-kieltä ei voi käyttää pienissä prosessoreissa, joissa ei ole tarpeeksi RAM-muistia.
Tilakoneen luonti
Tilakoneessa on sekvenssejä ja tapahtumia. Ahon Lohikäärmekirjassa on monia esimerkkejä tilakoneiden käytöstä.
Kuva 5 Alfred Ahon lohikäärmekirja
Alfred Aho oli Bellin laboratorioiden tietotekniikkaosaston johtaja.
Hänen kuuluisa kirjansa kertoo miten kääntäjäohjelmat tehdään, kuva 5.
750-sivuinen kirja sisältää myös 28 sivua viitteitä ohjelmointikirjoihin ja artikkeleihin, jotka käsittelevät kääntäjiä. Aho osasi asiansa. Aho käyttää tilakonetta melkein jokaisessa esimerkissään.
Ahon apulaiset Brian Kernighan ja Dennis Richie ottivat oppia kirjasta ja kehittivät PDP:n avulla B-kielestä C-kielen.
Unix-käyttöjärjestelmä kehitettiin C-kielellä. C- kieli on edelleenkin maailman tärkein ohjelmointikieli.
C-kieli ei tee omia salaisia temppujaan käännöksen aikana.
Jos käyttäjä ei ole tyytyväinen kielen mukana toimitettaviin kirjastoihin, käyttäjä voi aina tehdä itse paremmat.
Unixin käyttöjärjestelmän jatko Linux perustuu myös C-kielellä tehtyyn ydinohjelmaan.
Microsoftin kielet ja Java sopivat sellaisiin tietokoneisiin, jossa ei tarvita suorituskykyä, mutta niissä on paljon tehoa.
Tavallisten käyttäjien tekemät ohjelmat eivät ole reaaliaikaisia, eikä niillä ole tärkeitä tehdasprosesseihin liittyviä mittaustehtäviä.
Sulautetut järjestelmät eivät saa kaatua, koska niiden ohjelmia käyttäjät eivät pysty vaihtamaan uusiin versioihin.
Sulatetuissa järjestelmissä ei käytetä C++ tai Javaa. Yrityksiä on kyllä olemassa.
Sekvenssiongelman ratkaisu tilakoneella
Merkkijonojen tulkintaan on jokainen ohjelmoija törmännyt.
Olen nähnyt hirvittäviä yrityksiä tästä yksinkertaisista tehtävistä.
Ilman hallittua ajatusta tehtävää on yritetty ratkaista kuukausikaupalla ilman tulosta.
Kuva 6 Merkkijonon tulkinta tilakoneella
Kuvassa 6 näkyy kuinka yksinkertaista on etsiä oikeata merkkijonoa tilakoneen avulla.
Etsittävä sana on ”Alku”. Oletetaan, että merkkejä tulee sarjaliikenteeltä epämääräiseen tahtiin. Aluksi ollaan vapaa-tilassa. Kun ensimmäinen merkki saapuu tarkastetaan onko se oikea merkki ’A’. Jos merkki on A, niin siirrytään seuraavaan tilaan. Jos merkit eivät tule oikeassa järjestyksessä palataan aina alkutilaan.
Jos kaikki merkit tulevat oikeassa järjestyksessä päästään lopuksi tilaan 4 ja merkkijono on tunnistettu.
Koska merkit ovat epäsynkronisia, merkkejä ei saa jäädä odottaman, vaan tunnistustilakone voi olla itsenäinen päätilakoneesta riippumaton aliohjelma.
Jos ohjelmassa pitää etsiä useita samantapaisia sanoja, ongelma tulee monimutkaisemmaksi, mutta ei mahdottomaksi.
Kuva 9 Merkkijonon tulkinta yleisen tilakoneen avulla räjäyttää ohjelmoijan aivot
Jos edellisen tehtävän tilakone olisi yhdistetty ohjelman yleiseen tilakoneeseen sen toiminta saattaisi näyttää kuvan 7 mukaiselta.
Jokaisesta tilasta pitäisi olla mahdollisuus mennä merkkijonon tunnistustilaan.
Koska useimmissa ohjelmissa on suuri joukko rinnakkaisia tehtäviä tilakoneesta tulee alkuräjähdys, jota ohjelmoija ei enää hallitse.
Tilakoneen tehtävä on helpottaa ohjelman hallintaa, helpottaa vianhakua ja mahdollistaa toisten ohjelmoijien tekemät muutoksen.
Suuri ja monimutkainen tilakone ei ole tämän määritelmän mukainen.
Tilakone pitää jakaa pienempiin tilakoneisiin joiden hallinta onnistuu tavallisiltakin ohjelmoijiltakin.
Ystävällinen moniajokäyttöjärjestelmä
Kuva 10 Monimutkaiset tehtävät voidaan jakaa useampaan erilliseen tilakoneeseen tai monitasoiseen tilakoneeseen kuten tässä on tehty
Normaalissa reaaliaikakäyttöjärjestelmässä ohjelman suoritus voidaan keskeyttää koska tahansa ja käynnistää toinen tärkeämpi tehtävä.
Jotta tämä onnistuisi, pitää keskeneräisten ohjelmien prosessorin tilat pitää tallessa.
Tämä on aivan sama asia kuin normaali mikroprosessori keskeytystoiminta.
Reaalikäyttöjärjestelmissä tehtäviä voidaan luoda, lopettaa suoritus väli-aikaisesti, ajaa ja hävittää.
Reaalikäyttöjärjestelmissä tietojen vaihto suoritetaan postilaatikkojen avulla. Postilaatikossa on lippu, joilla välitetään tietoja eri prosessien välillä. Tällainen aikajakoinen järjestelmä hidastuu sitä enemmän mitä enemmän tehtäviä on suorituksessa, vaikka yhtäkään tehtävää ole tarpeen. Tämän huomasi PDP- ja VAX-tietokoneiden ohjelmien suorituksen hidastumisena kun useita pääteistuntoja oli auki vaikka niillä ei tehty mitään.
Windows-ohjelmat käyttävät ns. ystävällistä moniajokäyttöjärjestelmää.
Siinä ohjelmoija saa päättää koska se vapauttaa prosessinsa muille.
Windows ohjelmoijat käyttävät DoEvents() funktiota antamaan käyttöjärjestelmälle mahdollisuuden suorittaa muita tehtäviä.
Jos ohjelma tekee pitkäaikaista laskentaa, niin tietokone ei vastaa muiden ohjelmien tehtäviin.
Kuva 11 Tampere-tyylin mukainen tilakone. Siinä ulkoiset tapahtumat päivitetään yhdessä DoEvents funktiossa. Tämä välittää postilaatikoista saadut tiedot tilakoneille.
Tilakoneessa pitää tunnistaa tilojen muutokset joka tilanteessa, jotta tilakone pystyisi toimimaan.
Postilaatikkojen liput pitää tarkastaa jokaisen ohjelman jokaisessa tilassa. DoEvents() niminen ohjelma sopii hyvin tällaiseen tehtävään.
DoEvents() voi olla myös tilakone, mutta useimmissa tapauksissa ehditään tarkastaa kaikki muutoksiin
vaikuttavat tapahtumat.
Monet muutokset tapahtuvat oikeastaan keskeytyksissä, mutta muutokset käsitellään postilaatikkojen avulla tuossa DoEvents()-funktiossa.
Mitään tilakonetta ei saa jättää odottamaan jotakin tapahtumaa, vaan DoEvents() funktiolle pitää antaa mahdollisuus toimia jatkuvasti.
Hyvä tapa on käyttää vahtikoiraa, joka alustetaan sopivaan arvon ennen jokaista toimintaa jossa on mahdollisuus jäädä jumiin.
Sopiva nimi voi olla esim. Time.SecCounter. Vahtikoiraa voidaan päivittää ajastin ohjelmassa.
/* suoritetaan jokaisessa tilakoneen moduulissa===*/
void DoEvents ( void) {
Time.SecCounter =3; //3 sekuntia aikaa odottaa funktion valmistumista.
while (Time.SecCounter) {
if(kbhit())
Message.Ch=getchar();
if(PostBox1.DataAvailable)
DecodeData();
}
/* === End of DoEvents */
Loppusanat
Kirjoituksessa on esitetty monenlaisia ongelmia, joita sulatettujen järjestelmien kehittäjä kohtaa.
Ratkaisuksi esitetään vakiomuotoista tilakonetta, jossa ulkopuoliset asiat käsitellään yhdessä funktiossa. Tilakoneet jaetaan pieniin osatilakoneisiin. Muuttujien merkintöihin suositellaan struktuurityyliä yhdistettynä kamelinkyttyrätyyliin. Kirjoituksessa ei ole määritelty ohjelmointikieltä eikä prosessoria.
Työkalut ja kohdeprosessorit vaihtuvat, mutta sulatettujen järjestelmien järjestelmällinen ohjelmointityyli säilyy.
Jokainen ongelma uhka joillekin ihmiselle.
Toisille ihmisille sama asia on mahdollisuus.
Koska sulautettujen järjestelmien tekeminen on niin vaikeaa, niin ne jotka jaksavat siihen perehtyä, voivat olla huolettomia suhdanteista, heille löytyy aina töitä.
Enemmän ajattelutyötä ja vähemmän puhetta.
Lähdeluettelo:
1. Alfred V.Aho, Ravi Seti, Jeffery D.Ullman: Compilers Pronciples, Techniques and Tools – Addsison-Wesley Publishing Company 1988.
2. Brian W. Kerninghan, Dennis M. Richie: The C-Programming Language 1988
3. Brian W.Kerninghan, Rob Pike : The Practice of Programming