EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

{To TomW} GCC-Bug in IRQs

Started by Sten March 25, 2006
Hi Sten,

I was experiencing the same GCC bug as you encountered. It came out only
with optimization enabled.

I've searched around I and discovered that there seems to be some
patches out there but all of them are not 100% confirmed as working
patches. I read about the patches on bugzilla. After that I decided that
is better for me not to apply unconfirmed patches and I simply tricked
GCC by calling the "ISR_Body()" function from my ISR.

Like you I was also surprised that this bug has not been still fixed.

Regards,
marko
Sten wrote:

>Tom Walsh wrote:
>
>
>>Sten wrote:
>>
>>
>>
>>
>>>Tom Walsh wrote:
>>>
>>>
>>>
>>>
>>>
>>>>Sten wrote:
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>>Hello Tom,
>>>>>
>>>>>some days ago I discovered a GCC bug on interrupt service routines for functions with
>>>>>__attribute__((interrupt("IRQ"))). At GCC-Bugzilla I found that this bug has still been reported in
>>>>>2005 under bug report #16634 in which you are involved in. Do you know why this bug is still
>>>>>"UNCONFIRMED"?!?
>>>>>
>>>>>The bug still persists in:
>>>>>arm-elf-gcc (GCC) 4.0.1
>>>>>arm-elf-gcc (GCC) 4.1.0
>>>>>
>>>>>Do you (or somebody else) have a gcc-patch to solve this problem? I took a look to the gcc sources
>>>>>by myself but the problem occurs in conjunction with optimization under conditions, where LR
>>>>>register is used for subroutine branches, and this could a little bit more tricky to solve it than
>>>>>just hacking the ARM section of GCC!
>>>>>
>>>>>Can somebody confirm this bug in the binary-tool-chain from www.gnuarm.com or on other GCC-based
>>>>>cross compiler versions? It seems gnuarm don't have any special patches against this problem, too.
>>>>>(See test-case below!)
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>I am not sure what your question is. Why do you feel you have to
>>>>intentionally suppress the apcs stack frame?
>>>>
>>>>
>>>>
>>>>
>>>>
>>>With -mapcs-frame the code produced looks good but due to the APCS a lot of overhead at entry and
>>>exit of my functions is generated. Without that option (or with -mno-apcs-frame) gcc generates wrong
>>>entry/exit code but the code footprint is more slim.
>>>In my opinion an arm-elf-gcc should produce correct code for ARM cores in any case.
>>>
>>>GCC manual says for ARM option -mapcs-frame:
>>>"Generate a stack frame that is compliant with the ARM Procedure Call Standard for all functions,
>>>even if this is not strictly necessary for correct execution of the code."
>>>
>>>My question was if you know something about the detailed status of bug report #16634? I'm wondering
>>>why it is still UNCONFIRMED since 2005.
>>>
>>>
>>>
>>>
>>>
>>No, I don't. AFAIK, the apcs frame is used for backtracing code. So
>>far, the Insight debugger has been fine for backtracing with the options
>>I specify for compiles:
>>
>>arm-elf-gcc -c -O0 -mthumb -mcpu=arm7tdmi -march=armv4t
>>-DTOPLEVEL=/home/tom/MuxPad3Devel/EvntCPU/../ -I. -gstabs -DROM_RUN
>>-I/home/tom/MuxPad3Devel/EvntCPU/../include
>>-I/home/tom/MuxPad3Devel/EvntCPU/../libs/include -Wall
>>-Wstrict-prototypes -Wcast-align -Wcast-qual -Wimplicit
>>-Wmissing-declarations -Wmissing-prototypes -Wnested-externs
>>-Wpointer-arith -Wswitch -Wredundant-decls -Wreturn-type -Wshadow
>>-Wstrict-prototypes -Wunused -Wa,-adhlns=main2138.lst -std=gnu99
>>-nostdlib -nodefaultlibs
>>-L/home/tom/devtools/armThumb-4.0.2/arm-elf/lib/thumb/interwork/
>>-L/home/tom/devtools/armThumb-4.0.2/lib/gcc/arm-elf/4.0.2/interwork/ -MD
>>-MP -MF .dep/main2138.o.d -DLPC2138
>>-I/home/tom/MuxPad3Devel/EvntCPU//include -DLPC2138 main2138.c -o
>>main2138.o
>>
>>I am not optimizing as yet for two reasons:
>>
>>1. I have adequate codespace, yet.
>>2. It is a nightmare to debug optimized code!
>>
>>
>>
>
>Ok, that's the reason! I explored that it happens only in conjunction with optimization options. It
>seems that gcc is mixing up optimized code with non-optimized.
>
>Sometimes gcc results in very neat optimized code like this:
>irq:
> sub lr, lr, #4
> stmdb sp!, {r1,r2,lr}
> ...
> ldmia sp!, {r1,r2,pc} @ loading pc with lr-4 directly from stack
>
>or in the default code recommended in ARM manual:
>
>irq:
> stmdb sp!, {r1,r2,lr}
> ...
> ldmia sp!, {r1,r2,lr}
> subs pc, lr, #4
>
>The erronous output when optimizing looks like a mixture of both:
>
>irq:
> sub lr, lr, #4
> stmdb sp!, {r1,r2,lr}
> ...
> ldmia sp!, {r1,r2,lr}
> subs sp, lr, #4
>
>Has nobody else recognized this?!?
>
>Regards.
> Sten
>
>
>

