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.