Wyatt Hepler | f9fb90f | 2020-09-30 18:59:33 -0700 | [diff] [blame] | 1 | .. _module-pw_cpu_exception: |
Armando Montanez | 5104cd6 | 2019-12-10 14:36:43 -0800 | [diff] [blame] | 2 | |
| 3 | ---------------- |
| 4 | pw_cpu_exception |
| 5 | ---------------- |
| 6 | Pigweed's exception module provides a consistent interface for entering an |
| 7 | application's CPU exception handler. While the actual exception handling |
| 8 | behavior is left to an application to implement, this module deals with any |
| 9 | architecture-specific actions required before calling the application exception |
| 10 | handler. More specifically, the exception module collects CPU state that may |
| 11 | otherwise be clobbered by an application's exception handler. |
| 12 | |
| 13 | Setup |
| 14 | ===== |
Armando Montanez | a9ca999 | 2021-01-26 17:06:10 -0800 | [diff] [blame] | 15 | An application using this module **must** connect ``pw_cpu_exception_Entry()`` to |
| 16 | the platform's CPU exception handler interrupt so ``pw_cpu_exception_Entry()`` is |
Armando Montanez | 5104cd6 | 2019-12-10 14:36:43 -0800 | [diff] [blame] | 17 | called immediately upon a CPU exception. For specifics on how this may be done, |
| 18 | see the backend documentation for your architecture. |
| 19 | |
| 20 | Applications must also provide an implementation for |
Armando Montanez | a9ca999 | 2021-01-26 17:06:10 -0800 | [diff] [blame] | 21 | ``pw_cpu_exception_DefaultHandler()``. The behavior of this functions is entirely |
Armando Montanez | 356bf97 | 2020-06-04 10:35:55 -0700 | [diff] [blame] | 22 | up to the application/project, but some examples are provided below: |
Armando Montanez | 5104cd6 | 2019-12-10 14:36:43 -0800 | [diff] [blame] | 23 | |
| 24 | * Enter an infinite loop so the device can be debugged by JTAG. |
| 25 | * Reset the device. |
| 26 | * Attempt to handle the exception so execution can continue. |
| 27 | * Capture and record additional device state and save to flash for a crash |
| 28 | report. |
| 29 | * A combination of the above, using logic that fits the needs of your project. |
| 30 | |
| 31 | Module Usage |
| 32 | ============ |
| 33 | Basic usage of this module entails applications supplying a definition for |
Armando Montanez | a9ca999 | 2021-01-26 17:06:10 -0800 | [diff] [blame] | 34 | ``pw_cpu_exception_DefaultHandler()``. ``pw_cpu_exception_DefaultHandler()`` should |
Armando Montanez | 356bf97 | 2020-06-04 10:35:55 -0700 | [diff] [blame] | 35 | contain any logic to determine if a exception can be recovered from, as well as |
| 36 | necessary actions to properly recover. If the device cannot recover from the |
Armando Montanez | 5104cd6 | 2019-12-10 14:36:43 -0800 | [diff] [blame] | 37 | exception, the function should **not** return. |
| 38 | |
Armando Montanez | a9ca999 | 2021-01-26 17:06:10 -0800 | [diff] [blame] | 39 | ``pw_cpu_exception_DefaultHandler()`` is called indirectly, and may be overridden |
| 40 | at runtime via ``pw_cpu_exception_SetHandler()``. The handler can also be reset to |
| 41 | point to ``pw_cpu_exception_DefaultHandler()`` by calling |
| 42 | ``pw_cpu_exception_RestoreDefaultHandler()``. |
Armando Montanez | 356bf97 | 2020-06-04 10:35:55 -0700 | [diff] [blame] | 43 | |
Armando Montanez | 5104cd6 | 2019-12-10 14:36:43 -0800 | [diff] [blame] | 44 | When writing an exception handler, prefer to use the functions provided by this |
Armando Montanez | 356bf97 | 2020-06-04 10:35:55 -0700 | [diff] [blame] | 45 | interface rather than relying on the backend implementation of |
Armando Montanez | a9ca999 | 2021-01-26 17:06:10 -0800 | [diff] [blame] | 46 | ``pw_cpu_exception_State``. This allows better code portability as it helps |
Armando Montanez | 356bf97 | 2020-06-04 10:35:55 -0700 | [diff] [blame] | 47 | prevent an application fault handler from being tied to a single backend. |
Armando Montanez | 5104cd6 | 2019-12-10 14:36:43 -0800 | [diff] [blame] | 48 | |
| 49 | For example; when logging or dumping CPU state, prefer ``ToString()`` or |
Armando Montanez | 356bf97 | 2020-06-04 10:35:55 -0700 | [diff] [blame] | 50 | ``RawFaultingCpuState()`` over directly accessing members of a |
Armando Montanez | a9ca999 | 2021-01-26 17:06:10 -0800 | [diff] [blame] | 51 | ``pw_cpu_exception_State`` object. |
Armando Montanez | 5104cd6 | 2019-12-10 14:36:43 -0800 | [diff] [blame] | 52 | |
| 53 | Some exception handling behavior may require architecture-specific CPU state to |
| 54 | attempt to correct a fault. In this situation, the application's exception |
| 55 | handler will be tied to the backend implementation of the CPU exception module. |
| 56 | |
Armando Montanez | 5104cd6 | 2019-12-10 14:36:43 -0800 | [diff] [blame] | 57 | Backend Expectations |
| 58 | ==================== |
| 59 | CPU exception backends do not provide an exception handler, but instead provide |
| 60 | mechanisms to capture CPU state for use by an application's exception handler, |
| 61 | and allow recovery from CPU exceptions when possible. |
| 62 | |
Armando Montanez | a9ca999 | 2021-01-26 17:06:10 -0800 | [diff] [blame] | 63 | * A backend should provide a definition for the ``pw_cpu_exception_State`` |
Armando Montanez | 356bf97 | 2020-06-04 10:35:55 -0700 | [diff] [blame] | 64 | struct that provides suitable means to access and modify any captured CPU |
| 65 | state. |
Armando Montanez | 5104cd6 | 2019-12-10 14:36:43 -0800 | [diff] [blame] | 66 | * If an application's exception handler modifies the captured CPU state, the |
| 67 | state should be treated as though it were the original state of the CPU when |
| 68 | the exception occurred. The backend may need to manually restore some of the |
| 69 | modified state to ensure this on exception handler return. |
Armando Montanez | a9ca999 | 2021-01-26 17:06:10 -0800 | [diff] [blame] | 70 | * A backend should implement the ``pw_cpu_exception_Entry()`` function that will |
| 71 | call ``pw_cpu_exception_HandleException()`` after performing any necessary |
Armando Montanez | 356bf97 | 2020-06-04 10:35:55 -0700 | [diff] [blame] | 72 | actions prior to handing control to the application's exception handler |
| 73 | (e.g. capturing necessary CPU state). |
| 74 | |
| 75 | Compatibility |
| 76 | ============= |
| 77 | Most of the pw_cpu_exception module is C-compatible. The exception to this is |
| 78 | the "support" facade and library, which requires C++. |
| 79 | |
| 80 | Dependencies |
| 81 | ============ |
| 82 | * ``pw_span`` |
| 83 | * ``pw_preprocessor`` |