Over a million developers have joined DZone.

Building the NXP BLE Stack With Open Source GNU and Eclipse Tools

DZone's Guide to

Building the NXP BLE Stack With Open Source GNU and Eclipse Tools

NXP has made some great tools, but if you want to get the BLE Stack going, it requires a few closed-source libraries. Let's open it up with GNU Tools and Eclipse.

· IoT Zone
Free Resource

One of the biggest roadblocks (aside from closed source) in using the BLE (Bluetooth Low Energy) stack from NXP is that it requires expensive tools to compile and build the stack. The good news is that I now have the NXP BLE stack for the Mikroelektronika Hexiwear ported to Eclipse and GNU gcc build tools for ARM.

NXP BLE Stack in Eclipse

NXP BLE stack in Eclipse

The BLE stack, sources, and examples provided by NXP need the IAR Embedded Workbench to compile and build it. That stack is running on the NXP Kinetis KW40 SoC, which is responsible for the touch sensing and the BLE communication on the Hexiwear (see Hexiwear: Teardown of the Hackable ‘Do-Anything’ Device).

Nothing wrong with the IAR compiler (that’s a very good one!), but a license for EWARM (IAR Embedded Workbench for ARM) cost several thousand US dollars, and the baseline edition or even a license with a university discount is outside of my budget. There is the IAR free Kickstart edition, but with the code size limit, it is not possible to build the BLE stack

On the other hand, it is strange that NXP does not provide the BLE stack in the first place using their own tools: The NXP Kinetis Design Studio is based on open-source Eclipse and includes free-of-charge and unlimited GNU (gcc, gdb) tools. Why not using this instead?

The Hexiwear is using the NXP KW40 device. For the newer NXP KW41, there is an updated Connectivity Software V1.0.2, which now includes projects for Eclipse based Kinetis Design Studio.

GNU, GCC, GDB, and NXP Kinetis Design Studio

I thought that it should be possible to build the BLE stack with the free and unlimited GNU tools under Eclipse instead. For this, I’m using NXP Kinetis Design Studio V3.2.0. At the time of writing this article, things are now working on a FRDM-KW40Z board, which I’m using as test bench:

FRDM-KW40Z running Hexiwear BLE Stack

FRDM-KW40Z running Hexiwear BLE Stack

And the board is reporting as a Hexiwear BLE device:

Hexiwear recognized in LightBlue

Hexiwear recognized in LightBlue

In the next sections, I'll describe the most important porting steps. The current project and sources are available on GitHub.

In case you want to do something similar, here are the basic steps:

  1. Have a look at the following community thread, which details the steps to build the project in IAR: https://community.nxp.com/message/864451
  2. Create a new (basically empty) project in Eclipse and verify that you can debug it.
  3. Copy the sources into the project.
  4. Adjust compiler include paths.
  5. Specify preprocessor defines and macros, including any ‘include always’ files. Have a look at the original project and compiler settings.
  6. Add any necessary libraries.
  7. Build the project and fix any incompatibilities (e.g. rename ‘asm()’ to the standard ‘__asm’ syntax.
  8. Extend the linker file as needed, have a look at the original linker file.

Directory Structure

The original project uses an old SDK V1.3 with an outdated FreeRTOS version. I have simplified the very complex project/directory structure to a more flat one in Eclipse, which is much easier to handle:

IAR Project

IAR Project

NXP BLE Stack in Eclipse

NXP BLE Stack in Eclipse

The following shows the include settings:


The includes

The ‘app_preinclude.h’ is a header file that has global settings and is included for each compilation unit.


There are three libraries (BLE host, BLE Controller, and a crypto one) for which there are no sources available (closed source). All three libraries need to be linked with the project and are copied from the IAR project:



The GNU linker expects libraries to be named lib+name+.a (see Creating and using Libraries with ARM gcc and Eclipse), so the original libraries have been renamed to match the naming scheme:

Archive Libraries in Project

Archive libraries in a project

The IAR libraries are built with the wrong wide char (wchar_t) settings, so it will create many warnings at link time, which can be ignored:

c:/nxp/kds_3.2.0/toolchain/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/bin/ld.exe: warning: ../Sources/lib\libble_controller_lib.a(bt_le_bluetooth.o) uses 2-byte wchar_t yet the output is to use 4-byte wchar_t; use of wchar_t values across objects may fail

The IAR project used a canned (library) version of the SDK. For better portability and to be able to debug the SDK sources, I have added the SDK sources (and not the library for it) to the project.

The IAR libraries are referring several aeabi functions that might not be present in the GNU libraries. The following wrapper functions were added to main.c to cover for them:

/* wrappers needed as used in the IAR libraries */
void __aeabi_memset(void *dest, size_t n, int c) { memset(dest, c, n); }
void __aeabi_memset4(void *dest, size_t n, int c) { memset(dest, c, n); }
void __aeabi_memclr(void *dest, size_t n) { memset(dest, n, 0); }
void __aeabi_memclr4(void *dest, size_t n) { memset(dest, n, 0); }
void __aeabi_memcpy(void *to, void *from, size_t size) { memcpy(to, from, size); }

Linker File

The linker file must be changed to use the vector table in RAM:


Include symbols for the RAM vector table:

__RAM_VECTOR_TABLE_SIZE_BYTES = (__interrupts_ram_end__ - __interrupts_ram_start__);

The section .BootloaderFlags needs to be added to the end of the code/text section:

 .text :
    . = ALIGN(4);
    *(.text)                 /* .text sections (code) */
    *(.text*)                /* .text* sections (code) */
    *(.rodata)               /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)              /* .rodata* sections (constants, strings, etc.) */
    *(.glue_7)               /* glue arm to thumb code */
    *(.glue_7t)              /* glue thumb to arm code */
    KEEP (*(.init))
    KEEP (*(.fini))
    . = ALIGN(4);


  } > m_text

A special section for non-volatile configuration data needs to be added at the end of the text/code section:

  .nvm :
     . = ALIGN(8);
    . += 1024;
    . += 1024;
     . = ALIGN(8);
  } > m_text

Because initially the code and RAM did not fit the memory of the device with compiler optimizations turned off, I have added a few defines in app_preinclude.h to turn on/off functionality:

#define CONFIG_HAS_OTAP_SERVICE     0 /* over-the-air-application-programming service */
#define CONFIG_HAS_HEALTH_SERVICE   1 /* health service */
#define CONFIG_HAS_TSI              0 /* touch sensing interface */


I can now use free-of-charge and unlimited Eclipse and GNU tools to build the NXP BLE stack. Things have not been tested in all details, but I get advertisement packets and I can step through the code.

Things are not optimized yet. Because the BLE stack is using the Kinetis SDK V1.3, it adds many unnecessary layers and is using the (not needed) OS adaption (OSA) layer to FreeRTOS. If I can find the time, I will update the currently used V8.2.0 FreeRTOS in the stack to the more recent V9.0.0 FreeRTOS.

Other vendors make it easier and provide their stacks for GNU and Eclipse out of the box. I hope that, eventually, NXP will provide source code for more if not all parts of the BLE stack — because using archive libraries like this is not very development-friendly and can lead to all kinds of compatibility issues. For now, things seem to be working which is a good first step.

Happy stacking!


bluetooth low energy ,nxp kinetis ,iot ,tutorial ,ble stack

Published at DZone with permission of Erich Styger, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.


Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.


{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}