Concepts First
- Crash: a runaway program, illegal memory access, assert failure, etc. that pushes the chip into an exception. The CPU registers and call stack at that moment are together called a coredump.
- Core partition: the partition table region reserved for coredumps. The example opens the partition named
corevia MTD and writes the crash state there, so it survives reset and can be exported later. - Shell (command line): serial interactive commands. The example registers a
crashcommand to crash on purpose, making the coredump flow easy to demonstrate. - Analysis tool:
tools/byai/coredump.pyreads the coredump together with the build artifact (.elf) to reconstruct the call stack and registers, pinpointing where the crash happened.
Example Overview
This page is based on the crash example in the official Bouffalo SDK (examples/crash), which demonstrates generating, saving, and offline-analyzing a coredump:
- Initializes MTD, opens the
corepartition, and prints its address and size; core_partition_initconfigures where the coredump is written;- Starts a serial shell and registers the
crashcommand, which callsassert(0)to force a crash; - On crash, the coredump is written to the Flash core partition while crash info is printed on the serial port;
- After exporting the core partition,
tools/byai/coredump.pyreconstructs the call stack with the ELF file. - The example depends on FreeRTOS, shell, MTD, and partition components; the official README notes the analysis flow supports Linux.
Note
Crash debugging depends on the core partition in the partition table: without it the program prints No valid coredump partition found and no coredump is saved. Also, after the assert(0) crash you must re-enter download mode (or reset) before exporting data.
Operation Steps
No external wiring is needed for this page. Open a terminal and enter the SDK crash-debug example directory (prerequisite: set up the environment as in Quick Start (Linux) or Windows):
cd examples/crashRun the build command. The Ai-M62 (BL616) and Ai-M61 (BL618) belong to the same series, so both use bl616 (the example depends on FreeRTOS, shell, MTD, and partition components, enabled in its defconfig):
make CHIP=bl616 BOARD=bl616dkConnect the board with a USB cable, hold the BOOT button (IO2 on the Ai-M61-32S-Kit), briefly press EN/RST to enter download mode, then flash (replace the serial port with the one on your computer):
make flash CHIP=bl616 COMX=/dev/ttyUSB0Open a serial tool (baud rate 2000000). The program prints the core partition’s XIP address / flash address / size and starts the shell; type crash and press Enter. The shell calls assert(0) to force a crash: the serial port shows crash output and a coredump is written to the Flash core partition.
crashAfter the crash, re-enter download mode and read the core partition with the SDK tools, then use coredump.py with the compiled ELF to locate the crash (use the addresses printed at startup):
./tools/bflb_tools/bouffalo_flash_cube/BLFlashCommand-ubuntu --chip bl616 --read --flash --start 0x2f8000 --len 0x80000 --file crash.bin --port /dev/ttyACM0
./tools/byai/coredump.py crash.bin examples/crash/build/build_out/crash_bl616.elf
Code Execution Flow
The complete flow from startup to crash and analysis is shown below:
APIs Used by the Example
bflb_mtd_init()
Initializes MTD (Flash-partition abstraction); required before opening partitions by name.
Parameters: none
Return: 0 on success; negative error code on failure
bflb_mtd_open("core", &handle, flags)
Opens an MTD partition by name. The example opens "core" with BFLB_MTD_OPEN_FLAG_BUSADDR; a negative return means failure.
Parameters:
name: partition name,"core"in the examplehandle: returned partition handleflags: open flags
Return: 0 on success; negative error code on failure
bflb_mtd_info(handle, &info)
Gets partition info (XIP address, flash offset, size); the example prints these values.
Parameters:
handle: partition handleinfo:bflb_mtd_info_twithxip_addr/offset/size
Return: 0 on success; negative error code on failure
core_partition_init(flash_addr, flash_size)
Configures the coredump write location as the core partition (Flash address + size); crashes are then written there automatically.
Parameters:
flash_addr: core partition flash offset (info.offsetin the example)flash_size: core partition size (info.sizein the example)
Return: none
shell_init_with_task(uart_dev)
Starts the serial shell as a dedicated task, allowing commands such as crash to be typed.
Parameters:
uart_dev: UART device handle (uart0in the example)
Return: none
SHELL_CMD_EXPORT_ALIAS(func, name, desc)
Registers a C function as a shell command: the example registers shell_crash as crash, which calls assert(0) to force a crash.
Parameters:
func: command functionname: command name ("crash")desc: command description
Return: none
Complete Code
The complete source below matches the official example (examples/crash) verbatim. Collapsed by default, click to expand:
📜 Click to expand crash/main.c full code
#include <assert.h>
#include "bflb_mtimer.h"
#include "bflb_uart.h"
#include "shell.h"
#include <FreeRTOS.h>
#include "semphr.h"
#include "board.h"
#include "bflb_mtd.h"
#include "coredump.h"
static struct bflb_device_s *uart0;
extern void shell_init_with_task(struct bflb_device_s *shell);
int main(void)
{
bflb_mtd_info_t info;
bflb_mtd_handle_t handle;
int ret;
board_init();
bflb_mtd_init();
ret = bflb_mtd_open("core", &handle, BFLB_MTD_OPEN_FLAG_BUSADDR);
if (ret < 0) {
puts("No valid coredump partition found\r\n");
}
memset(&info, 0, sizeof(info));
bflb_mtd_info(handle, &info);
printf("Found Valid coredump partition, XIP Addr %08x, flash addr %08x, size %d\r\n",
info.xip_addr,
info.offset,
info.size);
core_partition_init(info.offset, info.size);
uart0 = bflb_device_get_by_name("uart0");
shell_init_with_task(uart0);
vTaskStartScheduler();
while (1) {
}
}
int shell_crash(int argc, char **argv)
{
printf("shell crash\r\n");
//asm ("ebreak");
assert(0);
return 0;
}
SHELL_CMD_EXPORT_ALIAS(shell_crash, crash, trigger crash.);FAQ
It says No valid coredump partition found
The partition table has no core partition. Check the partition config (partition_cfg / pt file) for an entry named core, then regenerate and flash the partition table and firmware.
Typing crash does nothing
Confirm you are typing a shell command (crash + Enter) at baud 2000000; if the shell is not running, check that CONFIG_SHELL is enabled and vTaskStartScheduler executed.
How do I know the export addresses
Use the flash addr / size printed at startup (0x2f8000 and 0x80000 in the official README are examples for the default partition config). With other configs, replace --start and --len with the printed values.
Have questions?
For any other questions, visit the unified Q&A and discussion board: Ai-Thinker Discussions

