PDA

View Full Version : Crashing program



Charles Linquis
- 3rd April 2006, 01:45
I have a PBP program running in an 18F8722.

I'm using a serial interrupt routine based on the example below given by MELABS:
;---------------------------------------------------------------------
IntHandler

; Save the state of critical registers
movwf wsave ; Save W
swapf STATUS, W ; Swap STATUS to W (swap avoids changing STATUS)
clrf STATUS ; Clear STATUS
movwf ssave ; Save swapped STATUS

movf Low FSR0, W ; Move FSR0 lowbyte to W
movwf fsave ; Save FSR0 lowbyte
movf High FSR0, W ; Move FSR0 highbyte to W
movwf fsave+1 ; Save FSR0 highbyte

;-------------------------------------------

(BASIC interrupt handler goes here)
;-----------------------------------------------
movf fsave, W ; retrieve FSR0 lowbyte value
movwf Low FSR0 ; Restore it to FSR0 lowbyte
movf fsave+1, W ; retrieve FSR0 highbyte value
movwf High FSR0 ; Restore it to FSR0 highbyte
swapf ssave, W ; Retrieve the swapped STATUS value (swap to avoid changing STATUS)
movwf STATUS ; Restore it to STATUS
swapf wsave, F ; Swap the stored W value
swapf wsave, W ; Restore it to W (swap to avoid changing STATUS)
retfie ; Return from the interrupt
EndAsm


00000000000000000000000000000000000000000000000000 00000000000000000000000000000

My problem is, my MAIN program (placed after the ASM routines) works fine as long as the program is small. As soon as it gets past a certain size (I'm assuming that forces it to do bank switching, my program appears to run, but toggles bits (output pins) all over the place.
Am I not saving all the pertinent registers?

Can anyone tell me what else I might be doing wrong?

Charles Linquist

sougata
- 4th April 2006, 06:17
Hi,

It is very unclear what you are doing with your ISR. While you are using the asm interrupt you cannot mix it up with basic code. That will overwrite your PBP system variables and you will get weird results. As for the 18F series if you are not using calls within your asm code. You can simply use retfie fast to restore your W,S and FSR without saving them. This is a single level shadow stack featured in the 18F series.

Charles Linquis
- 4th April 2006, 23:50
A couple of lines got left off. The basic flow is:
---------------------------------------------------------------------

DEFINE INTHAND IntSerial

(Setup main registers)

wsave VAR BYTE bankA system
ssave VAR BYTE bankA system
fsave VAR WORD bankA system

(Define other variables)


GOTO START

************** ISR STARTS HERE *************
asm
IntSerial

(Save W,STATUS,FSR0)

endasm

(BASIC PROGRAM to handle serial buffer, sets flag when carriage return received)


asm
(Restore W,STATUS,FSR0)
endasm

************ ISR ENDS HERE ***************

START:

(BASIC PROGRAM to handle buffer, do other things)

GOTO START

---------------------------------------------------------------

The program runs, but every once in awhile, I get odd port bits toggling.
Must I write my entire ISR in assembly, or can I keep it in BASIC as I am doing now?

Bruce
- 5th April 2006, 00:43
Hi Charles,

With assembler interrupts, you have two options.

1. Write your entire interrupt handler in assembler.

2. Save all PBP system variables on entry, and restore all PBP system
variables on exit, from your interrupt handler.

With assembler interrupts, you can interrupt any PBP command in mid-stroke.
What this means is you exit from "any" command whether it's completed
execution or not.

Then when you enter your interrupt handler, and use BASIC commands, you
are again using PBP system variables.

If you over-write a single system variable that was being used at the time
the interrupt occured, then once you return to the interrupted BASIC library
routine, there's a good chance you have corrupted whatever system variables
were being used by the interrupted BASIC library function.

Your program goes haywire, and the rest is history.

Darrel posted several excellent interrupt routines. Take a peek at this thread
http://www.picbasic.co.uk/forum/showthread.php?t=3251

The .lst file generated at compile time gives you a full list of all system vars
you'll need to save/restore during an assembler interrupt.

sougata
- 5th April 2006, 16:25
Hi,

What are you doing inside the basic routine ? If you are sure that you program is not taking much time for a single example then depending on the input baud rate / execution speed you can even handle the entire stuff in PBP. But if it needs to be fast then it is best to write in asm completely. Saving the PBP variables can be a little tricky if your code grows with future requirement. As you mentioned you are new to asm (so am I) give it a try and there are guys out here who can help. Keep the Faith

Charles Linquis
- 6th April 2006, 02:57
Unfortunately, Darrel himself states that the routines don't work with 18F parts - which is all I ever use.