Skip to content

Commit 054aced

Browse files
LucasTamborkartben
authored andcommitted
samples: boards: espressif: ulp
Add ULP directory for samples related to the Ultra Low Power Coprocessor. Add a sample to demonstrate the debug process of the LP Core Signed-off-by: Lucas Tamborrino <[email protected]>
1 parent c6f84d0 commit 054aced

File tree

13 files changed

+273
-0
lines changed

13 files changed

+273
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.. zephyr:code-sample-category:: ulp
2+
:name: Ultra Low Power coprocessor (ULP)
3+
:show-listing:
4+
5+
These samples demonstrate how to use the ULP in Espressif SOCs.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
5+
set(REMOTE_ZEPHYR_DIR ${CMAKE_CURRENT_BINARY_DIR}/../hello_ulp_lpcore/zephyr)
6+
7+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
8+
9+
message(STATUS "${CONFIG_BOARD_TARGET} compile as Master in this sample")
10+
project(debug_ulp_hpcore)
11+
12+
target_sources(app PRIVATE src/main.c)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
source "share/sysbuild/Kconfig"
5+
6+
config ULP_REMOTE_BOARD
7+
string
8+
default "esp32c6_devkitc/esp32c6/lpcore" if $(BOARD) = "esp32c6_devkitc"
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
.. zephyr:code-sample:: debug-ulp
2+
:name: Debug ULP
3+
4+
Debug the LP Core in ESP32C6.
5+
6+
Overview
7+
********
8+
9+
This example demonstrates how to build, flash and debug a simple application on the LP core.
10+
11+
This sample also provides a custom ``gdbinit`` file to be loaded by GDB to set up the debugging environment.
12+
It connects with the remote OpenOCD server, loads the symbols from the LP Core application
13+
and sets an initial breakpoint.
14+
15+
Limitations
16+
***********
17+
1. Currently debugging is not supported when either HP or LP core enters any sleep mode. So this limits debugging scenarios.
18+
2. OS support is disabled when debugging the LP core, so you won't be able to see tasks running in the system. Instead there will be two threads representing HP ('esp32c6.cpu0') and LP ('esp32c6.cpu1') cores:
19+
20+
.. code-block:: console
21+
22+
(gdb) info thread
23+
Id Target Id Frame
24+
1 Thread 1 "esp32c6.hp.cpu0" (Name: esp32c6.hp.cpu0, state: debug-request) arch_irq_unlock (key=8) at zephyr/include/zephyr/arch/riscv/arch.h:259
25+
* 2 Thread 2 "esp32c6.lp.cpu" (Name: esp32c6.lp.cpu, state: breakpoint) do_things (max=1000000000) at zephyr/samples/boards/espressif/ulp/lp_core/debug_ulp/remote/src/main.c:28
26+
27+
3. When setting HW breakpoint in GDB it is set on both cores, so the number of available HW breakpoints is limited to the number of them supported by LP core (2 for ESP32-C6).
28+
29+
Sysbuild
30+
********
31+
32+
Sysbuild is in charge of building the application located in the ``remote`` folder for the LP Core target.
33+
The build and flashing orders are as follows:
34+
35+
Build:
36+
37+
- MCUboot bootloader
38+
- LP Core application
39+
- HP Core application
40+
41+
Flash:
42+
43+
- MCUboot bootloader
44+
- HP Core application
45+
- LP Core application
46+
47+
Building and Flashing
48+
*********************
49+
50+
Build the sample code as follows:
51+
52+
.. zephyr-app-commands::
53+
:zephyr-app: samples/boards/espressif/ulp/lp_core/debug_ulp
54+
:board: esp32c6_devkitc/esp32c6/hpcore
55+
:west-args: --sysbuild
56+
:goals: build
57+
:compact:
58+
59+
Flash it to the device with the command:
60+
61+
.. zephyr-app-commands::
62+
:zephyr-app: samples/boards/espressif/ulp/lp_core/debug_ulp
63+
:board: esp32c6_devkitc/esp32c6/hpcore
64+
:west-args: --sysbuild
65+
:goals: flash
66+
:compact:
67+
68+
Debugging
69+
*********
70+
71+
Connect the USB cable to the USB port of the ESP32-C6 Devkitc board.
72+
73+
The ESP32-C6 modules require patches to OpenOCD that are not upstreamed yet.
74+
Espressif maintains their own fork of the project.
75+
The custom OpenOCD can be obtained at `OpenOCD ESP32`_.
76+
77+
In one terminal instance run the Espressif's OpenOCD:
78+
79+
.. code-block:: shell
80+
81+
<path/to/openocd-esp32>/bin/openocd -f board/esp32c6-lpcore-builtin.cfg
82+
83+
Wait for the following output to show up in the console:
84+
85+
.. code-block:: console
86+
87+
Info : Listening on port 3333 for gdb connections
88+
89+
On another terminal instance, run the GDB:
90+
91+
.. code-block:: shell
92+
93+
<path/to/zephyr/sdk>/riscv64-zephyr-elf/bin/riscv64-zephyr-elf-gdb -x samples/boards/espressif/ulp/lp_core/debug_ulp/gdbinit build/debug_ulp/zephyr/zephyr.elf
94+
95+
The following output should be displayed:
96+
97+
.. code-block:: console
98+
99+
[esp32c6.hp.cpu0] Reset cause (24) - (JTAG CPU reset)
100+
add symbol table from file "build/debug_ulp_lpcore/zephyr/zephyr.elf"
101+
Hardware assisted breakpoint 1 at 0x500000ec: file zephyr/samples/boards/espressif/ulp/lp_core/debug_ulp/remote/src/main.c, line 28.
102+
(gdb)
103+
104+
From now on you can use the GDB commands to debug the application. By using the command ``continue`` the LP Core application stop at the assigned breakpoint:
105+
106+
.. code-block:: console
107+
108+
(gdb) continue
109+
Continuing.
110+
[Switching to Thread 2]
111+
112+
Thread 2 "esp32c6.lp.cpu" hit Temporary breakpoint 1, do_things (max=1000000000) at zephyr/samples/boards/espressif/ulp/lp_core/debug_ulp/remote/src/main.c:28
113+
28 for (int i = 0; i < max; i++) {
114+
(gdb)
115+
116+
When the application reaches the ``abort()`` function it will automatically break.
117+
118+
References
119+
**********
120+
121+
.. target-notes::
122+
123+
.. _`OpenOCD ESP32`: https://github.com/espressif/openocd-esp32/releases
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
set pagination off
5+
target extended-remote :3333
6+
7+
mon reset halt
8+
maintenance flush register-cache
9+
10+
add-symbol build/debug_ulp_lpcore/zephyr/zephyr.elf
11+
thb do_things
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CONFIG_ULP_COPROC_ENABLED=y
2+
CONFIG_LOG=y
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
5+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
6+
7+
message(STATUS "${BOARD} compiles as remote in this sample")
8+
project(debug_ulp_lpcore)
9+
10+
target_sources(app PRIVATE src/main.c)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CONFIG_DEBUG=y
2+
CONFIG_NO_OPTIMIZATIONS=y
3+
4+
# Create a disassembly file
5+
CONFIG_OUTPUT_DISASSEMBLY=y
6+
CONFIG_OUTPUT_DISASSEMBLE_ALL=y
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stdio.h>
8+
#include "ulp_lp_core_utils.h"
9+
#include <esp_cpu.h>
10+
#include "riscv/rvruntime-frames.h"
11+
12+
/* Override for the ulp_lp_core_panic_handler() so it stops the debugger when abort() is called */
13+
void ulp_lp_core_panic_handler(RvExcFrame *frame, int exccause)
14+
{
15+
esp_cpu_dbgr_break();
16+
}
17+
18+
void do_crash(void)
19+
{
20+
volatile int *p = (int *)0x0;
21+
*p = 32;
22+
abort();
23+
}
24+
25+
void do_things(int max)
26+
{
27+
while (1) {
28+
for (int i = 0; i < max; i++) {
29+
ulp_lp_core_delay_us(100000);
30+
if (i > 0) {
31+
do_crash();
32+
}
33+
}
34+
}
35+
}
36+
37+
int main(void)
38+
{
39+
do_things(1000000000);
40+
return 0;
41+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
sample:
2+
name: ESP32C6 LP_CORE Debug Sample
3+
tests:
4+
sample.boards.espressif.ulp.lp_core.debug_ulp:
5+
platform_allow:
6+
- esp32c6_devkitc/esp32c6/hpcore
7+
tags:
8+
- samples

0 commit comments

Comments
 (0)