Compilation error with minimum configuration for developing ststm32 - Zephyr project in C++ not C

I would like to develop my embedded software in c++20.
That said , as well I would like to use C++ STL too such as
#include <vector>
#include <iostream>

I am developing for nucleo_l476rg using ZaphyrRTOS and following project files contents are as follows,

main.cpp

#include <vector>
void main(void) {
    std::vector<int> v(25);
}

prj.conf

CONFIG_GPIO=y
CONFIG_SERIAL=n
CONFIG_CPLUSPLUS=y
CONFIG_NEWLIB_LIBC=y

CMakeLists.txt

cmake_minimum_required(VERSION 3.13.1)
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(PIO_L476RG_Dev LANGUAGES CXX)

#Specify the C++ standard
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CONFIG_LIB_CPLUSPLUS ON)
set(CONFIG_NEWLIB_LIBC ON)

FILE(GLOB app_sources ../src/*.c*)
target_sources(app PRIVATE ${app_sources})

platform.ini

[env:nucleo_l476rg]
platform = ststm32
board = nucleo_l476rg
framework = zephyr
monitor_speed = 115200
build_flags =
    -std=gnu++2a
    -lstdc++
build_unflags =
    -fno-rtti
    -std=gnu++11
    -nostdinc

I am using platformio inside CLion Nova IDE
Executing build will return of following error

src\main.cpp:1:10: fatal error: vector: No such file or directory
    1 | #include <vector>
      |          ^~~~~~~~
compilation terminated.
Compiling .pio\build\nucleo_l476rg\arch__arm__core__cortex_m\zephyr\arch\arch\arm\core\cortex_m\irq_init.c.o
Compiling .pio\build\nucleo_l476rg\drivers__timer\zephyr\drivers\timer\cortex_m_systick.c.o
*** [.pio\build\nucleo_l476rg\src\main.o] Error 1

I do not know why the location of vector header file is not determined.

How should I fix the not recognizing vector header file ?

Thanks

You are missing some Zephyr options without which it will inject -nostdinc++ into the compile command, thus none of the builtin standard C++ files will be found.

prj.conf should be

CONFIG_GPIO=y
CONFIG_SERIAL=n
CONFIG_CPLUSPLUS=y
CONFIG_NEWLIB_LIBC=y
CONFIG_GLIBCXX_LIBCPP=y
CONFIG_STD_CPP2A=y
CONFIG_CPP_EXCEPTIONS=n
CONFIG_CPP_RTTI=n

This already configures the C++ mode to “0x2a” and this shows up correctly in the .vscode/c_cpp_properties.json.

Further, to avoid a linker failure with a double definition of __aeabi_atexit() with the compiler’s libstdc++, we have to inject -fno-use-cxa-atexit into the build process to.
platformio.ini:

[env:nucleo_l476rg]
platform = ststm32
board = nucleo_l476rg
framework = zephyr
monitor_speed = 115200
extra_scripts = no_atexit.py

with no_atexit.py having the content

Import("env")
env.Append(CXXFLAGS=["-fno-use-cxa-atexit"])

Finally, C++ really doesn’t like it when the main function doesn’t have a return type of int, so change your main.cpp to

#include <vector>
int main(void) {
    std::vector<int> v(25);
    return 0;
}

This makes the build go through for me.

Checking size .pio\build\nucleo_l476rg\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [=         ]   6.6% (used 6530 bytes from 98304 bytes)
Flash: [=         ]   7.8% (used 81968 bytes from 1048576 bytes)
Building .pio\build\nucleo_l476rg\firmware.bin
====== [SUCCESS] Took 23.64 seconds ======
1 Like

Thanks, I have tried the solution.
I made a python file no_atexit.py file with following content in the same folder
that platformio.ini resides.

Import("env")
env.Append(CXXFLAGS=["-fno-use-cxa-atexit"])

But I get following error

Linking .pio\build\nucleo_l476rg\zephyr\firmware-pre0.elf
c:/users/cs/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/12.3.1/../../../../arm-none-eabi/bin/ld.bfd.exe: C:\Users\cs\CLionProjects\PIO_L476RG_Dev\.pio\build\nucleo_l476rg\zephyr/arch/arch/arm/core/libarch__arm__core.a(__aeabi_atexit.c.o): in function `__aeabi_atexit':
F:\DevEnvs\Surface7Pro\.platformio\packages\framework-zephyr\arch\arm\core/__aeabi_atexit.c:26: multiple definition of `__aeabi_atexit'; C:\Users\coolspot\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\lib\thumb\v7e-m\nofp\libstdc++.a(atexit_arm.o):atexit_arm.cc:(.text.__aeabi_atexit+0x0): first defined here
c:/users/cs/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/12.3.1/../../../../arm-none-eabi/bin/ld.bfd.exe: warning: .pio\build\nucleo_l476rg\zephyr\firmware-pre0.elf has a LOAD segment with RWX permissions
Memory region         Used Size  Region Size  %age Used
           FLASH:       84824 B         1 MB      8.09%
             RAM:        6528 B        96 KB      6.64%
        IDT_LIST:         121 B        32 KB      0.37%
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\nucleo_l476rg\zephyr\firmware-pre0.elf] Error 1
========================= [FAILED] Took 72.38 seconds =========================

I am wondering why I get the mentioned error.
For your reference my files are as follows,

My modified files are as follows

main.cpp

#include <vector>
int main(void) {
    std::vector<int> v(25);
    return 0;
}

prj.conf

CONFIG_GPIO=y
CONFIG_SERIAL=n
CONFIG_CPLUSPLUS=y
CONFIG_NEWLIB_LIBC=y
CONFIG_GLIBCXX_LIBCPP=y
CONFIG_STD_CPP2A=y
CONFIG_CPP_EXCEPTIONS=n
CONFIG_CPP_RTTI=n

CMakeLists.txt

cmake_minimum_required(VERSION 3.13.1)
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(PIO_L476RG_Dev LANGUAGES CXX)

#Specify the C++ standard
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# making STL libraries such as vector and iostream available
set(CONFIG_LIB_CPLUSPLUS ON)
set(CONFIG_NEWLIB_LIBC ON)

FILE(GLOB app_sources ../src/*.c*)
target_sources(app PRIVATE ${app_sources})

platform.ini

[env:nucleo_l476rg]
platform = ststm32
board = nucleo_l476rg
framework = zephyr
monitor_speed = 115200
build_flags =
    -std=gnu++2a
    -std=c++2a
    -lstdc++
build_unflags =
    -fno-rtti
    -std=gnu++11
    -nostdinc
extra_scripts = no_atexit.py

Mhm… exactly that’s what is supposed to be fixed by -fno-use-cxa-atexit.

Can you set platform = ststm32@17.5.0 here to make sure you’re using the latest version?

Also delete that. Language settings and linker settings should already be set correctly. Or do you really want RTTI on an emebdded system?

I’ve posted the project to

and it compiles fine for all platforms with the latest PlatformIO core.

1 Like

Thanks, taking the -lstdc++ out from the build_flags of the platformio.ini file did the job.

While the build works fine I could not work with debugging the project.

I have changed the contents of the main.cpp file as below,

#include <vector>
int main(void) {
    std::vector<int> v = {1,2,3,4,5};
    int sum=0;
    for (const int& i:v) {
        sum += i;
    }
    sum = sum/4;
    return 0;
}

First of all the variables get optimised out which is undesirable, and during debug I get following error
pointing to the new_allocator.h file

  *_GLIBCXX20_CONSTEXPR*
  •  __new_allocator() _GLIBCXX_USE_NOEXCEPT { }*
    

I have changed the CMakeLists.txt to below but I failed to acheive following objectives,

(1) Producing verbose output for the build app (maybe make or ninja)
commented line
#set(CMAKE_VERBOSE_MAKEFILE ON)
(2) Disabling Optimisation using following settings
set(CMAKE_CXX_FLAGS_DEBUG “-O0”)
set(CMAKE_C_FLAGS “-O0”)

I would like to know if there are any solutions to the above objectives, so I can do the debugging task on the board properly?

CMakeLists.txt

cmake_minimum_required(VERSION 3.13.1)
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(PIO_L476RG_Dev LANGUAGES CXX)

#Specify the C++ standard
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# making STL libraries such as vector and iostream available
set(CONFIG_LIB_CPLUSPLUS ON)
set(CONFIG_NEWLIB_LIBC ON)
# taking out code optimisation
set(CMAKE_CXX_FLAGS_DEBUG "-O0")
set(CMAKE_C_FLAGS "-O0")
#set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_BUILD_PARALLEL_LEVEL 5)
FILE(GLOB app_sources ../src/*.c*)
target_sources(app PRIVATE ${app_sources})

I get no error at all when building in debug mode with the project I have posted above.

>pio debug
[..]
Building in debug mode
[..]
RAM:   [=         ]   6.7% (used 6555 bytes from 98304 bytes)
Flash: [=         ]   8.2% (used 86192 bytes from 1048576 bytes)
Building .pio\build\nucleo_l476rg\firmware.bin
===============[SUCCESS] Took 10.94 seconds ===============

Best to let PlatformIO handle how to build in debug mode. Remove the

set(CMAKE_CXX_FLAGS_DEBUG "-O0")
set(CMAKE_C_FLAGS "-O0")

from your CMake and just say (docs)

debug_build_flags = -O0 -g3 -ggdb3

in your platformio.ini. Then, when using the regular “Debug” sidebar, the variables should not be optmiized away anymore.

It seems that build for debug mode is success but the debugging fails,
I get following error

Processing nucleo_l476rg (platform: ststm32@17.5.0; board: nucleo_l476rg; framework: zephyr)
--------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/ststm32/nucleo_l476rg.html
PLATFORM: ST STM32 (17.5.0) > ST Nucleo L476RG
HARDWARE: STM32L476RGT6 80MHz, 96KB RAM, 1MB Flash
DEBUG: Current (stlink) On-board (stlink) External (blackmagic, cmsis-dap, jlink)
PACKAGES:
 - framework-zephyr @ 2.30600.240316 (3.6.0)
 - tool-cmake @ 3.21.3
 - tool-dtc @ 1.4.7
 - tool-ninja @ 1.9.0
 - toolchain-gccarmnoneeabi @ 1.120301.0 (12.3.1)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 0 compatible libraries
Scanning dependencies...
No dependencies
Building in debug mode
Checking size .pio\build\nucleo_l476rg\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [=         ]   6.7% (used 6587 bytes from 98304 bytes)
Flash: [=         ]  10.2% (used 106864 bytes from 1048576 bytes)
========================= [SUCCESS] Took 9.65 seconds =========================
Reading symbols from C:\Users\coolspot\CLionProjects\PIO_L476RG_Dev\.pio\build\nucleo_l476rg\firmware.elf...
Warning: 'set target-async', an alias for the command 'set mi-async', is deprecated.
Use 'set mi-async'.
PlatformIO Unified Debugger -> https://bit.ly/pio-debug
PlatformIO: debug_tool = stlink
PlatformIO: Initializing remote target...
xPack Open On-Chip Debugger 0.12.0-01004-g9ea7f3d64-dirty (2023-01-30-15:04)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
srst_only separate srst_nogate srst_open_drain connect_deassert_srst

Info : tcl server disabled
Info : telnet server disabled
Info : clock speed 500 kHz
Info : STLINK V2J34M25 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.273448
Info : [stm32l4x.cpu] Cortex-M4 r0p1 processor detected
Info : [stm32l4x.cpu] target has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32l4x.cpu on pipe
Info : accepting 'gdb' connection from pipe
[stm32l4x.cpu] halted due to debug-request, current mode: Handler MemManage
xPSR: 0x01000004 pc: 0x080174c0 msp: 0x20001340
Info : device idcode = 0x10076415 (STM32L47/L48xx - Rev 4 : 0x1007)
Info : RDP level 0 (0xAA)
Info : flash size = 1024 KiB
Info : flash mode : dual-bank
Info : device idcode = 0x10076415 (STM32L47/L48xx - Rev 4 : 0x1007)
Info : RDP level 0 (0xAA)
Info : OTP size is 1024 bytes, base address is 0x1fff7000
Warn : keep_alive() was not invoked in the 1000 ms timelimit. GDB alive packet not sent! (1042 ms). Workaround: increase "set remotetimeout" in GDB
0x080174c0 in arch_system_halt (reason=2) at F:\DevEnvs\Surface7Pro\.platformio\packages\framework-zephyr\kernel\fatal.c:30
30		for (;;) {
Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
[stm32l4x.cpu] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x080038a0 msp: 0x20000fc0
Loading section rom_start, size 0x188 lma 0x8000000
Loading section text, size 0x18248 lma 0x80001c0
Loading section .ARM.extab, size 0x134 lma 0x8018408
Loading section .ARM.exidx, size 0x1c0 lma 0x801853c
Loading section initlevel, size 0x70 lma 0x80186fc
Loading section device_area, size 0xc8 lma 0x801876c
Loading section sw_isr_table, size 0x290 lma 0x8018834
Loading section ctors, size 0xc lma 0x8018ac4
Loading section init_array, size 0x8 lma 0x8018ad0
Loading section rodata, size 0x1ad8 lma 0x8018ad8
Loading section datas, size 0x710 lma 0x801a5b0
Loading section device_states, size 0x14 lma 0x801acc0
Loading section k_mutex_area, size 0x28 lma 0x801acd4
Loading section .last_section, size 0x4 lma 0x801acfc
Info : Padding image section 0 at 0x08000188 with 56 bytes
Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
[stm32l4x.cpu] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x080038a0 msp: 0x20000fc0
Start address 0x080038a0, load size 109768
Transfer rate: 30 KB/sec, 5488 bytes/write.
Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
Unable to match requested speed 500 kHz, using 480 kHz
Unable to match requested speed 500 kHz, using 480 kHz
[stm32l4x.cpu] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x080038a0 msp: 0x20000fc0
[stm32l4x.cpu] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x080038a0 msp: 0x20000fc0
Temporary breakpoint 1 at 0x80020fe: file src\main.cpp, line 3.
Note: automatically using hardware breakpoints for read-only addresses.
PlatformIO: Initialization completed
PlatformIO: Resume the execution to `debug_init_break = tbreak main`
PlatformIO: More configuration options -> https://bit.ly/pio-debug

I do not know what causes the issue, I would be happy to know what causes this issue?
Thanks

When you press the Pause button, where is it stuck? Hardfault_Handler?

I cannot pause at all.
inside *reset.S * file
stops at

#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
    movs.n r0, #_EXC_IRQ_DEFAULT_PRIO
    msr BASEPRI, r0
#else

as well
in fatal.c file line 30

rch_system_halt (reason=2) at F:\DevEnvs\Surface7Pro\.platformio\packages\framework-zephyr\kernel\fatal.c:30
30		for (;;) {

Is there no backtrace available in the left debugger panel side when the processor is halted?

Did you test that with with a src/main.c and an empty main function, it correctly reaches main() without crashes? This would eliminate C++ as the error.

tried following main.c file instead on main.cpp file,

int main(void)
{
    unsigned int i=1;
    while (1)
    {
      i += 1;
    }
    return 0;
}

and I put debug point inside the loop.

Tried on platformio - CLion and debugging worked fine for the main.c file with no problem

Then it has to be found out at which point it crashes when a main.cpp is used instead. Sadly I don’t have the hardware for that until tomorrow.

You could set

debug_init_break = b Reset_Handler

to stop at the first instruction the processor execute, then with setting some breakpoints slowly work through initialization assembly and C code (copying flash data into RAM for the .data section, zeroing .bss section, setting up the clock, calling __libc_init_array(), starting the RTOS, calling into main()) to see where it crashes. Or as said, analyze the call stack after a crash and set breakpoints on when it goes wrong.

I am wondering if you were able to check with the nucleo board.
In case there is no debug_init_break in the platformio.ini file
the debug pointer stops at following line in the fatal.c exact at infinite for loop, the same issue is observed with the debug_init_break=b Reset_Handler

FUNC_NORETURN __weak void arch_system_halt(unsigned int reason)
{
	ARG_UNUSED(reason);

	/* TODO: What's the best way to totally halt the system if SMP
	 * is enabled?
	 */

	(void)arch_irq_lock();
	for (;;) {
		/* Spin endlessly */
	}
}
/* LCOV_EXCL_STOP */

