Beágyazott és Ambiens Rendszerek

Hasonló dokumentumok
Beágyazott és Ambiens Rendszerek

Járműfedélzeti rendszerek I. 4. előadás Dr. Bécsi Tamás

Az AVR programozás alapjai. Előadja: Both Tamás

I. C8051Fxxx mikrovezérlők hardverfelépítése, működése. II. C8051Fxxx mikrovezérlők programozása. III. Digitális perifériák

ÉRZÉKELŐK ÉS BEAVATKOZÓK I. GY1.1 SENSACT0 PÉLDAPROGRAM

Dr. Schuster György október 14.

C programozási nyelv Pointerek, tömbök, pointer aritmetika

Silabs STK3700, Simplicity Studio laborgyakorlat

Mikrovezérlők programozása

Mintavételezés tanulmányozása. AD - konverzió. Soros kommunikáció

Programozás alapjai gyakorlat. 2. gyakorlat C alapok

Mérési jegyzőkönyv. az ötödik méréshez

6. fejezet: Ciklusok

Újrakonfigurálható eszközök

A C# programozási nyelv alapjai

Vezérlési szerkezetek

1. Egyszerű (primitív) típusok. 2. Referencia típusok

Digitális ki-bemenetek kezelése, bitszintű műveletek

Mikrorendszerek tervezése

Dr. Oniga István DIGITÁLIS TECHNIKA 8

Mechatronika és mikroszámítógépek. 2018/2019 I. félév. Külső megszakítások

Felvételi vizsga mintatételsor Informatika írásbeli vizsga

MSP430 programozás Energia környezetben. Az I/O portok kezelése

Bevezetés a mikrovezérlők programozásába: MAX6958: Hétszegmenses LED kijelző vezérlő

Mikrovezérlők programozása

Mechatronika és mikroszámítógépek 2017/2018 I. félév. Bevezetés a C nyelvbe

Programozás I. 3. gyakorlat. Szegedi Tudományegyetem Természettudományi és Informatikai Kar

Hardver modellezés SystemC-vel és SDL grafikus könyvtárral Visual Stúdió alatt

Programozás alapjai C nyelv 4. gyakorlat. Mit tudunk már? Feltételes operátor (?:) Típus fogalma char, int, float, double

PWM elve, mikroszervó motor vezérlése MiniRISC processzoron

A MATLAB alapjai. Kezdő lépések. Változók. Aktuális mappa Parancs ablak. Előzmények. Részei. Atomerőművek üzemtana

5. KOMBINÁCIÓS HÁLÓZATOK LEÍRÁSÁNAK SZABÁLYAI

INFORMATIKA tétel 2018

Az interrupt Benesóczky Zoltán 2004

7. fejezet: Mutatók és tömbök

GPU Lab. 4. fejezet. Fordítók felépítése. Grafikus Processzorok Tudományos Célú Programozása. Berényi Dániel Nagy-Egri Máté Ferenc

1. Template (sablon) 1.1. Függvénysablon Függvénysablon példányosítás Osztálysablon

Egyszerű RISC CPU tervezése

Mintavételes szabályozás mikrovezérlő segítségével

ATMEL ATMEGA MIKROVEZÉRLŐ-CSALÁD

8. gyakorlat Pointerek, dinamikus memóriakezelés

Labor gyakorlat Mikrovezérlők

Laborgyakorlat 3 A modul ellenőrzése szimulációval. Dr. Oniga István

AVR assembly és AVR C modulok együttes használata AVR C projektben. Összeállította: Sándor Tamás

A fordítóprogramok szerkezete. Kódoptimalizálás. A kódoptimalizálás célja. A szintézis menete valójában. Kódoptimalizálási lépések osztályozása

Labor gyakorlat Mikrovezérlők

Bevezetés a programozásba I 3. gyakorlat. PLanG: Programozási tételek. Programozási tételek Algoritmusok

Programozás alapjai 9.Gy: Struktúra 2.

Vezérlési szerkezetek. Szelekció Ciklusok

Programozás alapjai gyakorlat. 4. gyakorlat Konstansok, tömbök, stringek

A Memory Interface Generator (MIG) beállítása a Logsys Kintex-7 FPGA kártyához

MSP430 programozás Energia környezetben. LED kijelzok második rész

Webprogramozás szakkör

