Bluetooth Low Energy (a.k.a Bluetooth LE, BTLE, Bluetooth Smart)

Building with arm-gcc

27 Apr 2015

Building with ARM-GCC

You can build your BLE projects using offline toolchains.

Building offline with actual sources - as opposed to using the online IDE or linking against pre-built libraries - allows for fine-grained control and supports a much better debugging experience. It is also a good learning experience to set up one of these.

Here's a complete setup for a Bluetooth-smart demo application built using ARM-GCC and CMake. Various people have contributed to it; many thanks go to Sandeep SS for contributing a working example of a build system.

Selecting a Toolchain

There are several license-free toolchains for ARM Cortex-M cross-compilation. We chose GCC ARM Embedded as the toolchain, and CMake as a cross-platform build-system generator. Cmake is a very mature and highly configurable cross-platform build system supported by good documentation. It abstracts a Makefile-like build system.

Installations

Packages and Directories

The following instructions apply to a Ubuntu development machine. You might want to install the following Debian packages since they'll be needed later:

$ sudo apt-get install build-essential
$ sudo apt-get install srecord

Create a directory to host files for your project; we'll refer to this as ``WORKSPACE_DIR``, but you can choose any name for it.

CMakeLists.txt

The ``CMakeLists.txt`` file describes the project dependencies using very simple, readable directives. It is what you would expect from a collection of toolchain-dependencies: include directories, compiler flags, sources (in C/C++ or assembly), the name of the final build target, and any custom post-build commands. CMake is driven by a collection of ``CMakeLists.txt`` files spread across the sources. There needs to be at least one of these at the top level of the sources. Copy this ``CMakeLists.txt`` to ``WORKSPACE_DIR``. We'll work with a single ``CMakeLists.txt`` file; you can change this if needed. CMake is far more capable than what can be gathered from this simple example. The highly readable nature of the ``CMakeLists.txt`` file works as an encouragement to refer to the documentation for CMake. In its default state, ``CMakeLists.txt`` is meant for the [BLE Heart Rate](http://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_HeartRate/) demo project. You may want to update the name of the project.

Note: The default ``CMakeLists.txt`` file assumes a ``main.cpp``.

mbed SDK

All mbed applications depend on the mbed-SDK. This is a Git repository, which can be cloned as:

$ git clone https://github.com/mbedmicro/mbed.git mbed-src

I typically clone that repository as mbed-src (as shown above). The actual mbed SDK resides under the subfolder libraries/mbed within mbed-src. Bluetooth Smart applications meant for the Nordic platform also depend on the ``BLE_API`` and ``nRF51822`` libraries.

$ git clone https://github.com/mbedmicro/BLE_API.git
$ git clone https://github.com/mbedmicro/nRF51822.git

Updating CMAKELists.txt

You’ll need to edit the ``CMakeLists.txt`` configuration to point to the correct dependencies. The following variables may need to be updated:

  • MBED_SRC_PATH to point to the location of the folder called ‘mbed’ within your local clone of mbed-src repository.
  • BLE_API_SRC_PATH to point to the local clone of the BLE_API repository.
  • NRF51822_SRC_PATH to point to the local clone of the nRF51822 repository.
  • CMAKE_CXX_COMPILER and CMAKE_C_COMPILER to point to your arm-none-eabi-g++ or gcc as appropriate.
  • SIZE_COMMAND and OBJCOPY_COMMAND to point to arm-none-eabi-size and objcopy (as appropriate).Git Sources in CMakeLists.txt

If you're not building for Nordic or Bluetooth Smart, then these libraries may not apply to you at all. Please update the following as needed:

# define some more paths to projects we depend on
set (MBED_SRC_PATH     ${BLE_HEART_RATE_SOURCE_DIR}/../../mbed-src/libraries/mbed)
set (BLE_API_SRC_PATH  ${BLE_HEART_RATE_SOURCE_DIR}/../../BLE_API)
set (NRF51822_SRC_PATH ${BLE_HEART_RATE_SOURCE_DIR}/../../nRF51822)

The ``CMakeLists.txt`` file can be switched to using a different toolchain if you need; change the following to do that:

# Decide about the actual compilers to be used; uncomment one of the following.
set(TOOLCHAIN armgcc)
# set(TOOLCHAIN armcc)

Application Sources

Please also install the sources of your application under ``WORKSPACE_DIR`` (or any subfolder), and make sure to use one of the ``add_sources()`` directives to add your sources.

Building with CMake

CMake can drive a build to generate object files either alongside the sources or in any separate build workspace. The latter is preferable and easily accomplished: Create a ``Build`` folder under ``WORKSPACE_DIR``. Change the build directory to your new directory. Run CMake, passing the path to the top level ``CMakeLists.txt`` folder as a parameter. This looks like:

