Anropa funktion vid avbrott i C
Anropa funktion vid avbrott i C
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.
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.
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.
> 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".
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".
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.
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.
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.
> > 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...
>
> 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...

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..
Såg dock att du hade gjort något liknande först, förstod bara inte om det var exakt såhär..

Ä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.
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.
> Ä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...
> 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...