2018, Diszkrét matematika

Assembly. Iványi Péter

PHP alapjai, bevezetés. Vincze Dávid Miskolci Egyetem, IIT

Az MSP430 mikrovezérlők digitális I/O programozása

The modular mitmót system. DPY kijelző kártya C API

Készítette: Nagy Tibor István

1. Jelölje meg az összes igaz állítást a következők közül!

Mit tudunk már? Programozás alapjai C nyelv 4. gyakorlat. Legnagyobb elem keresése. Feltételes operátor (?:) Legnagyobb elem keresése (3)

5-6. ea Created by mrjrm & Pogácsa, frissítette: Félix

Labor 2 Mikrovezérlők

DIGITÁLIS TECHNIKA 8 Dr Oniga. I stván István

Szoftvertervezés és -fejlesztés I.

Mutatók és mutató-aritmetika C-ben március 19.

Programozás alapjai C nyelv 5. gyakorlat. Írjunk ki fordítva! Írjunk ki fordítva! (3)

2005_01/1 Leírtunk egymás mellé hét racionális számot úgy, hogy a két szélső kivételével mindegyik eggyel nagyobb a két szomszédja szorzatánál.

Konkurens TCP Szerver

BME MOGI Gépészeti informatika 1.

Egész számok. pozitív egész számok: 1; 2; 3; 4;... negatív egész számok: 1; 2; 3; 4;...

Újrakonfigurálható eszközök

5. Laborgyakorlat. Számláló funkciók, időzítő funkciók.

MSP430 programozás Energia környezetben. Szervó motorok vezérlése

Mikrovezérlők Alkalmazástechnikája

Alkalmazott modul: Programozás. Programozási tételek, rendezések. Programozási tételek Algoritmusok és programozási tételek

A szemantikus elemzés helye. A szemantikus elemzés feladatai. A szemantikus elemzés feladatai. Deklarációk és láthatósági szabályok

Számítógépek felépítése

// keressük meg a legnagyobb faktoriális értéket, ami kisebb, // mint százmillió

Digitális technika (VIMIAA01) Laboratórium 9

Magas szintű optimalizálás

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós március 3. Széchenyi István Egyetem, Gy r

Függvény pointer. Feladat: Egy tömbben soroljunk fel függvényeket, és hívjuk meg valahányszor.

Programozás alapjai. 6. gyakorlat Futásidő, rekurzió, feladatmegoldás

Ismerkedjünk tovább a számítógéppel. Alaplap és a processzeor

Bevezetés a programozásba I.

Újrakonfigurálható eszközök

Programozás alapjai 2.Gy: A C nyelv alapjai P R O

Hobbi Elektronika. A digitális elektronika alapjai: Sorrendi logikai áramkörök 2. rész

APB mini PLC és SH-300 univerzális kijelző Általános használati útmutató

Kilencedik témakör: Lazarus-Firebird. Készítette: Dr. Kotsis Domokos

3 A C programozási nyelv szintaktikai egységei

Járműfedélzeti rendszerek I. 5. előadás Dr. Bécsi Tamás

Java és web programozás

Gyakorló feladatok 9.évf. halmaznak, írd fel az öt elemű részhalmazokat!. Add meg a következő halmazokat és ábrázold Venn-diagrammal:

A tervfeladat sorszáma: 1 A tervfeladat címe: ALU egység 8 regiszterrel és 8 utasítással

Írjon olyan programot a standard könyvtár alkalmazásával, amely konzolról megadott valós adatokból meghatározza és kiírja a minimális értékűt!

Mechatronika és mikroszámítógépek

Bevezetés a programozásba. 8. Előadás: Függvények 2.

MPLAB IDE - SIM - - Rövid ismertető a használathoz - Kincses Levente 3E22 89/ November 14. Szabadka

Átírás:

