You copied the Doc URL to your clipboard.

Why does my Cortex-M processor Lock Up with a Hard Fault a few cycles after reset?

Article ID: 103488011

Published date: 13 Feb 2018

Last updated: -

Applies to: Cortex-M


Why does my Cortex-M processor Lock Up with a Hard Fault a few cycles after reset?


My Cortex-M processor halts all activity and asserts its LOCKUP signal on-chip and sets bit S_LOCKUP in the Debug Halting Control and Status Register.


Various ARM architectures support interworking, which is the ability to switch between the ARM and Thumb instruction sets using certain kinds of branch instructions. This allows code routines implemented in alternate instruction sets to inter-operate, by informing the processor of the change of instruction set at the branch.

The mechanism for switching uses the fact that all instructions must be (at least) halfword-aligned, which means that bit[0] of the branch target address is redundant. Therefore this bit can be re-used to indicate the target instruction set at that address. Bit[0] cleared to 0 means the ARM instruction set and bit[0] set to 1 means the Thumb instruction set.

For example, consider the instruction:

BX lr

If the value in lr is 0x02000000 then the processor will branch to the instruction at 0x02000000 and interpret it as an ARM 32-bit instruction.

If the value in lr is 0x02000001 then the processor will branch to address 0x02000000 but interpret the instruction found there as a Thumb opcode.

The ARM Compiler (armcc) ensures that all branch target label addresses have bit[0] set correctly to represent the type of opcode found at that address. However, if the programmer creates an address manually, they must take care to ensure that bit[0] is correctly set to represent the opcode type of that branch target.

ARMv6-M, ARMv7-M and ARMv8-M processors (Cortex-M processors) support only the Thumb instruction set. Therefore all branch targets should be indicated as odd numbers, having bit[0] set for interworking, indicating that the target contains a Thumb opcode.

The vector table in Cortex-M processors (unlike other ARM processors) is a list of addresses (vectors). These vectors are defined as interworking-capable, therefore all populated vectors in the vector table must similarly have bit[0] set.

For ARMv7-M processors, if the Reset vector is an even number, the processor will immediately call a UsageFault of type INVSTATE due to the attempt to invoke the ARM instruction set for the Reset handler. Because the UsageFault is not enabled at Reset, the fault will escalate to HardFault. The HardFault vector itself will cause another UsageFault due to its bit[0] being clear. The occurrence of a fault inside the HardFault handler will result in the processor discontinuing execution, and asserting its LOCKUP output signal. For ARMv6-M processors, all faults are taken as HardFault, but the behavior is similar. ARMv8-M processors implement one or other of these behaviors, depending upon whether they are Baseline or Mainline implementations of ARMv8-M.

Vector table entries which are code entry point labels will be taken care of by the compilation toolset. For vector table entries which are written as literal constants in the code, the programmer must ensure that bit[0] is set to 1.





Related Information


Was this page helpful? Yes No