170 likes | 300 Views
Realtidsprogrammering. En introduktion – Implementering (med exempel från PIC). Utan timing. Periodtid varierar beroende på funktionernas exekveringstid. Specificera endast maxtid ( ∑ Worst case) och eventuellt mintid ( ∑ Best case).
E N D
Realtidsprogrammering En introduktion – Implementering (med exempel från PIC) Realtidsprog. - Anders Arvidsson
Utan timing • Periodtid varierar beroende på funktionernas exekveringstid. • Specificera endast maxtid (∑ Worst case) och eventuellt mintid (∑ Best case). • För garanterad mintid kan en funktion utgöras av en fördröjningsloop. Realtidsprog. - Anders Arvidsson
Utan timing • while(1){ // Evig loop • PWM = knapptest(); // Läs och behandla indata • PORTB = BinBCD(PWM); // Presentera • RA2 = PWM_styr(PWM); // Agera • delay(); // Eventuell fördröjningsloop • }Anm: Exekvering får ej stanna i någon funktion, se nästa sida. Realtidsprog. - Anders Arvidsson
while(1) { while (knapp==0) // Väntar tills knapp är tryckt continue; Led ^=1; while (knapp==1) // Väntar tills knapp är släppt continue; } while(1) { if (knapp ==1 && knappold ==0) // Detekterar att knappens Knapptryckt = 1;// tillstånd har gått från 0 till 1 Knappold = knapp; if (Knapptryckt == 1) { Led ^=1; Knapptryckt = 0; } } KodstrukturVilken kod fungerar i realtid? Realtidsprog. - Anders Arvidsson
Med timing start • Vid hård realtid får ∑ Worst case aldrig överstiga tiden från start av timer tills timern räknat ut. Periodtiden blir då konstant. • Tidsmarginalen kan mätas genom att mäta tiden i wait. Sätt en pinne i början av wait (= idle), nollställ vid återstart. • Ge felindikering om timern redan räknat ut när programmet når wait. • Vid mjuk realtid kan timern startas med en kortare tid nästa varv om det förra varvet tog lite för lång tid. (Ladda om timern genom subtraktion istället för att ladda med en konstant). wait Realtidsprog. - Anders Arvidsson
Med timing • while(1){ // Evig loop • start_timer(periodtid); // Starta timern • PWM = knapptest(); // Läs och behandla indata • PORTB = BinBCD(PWM); // Presentera • RA2 = PWM_styr(PWM); // Agera • idle(); // Vänta på att timern räknat ut // Parallellt med det kan en // bakgrundstask utföras • } • Anm: Funktionerna får tillsammans inte ta längre tid än periodtid Realtidsprog. - Anders Arvidsson
TidmätningTimer 0 • Timer • 8 bitar, räknar ständigt upp • Kan ”slöas ner” av prescaler • max 256 ggr => upp till 65536 cykler • Använder intern klocka eller extern pinne • Kan fungera som räknare Realtidsprog. - Anders Arvidsson
Timer Se option_reg (skriv bara option, i C) för konfigurering. Realtidsprog. - Anders Arvidsson
void init_timer(void) { PSA = 0; // Koppla prescaler till TMR0 PS0 = 0; // Prescaler satt till PS1 = 1; // dela med 128 PS2 = 1; T0CS = 0; // Väljer intern oscillator till timer } void start_timer(void) //Laddar om timer { TMR0 = timervalue; //(256-timervalue)*prescaler*1us + omladdningstid T0IF = 0; } void wait_timer(void) //Väntar på att timer räknar ut (CPU är “idle”) { while(!T0IF) continue; } TimerExempelkod Realtidsprog. - Anders Arvidsson
Med timing, funktioner med lång exekv. tid start • Om en funktion tar för lång tid kan den ibland delas upp i två (eller fler) delar där ena delen körs ena varvet, andra delen nästa. • Denna metod används när interrupt inte bör användas men någon funktion har behöver kortare periodtid än den långa funktionen kan möta. switch() wait Realtidsprog. - Anders Arvidsson
InterruptAvbrott = preemptive schemaläggning Realtidsprog. - Anders Arvidsson
ISR Med Avbrott • Större delen av programmet körs som en bakgrundstask. Avbrottsrutinen (ISR) kör med viss periodicitet (triggad av timern) och/eller vid vissa händelser. • Övriga programmet kan köras med timing som i tidigare exempel, synkronisera med en flagga från ISR eller använd en andra timer. Realtidsprog. - Anders Arvidsson
AvbrottExempelkod • void interrupttimer(void){ // timer = funktionens namn// interrupt = lägg funktionen på • int_handling(); // adress 4 • something_hard(); • } • i main() • while(1){ // Evig loop • something_soft(); • idle(); // Vänta på nästa interrupt // = Synk • } Realtidsprog. - Anders Arvidsson
InterruptKällor • Flaggor • IE = Interrupt Enable • IF = Interrupt Flag Realtidsprog. - Anders Arvidsson
Konfigurera InterruptExempelkod void interrupttimer(void) { Flag = 1; // Visa att int skett TMR0 = timervalue; // Sätt timervalue med #define T0IF = 0; } void init(void) { PSA = 0; // Använd prescaler till TMR0 PS0 = 1; // Prescaler satt till dela med 64 PS1 = 0; PS2 = 1; T0CS = 0; // Väljer intern oscillator T0IE = 1; // Timer0 Interrupt Enable GIE = 1; // Global Interrupt Enable } Realtidsprog. - Anders Arvidsson
Implementera schemaläggning • Robot från föreläsning om realtidsprinciper. Realtidsprog. - Anders Arvidsson
StrukturSwitch • switch (CykCnt) { // Var 10:e ms • case 0:{ // 0 ms • K(); // Krocksensor • S(); // Styr robot • H(); // Hjulräknare • break; • } • case 1: case 5: { // 10, 50 ms • K(); • break; • } • case 2: case 4: { // 20, 40 ms • K(); • S(); • break; • } • case 3: { // 30 ms • K(); • H(); • break; • } • default: { • CykCnt=0; • } • } • CykCnt=CykCnt++; • If (CykCnt == 6) • CykCnt=0; Realtidsprog. - Anders Arvidsson