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

One of the biggest road blocks (beside of closed source) 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 have now 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

Only IAR?

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 thousands of US$, 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 side, 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 the 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 Hexiwear BLE device:

Hexiwear recognized in LightBlue

Hexiwear recognized in LightBlue

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

Steps

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, 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

Includes

The following shows the include settings:

includes

includes

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

Libraries

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:

libraries

libraries

The GNU linker expects libraries named as 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 Project

The IAR libraries are built with 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 a better portability and be able to debug the SDK sources I have added the SDK sources (and not the library for it) to the project.

aeabi Functions

The IAR libraries are referring several aeabi functions which might not be present in the GNU libraries. The following wrapper functions added to main.c are covering 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:

M_VECTOR_RAM_SIZE = 0x0100;

Include symbols for the RAM vector table:

__VECTOR_RAM = __VECTOR_RAM__;
__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 */
    *(.eh_frame)
    KEEP (*(.init))
    KEEP (*(.fini))
    . = ALIGN(4);
    
    *(.BootloaderFlags)
    
  } > 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);
    FREESCALE_PROD_DATA_BASE_ADDR = .;
    . += 1024;
    NV_STORAGE_START_ADDRESS = .;
    . += 1024;
     . = ALIGN(8);
    NV_STORAGE_END_ADDRESS = .;
  } > m_text

Configurations

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 */

Summary

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 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 kind of compatibility issues. For now, things seem to be working which is a good first step :-).

Happy Stacking 🙂

Links

16 thoughts on “Building the NXP BLE Stack with Open Source GNU and Eclipse Tools

  1. Remember I told you I bought 2 KITs from NXP? you are God-sent my friend. And… that wasn’t long… NICE!!! The holidays aren’t even over yet and there is light at the end of the tunnel. I guess people have a lot of time on their hands :-). Thanks for posting.

    Like

    • I got the FRDM-KW1Z and FRDM-KW24D512 KITs, will be working on this with some students next few weeks as the semester has started. Hoping to report good progress.

      Like

  2. Hey there!

    Great Work! I`ve been trying to modify the KW4Z firmware on the Hexiwear and implement a 802.15.4 stack, but as the project was too big I wasnt able to do it with the free IAR version. In the following weeks I will try your aproach and see if it works.
    Could you explain the steps in a little more depht?

    Thank you very much in advance.

    Like

      • He Erich,

        Yeh, misspelt, meant KW40Z.
        Everything is perfect, dont worry.
        Ive managed to build the code in KDS and now im going to try to upload it to Hexiwear.
        Lets see how it goes!

        Thank you very much

        Jaime

        Like

      • Hello again!

        I`ve build the code succesfully but now Im having some trouble uploading it to the KW40Z on the Hexiwear. I set the switches on the docking station to the aproppiate configuration for flashing this MCU (3-5 up), set up a new Debug Configuration, and when I go to debug it I get the following errors:

        Traceback (most recent call last):
        File “pyOCD\tools\gdb_server.py”, line 259, in run
        File “pyOCD\board\mbed_board.py”, line 263, in chooseBoard
        File “pyOCD\board\board.py”, line 50, in init
        File “pyOCD\target\target_kinetis.py”, line 58, in init
        File “pyOCD\target\coresight_target.py”, line 76, in init
        File “pyOCD\coresight\dap.py”, line 137, in power_up_debug
        File “pyOCD\coresight\dap.py”, line 133, in write_reg
        File “pyOCD\coresight\dap.py”, line 225, in writeDP
        File “pyOCD\pyDAPAccess\dap_access_usb.py”, line 521, in write_reg
        File “pyOCD\pyDAPAccess\dap_access_usb.py”, line 726, in _write
        File “pyOCD\pyDAPAccess\dap_access_usb.py”, line 473, in flush
        File “pyOCD\pyDAPAccess\dap_access_usb.py”, line 624, in _read_packet
        File “pyOCD\pyDAPAccess\dap_access_usb.py”, line 329, in decode_data
        File “pyOCD\pyDAPAccess\dap_access_usb.py”, line 275, in _decode_transfer_data
        TransferError

        Any idea on how to fix this?

        Thanks for the help, very appreciated

        Jaime

        Like

        • Hi Jaime,
          I think the problem is with pyOCD. I was never able to use the pyOCD debug connection. I’m using P&E Multilink and Segger J-Link to debug the Hexiwear on the docking station.
          Erich

          Like

      • Hi Erich,

        It seems pyOCD doesnt have the KW40Z on its supported targets, thats why it wasnt working.
        Im trying to see if there is any way of modyfing the KW40Z firmware without having to purchase any additional hardware. Do you know if theres any way?
        If not could you give me guidelines on how to use the P&E Multilink and Segger J-Link to debug with the docking station please? Ive never used this kind of tools and Im a bit lost.

        Thank you very much

        Jaime

        Like

        • Hi Jaime,
          you could use a FRDM board with CMSIS-DAP to debug the board. But the problem won’t go away because the CMSIS-DAP (or even DAPLink) firmware is not to the level of commercial debug firmware like in a P&E Multilink or Segger J-Link. I recommend that you invest money into a commercial probe. I’m not sure about P&E, but Segger has an EDU version of their probe (around $50-60) which can be used for non-commercial/hobby/educational projects. If working in a company or doing commercial products, then not be able to afford $100 for a probe sounds not reasonable to me. With KDS you can use P&E/Segger probes out of the box for normal debugging. On the Hexiwear docking station you have to adjust the DIP switches, see https://mcuoneclipse.com/2016/12/07/flashing-and-restoring-the-hexiwear-firmware/.
          I hope this helps,
          Erich

          Like

      • Hi Erich, thanks again for your help.

        You mean using a FRDM Board with the KW40Z to program the Hexiwear like you explain here?

        Using the Freedom Board as SWD Programmer

        Im not so interested in bebugging as in flashing the code to Hexiwear´s KW40Z. Been trying to look for a way to flash it using the serial port and havent found one yet.
        If neither of these work Ill look into getting some commercial probes, but we wanted to avoid this and give users a less expensive way to program the device.

        Thanks again

        Jaime

        Like

      • Hi Erich,

        Thank you so much for your help man, you’re great.

        Your right, OpenOCD as pyOCD doesn’t support the KW40Z, a shame.

        My work is entirely educational, I wanted to do a project with Hexiwear for my universities Final Degree Assignment and use the 802.15.4 capabilities it has for gathering information from various sensors we have. For this I have to be able to change the KW40Z firmware. I tought It would be as easy as it was for the MK64, but Its been giving me a headache for the past two weeks.

        They just said on the Hexiwear forums that they’re going to upload some instructions on how to set up the KW40Z project with IAR so maybe I will be able to do it that way.
        If not I think I will grab a Segger EDU like you suggested.

        Thank you again for your help and advice

        Jaime

        Like

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.