An Engineer's Guide to the LPC2100 Series

Marko Panger wrote:
> Hi Sten,
>
> I was experiencing the same GCC bug as you encountered. It came out only
> with optimization enabled.
>
> I've searched around I and discovered that there seems to be some
> patches out there but all of them are not 100% confirmed as working
> patches. I read about the patches on bugzilla. After that I decided that
> is better for me not to apply unconfirmed patches and I simply tricked
> GCC by calling the "ISR_Body()" function from my ISR.
>
> Like you I was also surprised that this bug has not been still fixed.
>
> Regards,
> marko
> Sten wrote:
>>Tom Walsh wrote:
>>
>>>Sten wrote:
>>>
>>>
>>>
>>>
>>>
>>>>Tom Walsh wrote:
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>>Sten wrote:
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>Hello Tom,
>>>>>>
>>>>>>some days ago I discovered a GCC bug on interrupt service routines for functions with
>>>>>>__attribute__((interrupt("IRQ"))). At GCC-Bugzilla I found that this bug has still been reported in
>>>>>>2005 under bug report #16634 in which you are involved in. Do you know why this bug is still
>>>>>>"UNCONFIRMED"?!?
>>>>>>
>>>>>>The bug still persists in:
>>>>>>arm-elf-gcc (GCC) 4.0.1
>>>>>>arm-elf-gcc (GCC) 4.1.0
>>>>>>
>>>>>>Do you (or somebody else) have a gcc-patch to solve this problem? I took a look to the gcc sources
>>>>>>by myself but the problem occurs in conjunction with optimization under conditions, where LR
>>>>>>register is used for subroutine branches, and this could a little bit more tricky to solve it than
>>>>>>just hacking the ARM section of GCC!
>>>>>>
>>>>>>Can somebody confirm this bug in the binary-tool-chain from www.gnuarm.com or on other GCC-based
>>>>>>cross compiler versions? It seems gnuarm don't have any special patches against this problem, too.
>>>>>>(See test-case below!)
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>I am not sure what your question is. Why do you feel you have to
>>>>>intentionally suppress the apcs stack frame?
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>With -mapcs-frame the code produced looks good but due to the APCS a lot of overhead at entry and
>>>>exit of my functions is generated. Without that option (or with -mno-apcs-frame) gcc generates wrong
>>>>entry/exit code but the code footprint is more slim.
>>>>In my opinion an arm-elf-gcc should produce correct code for ARM cores in any case.
>>>>
>>>>GCC manual says for ARM option -mapcs-frame:
>>>>"Generate a stack frame that is compliant with the ARM Procedure Call Standard for all functions,
>>>>even if this is not strictly necessary for correct execution of the code."
>>>>
>>>>My question was if you know something about the detailed status of bug report #16634? I'm wondering
>>>>why it is still UNCONFIRMED since 2005.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>No, I don't. AFAIK, the apcs frame is used for backtracing code. So
>>>far, the Insight debugger has been fine for backtracing with the options
>>>I specify for compiles:
>>>
>>>arm-elf-gcc -c -O0 -mthumb -mcpu=arm7tdmi -march=armv4t
>>>-DTOPLEVEL=/home/tom/MuxPad3Devel/EvntCPU/../ -I. -gstabs -DROM_RUN
>>>-I/home/tom/MuxPad3Devel/EvntCPU/../include
>>>-I/home/tom/MuxPad3Devel/EvntCPU/../libs/include -Wall
>>>-Wstrict-prototypes -Wcast-align -Wcast-qual -Wimplicit
>>>-Wmissing-declarations -Wmissing-prototypes -Wnested-externs
>>>-Wpointer-arith -Wswitch -Wredundant-decls -Wreturn-type -Wshadow
>>>-Wstrict-prototypes -Wunused -Wa,-adhlns=main2138.lst -std=gnu99
>>>-nostdlib -nodefaultlibs
>>>-L/home/tom/devtools/armThumb-4.0.2/arm-elf/lib/thumb/interwork/
>>>-L/home/tom/devtools/armThumb-4.0.2/lib/gcc/arm-elf/4.0.2/interwork/ -MD
>>>-MP -MF .dep/main2138.o.d -DLPC2138
>>>-I/home/tom/MuxPad3Devel/EvntCPU//include -DLPC2138 main2138.c -o
>>>main2138.o
>>>
>>>I am not optimizing as yet for two reasons:
>>>
>>>1. I have adequate codespace, yet.
>>>2. It is a nightmare to debug optimized code!
>>>
>>>
>>>Ok, that's the reason! I explored that it happens only in conjunction with optimization options. It
>>seems that gcc is mixing up optimized code with non-optimized.
>>
>>Sometimes gcc results in very neat optimized code like this:
>>irq:
>> sub lr, lr, #4
>> stmdb sp!, {r1,r2,lr}
>> ...
>> ldmia sp!, {r1,r2,pc} @ loading pc with lr-4 directly from stack
>>
>>or in the default code recommended in ARM manual:
>>
>>irq:
>> stmdb sp!, {r1,r2,lr}
>> ...
>> ldmia sp!, {r1,r2,lr}
>> subs pc, lr, #4
>>
>>The erronous output when optimizing looks like a mixture of both:
>>
>>irq:
>> sub lr, lr, #4
>> stmdb sp!, {r1,r2,lr}
>> ...
>> ldmia sp!, {r1,r2,lr}
>> subs sp, lr, #4
>>
>>Has nobody else recognized this?!?
>>
>>Regards.
>> Sten
>>

