Anropa funktion vid avbrott i C

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
ankan
Inlägg: 1091
Blev medlem: 12 november 2004, 01:50:35

Anropa funktion vid avbrott i C

Inlägg av ankan »

Har flera olika funktioner jag vill köra igång vid avbrott.. Olika funktioner vid olika avbrott. Det hela är alltså i C för en 16f88 pic.

Sedan vill jag logga olika händelser. Och de flesta händelserna sker vid avbrott men även i huvudprogrammet. Att skriva till en variabel som sedan i huvudprogrammet kollas då och då för att se om den har ändrats var ingen bra lösning. Risken är att flera olika saker hinner hända innan programmet kommer till läget där den skriver händelsen till EEPROM.

Ska det inte gå att köra funktioner från avbrott eller måste de se ut på något speciellt sätt? Får följande felmeddelande nämligen:

function _skriv_till_eeprom appears in multiple call graphs: rooted at _avbrott and _main

Är det MACROs som gäller på något sätt eller? Har inte koll på Macros.
rehnmaak
Inlägg: 2204
Blev medlem: 13 december 2005, 01:43:41

Inlägg av rehnmaak »

Normalt sett ska det inte vara några problem att anropa funktioner från ett interrupt. Men det kan vara något specifikt problem med att anropa samma funktion från både interrupt och main när man använder PIC. Lösningen i ditt fall tror jag är att du skriver två funktioner skriv_till_eprom och skriv_till_eprom_vid_interrupt. Den ena anropar du från main och den andra från interrupt.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Har flera olika funktioner jag vill köra igång vid avbrott...

Anropar du samma funktion(er) från icke-ISR kod ?

Problemet är om du anropar samma funtion både från main
och från din ISR. Det skulle ju kunna inträffa att ett interrupt
kommer just när main ligger i funktionen, med intressanta resultat
när ISR'en också kör samma funktion innan retfie... :-)

> Att skriva till en variabel som sedan i huvudprogrammet kollas då och då för att se om den har ändrats var ingen bra lösning.

Och problemet var ?
Just det är väl annars standardlösningen...

> Risken är att flera olika saker hinner hända innan programmet kommer till läget där den skriver händelsen till EEPROM.

Det spelar i princip ingen roll om du skriver i main eller i ISR'en, hinner
inte koden med så gör den det inte. Du får kanske ser över den
övergripande designen istället.

> function _skriv_till_eeprom appears in multiple call graphs: rooted at _avbrott and _main

Gör två kopior av funktionen så att det inte "krockar".
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Men det kan vara något specifikt problem med att anropa samma funktion från både interrupt och main när man använder PIC.

Bara lite intresserad... :-)
På vilket sätt är det ett specifikt problem för PIC ?
rehnmaak
Inlägg: 2204
Blev medlem: 13 december 2005, 01:43:41

Inlägg av rehnmaak »

Jag vet inte OM det är ett specifikt problem för PIC:ar att man inte kan anropa samma funktion från BÅDE main OCH avbrott (det verkar vara ett problem map på felmeddelandet). Det jag vet är att det normalt sett inte ska behöva vara något problem (med tex 68k eller andra "riktiga" processorer). Problemet här är väl antagligen att man inte har någon stack att lagra variablerna i själva funktionen vilket gör att det blir fullständigt fel om man försöker köra sk reentrant kod.
ankan
Inlägg: 1091
Blev medlem: 12 november 2004, 01:50:35

Inlägg av ankan »

Kopierade funktionerna och gav dem ett annant namn och anropade dem. Fåt inte det där med rooted felmeddelandet men jag får fortfarande följande:

Error[000] : Can't find 0x1 words (0x1 withtotal) for psect intsave in segment BANK0

vilket är helt obegripligt för mig vad det betyder.

Det där med att skriva till en variabel som kollas då och då var ingen bra ide eftersom i huvudprogrammet finns det funktioner som vill göra samma sak och hoppar programmet tillbaka till ett ställe som är precis efter att den kollade varibeln så är det risk att något annat skriver över den.
rehnmaak
Inlägg: 2204
Blev medlem: 13 december 2005, 01:43:41

Inlägg av rehnmaak »

Det är riktigt att det är vanskligt att skriva till samma variabel från både main och interrupt. Ska du köra den metoden måste du stänga av avbrotten när du manipulerar den variabeln i main.

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

Inlägg av sodjan »

> > function _skriv_till_eeprom appears in multiple call graphs: rooted at _avbrott and _main
>
> Gör två kopior av funktionen så att det inte "krockar".

Fel av mig.
Det kommer fortfarande att bli konflikt kring registren för EEPROM
hanteringen, även om man för övrigt har privata variabler (och
funktionsparametrar via stack o.s.v)

Du kan/bör alltså inte ha EEPROM rutiner både i main och ISR,
*om* du inte helt stänger av interrupt innan anrop av EEPROM
rutinen från main (så att den får gå klar "i fred").

> Error[000] : Can't find 0x1 words (0x1 withtotal) for psect intsave in segment BANK0

Det finns inte plats för allokering av någon variabel i segment BANK0
(RAM minne) i sectionen "intsave".
Sannolikt något utrymme för att spara kontext vid interrupt...
C manualen borde ha mer detaljer...

> Det där med att skriva till en variabel som kollas då och då var ingen bra
> ide eftersom i huvudprogrammet finns det funktioner som vill göra
> samma sak och hoppar programmet tillbaka till ett ställe som är precis
> efter att den kollade varibeln så är det risk att något annat skriver över
> den.

Precis, om man använder *samma* variabler/flaggor i main och ISR,
så måste man vara försiktig... :-)
Användarvisningsbild
Mignon
EF Sponsor
Inlägg: 174
Blev medlem: 6 mars 2006, 18:37:46
Ort: Göteborg
Kontakt:

Inlägg av Mignon »

Vet inte om det var det du testade först men annars brukar man ju ha en variebel mutex som är 0 så länge ingen använder funktionen och 1 när den används. Då kan main först kolla så att mutex=0 innan den drar igång funktionen och på så sätt körs de aldrig samtidigt..

Såg dock att du hade gjort något liknande först, förstod bara inte om det var exakt såhär.. :)
ankan
Inlägg: 1091
Blev medlem: 12 november 2004, 01:50:35

Inlägg av ankan »

Även om jag i koden kan definiera det så så fattar nog inte kompilatorn att funktionen inte kan anropas samtidigt..
Jag har i alla fall löst problemet. Det blev till att flytta ut anropet av funktionen till huvudprogrammet. Det var bara ett anrop från avbrott jag behövde och sedan fixade jag så att övriga inte använder variabeln utan anropar funktionen direkt i stället för att kollavariabel och sedan anropa funktion.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Även om jag i koden kan definiera det så så fattar nog inte
> kompilatorn att funktionen inte kan anropas samtidigt..

Exakt. Jag tror inte att kompilatorn är tillräckligt smart för att
analysa allt, t.ex om interrupt är avstända medans main kör
funktionen o.s.v. Programmerar man i ASM har man ju själv
100% koll på allt... :-)

Mignon> en variebel mutex som är 0 så länge ingen använder
> funktionen och 1 när den används.

Problemet med sådana lösningar är att det ändå finns en risk att
något inträffar (t.ex ett interrupt) mellan att man kollar om mutex'en är
0 och att man sätter den till 1. Delvis kan man komma åt desa problem
genom att stänga av interrupt under tiden o.s.v., men deet är inte helt
enkelt på en processor som saknar "atomic" mutex instruktioner...
Skriv svar