PIC call stack in interrupt

hallo,
ik ben al een tijd bezig met het debuggen van een stukje programma.
ik gebruik een pic16F877A.
en ik gebruik de timer0 interrupt.
in de datasheet staat dat je tot 8 call instructies kunt geven zonder een return.

ik heb kunnen vast stellen dat de routine in mijn programma niet meer terug komt op de eerste call.
zonder dat ik daar een logisch verklaring voor kan vinden.

ik vraag me nu dus af, of een interrupt te vergelijken is met een call instructie!

de routine gaat tot in de 8e stack.
wat gebeurd er als er dan een interrupt komt?

even als voorbeeld:
dit kan!

call
---- call
--------- call
-------------- call
------------------- call
------------------------ call
----------------------------- call
---------------------------------- call
---------------------------------- ....
---------------------------------- ....
---------------------------------- ....
---------------------------------- ....
---------------------------------- ....
---------------------------------- return
----------------------------- return
------------------------ return
------------------- return
-------------- return
--------- return
---- return
return

maar werkt dit?:

call
---- call
--------- call
-------------- call
------------------- call
------------------------ call
----------------------------- call
---------------------------------- call
---------------------------------- ....
---------------------------------- ....
---------------------------------- ....
----------------------------------hier een interrupt
---------------------------------- ....
---------------------------------- ....
---------------------------------- return
----------------------------- return
------------------------ return
------------------- return
-------------- return
--------- return
---- return
return

ik heb het vermoeden dat een interrupt te vergelijken is met een call instructie, waardoor je eigenlijk 9 stack levels nodig zou hebben.
in de datasheet staat:

12.11 Context Saving During Interrupts
During an interrupt, only the return PC value is saved
on the stack.

dit is het enigste wat ik me kan verzinnen.
of zie ik toch nog iets over het hoofd?!!!

ik wil alles weten over pic stap voor stap
Arco

Special Member

Alle calls hebben stack nodig, of dat nu een interrupt routine of een gewone routine is. Als je meer call maakt, crasht het programma gewoon.
Normaal zit er bij een compiler wel een tool om te zien hoe diep de call stack gebruikt wordt in een programma.

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Een interrupt gebruikt uiteraard de stack.

Die stack is een zeer ernstige (en helaas ook niet de enige) tekortkoming in de standaard 8-bit PIC kern. Niet alleen de stack diepte van 8 posities, maar ook het compleet negeren van een stack overflow, waardoor ik me een keer een half jaar op het hoofd heb lopen krabben waarom mijn firmware op de mafste manieren "rogue" ging, dus niet deed wat het moest doen zonder te crashen.

Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com
Arco

Special Member

Ik heb met zo'n klein controllertje nog nooit gehad dat ik aan 8 levels stack niet genoeg had, dan ben je toch verkeerd bezig... ;)
Alle niet al te belegen types hebben 16 level (16F1xxx) of 31 level (18F) of software stack (24f). Alleen de hele oude (zoals de 16f628a) zijn nog 8 (of zelfs 2) levels.
De nieuwere hebben ook allemaal een stack under/overflow flag en reset.

[Bericht gewijzigd door Arco op dinsdag 7 maart 2017 02:16:31 (11%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Of juist goed bezig; ik heb een o.a. SMTP client in een PIC16F88 gestopt ;)

Maar inmiddels voor het serieuze werk op PIC24 overgestapt.

Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com

nou, weer wat geleerd.
dat een interrupt ook stack gebruikt wist ik nog niet.
komt ook omdat ik daar nog niet echt gebruik van heb gemaakt.
maar het is me nu wel duidelijk geworden.
ik moet maar eens een ander type uit gaan zoeken om mee te werken.
ik begin aardig tegen de beperkingen van dit type aan te lopen, en het kost me meer tijd om hier omheen te werken dan dat het voor mij werkt.
wat zouden betere alternatieven zijn?

ik wil alles weten over pic stap voor stap
Arco

Special Member

Alles wat een call maakt, moet toch ergens een adres opslaan om te weten waar naartoe terug te keren?... ;) (simpele logica)
Ik persoonlijk ben nog nooit tegen 8 level stack limit aangelopen, is ook simpel te vermijden. (al die calls geven ook veel overhead)
Maar als je toch wilt nesten, dan kun je een pic24 overwegen (mijn voorkeur), of een enhanced 8 bit(16f1xxx) danwel een 18F...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Het adres om naar terug te keren, en wellicht ook de registers van de cpu.

PE2BAS

Bij de PIC16 basis chipjes kun je geen registers op de stack pushen; er zijn geen PUSH of PULL commando's. De stack is puur en alleen voor CALLs, en die stack is in de hardware geïntegreerd, en volledig ontoegankelijk.

