pw_assert_basic: add a handler facade layer
Splits up the pw_assert_basic module to add a facade layer to
allow a user to provide a custom pw_assert_basic_HandleFailure()
implementation. The existing handler, previously named pw_Crash(),
was moved to a basic_handler facade which mirrors the
pw_cpu_exception structure and naming.
Unlike pw_cpu_exception, pw_assert_basic defaults to the
basic_handler backend.
This refactor should allow users, especially during initial
bringup, to trivially bring up assert support with target specific
handlers with less code duplication and complications.
Note that pw_assert_basic is still not recommended for production
use as it is rather heavy weight, we strongly recommend using
tokenized asserts.
Change-Id: I3a0c0aacc9a88d44b35b24ad0a13dd7e2badc209
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/28520
Commit-Queue: Ewout van Bekkum <ewout@google.com>
Reviewed-by: Keir Mierle <keir@google.com>
diff --git a/pw_assert_basic/docs.rst b/pw_assert_basic/docs.rst
index 45ff8f7..2ddc367 100644
--- a/pw_assert_basic/docs.rst
+++ b/pw_assert_basic/docs.rst
@@ -7,5 +7,60 @@
--------
Overview
--------
-This is a simple assert backend to implement the ``pw_assert`` facade.
+This is a simple assert backend to implement the ``pw_assert`` facade which
+relies on a single function ``pw_assert_basic_HandleFailure`` handler facade
+which defaults to the ``basic_handler`` backend. Users may be interested in
+overriding this default in case they need to do things like transition to
+crash time logging or implementing application specific reset and/or hang
+behavior.
+.. attention::
+
+ This log backend comes with a very large ROM and potentially RAM cost. It is
+ intended mostly for ease of initial bringup. We encourage teams to use
+ tokenized asserts since they are much smaller both in terms of ROM and RAM.
+
+Custom handler backend example
+------------------------------
+Here is a typical usage example implementing a simple handler backend which uses
+a UART backed sys_io implementation to print during crash time and then reboots.
+Note that this example uses CMSIS and a psuedo STM HAL, as a backend implementer
+you are responsible for using whatever APIs make sense for your use case(s).
+
+.. code-block:: cpp
+
+ #include "cmsis.h"
+ #include "hal.h"
+ #include "pw_string/string_builder.h"
+
+ using pw::sys_io::WriteLine;
+
+ extern "C" void pw_assert_basic_HandleFailure(
+ [[maybe_unused]] const char* file_name,
+ [[maybe_unused]] int line_number,
+ [[maybe_unused]] const char* function_name,
+ const char* message,
+ ...) {
+ // Global interrupt disable for a single core microcontroller.
+ __disable_irq();
+
+ // Re-initialize the UART to ensure it's safe to use at crash time.
+ HAL_UART_DeInit(sys_io_uart);
+ HAL_UART_Init(sys_io_uart);
+
+ WriteLine(
+ " Welp, that didn't go as planned. "
+ "It seems we crashed. Terribly sorry! Assert reason:");
+ {
+ pw::StringBuffer<150> buffer;
+ buffer << " ";
+ va_list args;
+ va_start(args, format);
+ buffer.FormatVaList(format, args);
+ va_end(args);
+ WriteLine(buffer.view());
+ }
+
+ // Reboot the microcontroller.
+ HAL_NVIC_SystemReset();
+ }