[ resend to sdcc-users -- botched address first time. ] hi -- i started this conversation privately with frieder the other day, and he correctly pointed out that it would be better taken to the openec or sdcc lists. so here i am. frieder has already addressed some of my issues, but i'll include my original mail here, for background, and down below, his initial response.
i'm working on EC firmware for the XO laptop (from OLPC). specifically, i'm in the middle of porting the code from the Keil compiler to sdcc. it seems that at least some of the instability that i've been seeing is that the interrupt routines (and/or some of the routines they call) weren't reentrant, when i thought they would be. annoyingly, some of the non-reentrant code was debugging code that i had added to make the problems more visible. for instance, i found that code that i added to blink an LED every 1024 times the routine was called was using __modsint, which has a register overflow argument. when i eliminated that call (by changing "(count % 1024)" to "(count & 0x3ff)"), things got much better. (frieder has since pointed out that if my counter had been unsigned, this wouldn't have been an issue.) i'm now in the position of ensuring that all of the remaining code that might be called during an interrupt is safe. since all of my ISR routines are in a single file, and there aren't that many to audit, it's not that bad. but i'm not completely sure what i'm looking for: if my routines don't call subroutines, and there are no references to internal support routines (e.g., the math code) that have foo_PARM references, am i safe? or are there other code generation issues that i might be subject to if i don't use --stack-auto and #pragma reentrant? (most of the interrupt service routines simply set a flag and return, but a few are more complicated than that. but they're still just logic and variables, no function calls.) any comments/advice appreciated... paul ------------------------------- and frieder's response (posted with his permission), with minor edits: > Date: Tue, 29 Jul 2008 20:27:04 +0200 > To: [EMAIL PROTECTED],.... > From: Frieder Ferlemann <[EMAIL PROTECTED]> > Subject: Re: 8051 reentrancy > In-Reply-To: <[EMAIL PROTECTED]> > > [EMAIL PROTECTED] schrieb: ..... > > > i'm now in the position of ensuring that all of the remaining > > code that might be called during an interrupt is safe. since all > > of my ISR routines are in a single file, and there aren't that many > > to audit, it's not that bad. > > thats a good situation: you can f.e. grep over the assembler source like: > "grep call xo_sample_interrupt.asm" > > I'm appending the C file. (you'll find that &0x3ff and %1024 are equivalent > there and irq_routine10 and irq_routine11 giving the most compact code) > > > but i'm not completely sure what i'm looking for: if my routines > > don't call subroutines, and there are no references to internal support > > You can look for lcall with the grep above. Or have a look into the > register pushing in the preamble for the IRQ. > In the example given you see the complete register bank being pushed > for irq_routine13. This makes irq_routine13 suspicious. > > > routines (e.g., the math code) that have foo_PARM references, am > > i safe? or are there other code generation issues that i might > > be subject to if i don't use --stack-auto and #pragma reentrant? > > If you'd call routines that need local storage (for local variables > but also for SLOC) you are in trouble. Also if you call functions > that need arguments that are not passed via a,b,dpl,dph. > > If you need to call a function foo() which is not reentrant it might > make sense to declare a function foo_IRQ() which is an exact copy > of foo() but only called within IRQ. (or disable IRQ within that function) > > Note if you do not use Interrupt priorities (I hope you don't have to) > then you only need one foo_IRQ() even if it's used within different > IRQ routines. > > > (most of the interrupt service routines simply set a flag and return, > > but a few are more complicated than that. but they're still just > > logic and variables, no function calls.) > > You should be safe then. I may be overlooking something though. > Some extra problems might be global >=16 bit variables (or global 8 bit > variables in xdata) which used by both IRQ and non-IRQ routines... > (also see http://sdcc.sourceforge.net/doc/sdccman.html/node66.html > (not a permanent link)) > .... > > Greetings, > Frieder > > > > static volatile unsigned int irq_count; > static volatile int irq_tmp; > > > void irq_routine10(void) __interrupt (10) > { > irq_count++; > irq_count %= 1024; > } > > void irq_routine11(void) __interrupt (11) > { > irq_count++; > irq_count &= 0x3ff; > } > > void irq_routine12(void) __interrupt (12) > { > irq_count = irq_count + 1; > irq_count = (irq_count % 1024); > } > > void irq_routine13(void) __interrupt (13) > { > irq_tmp++; > irq_tmp %= 1024; // <-- > } > > > void main(void) > { > } =--------------------- paul fox, [EMAIL PROTECTED] ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ Sdcc-user mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/sdcc-user
