ULP linker Issues with Folder Structure

gabika
Posts: 10
Joined: Sat Jun 21, 2025 12:55 pm

ULP linker Issues with Folder Structure

Postby gabika » Fri Jul 11, 2025 6:27 pm

Hi all,

I’m working with ESP32-S3 and using ULP RISC-V. I'm using PlatformIO (which uses idf.py). I've encountered a couple of issues in the linker stage, which I cannot find any documentation on.

ulp_main.h Not Generated Unless ULP Source is Outside src/:
My project layout uses a src/ folder for all code. When I place ulp_main.c under src/ulp/ and define the source like this:

Code: Select all

set(ulp_sources "ulp/ulp_main.c")
I get: fatal error: ulp_main.h: No such file or directory

I also tried placing ulp_main.c in include/ulp/ (outside src/) and referencing with:

Code: Select all

set(ulp_sources "../include/ulp/ulp_main.c")
Still fails with the same error, as the .h file is never generated.

Only when I place ulp_main.c in a sibling folder named ulp/ (next to src/) and reference it as:

Code: Select all

set(ulp_sources "../ulp/ulp_main.c")
ulp_main.h get generated and included properly.

This seems related to how

Code: Select all

ulp_embed_binary()
treats paths. Is this a known constraint? Any way to put ulp/ inside src/ as I see in all the examples? What am I missing?

Another issue I am encountering is Link Errors When Calling Code from src/ subfolders in ULP:
I have some subfolders under src/ for implementing the sensors I am using. for example BPW34.
I want to call those function from ulp_main.c. When I

Code: Select all

#include "../src/bpw34/bpw34.h"
inside ulp_main.c, compilation works, but I get undefined reference to adc_to_temperature

This is my src/CMakeLists.txt:

Code: Select all

idf_component_register(SRCS 
    "lora_remote.cpp" "lora_common.cpp" 
    "lora/ra01s.c" "lora_receiver.cpp" 
    "oled/ssd1306.c" "oled/ssd1306_i2c_new.c" 
    "hdc2010/hdc2010.c" "bpw34/bpw34.c"
    INCLUDE_DIRS "." "lora" "oled" "hdc2010" "bpw34"
    REQUIRES soc nvs_flash ulp driver esp_adc)

# ULP build integration (must come AFTER idf_component_register)
set(ulp_app_name ulp_main)
set(ulp_sources "../ulp/ulp_main.c")
set(ulp_exp_dep_srcs "lora_remote.cpp")

ulp_embed_binary(${ulp_app_name} "${ulp_sources}" "${ulp_exp_dep_srcs}")
Is it possible to call my c file's function in src/ subfolders from ULP main function?

Thank you!

MicroController
Posts: 2705
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: ULP linker Issues with Folder Structure

Postby MicroController » Fri Jul 11, 2025 8:36 pm

Any way to put ulp/ inside src/ as I see in all the examples? What am I missing?
Can you successfully build one of the RISC-V ULP examples?
I have some subfolders under src/ for implementing the sensors I am using. for example BPW34.
I want to call those function from ulp_main.c. When I

Code: Select all

#include "../src/bpw34/bpw34.h"
inside ulp_main.c, compilation works, but I get undefined reference to adc_to_temperature
Of course(?), when specifying the C source files to be built for the ULP, you have to specify all the source files you want to be compiled and linked into the ULP code.

gabika
Posts: 10
Joined: Sat Jun 21, 2025 12:55 pm

Re: ULP linker Issues with Folder Structure

Postby gabika » Sat Jul 12, 2025 6:05 pm

Of course(?), when specifying the C source files to be built for the ULP, you have to specify all the source files you want to be compiled and linked into the ULP code.
What do you mean by specifying the C source files? isn't my src/CMakeLists.txt looks fine?

Code: Select all

idf_component_register(SRCS 
    "lora_remote.cpp" "lora_common.cpp" 
    "lora/ra01s.c" "lora_receiver.cpp" 
    "oled/ssd1306.c" "oled/ssd1306_i2c_new.c" 
    "hdc2010/hdc2010.c" "bpw34/bpw34.c"
    INCLUDE_DIRS "." "lora" "oled" "hdc2010" "bpw34"
    REQUIRES soc nvs_flash ulp driver esp_adc)

# ULP build integration (MUST come AFTER idf_component_register)
set(ulp_app_name ulp_main)
set(ulp_sources "../ulp/ulp_main.c")
set(ulp_exp_dep_srcs "lora_remote.cpp")

ulp_embed_binary(${ulp_app_name} "${ulp_sources}" "${ulp_exp_dep_srcs}")
--
Regarding the ULP structure - I am checking by building RISC-V ULP examples and reporting back! thank you

MicroController
Posts: 2705
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: ULP linker Issues with Folder Structure

Postby MicroController » Sat Jul 12, 2025 9:24 pm

What do you mean by specifying the C source files?
This:

Code: Select all

set(ulp_sources "../ulp/ulp_main.c")

gabika
Posts: 10
Joined: Sat Jun 21, 2025 12:55 pm

Re: ULP linker Issues with Folder Structure

Postby gabika » Sun Jul 13, 2025 8:35 am

So I tried both:

Code: Select all

set(ulp_sources "../ulp/ulp_main.c bpw34/bpw34.c")
and

Code: Select all

set(ulp_sources "../ulp/ulp_main.c" "bpw34/bpw34.c")
While the following is:

Code: Select all

ulp_embed_binary(${ulp_app_name} "${ulp_sources}" "${ulp_exp_dep_srcs}")
And it seems to keep the error:
/Users/xxx/.platformio/packages/toolchain-riscv32-esp/bin/../lib/gcc/riscv32-esp-elf/14.2.0/../../../../riscv32-esp-elf/bin/ld: CMakeFiles/ulp_main.dir/Users/xxx/workspace/projects/esp32/my_project/ulp/ulp_main.c.obj: in function `main':
ulp_main.c:(.text.startup.main+0x2e): undefined reference to `bpw34_init'

gabika
Posts: 10
Joined: Sat Jun 21, 2025 12:55 pm

Re: ULP linker Issues with Folder Structure

Postby gabika » Sun Jul 13, 2025 1:29 pm

On the CMAKE file I see that the CMAKE_FLAGS get ULP_S_SOURCES flag, which might indicate on Assembly sources.
Does anyone knows if C files also supported?

https://github.com/espressif/esp-idf/bl ... .cmake#L61

gabika
Posts: 10
Joined: Sat Jun 21, 2025 12:55 pm

Re: ULP linker Issues with Folder Structure

Postby gabika » Tue Jul 15, 2025 3:43 pm

This is from GPT, anyone knows if that is true?
ULP code cannot call functions from the main app unless you provide ULP-specific copies and include them in the ULP build step.

MicroController
Posts: 2705
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: ULP linker Issues with Folder Structure

Postby MicroController » Tue Jul 15, 2025 7:31 pm

Yes, that is accurate.
Source files don't necessarily have to be "ULP-specific" though, namely when they don't need to access the hardware, FreeRTOS, or other functionality only available to the main CPU.

Who is online

Users browsing this forum: Amazon [Bot], PerplexityBot and 1 guest