De basis 8-bit kern van Microchip is eigenlijk te simpel voor wat je met zulke rijk uitgeruste controllers kunt.

Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com

Op 7 maart 2017 21:44:58 schreef Arco:
Alles wat een call maakt, moet toch ergens een adres opslaan om te weten waar naartoe terug te keren?... ;)

Ja, maar zo goed als ALLE andere cpu's gebruiken daarvoor een constructie genaamd "de stack". Dat is een stukje geheugen wat daarvoor gereserveerd wordt. De lol daarvan is dat je geheugen de beperking is, en niet een hardware limiet van 8.

Het hangt er sterk van af wat je programmeerstijl is of een stackdiepte van 8 genoeg is. Als de filosofie (zoals die van kevin, Bravo!) is dat het programmeren veel meer tijd-en-geld kost dan de hardware en dat kleine projectjes toch nooit problemen hebben met de resources, dan programmeer je met het doel om zo overzichtelijk mogelijke code te krijgen. En dat betekent dat je gewoon functies aanroept als het beter is voor het overzicht.

c code:


int factorial (int n)
{
  if (n > 1) return n * factorial (n-1);
  else       return 1;
}

Deze kan je makkelijk herschrijven om een loop te gebruiken. Maar gegeven de definitie is het wel de makkelijkste manier om het te schrijven. Er zijn andere problemen, denk aan quicksort die veel lastiger om te schrijven zijn naar een iteratieve aanpak.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Arco

Special Member

Ja, maar zo goed als ALLE andere cpu's gebruiken daarvoor een constructie genaamd "de stack".

Ja, dat weet ik ook wel. Een hardware stack is hetzelfde, alleen vast in grootte. De 2/8 level deep stack is er alleen bij oude tot heel oude pics...
(die hadden ook maar weinig peripherals. Als je ze toch wilt gebruiken, moet je ook niet klagen... :) )

Ik blijf erbij dat 8 stack levels ruim voldoende is om een goed programma te schrijven. Het hangt er zuiver vanaf hoe en waar je subroutines aanroept.
(ik heb vrij complexe software in een 16f648a geschreven zonder problemen, en die was zelfs nog voor bijna de helft leeg)
Als code veel ruimte inneemt of diep genest is, komt dat bijna altijd doordat de boel haastig in mekaar geflanst is. Wat langer denken voor je begint met programmeren...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Op 8 maart 2017 10:03:54 schreef Arco:

(ik heb vrij complexe software in een 16f648a geschreven zonder problemen, en die was zelfs nog voor bijna de helft leeg)

Je haalt je eigen stelling direct onderuit. :-) Het was niet echt complex als hij nog voor de helft leeg was. :-)

Het is een programmeerstijl kwestie. Als je de beperking hebt: "max 8 diep" dan MOET je een stijl gebruiken die niet te diep gaat. Als dat jou natuurlijke stijl is dan kan jij je lastig voorstellen dat er meer niveaus nodig zouden zijn. En je hebt gelijk het kan ook zo. Maar andere mensen hebben een stijl waarbij WEL snel die 8 levels gehaald wordt. Die moeten op zo'n architectuur zich aanpassen. Soms even wennen.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Arco

Special Member

Het was niet echt complex als hij nog voor de helft leeg was

De grootte van de code zegt niets over de complexiteit. Sommige code vult een hele processor zonder veel nuttigs te doen... :)
Nesten is geen 'stijl', maar een quick and dirty methode om iets te bereiken in zo kort mogelijke tijd. (ongeacht of dat goede code oplevert of niet)

Met Picbasic blijft het sowieso griezelig, omdat de functies niet re-entrant zijn...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
EricP

mét CE

De grootte van de code zegt niets over de complexiteit. Sommige code vult een hele processor zonder veel nuttigs te doen... :)

In zoverre kan ik nog met je mee. Kijk naar windows: het vult een hele HDD zonder veel nuttigs te doen... :)

Nesten is geen 'stijl', maar een quick and dirty methode om iets te bereiken in zo kort mogelijke tijd. (ongeacht of dat goede code oplevert of niet)

Dat ben ik dus absoluut niet met je eens. Er is niks 'dirty' aan om kleinere functions te maken. Makkelijker per stuk te testen en som sook best makkelijke om te recyclen. Een core die daar niet mee overweg kan, heeft een brakke architectuur...

Met Picbasic blijft het sowieso griezelig, omdat de functies niet re-entrant zijn...

Alleen om die reden? :) Wat op zich weer geen reden is, want re-entrancy is zelden noodzakelijk. In je libraries, ben je er zelf bij. In interrupt handlers... Tsja... Je zou wat kunnen aanroepen. Het zou kunnen als je het erg graag wilt het quick and dirty doet...