avbrottsrutiner i C

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
tobbetabbe
Inlägg: 35
Blev medlem: 2 februari 2005, 17:18:12
Ort: Göteborg

avbrottsrutiner i C

Inlägg av tobbetabbe »

Finns det några problem att använda sig av samma variabler i olika interrupt
har testat men funkar inte försöker spara w-registren mm
har någon nåt förslag


highpriorityinterrupt
{

//läser av tiden mellan externa pulser från pulsgivare

//TMR1 genererar avbrott,räknar 10 externa pulser sedan slår runt



TMR0L_temp=TMR0L;
TMR0H_temp=TMR0H;

}


lowpriorityinterrupt
{

//läser av senaste avläsningen 1mS

TMR0L_sample=TMR0L_temp;
TMR0H_sample=TMR0H_temp;

}
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Du tycker naturligtsvis inte att det har den minsta betydelse
vilken processor du använder ???
tobbetabbe
Inlägg: 35
Blev medlem: 2 februari 2005, 17:18:12
Ort: Göteborg

Inlägg av tobbetabbe »

PIC18F458 20MHz CC8e-demo komplilator
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Finns det några problem att använda sig av samma variabler i olika interrupt

Nej, inte om man tänker sig för. Annars, ja...

> har testat men funkar inte

Vad är testat och vad funkar inte ?

> försöker spara w-registren mm

"Försöker" ?

> har någon nåt förslag

I interrupt delen av databladet finns det exempel
på hur man ska hantera b.la WREG och STATUS när
man kör med dubbla prioriteter. Det är oklart vad du har
läst och vad du har gjort så...

Men vänta, du kör ju C !
Missade det...
tobbetabbe
Inlägg: 35
Blev medlem: 2 februari 2005, 17:18:12
Ort: Göteborg

Inlägg av tobbetabbe »

har följt de anvisningar från kompilatortillverkaren mde påstår
att man enbart behöver spara undan de register som man på verkar
i interruptrutinen.så jag undrar om det finns standardlösningar.

ex på sparande av register som gjort förut:

save_wreg=wreg
save_FSR=FSR
osv... , sedan återställer jag det när avbrottet är slut.


Det enda jag gör här är att avläsa timrar. jag har bara skrivit pseudokod
för att inte förvirra.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Jo, kompilatorn bör ju ta hand om de "vanliga" registren, d.v.s
W, STATUS och ett till. Man borde inte behöva göra det själv,
men jag vet inte säkert.


Men vad är det för symptom du ser ?
Vad får du för problem ?

En annan metod är att helt enkelt kolla på ASM koden
som kompilatorn spottar ur sig, och se själv om den
gör något konstigt...
Användarvisningsbild
Icecap
Inlägg: 26650
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Nu kör jag ju med MikroC till PIC men de C-kompilers jag har kommit över sparar alla nödvändiga registre automatisk, det är inget man ska pilla med själv.

Vad som däremot kan bli mer komplicerat är variabler, man ska tänka till ordentligt vilka delar av programmet som får göra vad med vilk variabler annars blir det mycket lätt pannkaka av det hela.
pagge
EF Sponsor
Inlägg: 933
Blev medlem: 15 juni 2004, 00:15:08
Ort: Luleå
Kontakt:

Inlägg av pagge »

Speciellt grisigt kan det bli om man har 16 eller 32 bitars variabler. Då tar alla updateringar av variabeln, te.ex.

min_16_bitars_variabel += 0xBEEF;

minst två instruktioner att utföra eftersom uCn bara arbetar med 8 bitar åt gången. Om ett interrupt sker i mitten av detta och interruptrutinen läser av variabeln så kan du få lite vad för skit som helst.

Man bör stänga av interrupt vid skrivning till delade variabler

disable(det_interrupt_som_läser_min_16_bitars_variabel);
min_16_bitars_variabel += 0xBEEF;
enable(det_interrupt_som_läser_min_16_bitars_variabel);
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Speciellt grisigt kan det bli om man har 16 eller 32 bitars variabler.

Vilket naturligtsvis inte är något specifikt för C eller något annat språk heller.
Det är exakt samma "problem" i assembler.

Men angående originalfrågan, man bör kanske, även om det sägs att
kompilatorn sparar unden register på rätt sätt, att det även fungerar OK
vid användning av dubbla prioritetsnivåer. Jag har för mig att *någon*
(minns inte vilken) C-kompilator har problem me det och man får
skriva sina funktionsdefinitioner på ett speciellt sätt för att komma runt det.

Saken är ju den att *normalt* på PIC18 med *en* int-prio nivå (så som
de flesta normalt kör), så sker context-saving automatiskt utan att man
behöver lägga till någon egen kod (och det ska naturligtsvis inte kompilatorn
heller göra, eftersom det är onödigt), men i något fall har de alltså missat
att detta inte fungerar om man kör med båda int-prio's. Low-prio
interruptet måste spara context "för hand", medans high-prio interruptet
kan köra med automatiken.

Kan det vara så att din kompilator missar på denna punkt ?
pagge
EF Sponsor
Inlägg: 933
Blev medlem: 15 juni 2004, 00:15:08
Ort: Luleå
Kontakt:

Inlägg av pagge »

Precis det problemet ramlade jag in i igår när jag programerade en PIC med skolans kompilator från CSS (http://www.ccsinfo.com/).

Man måste starta programmet med
#device HIGH_INTS=TRUE

och måste deklarera INT hanterarna med hög prioritet såhär


#int_ccp1 HIGH
min_hanterare(){
}

och inte som vanligt

#int_ccp1
min_hanterare(){
}

Ett eller två slitna hårstrån kan erkännas innan jag kom på det =)
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Alltså för att du ville köra med båda nivåerna ?
För det behövs väl inte annars (d.v.s "normalt") ?
pagge
EF Sponsor
Inlägg: 933
Blev medlem: 15 juni 2004, 00:15:08
Ort: Luleå
Kontakt:

Inlägg av pagge »

Jepp. Kör man i kompabilitetsläge, dvs utan prioritet, så är det inga problem.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

OK. Och det de kallar "kompabilitetsläge" vill jag kalla "normalläge"... :-)

Men den lösning som du visade är väll "as documented", antar jag,
eller var det verkligen något du "kom på" ? :-)

En annan sak, skall *alla* INT hanterarna ha "HIGH" ?

Vilken är då "low" ??
pagge
EF Sponsor
Inlägg: 933
Blev medlem: 15 juni 2004, 00:15:08
Ort: Luleå
Kontakt:

Inlägg av pagge »

Nä, naturligtvis skall bara de med hög prioritet deklareras som high :).
HIGH_INTS=TRUE är för att kompilatorn skall veta att man kör olika nivåer, sen deklarerar man de höga hanterarna som HIGH så den vet vilka som är high och low.

Jo, det var dokumenterat långt ner i C manualen, dock inte i labkompendiumet jag fick av läraren :evil:

Anledningen till att jag behövde olika prioriteter är att jag skall styra några servon och eftersom prollen bara har två PWM kanaler måste jag göra en mjukvarupwm av ena comparemodulen som styr flera servon. Eftersom jag har en massa anda interrupts från diverse givare så kan dessa störa mjukvarupwmen som är väldigt känslig. Man märkte att servot ryckte om man t.ex. körde A/Dn interruptdriven i maxfart. Men nu funkar det klockers då soft PWM en kör hög prioritet och alla andra interrupts kör låg.
Skriv svar