-------------------
Found 0 compatible libraries
Scanning dependencies...
No dependencies
Building in debug mode
Checking size .pio\build\nucleo_l476rg\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [=         ]   6.7% (used 6587 bytes from 98304 bytes)
Flash: [=         ]  10.2% (used 106868 bytes from 1048576 bytes)
========================= [SUCCESS] Took 15.52 seconds =========================
Reading symbols from C:\Users\cs\CLionProjects\PIO_L476RG_Dev\.pio\build\nucleo_l476rg\firmware.elf...
PlatformIO Unified Debugger -> https://bit.ly/pio-debug
PlatformIO: debug_tool = stlink
PlatformIO: Initializing remote target...
xPack Open On-Chip Debugger 0.12.0-01004-g9ea7f3d64-dirty (2023-01-30-15:04)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
srst_only separate srst_nogate srst_open_drain connect_deassert_srst

Info : tcl server disabled
Info : telnet server disabled
Info : clock speed 500 kHz
Info : STLINK V2J34M25 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.268119
Info : [stm32l4x.cpu] Cortex-M4 r0p1 processor detected
Info : [stm32l4x.cpu] target has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32l4x.cpu on pipe
Info : accepting 'gdb' connection from pipe
[stm32l4x.cpu] halted due to debug-request, current mode: Handler MemManage
xPSR: 0x01000004 pc: 0x080174c2 msp: 0x20001340
Info : device idcode = 0x10076415 (STM32L47/L48xx - Rev 4 : 0x1007)
Info : RDP level 0 (0xAA)
Info : flash size = 1024 KiB
Info : flash mode : dual-bank
Info : device idcode = 0x10076415 (STM32L47/L48xx - Rev 4 : 0x1007)
Info : RDP level 0 (0xAA)
Info : OTP size is 1024 bytes, base address is 0x1fff7000
Warn : keep_alive() was not invoked in the 1000 ms timelimit. GDB alive packet not sent! (1034 ms). Workaround: increase "set remotetimeout" in GDB
arch_system_halt (reason=2) at F:\DevEnvs\Surface7Pro\.platformio\packages\framework-zephyr\kernel\fatal.c:30
30		for (;;) {
Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
[stm32l4x.cpu] halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x080038a4 msp: 0x20000fc0
Info : Padding image section 0 at 0x08000188 with 56 bytes
Info : Padding image section 1 at 0x08018adc with 4 bytes
Unable to match requested speed 500 kHz, using 480 kHz
Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
[stm32l4x.cpu] halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x080038a4 msp: 0x20000fc0
Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
[stm32l4x.cpu] halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x080038a4 msp: 0x20000fc0
[stm32l4x.cpu] halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x080038a4 msp: 0x20000fc0
Function "Reset_Handler" not defined.
Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
PlatformIO: Initialization completed
No source file named C:/Users/cs/CLionProjects/PIO_L476RG_Dev/src/main.R.
Note: automatically using hardware breakpoints for read-only addresses.
The target architecture is set to "auto" (currently "armv7e-m").

I have the Nucleo-L476RG board with me, so I can test and debug now…

Right. So the reset handler isn’t the classical Reset_Handler as it is in literally every other framework, but it’s z_arm_reset, as can be read from the vector table (second entry).

x/10x 0x8000000
0x8000000 <_vector_table>:	0x20000fc0	0x080038b1	0x08015c89	0x0800389d
0x8000010 <_vector_table+16>:	0x0800389d	0x0800389d	0x0800389d	0x00000000
0x8000020 <_vector_table+32>:	0x00000000	0x00000000
{"token":57,"outOfBandRecord":[],"resultRecords":{"resultClass":"done","results":[]}}
disas 0x080038b0
Dump of assembler code for function z_arm_reset:
   0x080038b0 <+0>:	movs	r0, #16
   0x080038b2 <+2>:	msr	BASEPRI, r0
   0x080038b6 <+6>:	ldr	r0, [pc, #32]	@ (0x80038d8 <z_arm_reset+40>)
   0x080038b8 <+8>:	mov.w	r1, #2112	@ 0x840
   0x080038bc <+12>:	adds	r0, r0, r1
..

let’s see where it goes wrong…

I see. It crashes in the __do_init_array_aux() function. That thing is supposed to go through a list of function pointers that do initilization.

Specifically, the array contains the functions _GLOBAL__sub_I__ZN9__gnu_cxx9__freeresEv and _GLOBAL__sub_I___cxa_get_globals_fast.

The code enters the first function just fine.

Further going inside the init function, at some point it calls malloc(), which wants to acquire a lock (for multithreading safety). It crashes when unlocking that mutex again.

Specifically it causes a hardfault on the “cb0” instruction

disas $pc
Dump of assembler code for function z_impl_k_mutex_unlock:
   0x08006ca0 <+0>:	push	{r7, lr}
   0x08006ca2 <+2>:	sub.w	sp, sp, #880	@ 0x370
   0x08006ca6 <+6>:	add	r7, sp, #0
   0x08006ca8 <+8>:	add.w	r3, r7, #880	@ 0x370
   0x08006cac <+12>:	sub.w	r3, r3, #876	@ 0x36c
=> 0x08006cb0 <+16>:	str	r0, [r3, #0]
   0x08006cb2 <+18>:	add.w	r3, r7, #880	@ 0x370
   0x08006cb6 <+22>:	sub.w	r3, r3, #876	@ 0x36c

This function code is highly weird. It allocates 880 bytes of stack, although there should be no big stack variables in that function. That nearly exhausts the main stack already to only 28 bytes remaning.

x/10x $r3
0x20000bdc <z_main_stack+28>:	0x08015e6b	0x00000000	0x08015e6b	0x00000000
0x20000bec <z_main_stack+44>:	0x08015e6b	0x00000000	0x08015e6b	0x00000000
0x20000bfc <z_main_stack+60>:	0x08015e6b	0x00000000
{"token":464,"outOfBandRecord":[],"resultRecords":{"resultClass":"done","results":[]}}
i r r0
r0             0x20000724          536872740
{"token":476,"outOfBandRecord":[],"resultRecords":{"resultClass":"done","results":[]}}
x/10x $r0
0x20000724 <__lock___malloc_recursive_mutex>:	0x20000724	0x20000724	0x20000760	0x00000001
0x20000734 <__lock___malloc_recursive_mutex+16>:	0x00000000	0x20000738	0x20000738	0x00000000
0x20000744 <__lock___sfp_recursive_mutex+12>:	0x00000000	0x0000000e

So the str r0, [r3, #0] will try to load the first 4 bytes of the __lock___malloc_recursive_mutex into the stack (pointed to by r3 + 0). And that store operation fails immediatelly… I’m not sure why exactly though…

Hmpf. Increasing the main task’s stack size makes that function execute without a crash.

In the prj.conf

CONFIG_MAIN_STACK_SIZE=5000

Then it also reaches the main() function and executes the loop correctly…

It is still obscure how the lock function needs over 800 bytes of stack memory to operate. Even on -O0 that should not happen and is crazy…

Thanks for your reply.
Do you think this 800 bytes allocation for the stack is
Zephyr or the bundled stm32 fault?
By the way why such issue does not occur with main.c file?
I will give a try to your solution and check out the results.