Hello Marko,

do you still know where you to find these patches? I would take a look into, because I started to
search the gcc sources for the root of this problem. Maybe there is a simple patch which do not
touch sensible code in gcc. To fix something in the ARM section of GCC would be more easy, but the
fact that this occurs along with optimization makes it very tricky!

Sten

--
/************************************************
Do you need a tiny and efficient real time
operating system (RTOS) with a preemtive
multitasking for LPC2000 or AT91SAM7?

http://nanortos.net-attack.de/

Or some open-source tools and code for LPC2000?

http://www.net-attack.de/

************************************************/

Yahoo! Groups Links
Robert Adsett wrote:
> At 07:49 PM 3/25/2006 +0100, Sten wrote:
>
>>I've tried this. But entry/exit is still not correct.
>>Here's the result:
>>
>>void uart_irqHandler0(void) __attribute__((interrupt));
>>
>>00000204 <uart_irqHandler0>:
>> 204: e24ee004 sub lr, lr, #4 ; 0x4
>> 208: e92d500f stmdb sp!, {r0, r1, r2, r3, ip, lr}
>> 20c: e3a0120e mov r1, #-536870912 ; 0xe0000000
>> 210: e2811903 add r1, r1, #49152 ; 0xc000
>> 214: e3a00000 mov r0, #0 ; 0x0
>> 218: ebfffffe bl d0 <uart_irqHandler_common>
>> 21c: e8bd500f ldmia sp!, {r0, r1, r2, r3, ip, lr}
>> 220: e25ef004 subs pc, lr, #4 ; 0x4
>>
>>Question:
>>Which gcc version do you use? Which command line parameters do use?
>>How do you differentiate between IRQ and FIQ (only r0..r7 need to be
>>saved) if use
>>__attribute__((interrupt)) only?
>
>
>
> Rather than go through all this hand-wringing why not just write an
> assembly stub? You'd know it was correct and you'd be done already. At
> most it would cost you an extra call from the stub to your C
> function. Heck if it was small enough it might make sense to do the whole
> thing in asm. For that matter you could steal one of my stubs.
>
> Robert
>

