ESP32 ulp - can mos compile .S assembler files?

I am trying to make use of the ultra low power (ulp) feature on the ESP32. I am getting unresolved externals (for example “_binary_ulp_main_bin_start”) which are defined in a .S assembler file.

Is it possible for the mos tool to build assembler (.S) files?

Please try to build the .S file into the library, and link it as a library rather than a source file.

just to follow up with this: I have built a library (.a) using both the ESP IDF and with the Arduino ULP port but both are unable to find the ulp_entry variable:
(.literal._Z17start_ulp_programv+0x0): undefined reference to ‘ulp_entry’.

So other ulp_ variables are being recognized just not that one variable- the entry point into the assembler code.

I see ulp_entry (and ulp_exit) in the .ld file:
PROVIDE (ulp_entry = 0x50000190 );

so I think it is linked into the object file and in the .a library.

I added the library to my mos.yml using:

  • lib/libulp_custom.a

both local and remote build have the same error.

@ted @cpq did anyone had success comiling .S file with mos? My project heavily depends on ulp use, if there is no option for it, we have to move away from mongoose os :frowning:

  1. Compile .S file independently into a lib/libulp_custom.a
  2. In your mos.yml file, add path to it:
  - lib
  1. Rebuild

I gave up after a while- I got almost everything working except the one function in main which was an unresolved variable linker error. But I was able to get everything working in the Expressa IDF.

@cpq @ted thanks for your help. I compiled an .S file with ESP-IDF into an lib.a file, but after adding it to binary_libs I am getting the same errors ted described in the beginning: “unresolved externals (for example “_binary_ulp_main_bin_start”)”. How can this be solved?

per @ted, there is only one external variable that does not get resolved, ulp_entry.
Could you confirm that please?

@cpq for me every external variable does not get resolved

Could you show your mos.yml and your project file layout, please

@cpq I created a dedicated project to test it. So I cloned the mos empty example ( and copied the main content from the espressif ulp pulse counter example ( into it. I moved app_main() into mgos_app_init() and added build_vars and binary_libs to mos.yml. src dir contains lib dir and it contains libulp_custom.a.

mos.yml modifications:


– lib

If lib dir is in src, then the mos.yml should look like this:

  – src/lib

Thanks, I tried it this way, but still the same error.

@cpq if it helps, I can send you my ulp sample project. Btw, the libulp.a is build with binutils “2.28.51-esp-20191205”

Could you create a sample minimal mos project with the pre-built ULP binary library, please?
If you can pack it and attach the zip file to this thread, that’d be helpful

@cpq Here it is:

@cpq did you had success with it?

There are build errors, like:

build_ctx_210438974/src/main.c:47:40: error: 'ulp_main_bin_start' undeclared (

Is there some include file missing?

I reuploaded it with ulp_main.h wich was missing, but there is still "undefined reference to ‘_binary_ulp_main_bin_start’. Please check it.

We can see this:

libmosapp.a(main.o):(.text.mgos_app_init+0x24): undefined reference to `ulp_debounce_counter'

The ulp_main.h has this line:

extern uint32_t ulp_debounce_counter;

Symbols that are exported by nm lib/libulp.a:

p$ nm lib/libulp.a  | grep T
00000000 T ulp_process_macros_and_load
00000000 T ulp_load_binary
00000000 T ulp_run
00000000 T ulp_set_wakeup_period

Note that ulp_debounce_counter is not exported. Please make sure that the libulp.a exports everything that is required.