PIC16F1829paging

Ik werk in assembler.
Bij het oplossen van het probleem van paging en interrupts bleek ik het register PCLATH_SHAD nodig te hebben. Dit register zit in BANK31 en zou BANKSELECT nodig moeten hebben, gelet op de overlap van het adres (0x67) met de general purpose registers in andere banken. Merkwaardig genoeg lijkt het erop dat geen BANKSELECT nodig is. Wat ik ook doe met de overlappende registers in de andere banken en evenzo met PCLATH_SHAD: er treedt geen wederzijdse beinvloeding op.

Het is in dit speciale geval wel handig dat geen BANKSELECT nodig is maar het is natuurlijk wel zo prettig te weten dat dit ook zo hoort.
Weet iemand hoe het zit? Op het internet en bij Microchip kan ik niets vinden.
Overigens heb ik ook nergens een goede en duidelijke oplossing kunnen vinden voor het probleem van paging en interrupts, waarvoor ik zelf iets heb weten te bedenken dat simpel is en uitgebreid testen heeft doorstaan. A.u.b. geen adviezen over het toepassen van paging.

Sommige processors hebben een aparte "interrupt context". Een aantal (of alle) registers zijn dubbel uitgevoerd en zodra er een interrupt is, dan schakelt ie naar de andere registerset. Je hoeft dan niet alle registers op de stack te gooien en met de grote registersets van moderne cpus, wordt dat een tijdrovende zaak.

Dan zou het dus kunnen dat ie "default" in je interrupt op bank3 staat en je in de main gewoon op een andere bank.

Maar goed, hoe het bij een PIC precies werkt dat weet ik niet.

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

Dank voor de snelle reactie. Je commentaar klopt wel maar gaat niet precies in op mijn vraag. Het gaat er juist om hoe het precies zit met dit register.

Arco

Special Member

Banking wordt zelden meer gebruikt bij de enhanced 16F (16F1xxx), gewoon omdat het in assembly lastig werkt.
Je kunt het hele GPR ram gebied gewoon lineair aanspreken via de FSRxH:FSRxL registers.
Met de xxxx_SHAD registers hoef je helemaal niks te doen; context save/restore bij interrupt gaat automatisch...

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

@ARCO
Ja, wie werkt er nog in Assembler? Ik dus. Is het lastig het werken met paging? Het gaat, je moet weten hoe het in elkaar steekt. Het lijkt op banking. Het echte probleem ontstaat met interrupts want helaas heeft de ontwerper van de PICs bij de aanroep van een interrupt geen pageswitch ingebouwd, zodat de ISR de verkeerde kant op gestuurd kan worden. Die pageswitch moet dus softwarematig worden gerealiseerd (voor de goto ISR die meestal in page0 loopt, terwijl het programma misschien wel in een andere page zit) en daarbij komt het register PCLATH_SHAD om de hoek kijken. Want de automatische contextsaving haalt PCLATH_SHAD aan het eind weer op maar hoe wordt dit register gevuld bij de aanroep? Dat mag je zelf doen.

Arco

Special Member

Zoals gezegd: je kunt het geheugen lineair (als 1 blok) aanspreken, dus dan valt er niks meer te bankswitchen... ;)
(FSRx werkt simpel, zeker met de nieuwe MOVWI en MOVIW instructies)
Ook mét bankswitching hoef je niets te doen: de BSR/FSRx/PCLHIGH registers worden automatisch hersteld...

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

@Arco
Ik kan via de FSR-route (linmem) een register aanspreken in de PIC16F1829. Maar dat was mijn issue niet. Als ik het via de gewone weg doe, moet ik dan voor het PCLATH_SHAD register BANKSELECT gebruiken of niet? Zo nee, waarom niet, terwijl dit register duidelijk in één bepaalde bank zit? Zo ja, waarom werkt het dan in de praktijk terwijl ik van alles uithaal met de BSR (en dus de juiste bank niet is ingesteld voor PCLATH_SHAD) en ook in de geschaduwde registers in andere banken geen effect bespeur van wijzigingen in PCLATH_SHAD.