Thanks Robert.
At the moment I declare my IRQ functions as "naked" and write my own prologue/epilogue with inline
assembler. But it is less efficient because I don't know which registers are really used, so I have
to save all non-banked registers (r0..12 for IRQ and r0..r7 for FIQ) which is a wast of performance.

Sten

--
/************************************************
Do you need a tiny and efficient real time
operating system (RTOS) with a preemtive
multitasking for LPC2000 or AT91SAM7?

http://nanortos.net-attack.de/

Or some open-source tools and code for LPC2000?

http://www.net-attack.de/

************************************************/

> I'm thinking of writing a generic IRQ handler instead of a
> direct branch to VIC-vector register from vector table,

You mean something like this ....

irq_isr:
/* Save IRQ context, including the APCS registers, and r4-6 */
sub lr, lr, #4
stmfd sp!, {r0-r6, ip, lr}

/* Save the SPSR_irq register */
mrs r4, spsr

/* Read the VICVectAddr */
ldr r5, VICVECTADDR
ldr r6, [r5]

/* Change to SYS mode and enable IRQ */
msr cpsr_c, #SYS_MODE

/* Debug:
* Comment out the change to system mode with IRQs enabled
* and uncomment the following to leave IRQs disabled. IRQs
* are then handled non-nested (with more overhead than normal)
*/
/* msr cpsr_c, #SYS_MODE|IRQ_DISABLE*/

/* Save the banked SYS mode link register */
stmfd sp!, {lr}

/* Call the C-coded handler */
mov lr, pc
mov pc, r6

/* Restore SYS mode link register */
ldmfd sp!, {lr}

/* Change to IRQ mode and disable IRQ */
msr cpsr_c, #IRQ_MODE|IRQ_DISABLE

/* Restore the SPSR */
msr spsr, r4

/* Acknowledge the VIC */
mov r0, #0
str r0, [r5]

/* Restore IRQ context and return from interrupt */
ldmfd sp!, {r0-r6, ip, pc}^

VICVECTADDR: .word 0xFFFFF030

