pw_cpu_exception#

Pigweed AI summary: Pigweed's exception module provides a consistent interface for entering an application's CPU exception handler. The module deals with any architecture-specific actions required before calling the application exception handler and collects CPU state that may otherwise be clobbered by an application's exception handler. The module has three facades, each of whose backends are set with a different GN variable. The entry facade is hard-tied to the definition of the pw_cpu_exception_State, so splitting them into separate facades would require extra configurations

Pigweed’s exception module provides a consistent interface for entering an application’s CPU exception handler. While the actual exception handling behavior is left to an application to implement, this module deals with any architecture-specific actions required before calling the application exception handler. More specifically, the exception module collects CPU state that may otherwise be clobbered by an application’s exception handler.

Setup#

Pigweed AI summary: This module has three facades, each with a different GN variable for their backends. The first facade, pw_cpu_exception_ENTRY_BACKEND, handles early exception entry and prepares CPU state for the exception handler. Applications using this module must connect pw_cpu_exception_Entry() to the platform's CPU exception handler interrupt. The second facade, pw_cpu_exception_HANDLER_BACKEND, is backed by an application-specific handler that determines what to do when an exception is encountered. Applications must also provide an implementation for pw_cpu_exception_Default

This module has three facades, each of whose backends are set with a different GN variable.

pw_cpu_exception_ENTRY_BACKEND#

Pigweed AI summary: The pw_cpu_exception_ENTRY_BACKEND library handles early exception entry and prepares CPU state for the exception handler. The backend is architecture-specific and an application using this module must connect pw_cpu_exception_Entry() to the platform's CPU exception handler interrupt. The backend documentation for the architecture should be consulted for specifics on how to do this.

This is the library that handles early exception entry and prepares any CPU state that must be available to the exception handler via the pw_cpu_exception_State object. The backend for this facade is architecture-specific.

An application using this module must connect pw_cpu_exception_Entry() to the platform’s CPU exception handler interrupt so pw_cpu_exception_Entry() is called immediately upon a CPU exception. For specifics on how this may be done, see the backend documentation for your architecture.

pw_cpu_exception_HANDLER_BACKEND#

Pigweed AI summary: The pw_cpu_exception_HANDLER_BACKEND is a facade that is supported by an application-specific handler that determines what to do when an exception is encountered. Applications must also provide an implementation for pw_cpu_exception_DefaultHandler(), which can enter an infinite loop, reset the device, attempt to handle the exception, capture and record additional device state, or use a combination of these options. The behavior of this function is entirely up to the application/project.

This facade is backed by an application-specific handler that determines what to do when an exception is encountered. This may be capturing a crash report before resetting the device, or in some cases handling the exception to allow execution to continue.

Applications must also provide an implementation for pw_cpu_exception_DefaultHandler(). The behavior of this functions is entirely up to the application/project, but some examples are provided below:

  • Enter an infinite loop so the device can be debugged by JTAG.

  • Reset the device.

  • Attempt to handle the exception so execution can continue.

  • Capture and record additional device state and save to flash for a crash report.

  • A combination of the above, using logic that fits the needs of your project.

pw_cpu_exception_SUPPORT_BACKEND#

Pigweed AI summary: The pw_cpu_exception_SUPPORT_BACKEND facade offers architecture-independent functions for dumping CPU state in various forms, enabling the creation of portable application-specific handlers across multiple architectures.

This facade provides architecture-independent functions that may be helpful for dumping CPU state in various forms. This allows an application to create an application-specific handler that is portable across multiple architectures.

Avoiding circular dependencies with pw_cpu_exception_ENTRY_BACKEND#

Pigweed AI summary: This article discusses how to avoid circular dependencies with pw_cpu_exception_ENTRY_BACKEND. The entry facade is closely tied to the definition of pw_cpu_exception_State, making it difficult to split them into separate facades without extra configurations and compatibility checks. In GN, this issue is resolved by collecting the backend's full implementation, including the entry method, through the pw_cpu_exception:entry_impl group. Entry backends must provide their own *.impl target to collect their entry implementation.

