EmbeddedRelated.com
Forums
Memfault Beyond the Launch

interrupt Service Routines cannot be coded in Thumb mode

Started by klemen_dovrtel February 1, 2007
I compiled a winarm lpc2129_blinkswitch_irq example with no error.
Then i copied the ISP routine to lpc2138_uart0_irq example and tried
to copile it, but now i get an error: "interrupt Service Routines
cannot be coded in Thumb mode". What could be wrong?

ISP routine:
void __attribute__ ((interrupt("IRQ"))) tc0_cmp(void);
void tc0_cmp(void)
{
// do something
}

The makefile thumb options are the same for both:
THUMB = -mthumb
THUMB_IW = -mthumb-interwork

An Engineer's Guide to the LPC2100 Series

--- In l..., "klemen_dovrtel"
wrote:
>
> I compiled a winarm lpc2129_blinkswitch_irq example with no error.
> Then i copied the ISP routine to lpc2138_uart0_irq example and tried
> to copile it, but now i get an error: "interrupt Service Routines
> cannot be coded in Thumb mode". What could be wrong?

It's telling you what's wrong! I would have thought "interrupt
Service Routines cannot be coded in Thumb mode" was pretty
unambiguous!

To explain: when an interrupt is accepted by the processor it
automatically changes mode to ARM. See any good text on the ARM
architecture for details.

If you simply must have your interryupt function in Thumb you can
code a small stub routine in assembler or 'C' and call the Thumb
function from that. However, as ISRs are generally short, it's
usually simpler and more convenient to code them in ARM.
--- In l..., "klemen_dovrtel"
wrote:
>
> I compiled a winarm lpc2129_blinkswitch_irq example with no error.
> Then i copied the ISP routine to lpc2138_uart0_irq example and tried
> to copile it, but now i get an error: "interrupt Service Routines
> cannot be coded in Thumb mode". What could be wrong?
>
> ISP routine:
> void __attribute__ ((interrupt("IRQ"))) tc0_cmp(void);
> void tc0_cmp(void)
> {
> // do something
> }
>
> The makefile thumb options are the same for both:
> THUMB = -mthumb
> THUMB_IW = -mthumb-interwork
>
This has a lot to do with the way the ARM architecture works. If an
exception, e.g. an interrupt occurs, the core autmatically switches to
ARM mode. For one reason to have a defined mode when entering the
interrupt, for another reason because in a good architected device
such as the LPC2000 device, the ARM mode is about 30% faster than
Thumb mode. Interrupt are supposed to be fast, so ARM mode has been
selected by the ARM architects as default.

There are however some other devices on the market that would really
benefit if the interrupt could be executed in Thumb mode because they
are bus bandwidth limited, that is for all devices running faster than
30 MHz and having a buswidth of 32-bit or less. This is true for most
ARM7 devices, exceptions, LPC2000 and MAC7100. All SAM7, OKI or STR7
devices have to go through a bottleneck when switching into ARM mode
during an interrupt. When it matters the most, the bus handicap comes
in the worst.

Hope this help to understand it, Bob
> It's telling you what's wrong! I would have thought "interrupt
> Service Routines cannot be coded in Thumb mode" was pretty
> unambiguous!
>
> To explain: when an interrupt is accepted by the processor it
> automatically changes mode to ARM. See any good text on the ARM
> architecture for details.
>
> If you simply must have your interryupt function in Thumb you can
> code a small stub routine in assembler or 'C' and call the Thumb
> function from that. However, as ISRs are generally short, it's
> usually simpler and more convenient to code them in ARM.

Thank you, i did't know that.

But i still don't understand this, both examples
(lpc2129_blinkswitch_irq and lpc2138_uart0_irq) were compiled in thumb
mode (i have THUMB = -mthumb and THUMB_IW = -mthumb-interwork
instruction in makefile - btw. aren't this the settings for thumb
mode?), but compiler complained only once.

How should i set the compiler (makefile) then, if i want the main
program to be compiled in thumb mode and the ISR in arm mode?
--- In l..., "klemen_dovrtel"
wrote:
> > It's telling you what's wrong! I would have thought "interrupt
> > Service Routines cannot be coded in Thumb mode" was pretty
> > unambiguous!
> >
> > To explain: when an interrupt is accepted by the processor it
> > automatically changes mode to ARM. See any good text on the ARM
> > architecture for details.
> >
> > If you simply must have your interryupt function in Thumb you can
> > code a small stub routine in assembler or 'C' and call the Thumb
> > function from that. However, as ISRs are generally short, it's
> > usually simpler and more convenient to code them in ARM.
>
> Thank you, i did't know that.
>
> But i still don't understand this, both examples
> (lpc2129_blinkswitch_irq and lpc2138_uart0_irq) were compiled in thumb
> mode (i have THUMB = -mthumb and THUMB_IW = -mthumb-interwork
> instruction in makefile - btw. aren't this the settings for thumb
> mode?), but compiler complained only once.
>
> How should i set the compiler (makefile) then, if i want the main
> program to be compiled in thumb mode and the ISR in arm mode?
>

I will answer to myself :)

There is a "SRCARM = Timer.c VIClowlevel.c" command in makefile, which
enables you to compile a part of source in arm mode.

Regards
Klemen

Memfault Beyond the Launch