ryankurte / efm32-base

Base project for Silicon Labs EFM32 microcontrollers
90 stars 33 forks source link

Building BLE under efm32-base #31

Open KJ7LNW opened 1 year ago

KJ7LNW commented 1 year ago

Hi Ryan,

It looks like BLE_LIB is only defined once and never referenced:

efm32-base]$ git grep -i BLE_LIB
CMakeLists.txt:    # set(BLE_LIB EFR32BG13P)

Is it used? If so, how?

We're going to play with BLE so if you have any pointers or know of other projects that have used BLE with efm32-base then it would be nice to have a look.

This is the efm32-base project we have been working on and here is a presentation about it, if you're curious.

-Eric

ryankurte commented 1 year ago

howdy, it's been so long i'm not -entirely- sure tbqh. i did some exploratory work on supporting the EFR32BG which would have needed to pull in the bluetooth SDK, but, ended up using NRF52s and ESP32s preferentially. i think @ravnicas might have used this previously (https://github.com/ryankurte/efm32-base/issues/25)?

(as an aside, unless you need something specific to the EFM32 platform this will be a -high-effort- approach... if you're open to looking at other platforms, the NRF52 with rust/embassy is an incredible developer experience compared to the C adventures i'm used to, for wifi + BLE the ESP32 is fairly unbeatable, and i haven't tried one myself yet but the pi pico w looks like a neat option for low-performance tasks)

KJ7LNW commented 1 year ago

Wow, you could probably boot Linux on the ESP32... well almost, might need more RAM. Not sure I'm ready for Rust, but maybe I need to learn yet another language.

Would love to jump ship to ESP32, I like the WiFi option and they are surprisingly inexpensive for the feature set. The chip-specific stuff about our code is UART, systick/RTC, PWM, i2c, ADC...hmm...thats more than I thought.

Well we can use what we have w/o BLE if needed, but would be nice to get BLE working to avoid reworking all the hardware integration bits.

KJ7LNW commented 1 year ago

Hi @ryankurte,

Ok so we're making progress building BLE under efm32-base. This is a CMakeLists.txt question:

How do I tweak CMakeLists.txt so that it adds the following linker items?

  -Lprotocol/bluetooth/lib/EFR32MG21/GCC/ \
  -lbluetooth \
  -lmbedtls \
  -lpsstore \
  -lrail \

These need to appear emlib/libemlib.a (or at least it works without linker errors when I put them there).

This is a bit hacked together, but the following hand-coded linker line compiles most of the BLE SPP example without errors. The linker line is just a link line created by cmake from your build environment, all I've done is replace spaces with newlines so it is readable. You can see the lines I have added that are un-indented, below:

/opt/gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/bin/ld \
  -plugin \
  /opt/gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/liblto_plugin.so \
  -plugin-opt=/opt/gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/lto-wrapper \
  -plugin-opt=-fresolution=/tmp/ccZ3MWLa.res \
  -plugin-opt=-pass-through=-lgcc \
  -plugin-opt=-pass-through=-lg_nano \
  -plugin-opt=-pass-through=-lc_nano \
  -plugin-opt=-pass-through=-lgcc \
  -plugin-opt=-pass-through=-lc_nano \
  --sysroot=/opt/gcc-arm-none-eabi-7-2018-q2-update/bin/../arm-none-eabi \
  -X \
  -o \
  efm32-test \
  /opt/gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v8-m.main/fpv5-sp/hard/crti.o \
  /opt/gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v8-m.main/fpv5-sp/hard/crtbegin.o \
  /opt/gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v8-m.main/fpv5-sp/hard/crt0.o \
  -L/opt/gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v8-m.main/fpv5-sp/hard \
  -L/opt/gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v8-m.main/fpv5-sp/hard \
  -L/opt/gcc-arm-none-eabi-7-2018-q2-update/bin/../arm-none-eabi/lib/thumb/v8-m.main/fpv5-sp/hard \
  -L/opt/gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1 \
  -L/opt/gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc \
  -L/opt/gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib \
  -L/opt/gcc-arm-none-eabi-7-2018-q2-update/bin/../arm-none-eabi/lib \
  -T/home/ewheeler/src/efm32-base/protocol/bluetooth/ble_stack/linker/GCC/efr32mg21a010f1024im32.ld \
  -Map=/home/ewheeler/src/efm32-base/build/efm32-test.map \
  --gc-sections \
  -v \
  CMakeFiles/efm32-test.dir/source/main.c.obj \
  CMakeFiles/efm32-test.dir/source/gatt_db.c.obj \
  -lgcc \
  -lc_nano \
  -lnosys \
  -lgcc \
  -lc_nano \
  -lnosys \
  ./CMakeFiles/efm32-test.dir/emdrv/sleep/src/sleep.c.obj \
-L../protocol/bluetooth/lib/EFR32MG21/GCC/ \
-lbluetooth \
-lmbedtls \
-lpsstore \
-lrail \
  emlib/libemlib.a \
  device/libdevice.a \
  --start-group \
  -lgcc \
  -lg_nano \
  -lc_nano \
  --end-group \
  --start-group \
  -lgcc \
  -lc_nano \
  --end-group \
  /opt/gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v8-m.main/fpv5-sp/hard/crtend.o \
  /opt/gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v8-m.main/fpv5-sp/hard/crtn.o
ryankurte commented 1 year ago

nice work! the right place to add this is probably protocol/CMakeLists.txt, where you could add a target_link_libraries command to link in the appropriate precompiled archives for the platform

KJ7LNW commented 1 year ago

So it builds if I make the following changes to the root-level CMakeLists.txt file:

-set(CMAKE_EXE_LINKER_FLAGS "${COMMON_DEFINITIONS} -Xlinker -T${LINKER_SCRIPT} -Wl,-Map=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}.map -Wl,--gc-sections -Wl,-v")
+set(CMAKE_EXE_LINKER_FLAGS "-L../protocol/bluetooth/lib/EFR32MG21/GCC/ ${COMMON_DEFINITIONS} -Xlinker -T${LINKER_SCRIPT} -Wl,-Map=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}.map -Wl,--gc-sections -Wl,-v ")
[...]
-target_link_libraries(${PROJECT_NAME} ${LIBS} emlib cmsis device)
+target_link_libraries(${PROJECT_NAME} ${LIBS} bluetooth mbedtls psstore rail protocol emlib cmsis device )

Note that I have to hardcode a -L path which I'm sure is not a proper way to do this since ../ takes it out of cmake build directory.

I also tried adding this to protocol/CMakeLists.txt:

target_link_libraries(bluetooth mbedtls psstore rail)

but I get the following error when I run cmake:

CMake Error at protocol/CMakeLists.txt:28 (target_link_libraries):
  Cannot specify link libraries for target "bluetooth" which is not built by
  this project.

I think this boils down to about two questions:

  1. How do I specify the search path along the lines of -Lbluetooth/lib/${DEVICE_FAMILY}/GCC?
    • Do you already have a variable that represents what I called DEVICE_FAMILY?
  2. What do I need to do so target_link_libraries will not give the error listed above?

Thanks for your help on this, I'm brand-new to cmake, I've only ever used it with efm32-base.

-Eric

ryankurte commented 1 year ago

How do I specify the search path along the lines of -Lbluetooth/lib/${DEVICE_FAMILY}/GCC?

target_link_options should do the job, and if you look at toolchain/efm32-base.cmake you can see the available variables.

What do I need to do so target_link_libraries will not give the error listed above?

cmake models components as targets, and the first argument to these functions is the target, target. you're probably looking for target_link_libraries(${PROJECT_NAME} bluetooth mbedtls psstore rail) (similar to here) to link the precompiled libraries to your top level project target.

Thanks for your help on this, I'm brand-new to cmake, I've only ever used it with efm32-base.

cmake is, certainly not easy, but among the best tools we have :-/