blob: cf969961d98b1f260d72d0b69b82fa55db0c4858 [file] [log] [blame]
Armando Montanez5104cd62019-12-10 14:36:43 -08001.. _chapter-cpu-exception-armv7m:
2
3.. default-domain:: cpp
4
5.. highlight:: sh
6
7-----------------------
8pw_cpu_exception_armv7m
9-----------------------
10This backend provides an ARMv7-M implementation for the CPU exception module
11frontend. See the CPU exception frontend module description for more
12information.
13
14Setup
15=====
16There are a few ways to set up the ARMv7-M exception handler so the
17application's exception handler is properly called during an exception.
18
19**1. Use existing CMSIS functions**
20 Inside of CMSIS fault handler functions, branch to ``pw_CpuExceptionEntry``.
21
22 .. code-block:: cpp
23
24 __attribute__((naked)) void HardFault_Handler(void) {
25 asm volatile(
26 " ldr r0, =pw_CpuExceptionEntry \n"
27 " bx r0 \n");
28 }
29
30**2. Modify a startup file**
31 Assembly startup files for some microcontrollers initialize the interrupt
32 vector table. The functions to call for fault handlers can be changed here.
33 For ARMv7-M, the fault handlers are indexes 3 to 6 of the interrupt vector
34 table. It's also may be helpful to redirect the NMI handler to the entry
35 function (if it's otherwise unused in your project).
36
37 Default:
38
39 .. code-block:: cpp
40
41 __isr_vector_table:
42 .word __stack_start
43 .word Reset_Handler
44 .word NMI_Handler
45 .word HardFault_Handler
46 .word MemManage_Handler
47 .word BusFault_Handler
48 .word UsageFault_Handler
49
50 Using CPU exception module:
51
52 .. code-block:: cpp
53
54 __isr_vector_table:
55 .word __stack_start
56 .word Reset_Handler
57 .word pw_CpuExceptionEntry
58 .word pw_CpuExceptionEntry
59 .word pw_CpuExceptionEntry
60 .word pw_CpuExceptionEntry
61 .word pw_CpuExceptionEntry
62
63 Note: ``__isr_vector_table`` and ``__stack_start`` are example names, and may
64 vary by platform. See your platform's assembly startup script.
65
66**3. Modify interrupt vector table at runtime**
67 Some applications may choose to modify their interrupt vector tables at
68 runtime. The ARMv7-M exception handler works with this use case (see the
69 exception_entry_test integration test), but keep in mind that your
70 application's exception handler will not be entered if an exception occurs
71 before the vector table entries are updated to point to
72 ``pw_CpuExceptionEntry``.
73
74Module Usage
75============
76For lightweight exception handlers that don't need to access
77architecture-specific registers, using the generic exception handler functions
78is preferred.
79
80However, some projects may need to explicitly access architecture-specific
81registers to attempt to recover from a CPU exception. ``CpuState`` provides
82access to the captured CPU state at the time of the fault. When the
83application-provided ``HandleCpuException()`` function returns, the CPU state is
84restored. This allows the exception handler to modify the captured state so that
85execution can safely continue.
86
87Expected Behavior
88-----------------
89In most cases, the CPU state captured by the exception handler will contain the
90ARMv7-M basic register frame in addition to an extended set of registers (see
91``cpu_state.h``). The exception to this is when the program stack pointer is in
92an MPU-protected or otherwise invalid memory region when the CPU attempts to
93push the exception register frame to it. In this situation, the PC, LR, and PSR
94registers will NOT be captured and will be marked with 0xFFFFFFFF to indicate
95they are invalid. This backend will still be able to capture all the other
96registers though.
97
98In the situation where the main stack pointer is in a memory protected or
99otherwise invalid region and fails to push CPU context, behavior is undefined.
100
101Nested Exceptions
102-----------------
103To enable nested fault handling:
104 1. Enable separate detection of usage/bus/memory faults via the SHCSR.
105 2. Decrease the priority of the memory, bus, and usage fault handlers. This
106 gives headroom for escalation.
107
108While this allows some faults to nest, it doesn't guarantee all will properly
109nest.