howstuffworks

Today: set up your toolchain

Setting up Firmware Toolchain

Intro

The aconno firmware is highly configurable using the aconno Sensorics app.
Still, you might want to make some changes to it. For that, you will need the ARM toolchain (which contains the compiler), Nordic’s SDK (Software Development Kit), the aconno codebase, an editor (preferably an IDE or specialized code editor), and a SEGGER J-Link device or an aconno programmer (to transfer the code to your device).

We recommend following this tutorial carefully step by step in order to set up an environment that will enable you to edit, compile and flash aconno projects.

First things first: The Compiler

In order to translate the source code into a hex file (hex file is a special binary format that your microprocessor understands, zeros and ones), you need to use a special program – the compiler. More about compilers can be found here.

Here at aconno, we use the GNU GCC arm-none-eabi-gcc compiler for the cross-compiling process. Since it’s cross-compiling, you can use either Windows, macOS or Linux based operating systems.

On Windows:

The installation process on Windows is easy. First download the software package for your desired platform (in this case win32) here: Windows source, run the installer and set the PATH variables.

On Linux:

We know that Linux users love to use their package managers for convenient installations of software packages and libraries but that is unfortunately not the case here.
It is better to install the compiler the old fashioned way (manually) instead of using your preferred package manager because they more often than not contain outdated and buggy versions.

You can find a stable version of the compiler here.
And here is a detailed installation tutorial.

Basic installation steps are shown below:

Windows:

  1. Create a folder called “opt” in your user directory
  2. Extract downloaded compiler into that folder using your favorite archiver (we love 7-Zip)
  3. After doing that, you will want to add the toolchain directory to the system/user path so you can call it from the command line without having to type the full path to the executables. To do this just go to your Environmental Variables and add it to your PATH variable.
  4. To use the commands just close and reopen your command line.

Linux:

  1. Open the terminal
  2. Create the “opt” folder in your home directory if it’s missing
    $ mkdir ~/opt
  3. Extract downloaded compiler there
    $ tar xjf ~/Downloads/gcc-arm-none-eabi-version
  4. Fix the file permissions
    $ chmod -R -w gcc-arm-none-eabi-version
  5. After doing all that, you will want to add the toolchain directory to the system/user path so you can call it from the command line without having to type the full path to the executables. To do this you will want to add the following to your ~/.bashrc file.
    $ export PATH="$PATH:$HOME/opt/gcc-arm-none-eabi-VERSION/bin"
  6. To use the commands just close and reopen your terminal.


aconno codebase

The aconno codebase consists of many libraries developed by our programmers to support all the sensors used on our products. Other than these libraries you can also find finished firmware projects related to our hardware products. For example, in our codebase, you can find firmware source code for acnSENSA, acnRANGE, etc. aconno products are based on Nordic Semiconductors nRF528xx chips, thus we use their SDK (Software Development Kit) as a base for our projects. More info about it, its APIs and examples can be found here.

The Firmware of our products is also based on an RTOS (Real-Time Operating System) called freeRTOS, thus some modifications are needed official Nordic SDK to fit our requirements (don’t worry, we already did that). This modified SDK version is a part of our codebase too and the source code for it can be found here:

Source.

To make modifications to any of our projects, you need to have a copy of the source code of aconno’s version of Nordic SDK on the machine you are cross-compiling on. The location of the aconno SDK root directory is not arbitrary. The aconno SDK should be located in the same folder as the project you want to work on.

The following folder tree demonstrates that scenario:

.
├── acnProject
│ ├── Source
│ │ └── main.cpp
│ ├── aconnoBLE
│ └── aconnoConfig
├── nRF5_SDK_15.2.0
│ └── Components

Therefore, to prepare a modified version of the Nordic SDK for use with aconno codebase:
  1. Clone https://git.simvelop.de/aconnoProducts/aconnoLibs/nRF5_SDK_15.2.0.git  (default to the same folder, where the projects will be loaded to)
  2. Set nRF5_SDK_”15.2.0/components/toolchain/gcc/MakeFile.posix” settings, it contains the path and prefix of the gcc arm compiler
The base project used to start development is acnBEACON. It usually only advertises a few beacon signals, but with a few modifications it can be changed into any project.

The build system, it’s all about make

To translate the C/C++ source code into a hex file for your microprocessor, you will need to compile it. You could do it manually file by file if you had a lot of time, but please do not do that. Let the machine do the boring job for you – use one of the build system programs. We use and recommend the ‘make’ program. You can find a good tutorial about it here. You basically feed it a set of instructions on what to compile, where to find it, and where to put it, like a cooking recipe for nerds.