[Bericht gewijzigd door BenZ op vrijdag 22 februari 2019 21:25:18 (10%)

Arco

Special Member

De shadow registers moet je altijd afblijven.
(of je moet met 'onfrisse' zaken bezig zijn, zoals na een interrupt terugkeren naar een ander adres als waar de interrupt begon)

Zoals gezegd, BSR eb PCH worden automatisch hersteld.
(er zit speciale hardware in daarvoor, dus opgeven waar BSR zich bevindt is niet nodig/nutteloos. Alle registers worden in 2 cycles gesaved/restored)

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

@ARCO
Van de shadowregisters afblijven? Misschien, maar wat is dan de oplossing om een ISR uit te voeren als er paging is? Bv. Het hoofdprogramma is beland in page2. Er treedt een IRQ op (bv door een timer). Dan gaat de vector naar adres 0x004 (Lowint) maar helaas gaat het programma niet naar het opgegeven ISR adres (de goto instructie), want PCLATH bevat page2 (01). Het programma springt naar een niet bestaande routine en voert de ISR niet uit. Wat de automatic context saving ook moge zijn, als de ISR niet wordt uitgevoerd telt die niet.
De vraag is dus hoe krijg ik de PC in de goede stand dat de ISR wordt uitgevoerd en daarna de PC teruggaat naar het hoofdprogramma (in het voorbeeld in page2).
Mijn oplossing: save W tijdelijk, zet PCLATH in PCLATH_SHAD (mbv W), zet PCLATH op de pagina van de ISR (meestal page0), haal W terug. Dan gaat het programma werkelijk naar de ISR en keert terug naar het adres met PCLATH_SHAD door de automatic context saving. Uitgebreid getest werkt dit. Resteert de vraag BANKING or not?

Arco

Special Member

De interruptvector zit altijd op 0x0004, dus dat is geen probleem.
Wat er in de interruptroutine gebeurt ben je zelf verantwoordelijk voor. Ik heb vaak interruptroutines in een andere page, gebruik dan pagesel (dat is daarvoor)
Als je al iets wilt veranderen moet dat in PCLATH zelf, niet in de shadow registers...

Overigens hebben pages en banks niks met elkaar te maken...

pic asm code:


#IfDef __16F648A
irq             movwf   w_save		;Context save 
		swapf	status,w	;
                movwf   status_save	; 
                clrf    status      	; 
                movf    pclath,w      	;
                movwf   pclath_save	;
                movf    fsr,w		; 
                movwf   fsr_save	; 
		clrf	pclath		;
;..............................................................
		banksel pir1
		btfss   pir1,tmr2if     ;See if Tmr2 interrupt
                goto    irq_return	;If not, end
                bcf     pir1,tmr2if     ; 
		pagesel get_tone	;get_tone is irq routine
		call	get_tone	;
		pagesel	$		;Reset page
;..............................................................
irq_restore     movf    fsr_save,w	;Context restore  
                movwf   fsr		;
                movf    pclath_save,w	;
                movwf   pclath      	;
                swapf   status_save,w	;
		movwf	status		;
                swapf   w_save,f	;
                swapf   w_save,w	;
                retfie			;
#EndIf



#IfDef __16LF1827
irq                          
		banksel pir1
		btfss   pir1,tmr2if     ;See if Tmr2 interrupt
                goto    irq_return	;If not, end
                bcf     pir1,tmr2if     ; 
		pagesel get_tone	;get_tone is irq routine
		call	get_tone	;
		pagesel	$		;Reset page
irq_return	retfie			;
#EndIf


[Bericht gewijzigd door Arco op zaterdag 23 februari 2019 13:36:33 (42%)

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

Arco, je hebt helemaal gelijk. Ik maakte een ernstige denkfout. Gewoon pageselect voor de goto lowint is voldoende. Het gedoe met overzetten van de PC is nergens voor nodig en werkt ook niet. Het doet gewoon niets en dus is ook de kwestie banking irrelevant (zou PCLAH_SHAD wel nuttig gebruikt worden dan is banking natuurlijk wel noodzakelijk).

Mijn aanpak:

pic asm code:


0x004
       pagesel lowint
       goto lowint

met in de lowint alle IRQ afhandeling t/m retfie en daarbinnen het gewone programmeerwerk.

Mijn excuses voor het opzetten van een zinloze discussie. Bedankt voor het meedenken.