Yahoo! Groups Links
At 09:33 PM 3/25/2006 +0100, Sten wrote:
>Robert Adsett wrote:
> > At 08:17 PM 3/25/2006 +0100, Sten wrote:
> >
> >>Robert Adsett wrote:
> >>
> >>>Rather than go through all this hand-wringing why not just write an
> >>>assembly stub? You'd know it was correct and you'd be done already. At
> >>>most it would cost you an extra call from the stub to your C
> >>>function. Heck if it was small enough it might make sense to do the whole
> >>>thing in asm. For that matter you could steal one of my stubs.
> >>
> >>At the moment I declare my IRQ functions as "naked" and write my own
> >>prologue/epilogue with inline
> >>assembler. But it is less efficient because I don't know which registers
> >>are really used, so I have
> >>to save all non-banked registers (r0..12 for IRQ and r0..r7 for FIQ) which
> >>is a wast of performance.
> >
> >
> >
> > If you write a stub that problem disappears. The procedure call standard
> > ensures that the proper registers are saved when you call out of the stub.
> > You only have to save something like 6 registers for IRQ, the called
> > routine preserves any of the others it uses..
> >
> > Also are you sure you actually really care about the extra saves? Beware
> > of premature optimization. Didn't Knuth call it the root of all evil?
> > :) If your response time is sufficient and your are not overloading the
> > CPU forget about the wasted cycles, you are spending time doing something
> > that simply does not matter.
> >
> > I do a stub not for efficiency but because experience has taught me to
> > never trust any compiler to produce correct interrupt code. Correct does
> > sometimes mean efficient but it can also mean the more obvious things.
> >
> > Robert
>
>Ok, what exactly did you mean by a "stub"? You write a piece of assembler
>code for a particular IRQ
>and then branch to your (normal) C service function, don't you?

As a matter of fact, yes. That would be a stub.

>I'm thinking of writing a generic IRQ handler instead of a direct branch
>to VIC-vector register from
>vector table, I'm using at the moment. This IRQ handler (in clean
>assembler) could have correct
>entry and exit code and is branching to the service function from
>VIC-vector. The overhead would be
>very less.

That would also be a stub. I don't see any reason off hand not to do it
that way although I also don't see that it will change the overhead at all.

branch to irq source specific stub
save registers
call service function

versus

branch to stub
save registers
call irq source specific function

Since you cannot take advantage of the 'wrap-around indexing' into the VIC
table it might even be a little more overhead in the second case. I doubt
it matters in most cases and I can see some real clarity advantages to
doing it that way. Hmmmm....

Robert

" 'Freedom' has no meaning of itself. There are always restrictions, be
they legal, genetic, or physical. If you don't believe me, try to chew a
radio signal. " -- Kelvin Throop, III
http://www.aeolusdevelopment.com/

Yahoo! Groups Links
At 08:17 PM 3/25/2006 +0100, Sten wrote:
>Robert Adsett wrote:
> > Rather than go through all this hand-wringing why not just write an
> > assembly stub? You'd know it was correct and you'd be done already. At
> > most it would cost you an extra call from the stub to your C
> > function. Heck if it was small enough it might make sense to do the whole
> > thing in asm. For that matter you could steal one of my stubs.
>At the moment I declare my IRQ functions as "naked" and write my own
>prologue/epilogue with inline
>assembler. But it is less efficient because I don't know which registers
>are really used, so I have
>to save all non-banked registers (r0..12 for IRQ and r0..r7 for FIQ) which
>is a wast of performance.
If you write a stub that problem disappears. The procedure call standard
ensures that the proper registers are saved when you call out of the stub.
You only have to save something like 6 registers for IRQ, the called
routine preserves any of the others it uses..

Also are you sure you actually really care about the extra saves? Beware
of premature optimization. Didn't Knuth call it the root of all evil?
:) If your response time is sufficient and your are not overloading the
CPU forget about the wasted cycles, you are spending time doing something
that simply does not matter.

I do a stub not for efficiency but because experience has taught me to
never trust any compiler to produce correct interrupt code. Correct does
sometimes mean efficient but it can also mean the more obvious things.

Robert