WORKSPACE_DIR$ mkdir Build
WORKSPACE_DIR$ cd Build
WORKSPACE_DIR$ cmake ..
    ...
    ... a lot of useful information emitted by CMake regarding build settings
    ...
WORKSPACE_DIR$ make

If everything goes well with 'make', you'll end up with an executable called ``combined.hex`` that is ready to be deployed on the Nordic target. Running make with the ``VERBOSE=1`` command line option will expose the details about the commands being executed.

05 Nov 2014

@rohit - here is another project https://github.com/mrquincle/bluenet which is working for a full offline gcc-arm build.

I have been in touch with them asking if they would be interested in an mbed based flow - looking at their build, could you comment on where to get started ?

According to the maintainer "However, to implement all functions using the signatures of mbed, say e.g. https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/hal/serial_api.h as referenced from http://developer.mbed.org/handbook/mbed-SDK-porting, is a lot of work."

06 Nov 2014

I updated all of the project and library files per @Rohit above. When I run "make" builds 100%, but get the following during the linking process:

F51822/TOOLCHAIN_GCC_ARM/startup_NRF51822.s.o

Linking CXX executable BLE_HEART_RATE.elf

/Users/rah/gcc-arm-none-eabi-4_8-2014q3/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/bin/ld: BFD (GNU Tools for ARM Embedded Processors) 2.23.2.20140731 assertion fail /Users/build/GCC-4-8-build/gcc-arm-none-eabi-4_8-2014q3-20140805/src/binutils/bfd/elf32-arm.c:12394

/Users/rah/gcc-arm-none-eabi-4_8-2014q3/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/bin/ld: warning: cannot find entry symbol arch_paths_first; defaulting to 0000000000016000

collect2: error: ld returned 1 exit status make[2]: * [BLE_HEART_RATE.elf] Error 1 make[1]: * [CMakeFiles/BLE_HEART_RATE.elf.dir/all] Error 2 make: * [all] Error 2

06 Nov 2014

run "make VERBOSE=1 | tee /tmp/output.log" and paste the output to pastebin.com and put the link here.

06 Nov 2014

Nice guide! I think the instructions for Github should use https rather than git@, since that will always work. The current instruction will depend on having set up SSH keys on Github, which may not be the case for everyone.

Is there any chance the BLE_API and nRF51822 libraries will be moved to Github soon? (Getting a certificate error while attempting Mercurial clone. Adding the --insecure command fixes the problem.)

06 Nov 2014
06 Nov 2014

@Sandeep Here is an updated version of your project with Rohit's latest CheckLists.txt and libraries, that I did the build above with.

https://github.com/rahdev/mbed-nrf51-gcc-test

Should we use the same repository so everyone is working on a similar base? I only created my own repository because I tried to push to your original repository but did not have access. @Rohit any ideas on how we should proceed with this?

I also think this could be beneficial for others as well if we had a single repository others could contribute to. Maybe with branches for different OS's (E.g. Ubuntu, MacOS, RaspberryPi, etc.) I am building on MacOSX Mavericks right now. Will build on MacOSX Yosemite next once I get this one working.

06 Nov 2014

Also, just a thought. I notice at Universities, they provide Virtual Machines for students to use so that everyone is working in the same environment(OS, etc.). Since I am on a Mac, I was thinking about using one of the Ubuntu virtual machines on my Mac with VirtualBox so that I could work in the same environment as Rohit. Would this work with embedded projects such as this?

06 Nov 2014

Trying to build here. How do you define BLE_HEART_RATE_SOURCE_DIR? Could surely figure it out or do something, but for at tutorial I think the best thing is to describe the setup you used, including these details, in order to let the user just follow the instructions.

By the way, I'm trying to run the the offline build with CMake on Windows. It seems to believe that I should use nmake and complains that cl cannot be found. Any advice on how to solve this problem?

06 Nov 2014

Rah Dev wrote:

Also, just a thought. I notice at Universities, they provide Virtual Machines for students to use so that everyone is working in the same environment(OS, etc.). Since I am on a Mac, I was thinking about using one of the Ubuntu virtual machines on my Mac with VirtualBox so that I could work in the same environment as Rohit. Would this work with embedded projects such as this?

yes - it should work. In fact, I have no idea how to build this on anything other than linux.

06 Nov 2014

you need to remove -Wl,-search_paths_first from your cmake files

06 Nov 2014

Not clear on exactly where to do this.

In the CMakeLists.txt file, this is the only thing I see related, but nothing related to -search_paths_first.

