Both sides previous revisionPrevious revisionNext revision | Previous revision |
et:examples:timer:software_delay [2010/02/08 12:11] – Links to et:software:library:pin changed to et:software:homelab:library:pin mikk.leini | et:examples:timer:software_delay [2020/07/20 09:00] (current) – external edit 127.0.0.1 |
---|
| <pagebreak> |
====== Tarkvaraline viide ====== | ====== Tarkvaraline viide ====== |
| |
//Vajalikud teadmised: [HW] [[et:hardware:controller]], [AVR] [[et:avr:architecture]], [LIB] [[et:software:homelab:library:pin]], [LIB] [[et:software:homelab:library:delay]]// | //Vajalikud teadmised: [HW] [[et:hardware:homelab:controller]], [AVR] [[et:avr:architecture]], [LIB] [[et:software:homelab:library:pin]], [LIB] [[et:software:homelab:library:delay]]// |
| |
===== Teooria ===== | ===== Teooria ===== |
| |
Tihti on mikrokontrollerite programmis vaja tekitada viiteid, et tegevusi ajastada või nende lõppu oodata. Üks idee poolest lihtsamaid meetodeid mikrokontrolleri tegevuses paus tekitada on selle protsessor mingi muu tegevusega üle koormata - näiteks panna see lugema suuri arve. Protsessori taktsagedusest saab välja arvutada, mitmeni see arve loendama peaks, et kindlat ajalist viidet tekitada. Teoreetiliselt tekitaks siis mingi arvu loendamine nullist protsessori taktsageduse väärtuseni hertsides viite üks sekund. Praktikas see päris nii lihtne ei ole ning põhjuseid on mitmed. | Tihti on mikrokontrollerite programmis vaja tekitada viiteid, et tegevusi ajastada või nende lõppu oodata. Üks idee poolest lihtsamaid meetodeid mikrokontrolleri töös paus tekitada on selle protsessor mingi muu tegevusega üle koormata - näiteks panna see lugema suuri arve. Protsessori taktsagedusest saab välja arvutada, mitmeni see arve loendama peaks, et kindlat ajalist viidet tekitada. Mingi arvu loendamine nullist protsessori taktsageduse väärtuseni hertsides tekitaks teoreetiliselt viite üks sekund. Praktikas see erinevatel põhjustel päris nii lihtne ei ole. |
| |
Kui mikrokontrolleri protsessor arvutab arvudega, mille kahendkuju on sama lai kui selle sisemine siin (AVR puhul 8-bitti), siis protsessoritel võtab üks aritmeetiline tehe, näiteks arvu liitmine ühega, aega 1 protsessori töötakt. Selleks et arvutada tuhandete või miljonitega, peab arv olema 16- või 32-bitine ja nende arvutamiseks kulub 8-bitistel protsessoritel rohkem kui 1 töötakt. Niisiis, suurte arvude puhul peab tundma protsessori sisemust - täpsemalt selle käsustikku. | Kui mikrokontrolleri protsessor arvutab arvudega, mille kahendkuju on sama lai kui selle sisemine siin (AVR puhul 8-bitti), siis protsessoritel võtab üks aritmeetiline tehe, näiteks arvu liitmine ühega, aega 1 protsessori töötakt. Selleks, et arvutada tuhandete või miljonitega, peab arv olema 16- või 32-bitine ja nende arvutamiseks kulub 8-bitistel protsessoritel rohkem kui 1 töötakt. Niisiis, suurte arvude puhul peab tundma protsessori sisemust - täpsemalt selle käsustikku. |
| |
Kuna kõrgtaseme keeles (näiteks C-keeles) programmeerides ei kirjutata programmi otse käsustiku baasil, peab tarkvaralise viite tekitamiseks tundma ka kompilaatorit, mis programmi masinkoodi teisendab. Just sellest sõltub, mitu instruktsiooni (ja sellest tulenevalt mitu takti) kulub aritmeetilisteks arvutusteks. Keerukust lisab veel asjaolu, et kompilaator võib programmi masinkoodi teisendada mitut moodi - näiteks tehes masinkoodi võimalikult mälusäästlikuks või võimalikult kiiresti täidetavaks. Neid kompilaatori tegevusi nimetatakse optimeerimiseks. Erinevate optimeerimise režiimidega tuleb ka tarkvaralise viite masinkood ja selle ajaline kestus erinev. | Kuna kõrgtaseme keeles (näiteks C-keeles) programmeerides ei kirjutata programmi otse käsustiku baasil, peab tarkvaralise viite tekitamiseks tundma ka kompilaatorit, mis programmi masinkoodi teisendab. Just sellest sõltub, mitu instruktsiooni (ja sellest tulenevalt mitu takti) kulub aritmeetilisteks arvutusteks. Keerukust lisab veel asjaolu, et kompilaator võib programmi masinkoodi teisendada mitut moodi - näiteks tehes masinkoodi võimalikult mälusäästlikuks või võimalikult kiiresti täidetavaks. Neid kompilaatori tegevusi nimetatakse optimeerimiseks. Erinevate optimeerimise režiimidega tulevad ka tarkvaralise viite masinkood ja selle ajaline kestus erinevad. |
| |
===== Teooria praktikas ====== | ===== Praktika ====== |
| |
Järgnevalt on toodud näide tarkvaralise viite tekitamisest AVR mikrokontrolleriga. Kirjutatud on C-keele programmilõik, mis loendab //for//-tsüklis muutujat //x// nullist sajani. Iga tsükli sees toimub ühe mittemidagitegeva tühiinstruktsiooni täitmine. Seda on seal vaja, kuna tsükli sisu tühjaks jättes optimeerib kompilaator tsükli programmist üldse välja, sest see on tema arvates kasutu. | Järgnevalt on toodud näide tarkvaralise viite tekitamisest AVR mikrokontrolleriga. Kirjutatud on C-keele programmilõik, mis loendab //for//-tsüklis muutujat //x// nullist sajani. Iga tsükli sees toimub ühe mittemidagitegeva tühiinstruktsiooni täitmine. Seda on seal vaja, kuna tsükli sisu tühjaks jättes optimeerib kompilaator tsükli programmist üldse välja, sest see on tema arvates kasutu. |
| |
<code c> | <code c> |
</code> | </code> |
| |
Kompileeritud kujul on näha, mis tegelikult C-keele tsüklist saab, ja selle järgi saab arvutada, mitu takti ühe tsükli perioodi puhul kulub. Infot instruktsioonide toime ja tööaja kohta leiab AVR käsustiku andmelehest. Antud näites kulub ühes tsükli perioodis 4 instruktsiooni täitmiseks 4 takti, sest kõik instruktsioonid võtavad ühe töötakti. Lisaks kulub enne tsüklit 1 takt laadimisinstruktsiooni jaoks ja tsüklist väljudes 1 lisatakt. Oletades, et kontrolleri töötakt on 14,7456 MHz, võib välja arvutada kogu programmilõigu tekitatud ajalise viite: | Kompileeritud kujul on näha, mis tegelikult C-keele tsüklist saab, ja selle järgi saab arvutada, mitu takti ühe tsükli perioodi täitmiseks kulub. Infot instruktsioonide toime ja tööaja kohta leiab AVR käsustiku andmelehest. Antud näites kulub ühe tsükli perioodis 4 instruktsiooni täitmiseks 4 takti, sest kõik instruktsioonid võtavad ühe töötakti. Lisaks kulub enne tsüklit 1 takt laadimisinstruktsiooni jaoks ja tsüklist väljudes 1 lisatakt. Oletades, et kontrolleri töötakt on 14,7456 MHz, võib välja arvutada kogu programmilõigu tekitatud ajalise viite: |
| |
(1 + 100 ⋅ 4 + 1) / 14745600 = 27,26 μs | (1 + 100 ⋅ 4 + 1) / 14745600 = 27,26 μs |
| |
Näites tekitatud viide on mikrosekundites ja kasutav muutuja on 8-bitine, seega on ka masinkood üsna lihtne. Selleks, et tekitada pausi millisekundites, on vaja loendada palju suuremaid arve ja siis läheb ka masinkood pikemaks. Võib kasutada ka üksteise sees töötavaid tsükleid, kuid selle meetodi puhul pole kogu viide lineaarses sõltuvuses tsüklite arvust, sest iga tsükli tasemega tekivad pisikesed lisaviited. | Näites tekitatud viide on mikrosekundites ja kasutatav muutuja on 8-bitine, seega on ka masinkood üsna lihtne. Selleks, et tekitada pausi millisekundites, on vaja loendada palju suuremaid arve ja siis läheb ka masinkood pikemaks. Võib kasutada ka üksteise sees töötavaid tsükleid, kuid selle meetodi puhul pole kogu viide lineaarses sõltuvuses tsüklite arvust, sest iga tsükli tasemega tekivad pisikesed lisaviited. |
| |
Käesoleva harjutuse eesmärk ei ole siiski masinkoodi tasandil täpset tarkvaralist viidet tekitada, sest see on üsna peen töö ja pealegi on viite tekitamiseks avr-libc ja Kodulabori teegis juba funktsioonid olemas. Need tulevad ka näites kasutusele. | Käesoleva harjutuse eesmärk ei ole siiski masinkoodi tasandil täpset tarkvaralist viidet tekitada, sest see on üsna peen töö ja pealegi on viite tekitamiseks avr-libc ja Kodulabori teegis juba funktsioonid olemas. Need kasutatakse ka järgmistes näidetes. |
| |
Tarkvaralise viite puhul on aga oluline teada, et hoolimata oma põhimõttelisest lihtsusest on see äärmiselt ebaefektiivne meetod energiatarbe seisukohast. Kõigil neil taktidel, mil mikrokontroller tegeleb kasutu loendamisega, kulub energiat. Patareidega rakenduses ei ole seega soovitatav pikki tarkvaralisi viiteid teha, vaid tuleks kasutada raudvaralisi taimereid, mis töötavad iseseisvalt ning äratavad protsessori uneolekust üles, kui on vaja midagi teha. | Tarkvaralise viite puhul on aga oluline teada, et hoolimata oma põhimõttelisest lihtsusest on see äärmiselt ebaefektiivne meetod energiatarbe seisukohast. Kõigil neil taktidel, mil mikrokontroller tegeleb kasutu loendamisega, kulub energiat. Patareidega rakenduses ei ole seega soovitatav pikki tarkvaralisi viiteid teha, vaid tuleks kasutada raudvaralisi taimereid, mis töötavad iseseisvalt ning äratavad protsessori uneolekust üles, kui on vaja tööd jätkata. |
| |
===== Praktika ====== | ===== Praktika ====== |
</code> | </code> |
| |
Kuigi näib, et LED vilgatab tõesti 1 sekundi järel, on aeg tegelikult siiski natuke pikem, sest LED-i ja viite funktsioonide väljakutsumine võtavad ka mõned mikrokontrolleri taktid aega. | Kuigi näib, et LED vilgatab tõesti 1 sekundi järel, on aeg tegelikult siiski natuke pikem, sest LED-i ja viite funktsioonide väljakutsumised võtavad ka mõned mikrokontrolleri taktid aega. |