Beágyazott és Ambiens Rendszerek 5. gyakorlat tematikája Futási idő mérése, időmérés A gyakorlat során a következő témakörökkel ismerkedünk meg: futási idő mérésének technikája, néhány tipikus utasítás erőforrásigénye, időmérés általában. 1. Futási idő mérése Háttérismeretek A következőkben megismerkedünk a futási idő mérésének módszerével és néhány tipikus utasítás futási idejét is megvizsgáljuk. A futási idő mérésének több módszere ismert (lásd előadás), a gyakorlat során a mikrokontroller egy beépített speciális időzítőjét/számlálóját fogjuk használni. Ezt a számlálót a processzorban a Debug Interface-en belül a Data Watch point and Trace (DWT) nevű egység tartalmazza. Megoldható a feladat természetesen más számláló/időzítő egységgel is, de jelen esetben ezen számláló használata a egyszerűbb. A számláló 32 bites, tehát a 14 MHz-es default órajel esetén hosszúságú futási időt is tudunk mérni. Itt jegyezzük meg, hogy a futási idő mérése igazából futási ciklusidő mérése, tehát azt fogjuk meghatározni, hogy hány órajelciklus alatt fut le egy adott kódrészlet, ami viszont az órajel-frekvencia ismeretében könnyen átváltható idővé is. A futási idő mérésére felhasznált számláló neve: Cycle Count Register. Ez a regiszter a processzor indulásakor nulláról indul, és minden órajelütemben eggyel nő az értéke. A számláló regisztert a következő módon érhetjük el: DWT->CYCCNT Egy lehetséges megoldás a mérésre: runtime = DWT->CYCCNT; Ide jön a programkód, aminek a futási idejét mérni szeretnénk. runtime = DWT->CYCCNT - runtime - COMP_CONST; A fenti kód lefutását követően a runtime változó fogja tartalmazni az órajelekben mért futási időt. A COMP_CONST helyére egy olyan konstanst írjunk, aminek a segítségével a fenti kifejezés nulla értéket ad, ha nincsen semmilyen programkód megadva. Ezzel korrigáljuk a számítással és a regiszterolvasással eltöltött időt, amit belemérünk a futási időbe, de egyébként nem része a programnak. 1

Feladatok 1. Hozzunk létre egy üres projektet, és a futási idő méréséhez megadott programkódban határozzuk meg a COMP_CONST konstans értékét. 2. Mérjük meg a következő három művelet futási idejét három féle adattípus esetén a következő táblázatnak megfelelően: -O0 int32_t float double összeadás 5 89 136 szorzás 5 62 123 osztás 10 89 168 Mintakód: int32_t a=300, b=20, c=0; runtime = DWT->CYCCNT; c=a+b; runtime = DWT->CYCCNT - runtime - COMP_CONST; Honnan látható, hogy a processzor rendelkezik osztást támogató utasítással? 3. Kikapcsolt O0 szintű optimalizáció mellett mérd meg, hogy a következő típuskonverziók hány órajel alatt futnak le. Mintakód: a_float = (float) a_int; Megjegyezzük, hogy a típuskonverziót (kasztolást) akkor is elvégzi a fordító, ha azt explicite nem adjuk meg, tehát a következő sor is tartalmaz egy implicit típuskonverziót, ugyanaz, mintha kiírnánk a (float) a_int konverziót: a_float = a_int; forrás \ cél int32_t float double int32_t 62 77 float 41 35 double 43 43 2

4. Mérjünk meg újra az egyik típuskonverzió futási idejét O3 optimalizációs szint esetén is: Project Properties C/C++ Build Settings Optimization Optimize most (-O3) Figyeljük meg, hogy a projekt újrafordítását követően milyen eredményt kapunk a futási időre (pl. double osztás esetén). Ebben az esetben furcsaságokat figyelhetünk meg, mert a fordító eltávolítja a nem használt változókat, így a mért programkód gyakorlatilag eltűnhet. Érdemes tehát a műveletek ki- és bemeneti változóit, illetve a futási idő mérésére szolgáló változót volatile változóként deklarálni, így a fordító nem optimalizálja ki azokat. 5. Bekapcsolt O3 szintű optimalizáció mellett deklarálj két darab N méretű int32_t típusú tömböt (volatile legyen), és számítsd ki a szorzatok összegét:. Jegyezd fel a futási időket H=15 20 méretű tömbök esetére. N 15 16 17 18 19 20 órajelciklus 119 127 135 218 230 242 ( O3 ) órajelciklus ( O0 ) 558 Vizsgáld meg, hogy mennyire egyenletes a változás a ciklus hosszának növelésével. Figyeld meg a fordító loop unroll 1 funkcióját a dissasemblált kódban. N=15 esetére nézd meg, hogy kikapcsolt optimalizáció esetén mekkora a futási idő. 1 loop unroll: a for ciklusok kifejtése úgy, hogy az N-szer végrehajtandó kódot N-szer megismétli a fordító. Növeli a kód méretét, de általában gyorsabb, mert nem kell a ciklusváltozót kezelni és ugró utasítást végrehajtani. Probléma lehet még, hogy az utasítás cache nem használható ki úgy, mint egy ciklus esetén. 3