"${CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS} -Wl,gc-sections -Wl,wrap,main -Wl,-Map=${PROJECT_NAME}.map -mcpu=cortex-m0 -mthumb specs=nano.specs -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys")

Also, some of the files are automatically generated by CMake. Are you saying remove the -Wl entries from above line or is there something else?

Thanks

06 Nov 2014

Looks like Darwin (OSX) specific - https://github.com/Kitware/CMake/blob/master/Modules/Platform/Darwin.cmake

Dont have a Mac, sorry !

07 Nov 2014

@Eirik:

Quote:

Is there any chance the BLE_API and nRF51822 libraries will be moved to Github soon?

Yes, I'd like to move over to github and have a mirror at mbed.org. Working on it.

07 Nov 2014

@Raheem:

Does the build system at https://github.com/rahdev/mbed-nrf51-gcc-test work for you?

07 Nov 2014

@rohit - no that repo cannot be used. The janekm mirror for BLE_API is out of sync (especially the header files for HeartRateService.h, etc.). IMHO, this is after you synced to 0.2.0 of the BLE API some time back.

I'm using git-hg to add the ble-api mercurial repo as a submodule. Would you prefer to maintain them in hg ? then I'll update my repo accordingly (with git-hg instructions)

The easier thing, obviously would be to have a mirror of ble_api. This is the reason, I havent updated my repo with your updated code and pushed, because people cannot use it unless they are using the mercurial repos to pull the other code.

Let me know and I can update accordingly.

07 Nov 2014

@sandeep: I'd rather have a git mirror of the BLE API.

07 Nov 2014

sure - go ahead please. I was just answering your question on whether my repo will be suitable for building with your latest heartbeat-demo code. Please let me know when you have your mirrors for BLE_API and nRF51822 up and running. I can then update my code to be compatible with them.

07 Nov 2014

I'm about to clone BLE_API into a git repo maintained under ARMmbed.

07 Nov 2014
07 Nov 2014

@rohit, the nrf51822 code also needs to be updated, there is a header declaration error. Could you create that as well please, so I can add as a mirror.

http://pastebin.com/8EzgmNUj

07 Nov 2014

@sandeep, I don't see the build error you just posted. I believe the nRF51822 library is up to date. Could you please confirm?

07 Nov 2014

@rohit - your mercurial repository is indeed up to date. But I am unable to find a suficiently up-to-date git repository to add as a submodule. If you prefer that the nrf repo be always fetched from mercurial as a separate step, that is OK.. but I was thinking that it might as well be great to have you add a git mirror for the nRF51822 library (in any case, I dont think it is updated too often)

07 Nov 2014
08 Nov 2014

Rohit Grover wrote:

Does the build system at https://github.com/rahdev/mbed-nrf51-gcc-test work for you?

No, it did not work on MacOSX (I previously posted the errors and output). Per your request, I created a Ubuntu 14.04.1 virtual machine on MacOSX and am working on the build now. Will let you know status when done. When I pulled the rahdev repository to the Ubuntu VM, I noticed the BLE_API, nRF51822, and mbed-src directories were empty. I assume it is because they were pulled from the mercurial repository so git does not know about them. I will pull from the github mbedmicro repositories above.

08 Nov 2014

I get this error with my MacOSX Ubuntu 14.04.1 VM build. (This is using the latest github libraries and CMakeLists.txt above)

http://pastebin.com/cXugLZSV

08 Nov 2014

@rohit - SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS -T${MBED_SRC_PATH}/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/TARGET_MCU_NORDIC_16K/NRF51822.ld) is failing

There is no TARGET_MCU_NORDIC_16K.

I have pushed my repo anyway with the new submodules - http://github.com/sandys/mbed-nrf51-gcc-test/ - you will be able to reproduce it yourself

08 Nov 2014

@rohit - I brought in the earlier link path and the s110_nrf51822_7.1.0_softdevice.hex path to get a working build. I have pushed that to branch "build2" of same repo http://github.com/sandys/mbed-nrf51-gcc-test/

I'm not near my workbench, so dont have my hardware - so though it builds fine, I'm not able to comment whether it flashes correctly.

08 Nov 2014

@rah dev: you're missing standard header files on you system. Try to get a working compiler setup on your ubuntu VM. you might want to do: $ sudo apt-get install build-essential

08 Nov 2014

@sandeep ss: your mbed-src is dated 8-Aug. Please update.

there does exist a TOOLCHAIN_GCC_ARM/TARGET_MCU_NORDIC_16K:

https://github.com/mbedmicro/mbed/tree/master/libraries/mbed/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/TARGET_MCU_NORDIC_16K