ULP core program stops after deep sleep
Posted: Fri Sep 19, 2025 8:25 am
Hello, I am tinkering a bit with ULP LP core on ESP32C6 and doing a LP sensor monitoring system over I2C. To start testing I copied lp_core_gpio_example from the examples and modified it a bit to perform really simple task and check the variable sharing between LP core and HP Core.
The program starts the ulp core in the first wake up, with LP timer waking up LP core every 2 seconds and the main program checks a variable ulp_loop_count once waits 5 seconds, checks it again and then goes to deep_sleep for 5 seconds before waking up from the deep sleep timer.
HP core main:
>>>
<<<
LP core main:
>>>
<<<
sdkconfig has the LP core activated:
>>>
..........................
............................
<<<
and the CMakeLists for the HP main::
>>>
<<<
What i was expecting is for the ulp_loop_count to get increasingly bigger every cycle, but as you will se the ulp_loop_count goes from 0 to 2 in the first main HP loop but after the deep sleep wake up gets stuck in 2 like the ulp_core is not alive or the accesing to ulp_loop_count variable is not correct from one of the cores.
3 loop example:
>>>
--- Warning: GDB cannot open serial ports accessed as COMx
--- Using \\.\COM5 instead...
--- esp-idf-monitor 1.8.0 on \\.\COM5 115200
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H
ESP-ROM:esp32c6-20220919
Build:Sep 19 2022
rst:0x1 (POWERON),boot:0x4c (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:2
load:0x40875730,len:0x1264
load:0x4086b910,len:0xc8c
load:0x4086e610,len:0x2f0c
entry 0x4086b910
W (65) spi_flash: Detected size(8192k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
Hello world!
ESP32-C6 ULP Playground
Not a TIMER wakeup, initializing ULP first time!
ULP Loop Count: 0
ULP Loop Count: 2
ESP-ROM:esp32c6-20220919
Build:Sep 19 2022
rst:0x5 (SLEEP_WAKEUP),boot:0x4c (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:2
load:0x40875730,len:0x1264
load:0x4086b910,len:0xc8c
load:0x4086e610,len:0x2f0c
entry 0x4086b910
W (66) spi_flash: Detected size(8192k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
Hello world!
ESP32-C6 ULP Playground
Woke up from a timer DO NOT INITIALIZE AGAIN ULP.
ULP Loop Count: 2
ULP Loop Count: 2
ESP-ROM:esp32c6-20220919
Build:Sep 19 2022
rst:0x5 (SLEEP_WAKEUP),boot:0x4c (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:2
load:0x40875730,len:0x1264
load:0x4086b910,len:0xc8c
load:0x4086e610,len:0x2f0c
entry 0x4086b910
W (66) spi_flash: Detected size(8192k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
Hello world!
ESP32-C6 ULP Playground
Woke up from a timer DO NOT INITIALIZE AGAIN ULP.
ULP Loop Count: 2
ULP Loop Count: 2
<<<
How can i adress this?, any help is welcome!.
The program starts the ulp core in the first wake up, with LP timer waking up LP core every 2 seconds and the main program checks a variable ulp_loop_count once waits 5 seconds, checks it again and then goes to deep_sleep for 5 seconds before waking up from the deep sleep timer.
HP core main:
>>>
Code: Select all
#include <stdio.h>
#include "esp_sleep.h"
#include "driver/gpio.h"
#include "driver/rtc_io.h"
#include "ulp_lp_core.h"
#include "ulp_main.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_sleep.h"
extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end");
static void init_ulp_program(void);
static const char *TAG = "example";
extern uint32_t ulp_loop_count;
void app_main(void)
{
printf("Hello world!\n");
printf("ESP32-C6 ULP Playground\n");
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
if (cause != ESP_SLEEP_WAKEUP_TIMER) {
printf("Not a TIMER wakeup, initializing ULP first time! \n");
init_ulp_program();
}
else {
printf("Woke up from a timer DO NOT INITIALIZE AGAIN ULP. \n");
}
printf("ULP Loop Count: %d\n", (int)ulp_loop_count);
vTaskDelay(pdMS_TO_TICKS(5000));
printf("ULP Loop Count: %d\n", (int)ulp_loop_count);
esp_sleep_enable_timer_wakeup(5000 * 1000);
esp_deep_sleep_start();
}
static void init_ulp_program(void)
{
esp_err_t err = ulp_lp_core_load_binary(ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start));
ESP_ERROR_CHECK(err);
// Start the program
ulp_lp_core_cfg_t cfg = {
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_LP_TIMER,
.lp_timer_sleep_duration_us = 2*1000*1000,
};
err = ulp_lp_core_run(&cfg);
ESP_ERROR_CHECK(err);
}LP core main:
>>>
Code: Select all
#include <stdint.h>
#include <stdbool.h>
#include "ulp_lp_core.h"
#include "ulp_lp_core_utils.h"
#include "ulp_lp_core_gpio.h"
volatile uint32_t loop_count;
int main (void)
{
loop_count++;
}sdkconfig has the LP core activated:
>>>
..........................
Code: Select all
#
# Ultra Low Power (ULP) Co-processor
#
CONFIG_ULP_COPROC_ENABLED=y
CONFIG_ULP_COPROC_TYPE_LP_CORE=y
CONFIG_ULP_COPROC_RESERVE_MEM=4096
CONFIG_ULP_SHARED_MEM=0x10<<<
and the CMakeLists for the HP main::
>>>
Code: Select all
# Set usual component variables
set(app_sources "lp_core_gpio_example_main.c")
idf_component_register(SRCS ${app_sources}
REQUIRES ulp soc
WHOLE_ARCHIVE)
#
# ULP support additions to component CMakeLists.txt.
#
# 1. The ULP app name must be unique (if multiple components use ULP).
set(ulp_app_name ulp_${COMPONENT_NAME})
#
# 2. Specify all C and Assembly source files.
# Files should be placed into a separate directory (in this case, ulp/),
# which should not be added to COMPONENT_SRCS.
set(ulp_sources "ulp/main.c")
#
# 3. List all the component source files which include automatically
# generated ULP export file, ${ulp_app_name}.h:
set(ulp_exp_dep_srcs ${app_sources})
#
# 4. Call function to build ULP binary and embed in project using the argument
# values above.
ulp_embed_binary(${ulp_app_name} "${ulp_sources}" "${ulp_exp_dep_srcs}")What i was expecting is for the ulp_loop_count to get increasingly bigger every cycle, but as you will se the ulp_loop_count goes from 0 to 2 in the first main HP loop but after the deep sleep wake up gets stuck in 2 like the ulp_core is not alive or the accesing to ulp_loop_count variable is not correct from one of the cores.
3 loop example:
>>>
--- Warning: GDB cannot open serial ports accessed as COMx
--- Using \\.\COM5 instead...
--- esp-idf-monitor 1.8.0 on \\.\COM5 115200
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H
ESP-ROM:esp32c6-20220919
Build:Sep 19 2022
rst:0x1 (POWERON),boot:0x4c (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:2
load:0x40875730,len:0x1264
load:0x4086b910,len:0xc8c
load:0x4086e610,len:0x2f0c
entry 0x4086b910
W (65) spi_flash: Detected size(8192k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
Hello world!
ESP32-C6 ULP Playground
Not a TIMER wakeup, initializing ULP first time!
ULP Loop Count: 0
ULP Loop Count: 2
ESP-ROM:esp32c6-20220919
Build:Sep 19 2022
rst:0x5 (SLEEP_WAKEUP),boot:0x4c (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:2
load:0x40875730,len:0x1264
load:0x4086b910,len:0xc8c
load:0x4086e610,len:0x2f0c
entry 0x4086b910
W (66) spi_flash: Detected size(8192k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
Hello world!
ESP32-C6 ULP Playground
Woke up from a timer DO NOT INITIALIZE AGAIN ULP.
ULP Loop Count: 2
ULP Loop Count: 2
ESP-ROM:esp32c6-20220919
Build:Sep 19 2022
rst:0x5 (SLEEP_WAKEUP),boot:0x4c (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:2
load:0x40875730,len:0x1264
load:0x4086b910,len:0xc8c
load:0x4086e610,len:0x2f0c
entry 0x4086b910
W (66) spi_flash: Detected size(8192k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
Hello world!
ESP32-C6 ULP Playground
Woke up from a timer DO NOT INITIALIZE AGAIN ULP.
ULP Loop Count: 2
ULP Loop Count: 2
<<<
How can i adress this?, any help is welcome!.