2021-12-05 06:49 AM
I have an atomic variable and want to use compare_exchange_weak on it.
But I'm getting the following linker error when compiling with STM32CubeIDE v1.8.0 (arm-none-eabi 9.3.1:(
arm-none-eabi\bin\ld.exe: ./Core/Src/main.o: in function `std::__atomic_base<unsigned char>::compare_exchange_weak(unsigned char&, unsigned char, std::memory_order, std::memory_order)':
arm-none-eabi\include\c++\9.3.1\bits/atomic_base.h:457: undefined reference to `__atomic_compare_exchange_1'
Here is a minimal example to demonstrate the linker error:
/* main.cpp */
#include <cstdint>
#include <cstdio>
#include <atomic>
int main() {
std::atomic<uint8_t> some_atomic_var { 0 };
some_atomic_var.store(3U); // atomic store works fine
printf("%u\n", some_atomic_var.load()); // atomic load works fine
auto val = some_atomic_var.load();
// set second bit
while (!some_atomic_var.compare_exchange_weak(val, val | (1 << 2U))); // gives linker error
printf("%u\n", some_atomic_var.load());
return 0;
}
Update 6.12.2021:
Platform:Windows version of CubeIDE 1.8.0
STM32 target: STM32F030CC
Solved! Go to Solution.
2021-12-06 03:08 AM
Internet wisdom says that you should link -latomic in that case, but I cannot find it in the STM32 release.
otoh, Cortex-M0 is so simple. Are you using multi tasking? If so, check the implementation in RIOT OS https://github.com/RIOT-OS/RIOT/blob/master/core/atomic_c11.c for adding the missing function. If not, you could further simplify it.
Did you write that code or is it meant to be super portable, e.g. for multi-core, out-of-order execution CPUs?
hth
KnarfB
2021-12-06 01:32 AM
Hmm. It links here without errors:
10:30:16 **** Incremental Build of configuration Debug for project atomic ****
make -j12 all
arm-none-eabi-g++ "../Core/Src/main.cpp" -mcpu=cortex-m4 -std=gnu++14 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L432xx -c -I../Core/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-use-cxa-atexit -Wall -fstack-usage -MMD -MP -MF"Core/Src/main.d" -MT"Core/Src/main.o" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "Core/Src/main.o"
arm-none-eabi-g++ -o "atomic.elf" @"objects.list" -mcpu=cortex-m4 -T"STM32_workspace\atomic\STM32L432KCUX_FLASH.ld" --specs=nosys.specs -Wl,-Map="atomic.map" -Wl,--gc-sections -static --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -Wl,--start-group -lc -lm -lstdc++ -lsupc++ -Wl,--end-group
Finished building target: atomic.elf
arm-none-eabi-size atomic.elf
arm-none-eabi-objdump -h -S atomic.elf > "atomic.list"
arm-none-eabi-objcopy -O binary atomic.elf "atomic.bin"
text data bss dec hex filename
5848 116 1600 7564 1d8c atomic.elf
Finished building: default.size.stdout
Finished building: atomic.bin
Finished building: atomic.list
2021-12-06 01:42 AM
Thanks a lot for trying it out!
Did you use STM32CubeIDE v1.8.0 (also tried it with 1.7.0) and are you using the Windows version of the CubeIDE?
2021-12-06 01:46 AM
Yes and yes.
gcc version 9.3.1 20200408 (release) (GNU Tools for STM32 9-2020-q2-update.20201001-1621)
2021-12-06 01:54 AM
Interestingly, it builds fine when using an STM32L432 as target MCU.
But I get the linker error when trying to build for an STM32F030CC MCU.
A wild guess without having investigated it further:
The Cortex M0 (used in STM32F030) does not have an atomic compare-exchange instruction in its set, unlike the Cortex M4 (used in STM32L432) and the arm-none-eabi toolchain doesn't handle this fact correctly.
2021-12-06 02:06 AM
Confirmed. F0 uses ARMv6 but L4 ARMv7 instruction set. Maybe some emulation is missing here.
2021-12-06 03:08 AM
Internet wisdom says that you should link -latomic in that case, but I cannot find it in the STM32 release.
otoh, Cortex-M0 is so simple. Are you using multi tasking? If so, check the implementation in RIOT OS https://github.com/RIOT-OS/RIOT/blob/master/core/atomic_c11.c for adding the missing function. If not, you could further simplify it.
Did you write that code or is it meant to be super portable, e.g. for multi-core, out-of-order execution CPUs?
hth
KnarfB
2021-12-06 03:53 AM
Thanks a lot for your effort and your input!
I'm writing a multithreaded application based on FreeRTOS and wanted to youse the nice and shiny modern cpp features, but yeah I will protect the critical sections with a mutex instead that is the shorter path :)
The only need in terms of portability is, that I'm able to build and run it on a Windows host system so that I'm independent of the hardware for the high level application logic. Which works fine so far. The atomic thing is the first issue I had so far (ok plus some issues with CMSIS-OS).
All the best!
Chris