" 'Freedom' has no meaning of itself. There are always restrictions, be
they legal, genetic, or physical. If you don't believe me, try to chew a
radio signal. " -- Kelvin Throop, III
http://www.aeolusdevelopment.com/
Robert Adsett wrote:
> At 09:33 PM 3/25/2006 +0100, Sten wrote:
>
>>Robert Adsett wrote:
>>
>>>At 08:17 PM 3/25/2006 +0100, Sten wrote:
>>>
>>>
>>>>Robert Adsett wrote:
>>>>
>>>>
>>>>>Rather than go through all this hand-wringing why not just write an
>>>>>assembly stub? You'd know it was correct and you'd be done already. At
>>>>>most it would cost you an extra call from the stub to your C
>>>>>function. Heck if it was small enough it might make sense to do the whole
>>>>>thing in asm. For that matter you could steal one of my stubs.
>>>>
>>>>At the moment I declare my IRQ functions as "naked" and write my own
>>>>prologue/epilogue with inline
>>>>assembler. But it is less efficient because I don't know which registers
>>>>are really used, so I have
>>>>to save all non-banked registers (r0..12 for IRQ and r0..r7 for FIQ) which
>>>>is a wast of performance.
>>>
>>>
>>>
>>>If you write a stub that problem disappears. The procedure call standard
>>>ensures that the proper registers are saved when you call out of the stub.
>>>You only have to save something like 6 registers for IRQ, the called
>>>routine preserves any of the others it uses..
>>>
>>>Also are you sure you actually really care about the extra saves? Beware
>>>of premature optimization. Didn't Knuth call it the root of all evil?
>>>:) If your response time is sufficient and your are not overloading the
>>>CPU forget about the wasted cycles, you are spending time doing something
>>>that simply does not matter.
>>>
>>>I do a stub not for efficiency but because experience has taught me to
>>>never trust any compiler to produce correct interrupt code. Correct does
>>>sometimes mean efficient but it can also mean the more obvious things.
>>>
>>>Robert
>>
>>Ok, what exactly did you mean by a "stub"? You write a piece of assembler
>>code for a particular IRQ
>>and then branch to your (normal) C service function, don't you?
> As a matter of fact, yes. That would be a stub.
>>I'm thinking of writing a generic IRQ handler instead of a direct branch
>>to VIC-vector register from
>>vector table, I'm using at the moment. This IRQ handler (in clean
>>assembler) could have correct
>>entry and exit code and is branching to the service function from
>>VIC-vector. The overhead would be
>>very less.
> That would also be a stub. I don't see any reason off hand not to do it
> that way although I also don't see that it will change the overhead at all.
>
> branch to irq source specific stub
> save registers
> call service function
>
> versus
>
> branch to stub
> save registers
> call irq source specific function
>
> Since you cannot take advantage of the 'wrap-around indexing' into the VIC
> table it might even be a little more overhead in the second case. I doubt
> it matters in most cases and I can see some real clarity advantages to
> doing it that way. Hmmmm....
>
> Robert
>

You're right, the overhead is exceptable. And it needs less clocks than my current work-around. I
think, I will write a stub tomorrow! ;-)

Sten

--
/************************************************
Do you need a tiny and efficient real time
operating system (RTOS) with a preemtive
multitasking for LPC2000 or AT91SAM7?

http://nanortos.net-attack.de/

Or some open-source tools and code for LPC2000?

http://www.net-attack.de/

************************************************/

Yahoo! Groups Links
David Hawkins wrote:
>>I'm thinking of writing a generic IRQ handler instead of a
>>direct branch to VIC-vector register from vector table,
> You mean something like this ....
>
> irq_isr:
> /* Save IRQ context, including the APCS registers, and r4-6 */
> sub lr, lr, #4
> stmfd sp!, {r0-r6, ip, lr}
>
> /* Save the SPSR_irq register */
> mrs r4, spsr
>
> /* Read the VICVectAddr */
> ldr r5, VICVECTADDR
> ldr r6, [r5]
>
> /* Change to SYS mode and enable IRQ */
> msr cpsr_c, #SYS_MODE
>
> /* Debug:
> * Comment out the change to system mode with IRQs enabled
> * and uncomment the following to leave IRQs disabled. IRQs
> * are then handled non-nested (with more overhead than normal)
> */
> /* msr cpsr_c, #SYS_MODE|IRQ_DISABLE*/
>
> /* Save the banked SYS mode link register */
> stmfd sp!, {lr}
>
> /* Call the C-coded handler */
> mov lr, pc
> mov pc, r6
>
> /* Restore SYS mode link register */
> ldmfd sp!, {lr}
>
> /* Change to IRQ mode and disable IRQ */
> msr cpsr_c, #IRQ_MODE|IRQ_DISABLE
>
> /* Restore the SPSR */
> msr spsr, r4
>
> /* Acknowledge the VIC */
> mov r0, #0
> str r0, [r5]
>
> /* Restore IRQ context and return from interrupt */
> ldmfd sp!, {r0-r6, ip, pc}^
>
> VICVECTADDR: .word 0xFFFFF030
>

