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