CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

What registers should I save and restore...? (Interrupt)

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
E_Blue



Joined: 13 Apr 2011
Posts: 410

View user's profile Send private message

What registers should I save and restore...? (Interrupt)
PostPosted: Sat Mar 06, 2021 8:22 pm     Reply with quote

What registers should I save and restore in a global interrupt handler?

The last time I used ASM code was about 2008 and as far I remember I always save WREG, STATUS, BSR and FSR0H:L and must be saved and restored in a right order.

Should I consider another register?
I don't know if CCS uses another registers Maybe FSR1H:L?

I just need to handle UART1 TX and RX on a PIC18F67J50 at high speed.
_________________
Electric Blue
temtronic



Joined: 01 Jul 2010
Posts: 9100
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Mar 06, 2021 8:41 pm     Reply with quote

Why not just let the compiler handle it ?
While the compiler defaults to saving a lot of registers, you can have it save just the 'minimum'.
I have to ask what you consider 'high speed' as I have used a variation of their ex_sisr.c for years in the 18f46k22 without any problems.
Jay
E_Blue



Joined: 13 Apr 2011
Posts: 410

View user's profile Send private message

PostPosted: Sat Mar 06, 2021 9:04 pm     Reply with quote

Is a bootloader firmware that must handle a GPRS modem to perform a FOTA update and since the bootloader only have a #int_global ISR.

I'm thinking in to use some routines(cloned in boot area) from the real program to handle the modem and those routines was created to run with interrupts.
I can make a inline code but is a lot to rework.

Something like this.(Is not finished)
Code:

//Same variable declaration on boot and main program
#define BootMode 'B'
unsigned int8 isrMode;
#locate isrMode=0x0F3F

#int_global
void isr()
{
   if(isrMode!=BootMode)
   {
      jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
   }
   else
   {
       //Save context
       #asm //From ex_glint.c
       //store current state of processor
       MOVWF save_w
       SWAPF status,W
       BCF   status,5
       BCF   status,6
       MOVWF save_status
       // Save anything else your code may change
       // You need to do something with PCLATH if you have GOTOs
       #endasm
      
      if(interrupt_active(INT_RDA)
      {
         SendGSM_TxBuffer();
      }
      else if(interrupt_active(INT_TBE)
      {
         SendGSM_TxBuffer();
      }
      //Restore context
      #asm //From ex_glint.c
      // restore processor and return from interrupt
       SWAPF save_status,W
       MOVWF status
       SWAPF save_w,F
       SWAPF save_w,W
       #endasm
         
   }
}

_________________
Electric Blue
Ttelmah



Joined: 11 Mar 2010
Posts: 19217

View user's profile Send private message

PostPosted: Sun Mar 07, 2021 12:50 am     Reply with quote

The answer is, it depends what you use.

You need to look through the assembler for the code your interrupt
routine actually uses, and save every register used inside the routine
(and the W, status etc.).
However simpler, to just copy what the compiler does, and save every
register. That way nothing can be missed.

Remember you can 'use interrupts', without 'using interrupts', in the
bootloader, by simply not enabling the global interrupt, and instead polling
the interrupt flags in your routine. This then gets rid of the need to do
handling like you are trying to do.
Also remember that what you are showing, would mean that nothing at
all in the interrupt code in the loaded program can ever change. If you
change even one byte in an interrupt routines, the addresses will shift,
and result 'disaster', since these are hardwired into your bootloader
as shown. A way 'round' this is to use a jump table stored at a fixed location
in the 'main', that contains the addresses of the routines you want to use,
then the address in this table can be used instead of the direct jump.
temtronic



Joined: 01 Jul 2010
Posts: 9100
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Mar 07, 2021 6:10 am     Reply with quote

re:
Quote:
since the bootloader only have a #int_global ISR

If you only want interrupt from UART during the bootloader program code, then only enable it, you don't have to enable other interrupts from say timers ,SPI, I2C, etc.
'Global' allows whatever interrupts you want, it doesn't enable ALL of them.

While I don't use a bootloader, lots here do probably variations of the CCS supplied example. haven't seen too many posts about 'it doesn't work'.
Ttelmah



Joined: 11 Mar 2010
Posts: 19217

View user's profile Send private message

PostPosted: Sun Mar 07, 2021 7:23 am     Reply with quote

You are fractionally missing what he is trying to do.

He has the #int_global, to redirect the interrupts to the loaded program.
Standard code.
He is then adding a test inside this to see if he is in 'bootloader' mode
and if he is, instead use two interrupts (RDA, and TBE), with these then
actually calling routines that are inside his main code!....
As I've already outlined, there are huge potential problems with this.
Sad
E_Blue



Joined: 13 Apr 2011
Posts: 410

View user's profile Send private message

PostPosted: Sun Mar 07, 2021 10:12 am     Reply with quote

No, I'm not calling routines that are inside my main code, I have cloned them in the boot area; but yes, I'm adding a test inside this to see if is in 'bootloader' mode or not, so the isr jumps to bootloader isr or to main isr in normal mode.
_________________
Electric Blue
Ttelmah



Joined: 11 Mar 2010
Posts: 19217

View user's profile Send private message

PostPosted: Sun Mar 07, 2021 10:47 am     Reply with quote

OK. That makes things enormously easier!... Very Happy

If the serial routines are using indexed accesses to buffers, then a lot
or registers will be involved. Expect to have to save perhaps 8 other
registers than W and status.
E_Blue



Joined: 13 Apr 2011
Posts: 410

View user's profile Send private message

PostPosted: Sun Mar 07, 2021 11:54 am     Reply with quote

Now I'm thinking in to do a superloop, as you suggested, so now I'm checking if is there some routines that takes too much time, like write in to the EEPROM.
_________________
Electric Blue
Ttelmah



Joined: 11 Mar 2010
Posts: 19217

View user's profile Send private message

PostPosted: Mon Mar 08, 2021 1:56 am     Reply with quote

If you look at the standard bootloader, this is 'why' it has to have handshaking.
It stops transmission, while the write takes place.
Understand, that using or not using the interrupt, makes no difference
to this. During a program memory write, the whole CPU halts. Complete
'non operation' during this. Whatever protocol you use to actually send the
data to be written, this has to be 'built in' to how it works....
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group