YES, something like that! ;-) But without nesting and change of cpu-mode.

Sten

--
/************************************************
Do you need a tiny and efficient real time
operating system (RTOS) with a preemtive
multitasking for LPC2000 or AT91SAM7?

http://nanortos.net-attack.de/

Or some open-source tools and code for LPC2000?

http://www.net-attack.de/

************************************************/

Yahoo! Groups Links
> YES, something like that! ;-) But without nesting and change of cpu-mode.

Then perhaps this :)

irq_isr:
sub lr, lr, #4
stmfd sp!, {r0-r3, ip, lr}
bl irq_handler
ldmfd sp!, {r0-r3, ip, pc}^
/* VICVectAddr dispatch loop */
void irq_handler(void)
{
/* Process IRQ interrupts */
irq_handler_t handler;
while (VICIRQStatus) {
/* Get the address of the highest priority handler */
handler = (irq_handler_t)VICVectAddr;

/* Execute the handler */
(*handler)();

/* Acknowledge the VIC */
VICVectAddr = 0;
}
}

Yahoo! Groups Links
Robert Adsett wrote:
> At 08:17 PM 3/25/2006 +0100, Sten wrote:
>
>>Robert Adsett wrote:
>>
>>>Rather than go through all this hand-wringing why not just write an
>>>assembly stub? You'd know it was correct and you'd be done already. At
>>>most it would cost you an extra call from the stub to your C
>>>function. Heck if it was small enough it might make sense to do the whole
>>>thing in asm. For that matter you could steal one of my stubs.
>>
>>At the moment I declare my IRQ functions as "naked" and write my own
>>prologue/epilogue with inline
>>assembler. But it is less efficient because I don't know which registers
>>are really used, so I have
>>to save all non-banked registers (r0..12 for IRQ and r0..r7 for FIQ) which
>>is a wast of performance.
>
>
>
> If you write a stub that problem disappears. The procedure call standard
> ensures that the proper registers are saved when you call out of the stub.
> You only have to save something like 6 registers for IRQ, the called
> routine preserves any of the others it uses..
>
> Also are you sure you actually really care about the extra saves? Beware
> of premature optimization. Didn't Knuth call it the root of all evil?
> :) If your response time is sufficient and your are not overloading the
> CPU forget about the wasted cycles, you are spending time doing something
> that simply does not matter.
>
> I do a stub not for efficiency but because experience has taught me to
> never trust any compiler to produce correct interrupt code. Correct does
> sometimes mean efficient but it can also mean the more obvious things.
>
> Robert

Ok, what exactly did you mean by a "stub"? You write a piece of assembler code for a particular IRQ
and then branch to your (normal) C service function, don't you?
I'm thinking of writing a generic IRQ handler instead of a direct branch to VIC-vector register from
vector table, I'm using at the moment. This IRQ handler (in clean assembler) could have correct
entry and exit code and is branching to the service function from VIC-vector. The overhead would be
very less. In this case I can also add some extra code to serve spurious interrupts in any way I
like. (STOP! I DONT WANT TO START A NEW ENDLESS THREAD HERE!)

Sten

--
/************************************************
Do you need a tiny and efficient real time
operating system (RTOS) with a preemtive
multitasking for LPC2000 or AT91SAM7?

http://nanortos.net-attack.de/

Or some open-source tools and code for LPC2000?

http://www.net-attack.de/

************************************************/


The 2024 Embedded Online Conference