The entry facade is hard tied to the definition of the pw_cpu_exception_State, so spliting them into separate facades would require extra configurations along with extra compatibility checks to ensure they are never mismatched.

In GN, this circular dependency is avoided by collecting the backend’s full implementation including the entry method through the pw_cpu_exception:entry_impl group. When pw_cpu_exception_ENTRY_BACKEND is set, $dir_pw_cpu_exception:entry_impl must listed in the pw_build_LINK_DEPS variable. See Link-only deps.

Entry backends must provide their own *.impl target that collects their entry implementation.

Module Usage#

Pigweed AI summary: This section explains the basic usage of the module, which involves defining the pw_cpu_exception_DefaultHandler() function to handle exceptions. The function should contain logic to determine if an exception can be recovered from and necessary actions to recover. The function can be overridden at runtime using pw_cpu_exception_SetHandler() and reset to the default using pw_cpu_exception_RestoreDefaultHandler(). It is recommended to use the functions provided by the interface rather than relying on the backend implementation for better code portability. In some

Basic usage of this module entails applications supplying a definition for pw_cpu_exception_DefaultHandler(). pw_cpu_exception_DefaultHandler() should contain any logic to determine if a exception can be recovered from, as well as necessary actions to properly recover. If the device cannot recover from the exception, the function should not return.

pw_cpu_exception_DefaultHandler() is called indirectly, and may be overridden at runtime via pw_cpu_exception_SetHandler(). The handler can also be reset to point to pw_cpu_exception_DefaultHandler() by calling pw_cpu_exception_RestoreDefaultHandler().

When writing an exception handler, prefer to use the functions provided by this interface rather than relying on the backend implementation of pw_cpu_exception_State. This allows better code portability as it helps prevent an application fault handler from being tied to a single backend.

For example; when logging or dumping CPU state, prefer ToString() or RawFaultingCpuState() over directly accessing members of a pw_cpu_exception_State object.

Some exception handling behavior may require architecture-specific CPU state to attempt to correct a fault. In this situation, the application’s exception handler will be tied to the backend implementation of the CPU exception module.

Backend Expectations#

Pigweed AI summary: This paragraph discusses the expectations for CPU exception backends, which do not provide an exception handler but instead capture CPU state for use by an application's exception handler and allow recovery from CPU exceptions when possible. The entry backend should provide a definition for the pw_cpu_exception_State object and implement the pw_cpu_exception_Entry() function that calls pw_cpu_exception_HandleException() after performing necessary actions. If an application's exception handler backend modifies the captured CPU state, the state should be treated as the original state of the

CPU exception backends do not provide an exception handler, but instead provide mechanisms to capture CPU state for use by an application’s exception handler, and allow recovery from CPU exceptions when possible.

  • The entry backend should provide a definition for the pw_cpu_exception_State object through pw_cpu_exception_backend/state.h.

  • In GN, the entry backend should also provide a .impl suffixed form of the entry backend target which collects the actual entry implementation to avoid circular dependencies due to the state definition in the entry backend target.

  • The entry backend should implement the pw_cpu_exception_Entry() function that will call pw_cpu_exception_HandleException() after performing any necessary actions prior to handing control to the application’s exception handler (e.g. capturing necessary CPU state).

  • If an application’s exception handler backend modifies the captured CPU state, the state should be treated as though it were the original state of the CPU when the exception occurred. The backend may need to manually restore some of the modified state to ensure this on exception handler return.

Compatibility#

Pigweed AI summary: The pw_cpu_exception module is mostly compatible with C, except for the "support" facade and library which requires C++.

Most of the pw_cpu_exception module is C-compatible. The exception to this is the “support” facade and library, which requires C++.

Dependencies#

Pigweed AI summary: This paragraph lists the dependencies of a project, which include "pw_span" and "pw_preprocessor".

  • pw_span

  • pw_preprocessor