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 CCS Technical Support

Argh !! Interrupt scratchpad variables !!

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



Joined: 09 Sep 2003
Posts: 95
Location: UK

View user's profile Send private message Send e-mail Visit poster's website

Argh !! Interrupt scratchpad variables !!
PostPosted: Tue Mar 15, 2005 9:57 am     Reply with quote

I have seen this before, but I've never found a *real* solution to the problem.

I have a largish program using up 44% ROM and 63% RAM in a PIC18F8720, compiler 3v190.

In this code I use the RDA interrupt, which calls a function queue_in_irq() to queue any incoming serial characters.

I also have a function, display_show_bitmap() that displays a bitmap to an LCD. This can take a (relatively) long time, and it is quite possible for one (or more) RDA interrupts to occur while this display_show_bitmap() function is running.

My problem is that, as shown in my .SYM listing, the compiler has chosen to overlap it's queue_in_irq() SCRATCH variables with the variables and parameters used in display_show_bitmap().

I know I can define the local variables in display_show_bitmap() as STATIC to overcome this overlapping problem, but how do I prevent the compiler from overlapping the parameters ?

The code extract looks something like this ...

Code:
int1 queue_in_irq(queue_struct *q, char c) {
   // ... code removed ...
}

#int_rda
void rx_irq_com1(void) {
   int8 rx_char;
   int1 got_rx_data = false;
   
   // store rx data (and clear irq at the same time)
   rx_char = RCREG1;
   
   // ... parity checking removed ...
   
   // if valid char, add to rx queue
   if (got_rx_data) {
      queue_in_irq(&serial.com1.qrx, rx_char);
   }
}

void display_show_bitmap(int32 addr, int8 x, int8 y, int8 width, int8 height) {
   int16 gfx_addr = GRAPHICS_BASE;
   
   // ... code removed ...
}


The .SYM listing shows ...
Code:
959-95C display_show_bitmap.addr
95A     keyboard_scan_irq.scan_in_value
95B     keyboard_scan_irq.i
95C     keyboard_scan_irq.j
95D     display_show_bitmap.x
95D     keyboard_scan_irq.key_value
95E     display_show_bitmap.y
95E.0   keyboard_scan_irq.key_found
95F     beeper_start.timeout
95F-960 queue_in_irq.q
95F     display_show_bitmap.width
95F     keyboard_scan_irq.@SCRATCH
960     digio_set_status_bit.i
960     display_show_bitmap.height
960     keyboard_scan_irq.@SCRATCH
961     queue_in_irq.c
961     digio_write_status.data
961-962 display_show_bitmap.gfx_addr
961     keyboard_scan_irq.@SCRATCH
962     keyboard_scan_irq.@SCRATCH
962     queue_in_irq.@SCRATCH
963-964 lcd_set_ptr.addr
963     multiply8x8.x
963     display_show_bitmap.@SCRATCH
963     queue_in_irq.@SCRATCH
964     multiply8x8.y
964     display_show_bitmap.@SCRATCH
964     queue_in_irq.@SCRATCH


As you can see several of my "_irq" routines share ram locations with other functions.

How can I define the locations of the @SCRATCH variables such that they don't overlap ?
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Mar 15, 2005 11:09 am     Reply with quote

My guess is you are calling queue_in_irq() from both inside the interrupt and from within main()?
If yes, then this is what causes the memory overlap. Check the compiler manual in the chapter 'What are the restrictions on function calls from an interrupt function?'. According to this chapter the overlap shouldn't be a problem because the compiler adds instructions for disabling interrupts when entering the shared function. Disadvantage is that this causes additional interrupt latency.

A way around this is to create a diffent named copy of the shared function. Easier and more beautiful is using the #separate identifier, but I'm not sure this will work.
mpfj



Joined: 09 Sep 2003
Posts: 95
Location: UK

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue Mar 15, 2005 2:37 pm     Reply with quote

ckielstra wrote:
My guess is you are calling queue_in_irq() from both inside the interrupt and from within main()?


Argh, argh and more argh ... Evil or Very Mad

All this time I've been looking at an old copy of the .SYM file ... Embarassed

As you correctly pointed out, I *do* call the display_show_bitmap() from both inside and outside the ISR. This is now fixed.

Sorry for wasting everyone's time.
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