Since I started with questions, I'm going to declare my conclusions, as
concise I possibly can:
The GCC OPTIMIZER disregards details about ARM mode switching.
That's it.
So, as long as you don't let the optimizer touch the code that does the
mode switching, you're good. There are of course many ways to do that. One
quite straight-forward way to do it, is this:
1. Make a special C file for wrapping-functions for the actual IRQ and FIQ
handlers.
2. Declare the wrapper functions __attribute__((interrupt("IRQ"))). Or "FIQ".
3. Make those wrapper functions void with no arguments (of course).
4. The wrapper function implementations should do just one thing - call the
actual IRQ or FIQ handler.
5. Make sure the wrapper function module is compiled WITHOUT optimization.
Note that this does NOT take care of another related problem - NESTING, that is,
allow IRQ interrupts while another IRQ is being serviced. GCC simply has no
support for that, not even dysfunctional.
It shows non-nested and nested interrupt code using assembler
stubs.
Cheers,
Dave
Reply by Miguel Angel●October 15, 20092009-10-15
Link registers (LR) aren't independent from mode-to-mode in ARM7 ?
FIQ shouldn't be overwriting your IRQ's LR....
Are the stacks big /separated enough? (I guessing that It could be an
overlapping stacks problem...)
Miguel Angel Ajo Pelayo http://www.nbee.es
+34 91 120 1798
+34 636 52 25 69
skype: ajoajoajo
2009/10/15 ttl_idiot
> > Could you please post the objdump with the
preambles and post of your
> > IRQ/FIQ functions?
> >
> > arm-xxxx-objdump --disassemble yourfile.o
> > I am quite new to the architechture. Correct me if I am wrong,
> but it seems that the only preample of the FIQ is the following. The dump
> is from the elf file.
>
> 00000000 :
> 0: e24ee004 sub lr, lr, #4 ; 0x4
> 4: e92d403f push {r0, r1, r2, r3, r4, r5, lr}
>
> and that the returns look like this:
>
> 390: e8fd803f ldm sp!, {r0, r1, r2, r3, r4, r5, pc}^
>
> which appears in several other places also in the FIQ handler, two of them
> are conditional, "ldmhi" and "ldmeq".
>
> And as I said, it is seems to be the link register that suddenly has the
> wrong value in the IRQ.
>
> I can see from the program, that the problem occours after IRQ-preambling,
> and before it leaves IRQ. So, it has to do with the FIQ.
>
> I saw the other answers. Sorry to bring up an old issue. I will study the
> pointed posts. Thank you! Anyway I would like to understand why the above
> code doesn't work. And just a confirmation that it is the same problem
with
> FIQ over IRQ as with IRQ over user mode. Thanks!
>
>
>
Reply by ttl_idiot●October 15, 20092009-10-15
> Could you please post the objdump with the preambles
and post of your
> IRQ/FIQ functions?
>
> arm-xxxx-objdump --disassemble yourfile.o
>
I am quite new to the architechture. Correct me if I am wrong,
but it seems that the only preample of the FIQ is the following. The dump is
from the elf file.
which appears in several other places also in the FIQ handler, two of them are
conditional, "ldmhi" and "ldmeq".
And as I said, it is seems to be the link register that suddenly has the wrong
value in the IRQ.
I can see from the program, that the problem occours after IRQ-preambling, and
before it leaves IRQ. So, it has to do with the FIQ.
I saw the other answers. Sorry to bring up an old issue. I will study the
pointed posts. Thank you! Anyway I would like to understand why the above code
doesn't work. And just a confirmation that it is the same problem with FIQ
over IRQ as with IRQ over user mode. Thanks!
Reply by Miguel Angel●October 15, 20092009-10-15
If you don't want to rely on GCC to write your preamble/postamble, you
can
use naked, and then asm(...) to write it yourself.
Remember that for FIQ you have your own set of registers that you
shouldn't
need to save (unless you're nesting)
static void MyIntHandler(void) __attribute__ ((naked));
static void MyIntHandler(void) /* naked */
{
asm("SUB LR,LR,#4"); /* setup the return address */
asm("PUSH {R0-R12,LR}"); /* store all registers into stack */
asm("LDMFD SP!, {r0-r12,PC}^"); /*restore status and registers, return */
}
Miguel Angel Ajo Pelayo http://www.espardino.com
+34 91 120 1798
+34 636 52 25 69
skype: ajoajoajo
2009/10/15 rtstofer
> --- In l... ,
"ttl_idiot"
> wrote:
> >
> > I have some strange problem with screwed-up r14 (link register). It
> happens in IRQ mode, and seems to be related to an FIQ that interrupts the
> IRQ. I am currently using GCC 4.3.2, and using optimization. It's a bad
time
> for upgrading GCC at this point, if it doesn't solve this specific
problem.
> >
> > 1. Is the __attribute__ ((interrupt ("IRQ")) problem still unsolved in
> latest version of GCC?
> >
> > 2. Does the problem discussed as __attribute__ ((interrupt ("IRQ")) also
> apply similarily to __attribute__ ((interrupt ("FIQ")), i.e. when FIQs are
> interrupting IRQs?
> >
> > I'd really appreciate input on this. Thanks!
> > This has been discussed in depth and the 'consensus' is that using
the
> __attribute__ approach is not the best way to do the job. Maybe a better
> characterization: it almost never works and it almost certainly won't
nest.
> I'm pretty sure that's how it came out.
>
> It is far better to write your handlers as normal functions and use a
> little wrapper to enter and exit.
>
> See http://tech.groups.yahoo.com/group/lpc2000/message/32431 for one
> example.
>
> I think there has been at least one other approach shown here but I
didn't
> find it. Unfortunately, my Linux box is toast so I can't get at the
files.
>
> Search the archives for interrupt wrapper or something like that. Maybe
> search for __attribute__
>
> Richard
>
>
>
Reply by rtstofer●October 15, 20092009-10-15
--- In l..., "ttl_idiot" wrote: >
> I have some strange problem with screwed-up r14 (link register). It happens in
IRQ mode, and seems to be related to an FIQ that interrupts the IRQ. I am
currently using GCC 4.3.2, and using optimization. It's a bad time for
upgrading GCC at this point, if it doesn't solve this specific problem.
>
> 1. Is the __attribute__ ((interrupt ("IRQ")) problem still unsolved in latest
version of GCC?
>
> 2. Does the problem discussed as __attribute__ ((interrupt ("IRQ")) also apply
similarily to __attribute__ ((interrupt ("FIQ")), i.e. when FIQs are
interrupting IRQs?
>
> I'd really appreciate input on this. Thanks!
> This has been discussed in depth and the 'consensus' is that
using the __attribute__ approach is not the best way to do the job. Maybe a
better characterization: it almost never works and it almost certainly
won't nest. I'm pretty sure that's how it came out.
It is far better to write your handlers as normal functions and use a little
wrapper to enter and exit.
I think there has been at least one other approach shown here but I didn't
find it. Unfortunately, my Linux box is toast so I can't get at the
files.
Search the archives for interrupt wrapper or something like that. Maybe search
for __attribute__
Richard
Reply by Miguel Angel●October 15, 20092009-10-15
Hi ttl_idiot,
I had problems with WinARM, but we finally come up with our 4.4.0 GCC
based
toolchains, and we got no problems with the IRQ preambles (FIQ untested)
Could you please post the objdump with the preambles and post of your
IRQ/FIQ functions?
arm-xxxx-objdump --disassemble yourfile.o
Miguel Angel Ajo Pelayo http://www.nbee.es
+34 91 120 1798
+34 636 52 25 69
skype: ajoajoajo
2009/10/15 ttl_idiot
> I have some strange problem with screwed-up r14 (link
register). It happens
> in IRQ mode, and seems to be related to an FIQ that interrupts the IRQ. I
am
> currently using GCC 4.3.2, and using optimization. It's a bad time for
> upgrading GCC at this point, if it doesn't solve this specific
problem.
>
> 1. Is the __attribute__ ((interrupt ("IRQ")) problem still unsolved in
> latest version of GCC?
>
> 2. Does the problem discussed as __attribute__ ((interrupt ("IRQ")) also
> apply similarily to __attribute__ ((interrupt ("FIQ")), i.e. when FIQs are
> interrupting IRQs?
>
> I'd really appreciate input on this. Thanks!
>
>
>
Reply by ttl_idiot●October 15, 20092009-10-15
I have some strange problem with screwed-up r14 (link register). It happens in
IRQ mode, and seems to be related to an FIQ that interrupts the IRQ. I am
currently using GCC 4.3.2, and using optimization. It's a bad time for
upgrading GCC at this point, if it doesn't solve this specific problem.
1. Is the __attribute__ ((interrupt ("IRQ")) problem still unsolved in latest
version of GCC?
2. Does the problem discussed as __attribute__ ((interrupt ("IRQ")) also apply
similarily to __attribute__ ((interrupt ("FIQ")), i.e. when FIQs are
interrupting IRQs?