To build aconno project:

  1. Install nRF command line tools (also include J-link software in Windows installer)
  2. Install J-Link Software and Documentation Pack
  3. In terminal, navigate to your projects directory
  4. Run the following command to start a make script
    $ make all

The result is stored in the acnProject/build/_build folder. The command will compile all the source files and make a single hex file from them. It will then search for the SoftDevice hex file (it contains the code that allows you to use the the BLE part of the nRF chip) and combine it with your application’s hex file into a single merged hex file. Next, the script will try to flash that hex file. If a SEGGER J-Link device is connected to the PC and the module, and ONE power supply is active (you can either use the SEGGER J-Link power supply OR the battery, NEVER both at the same time) it will connect to the device, erase its memory, and flash the merged hex file.
After that is done, you can start the JLinkRTTClient program to see the log output of the device.

All open-sourced aconno projects and libraries can be found here.


Change the code, use an Editor

Now that you know how to compile the source code into a usable hex you can compile yourself some firmware. It would be even cooler if we changed some of the code to fit our requirements.
To change the source we need some sort of text editor, so you could even do it with VI but then you would need to know how to exit it (we think its :wq but don’t quote us on that).
But today we have tools much more powerful than simple text editors called IDEs.

An IDE brings you the comfort of having a debugger, a C++ checker, automated build systems, automated flashing, faster code browsing, an overview of function usage and tons of other useful functions. 

We recommend the use of these IDEs: Visual Studio Code (free and light), CLion (a C++ monster, the best you can get), Keil (old industry standard, we do not really recommend this, it’s just listed as everybody uses it without knowing why) and Embedded Studio by Segger.

Next, we will showcase the installation and configuration of the Visual Studio Code editor. If you would like to use another IDE you will need to set it up yourself, and with all the documentation available on Google, it shouldn’t be too hard. 

Visual Studio Code editor

At aconno, we use the VS Code editor. One might ask why do we not use the well known Keil editor… Well, VSCode is equipped with many advanced features such as code completion, static code analysis, a dark theme (one of the most important features if you ask our developers) and tons of other free add-ons.

Here are the steps you need to follow to install the editor and get it ready to write some awesome code for aconno devices.

  1. Install Visual Studio Code
  2. Install Visual Studio Code Cortex-Debug from marus25 via Extensions
  3. Clone the FreeRTOS project
  4. Set SDK_ROOT in {projectDir}/build/Makefile to where you cloned nRF5_SDK_15.2.0 (should already be the proper relative path)
  5. Get nRF52 SoftDevice
  6. Within projects .vscode folder create tasks.json and paste the code from below
  7. Within projects .vscode folder create launch.json and paste and paste the code from below
  8. Within projects .vscode folder modify existing c_cpp_properties.json to look like the example below, then add in correct paths for your system
  9. Start JLinkRTTClient for serial output, it will automatically connect with the debugger
  10. Press F5 in Visual Studio Code for debugging

tasks.json

{
   // See https://go.microsoft.com/fwlink/?LinkId=733558
   // for the documentation about the tasks.json format
   "version": "2.0.0",
   "tasks": [
       {
           "label": "all",
           "type": "shell",
           "linux": {
               "command": "make nrf52832_debug upload"
           },
       }
   ]
}

launch.json

{
   // Use IntelliSense to learn about possible attributes
   // Hover to view descriptions of existing attributes.
   // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
   "version": "0.2.0",
   "configurations": [
       {
           "name": "Cortex Debug",
           "cwd": "${workspaceRoot}",
           "linux": {
               "executable": "./build/_build/nrf52832_xxaa.out"
           },
           "request": "launch",
           "type": "cortex-debug",
           "servertype": "jlink",
           "device": "nRF52832_xxAA",
           "interface": "swd",
           "ipAddress": null,
           "serialNumber": null,
           "preLaunchTask": "all",
       }
   ]
}

c_cpp_properties.json (pay attention to compiler path!)

{
    "version":4,
    "configurations":[
        {
            "name":"Linux",
            "includePath":[
                "${workspaceFolder}/**",
                "<nrf sdk path>",
                "<freeRTOS path>",
                "/usr/local/include",
                "/usr/include"
            ],
            "defines":[
            ],
            "compilerPath":"wherever your embedded compiler is",
            "cStandard":"c11",
            "cppStandard":"c++2a",
            "intelliSenseMode":"clang-x64"
        }
    ]
}