GCC ARM Cortex-M3/M4: SVC instruction puts CPU from Thumb to ARM state because of wrong value in Vector table

883 views Asked by At

I'm porting real-time kernel TNeoKernel to the Cortex-Mx processors, it works when compiled with ARMCC, but doesn't work when compiled with GCC: just after calling SVC instruction, PC is updated to the SVC_Handler, and at the next (any) instruction, UsageFault exception happens.

Examining of CFSR shows that INVSTATE bit is set: i.e. the processor is in ARM state, which is illegal on Cortex-M CPUs. I've checked xPSR: yes, T bit is cleared.

Then I've examined Vector table: yes, at the offset 0x2c I have the address of my SVC_Handler, but LSB is cleared: 0x8013c40. So, there's no surprise that CPU is put to the ARM state. The surprise is why do I have LSB cleared?

I re-checked address of SVC_Handler when compiled with ARMCC, and yes, LSB is set there: actual address of SVC_Handler is 0x0800297a, but Vector table contains 0x0800297b.

So, GCC generates wrong Vector table.

Currently I use CooCox IDE and arm-none-eabi-gcc version 4.8.4; options that are given to GCC are:

-mthumb -mcpu=cortex-m4

It seems pretty enough to make GCC know that the CPU does not support ARM state, so, is it a bug in GCC? Or, should I give some more keys to it, to make it generate correct Vector table?

UPD: here is the source file tn_arch_cortex_m.S on bitbucket. I have .thumb directive there; please note that this file is intended to work with GCC as well as ARMCC, so there are some macros to cope for both tools.

0

There are 0 answers