Mintakód: sum=0; for (ii=0; ii<n; ii++) { sum += A[ii]*B[ii]; Kiegészítő feladatok 6. Bekapcsolt O3 szintű optimalizáció mellett deklarálj két darab N=100 méretű int32_t típusú tömböt (volatile legyen), és számítsd ki a szorzatok összegét három módszerrel:... Ez a loop unroll egy speciális esete, amikor a programozó kézzel teríti ki a hurkot, de csak kisebb részletekben. Tehát például négyesével lépkedve a tömbben a négyes blokkokat egyszerre összeadjuk. Ebben az esetben a ciklusváltozó kezelése negyedannyi időt igényel. A megvalósítás a következő lehet (pl. 2-es unroll esetén): sum=0; for (ii=0; ii<n; ii+=2) { sum += A[ii]*B[ii]+ A[ii+1]*B[ii+1]; A ciklusban tehát kettesével lépkedünk, és vesszük az i és (i+1)-edik elemet. Végezd ez a mérést N=1000-re is. fokszám \ unroll 1 (sum: i) 2 (sum: i, i+1) 4 (sum: i, i+1, i+2, i+3) N=100 1105 857 711 N=1000 11005 8506 7509 7. Bekapcsolt O3 szintű optimalizáció mellett deklarálj két darab N=100 méretű int32_t típusú tömböt (volatile legyen), és számítsd ki a szorzatok összegét:. Hozzuk létre a következő függvényt: int32_t mult(int32_t a, int32_t b){ return a*b; A szorzást végezd el háromféle módon: A*B A mult függvény használatával: mult(a,b). 4

Úgy, hogy a mult függvény elé betesszük a következő függvényattribútumot: attribute ((noinline)) int32_t mult(int32_t a, int32_t b) Jegyezd fel a futási időket. fokszám \ unroll A*B mult(a,b) noinline mult N=100 1114 1114 1717 Látható, hogy optimalizáció esetén a fordító automatikusan is felismerheti, hogy melyik függvényt érdemes inline függvényként használni. 5

2. Időmérés, időzítő konfigurálása A következőkben az időmérés általános módszerével, az időzítők használatával ismerkedünk meg. A mikrokontrollerek timer egységeinek általában két fő üzemmódja van: Időzítő: valamilyen belső órajelforrás segítségével időt mérünk, megszakításokat generálunk. Számláló: általában valamilyen külső forrásból beérkező impulzusokat számláljuk. Ezeken belül még több aleset is elképzelhető. A gyakorlaton használt mikrokontroller timer egysége a következő módon épül föl (a Timer0 egységet fogjuk használni): Mi az alábbi egyszerűsített ábrának megfelelő időzítő üzemmódban fogjuk használni (a fenti ábra pirossal bekeretezett részének magyarázata): CLK (cmuclock_hfper) prescaler reset TIMER0->CNT TIMER0->TOP == IT +1 TIMER0->CNT TIMER0->TOP void TIMER0_IRQHandler(void) IT IT idő 6

A Timer egyszerű időzítő üzemmódjában a bemenő órajel minden ütemére a CNT regiszter értéke eggyel nő mindaddig, amíg a TOP regiszterben tárolt értéket el nem éri. Ekkor a CNT számláló nullázódik, és a megfelelő megszakításvonalon megszakítást generál (TIMER_IF_OF). Az időzítő kezeléséhez hozzá kell adni a projekthez az em_timer.c és em_cmu.c fájlokat 2, és includeolni kell a em_cmu.h és em_timer.h fájlokat. A LED-ek kezeléséhez a projekthez hozzá kell adni a bsp_bcc.c, bsp_stk_leds.c, bsp_stk.c és em_gpio.c fájlokat 3, és include-oljuk a bsp.h fájlt. Az időzítőt könyvtári függvényei segítségével konfiguráljuk a következő módon: a periféria órajel osztójának beállítása időzítő órajelének engedélyezése létrehozzuk az inicializációhoz szükséges paraméterstruktúrát o a prescalert átállítjuk a megfelelő értékre reseteljük az időzítőt beállítjuk a TOP értéket töröljük az esetleges függő megszakítást Engedélyezzük a megszakítást o Engedélyezzük az időzítő perifériánál o Engedélyezzük a központi megszakítás-kezelőnél a Timer megszakítást (NVIC) A fenti inicializációs folyamatot az alábbi programkód valósítja meg. // a periféria órajel osztójának beállítása CMU_ClockDivSet(cmuClock_HFPER, cmuclkdiv_1); // ******************************* // * TIMER inicializálása * // ******************************* // időzítő órajelének engedélyezése CMU_ClockEnable(cmuClock_TIMER0, true); // létrehozzuk az inicializációhoz szükséges paraméterstruktúrát TIMER_Init_TypeDef TIMER0_init = TIMER_INIT_DEFAULT; // a prescaler-t átállítjuk 2 elérési útvonal: SimplicityStudio\developer\sdks\gecko_sdk_suite\v1.1\platform\emlib\src\ 3 elérési útvonal: SimplicityStudio\developer\sdks\gecko_sdk_suite\v1.1\hardware\kit\common\bsp\ 7

TIMER0_init.prescale = timerprescale1; // timerprescale1...timerprescale1024 // inicializálás a paraméterstruktúrával //void TIMER_Init(TIMER_TypeDef *timer, const TIMER_Init_TypeDef *init); TIMER_Init(TIMER0, &TIMER0_init); // reseteljük a számlálót TIMER_CounterSet(TIMER0, 0); // // beállítjuk a TOP értéket // STATIC_INLINE void TIMER_TopSet(TIMER_TypeDef *timer, uint32_t val) TIMER_TopSet(TIMER0, IDE_KELL_ÍRNI_A_TOP_ÉRTÉKET); // 14MHz/presc/TOP // töröljük az esetleges függő megszakításokat // STATIC_INLINE void TIMER_IntClear(TIMER_TypeDef *timer, uint32_t flags); TIMER_IntClear(TIMER0, TIMER_IF_OF); // Timer IT engedélyezése //TIMER_IntEnable(TIMER_TypeDef *timer, uint32_t flags); TIMER_IntEnable(TIMER0, TIMER_IF_OF); // Timer IT engedélyezése az NVIC-ben NVIC_EnableIRQ(TIMER0_IRQn); // ******************************* // * LED inicializálása * // ******************************* BSP_LedsInit(); A megszakítás lekezeléséhez az alábbi függvényt kell implementálni a programkódban: void TIMER0_IRQHandler(void){ BSP_LedToggle(0); TIMER_IntClear(TIMER0, TIMER_IF_OF); //TIMER flag törlése A függvénynevek beszédesek, a fenti programkód értelmezését a hallgatókra bízzuk. A timer inicializálásához használt default értékek. #define TIMER_INIT_DEFAULT { \ 1, /* Enable timer when init complete. */ \ 0, /* Stop counter during debug halt. */ \ timerprescale1, /* No prescaling. */ \ timerclkselhfperclk, /* Select HFPER clock. */ \ 0, /* Not 2x count mode. */ \ 0, /* No ATI. */ \ timerinputactionnone, /* No action on falling input edge. */ \ timerinputactionnone, /* No action on rising input edge. */ \ timermodeup, /* Up-counting. */ \ 0, /* Do not clear DMA requests when DMA channel is active. */ \ 0, /* Select X2 quadrature decode mode (if used). */ \ 0, /* Disable one shot. */ \ 0 /* Not started/stopped/reloaded by other timers. */ \ 8

Feladatok 1. A fent leírtak alapján inicializáljuk a timer0 perifériát. 2. Állítsuk be a prescaler-t és az időzítő TOP értékét úgy, hogy 1 másodpercenként generáljunk megszakításokat (a megszakításrutinban váltogassuk az egyik LED állapotát). a. Valójában mekkora a beállított frekvencia névleges értéke? 3. Állítsuk be a prescaler-t 1-es értékűre, és az időzítő TOP értékét 14000-re. A megszakításrutinban szoftveresen oldjuk meg, hogy 1 másodpercenként váltson a LED állapotot. 9