diff --git a/content/hardware/07.opta/opta-family/opta/tutorials/24.reading-crash-logs-over-rs485/content.md b/content/hardware/07.opta/opta-family/opta/tutorials/24.reading-crash-logs-over-rs485/content.md new file mode 100644 index 0000000000..c50c491293 --- /dev/null +++ b/content/hardware/07.opta/opta-family/opta/tutorials/24.reading-crash-logs-over-rs485/content.md @@ -0,0 +1,173 @@ +--- +title: 'Reading Mbed Crash Logs over RS485 on Arduino Opta' +difficulty: advanced +description: "This tutorial explains how to read Mbed crash logs over RS485 on the Arduino Opta. By redirecting the crash logs to the RS485 bus, you can capture and analyze them using another Opta or an RS485 dongle." +tags: + - Opta + - RS485 + - Mbed OS + - Debugging + +author: 'Sebastian Romero' +hardware: + - hardware/07.opta/opta-family/opta +--- + +## Introduction + +This tutorial shows how to redirect the Mbed crash log output (STDOUT) to the RS485 bus on the **Arduino Opta**. +This feature is available only when using the **Arduino Mbed Core** for Opta. + +By default, crash logs and other Mbed debug messages are printed to the hardware serial port, which is not easily accessible on the Opta. +Redirecting STDOUT to RS485 provides a simple and reliable way to capture these logs using another Opta, an RS485 dongle, or an MKR 485 Shield. + +--- + +## Hardware Required + +- **Arduino Opta** (Mbed core) +- A second **Opta**, **RS485 USB dongle**, or **Arduino MKR 485 Shield** (for reading RS485 output) +- RS485 wiring (A/B lines) + +--- + +## Circuit + +Connect the RS485 lines as follows: + +| Opta (sender) | Receiver (Opta / RS485 dongle / MKR 485 Shield) | +|----------------|-------------------------------------------------| +| A | A | +| B | B | +| GND | GND (recommended) | + +--- + +## Example Code + +Upload the following example sketch to your **Opta (sender)**: + +```cpp +#include "RS485FileHandle.h" +REDIRECT_STDOUT_TO(&RS485Console) // Redirect Mbed crash log output to RS485 + +void setup() { + // Force a crash to demonstrate the crash log over RS485 + volatile int* p = nullptr; + *p = 42; // Dereference null pointer to cause a crash +} + +void loop() { + // Nothing to do here +} +``` + +Once uploaded, the Opta will crash on startup, and the crash log will be sent over the RS485 bus. + +--- + +## Reading the RS485 Output + +You can read the crash log output using: + +- Another **Opta** running a simple RS485 receiver sketch +- An **RS485 USB dongle** connected to your computer +- An **Arduino MKR 485 Shield** attached to a compatible board + +For example, with another Opta, you can run this minimal receiver sketch: + +```cpp +#include + +void setup() { + Serial.begin(115200); + RS485.begin(115200); + RS485.receive(); + Serial.println("Listening for RS485 data..."); +} + +void loop() { + while (RS485.available()) { + Serial.write(RS485.read()); + } +} +``` + +You should see the raw crash log appear on the serial monitor. + +--- + +## Parsing the Crash Log + +The crash log generated by Mbed OS is not human-readable by default. A typical output on the receiver might look like this: + +``` ++++ MbedOS Fault Handler +++ +FaultType: HardFault +Context: +R0 : 00000000 +R1 : 0000002A +R2 : 00000000 +R3 : 00000000 +... +PC : 08007E12 +LR : 08006B5B +SP : 2001FFEC +PSR : 61000000 +Fault: Null pointer dereference ++++ End Fault Handler +++ +``` + +To interpret it, you can use the **Mbed crash log parser** available here: +[mbed-os-example-fault-handler/crash_log_parser.py](https://github.com/ARMmbed/mbed-os-example-fault-handler/blob/master/crash_log_parser.py) + +### 1. Generate a `.map` file + +You need to provide the parser with a **map file** from your compiled firmware. +You can generate it using the Arduino CLI: + +```bash +arduino-cli compile demo.ino \ + --fqbn arduino:mbed_opta:opta \ + --board-options "target_core=cm7" \ + --board-options "split=100_0" \ + --build-path build \ + --build-property compiler.cpp.extra_flags="-Og -Wl,-Map,output.map" +``` + +This produces an `output.map` file in the `build` directory. + +### 2. Run the Crash Log Parser + +Once you’ve captured the crash log over RS485 (for example, saved to a file named `crash.txt`), you can parse it as follows: + +```bash +python3 crash_log_parser.py -m output.map -c crash.txt +``` + +You’ll get a human-readable report showing the stack trace, fault details, and memory addresses — for example: + +``` +Crash Info: + Crash location = demo.ino:7 (0x08001234) + Current thread = Id: 0x20001C80 + Fault type = Hard Fault + Registers: + R0 = 0x00000000 + R1 = 0x0000002A + R2 = 0x20001E40 +``` + +In this example, it indicates that the crash occurred at line 7 in `demo.ino`, which corresponds to the null pointer dereference we introduced. + +--- + +## Summary + +Redirecting STDOUT to RS485 on the Arduino Opta allows you to: + +- Access otherwise hidden **crash logs** and **debug messages** +- Use standard Mbed functionality for **fault analysis** +- Capture logs easily via **RS485-compatible tools** + +This feature is particularly useful for diagnosing issues in field-deployed Opta systems where the serial port is inaccessible.