EmbeddedRelated.com
Forums

THUMB compile option in WinARM

Started by Srdan Suka July 25, 2006
Hi!

I am trying to compile my code in WinARM with -THUMB option enabled.
I am using LPC2103 and want to make my code smaller.

But problem is in ISR's and asm calls.

static inline unsigned __get_cpsr(void)
{
unsigned long retval;
asm volatile (" mrs %0, cpsr" : "=r" (retval) : );
return retval;
}

I get an error:

Error: selected processor does not support `mrs r0,cpsr'

The same thing is with ISR_ENTRY() and ISR_EXIT() in UART interrupt.

Is there any solution for this issue?

Thanks,

Srdan Suka

An Engineer's Guide to the LPC2100 Series

--- In l..., "Srdan Suka" wrote:
>
> Hi!
>
> I am trying to compile my code in WinARM with -THUMB option enabled.
> I am using LPC2103 and want to make my code smaller.
>
> But problem is in ISR's and asm calls.
>
> static inline unsigned __get_cpsr(void)
> {
> unsigned long retval;
> asm volatile (" mrs %0, cpsr" : "=r" (retval) : );
> return retval;
> }
>
> I get an error:
>
> Error: selected processor does not support `mrs r0,cpsr'
>
> The same thing is with ISR_ENTRY() and ISR_EXIT() in UART interrupt.
>
> Is there any solution for this issue?
>
> Thanks,
>
> Srdan Suka
>

The specific problem in your example is that the "mrs" instruction is
not available in Thumb mode.

The simplest way round this, and one that will reduce the possibility
of ongoing problems, is to code anything that required access to
assembler in a separate ARM assembler file.

For example:

GetCpsr:
mrs r0, cpsr /* get CPSR
bx lr /* return to caller */

This can be called from either ARM or Thumb code.

Again, if you code a generic interrupt entry and exit handler in
assembler, you can code the actual handler in standard 'C' (i.e. no
special MACROs or in-line assembler), and compile it either as ARM or
Thumb code. There are examples of this in the Files section.

You should find you need about 50 lines or less of assembler code in
total (exception vectors, interrupt dispatch and a couple of support
functions).

Brendan.

Thanks for your suggestion. It works.
But I still have no idea how to use
ISR under Thumb.

ie.

void __attribute__((interrupt("IRQ"))) wdi(void)
{

WDMOD = 0x03; // 8 bits, WDINT and WDRESET
VICVectAddr = (unsigned long)reset;
}

Can I code them also in .S ?

Thanks.

Srdan Suka

--- In l..., "Srdan Suka" wrote:
>
> Thanks for your suggestion. It works.
> But I still have no idea how to use
> ISR under Thumb.
>
> ie.
>
> void __attribute__((interrupt("IRQ"))) wdi(void)
> {
>
> WDMOD = 0x03; // 8 bits, WDINT and WDRESET
> VICVectAddr = (unsigned long)reset;
> }
>
> Can I code them also in .S ?
>
> Thanks.
>
> Srdan Suka

I should have been more specific: see the file gcc_and_ucosii.zip in
the Files section, in particular the PDF document in there that
describes several ways of handling exceptions/interrupts.

My own preference, which is what I was suggesting, is to avoid the
use of non-standard keywords such as "attribute interrupt" etc. This
can be done by having a small amount of assembler code to save
context and call the correct interrupt handler. The main body of each
interrupt handler can then be coded as standard 'C' (i.e. no special
keywords), and compiled as either ARM or Thumb code. Just remember
that when the processor automatically switches to ARM mode when an
exception happens, so your assembler will have to taks this into
account.

An alternative is to have your interrupt handler in its own source
file and compile it in ARM mode, not forgetting to compile everything
with "Thumb interworking" if they make calls into library functions
compiled as Thumb. If your interrupt handlers are short (and if
they're not, you might want to ask why!), there's little to be saved
from compiling them in Thumb mode.

Brendan
Thanks for your help.
Everything works fine and executable code is smaller 25%.

Have a nice day.

Srdan Suka