Skip to content

TI Sensortag cc2650: BLE Device Monitor OAD (Over-The-Air-Download) Fail : Solving Method

To perform OAD on TI sensortag, TI software ‘BLE Device Monitor’ can be use. However, the OAD is not stable and many time the process will fail during data transfer.

With trial and error, a few changes on BLE Device Monitor settings allow me to create a stable OAD update. Below are the changes require to enable a stable OAD update.

So far has been testing with TI software stack version: and working well.


The default settings in Program tab: Blk/conn(4) and 20ms



Change to above settings to create stable OAD


Coding Standard – 2.0

This is subsequent article from my previous one here.

A Switch Case Must Have A Default Case

Make it as a habit to include a default case whenever you create a switch case. This will use as a checking point in expecting the unexpected and force us to think of a recovery method. Example, do not do this:

    case 0:
    case 1:

Do this

    case 0:
    case 1:

While(1) Always Wrote With A Break

When we are waiting for hardware to complete UART transmission or waiting for ADC result, we usually would write in such a way:

    if(SFR_Flag == 1)

Instead of writing as below, I usually avoid creating infinite loop and create an escape case as example below:

unsigned char ReadADC(unsigned char *result)
    unsigned char count=0;
        if(SFR_Flag == 1)
        if(count >= MAX_WAIT)
            return 1;
    //perform adc read
    return 0;

Type Checking: Getting Compiler To Do The Validation

When calling function, we need to passing parameter in/out. We can use a common type such at unsigned char/unsigned int to represent our parameter. But there is a better way in doing this. A typical method of passing parameter as below:

#define MAX_ACTION_KEY (2)
unsigned char Function1(unsigned char param1)
    if(param1 >= MAX_ACTION_KEY)
        return 1;
    return 0;

We can do the following instead:

typedef enum{

typedef enum{

EnumReturnCode Function1(EnumActionKey param1)
    if(param1 >= MAX_ACTION_KEY)
        return RET_INVALID_PARAM_IN;
    return RET_OK;

The advantages of using this method:

  • compiler will perform stict type checking and report warning/error when invalid type is use. We can utilise this features to ensure we always pass the valid parameter into Function1
  • Is more elaborate to whoever reading the source code

Why We Need Hardware Abstraction Layer (HAL)?

In embedded system development, one of the tedious work is to control microcontroller(MCU) hardware through special function register(SFR). Microcontroller hardware such as timer/interrupt/GPIO etc is control through SFR. Applications software that implement business logic will then ride on top of the hardware. From applications perspective, there are 2 way of accesssing the hardware:

  • directly access SFR from application or
  • through HAL(Harwdare Abstraction Layer) API.

HAL-API is a separation layer between application and hardware, any MCU hardware control has to be done by calling this HAL-API layer.

Among the advantages of using HAL-API as lists below:

  • Enforce a design that have clear separation between HAL and application
  • Ease code maintainence. Hardware modification will only inolve code change in HAL. And testing is only require to be perform on HAL layer, without application
  • Ease future migration to a new microcontroller(by re-implementing hardware driver, with application layer unchange)
  • Ease future changes if expansion is require to support external hardware
  • Enable engineers to think and work in modular design


Coding Standard – 1.0

Throughout my career life as embedded software/firmware engineer, I always study and ‘blend’ my changes by following existing style. Along the way I pick up way of coding that has become part of a norm. Maybe it has become too common that I think everyone would practise the same, and apparently I am wrong on this. I have come across come code that is seems should not be written by any engineer. This encourage me to write on this article, listing down coding method. Hopefully someone will find it useful and avoiding the same pitfall in future.

Never Use Magic Number

All the number should be declare by defining a symbol, and use the symbol in the source code. It is prohibited to use number in the source code directly.

Example: Replace the following



#define NUM_ITEMS    (5)

The rasionale behind this is for future code maintenance. E.g. increasing the items from 5 to 6 just require a line change. While for the first code, engineer have to search all the source code and change each of it from 5 to 6.

One Define At Single Place

For one project, when defining a symbol, always ensure there is only a single define located at a single file. Never, never define the same symbol in multiple files.

Example: File A

#define NUM_ITEMS    (5)

File B, same define again

#define NUM_ITEMS    (5)

Instead, create a project scope header file, e.g. global_define.h, and put the NUM_ITEMS define in it.

File A, File B, just include the header file

#include "global_define.h"

Do Not Create Multiple Define That Represent Same Meaning

Defining the same item with different name is a bad practise. Example, defining a size of buffer:

#define MAX_BUFFER_SIZE       (10)
#define MAX_BUFF_SIZE         (10)
#define MAX_CAR               (10) //buffer is use to represent car

Abusing define in such a way will create un-maintainable source code. It would be a nightmare to make changes of these code, like increasing the buffer size from 10 to 11.


The key points is always writing maintainable code. Always ask yourself what if in future things need expands, is my code good enough to cater that?

Eclipse IDE:A Workaround To Include a Link Folder

On my development host, I have an pretty old Eclipse IDE, version 3.7.2.

I am trying to import a folder as ‘link folder’ into a project. This target folder will be include in multiple projects uner Eclipse.  A link folder is better suit so that any modification on target folder(files) is only require to be perform once and it will reflect to all relevant projects.

A typical link folder would shown with a small arrow icon as shown below. Folder name Database, define, device would be the link folder. While Debug is not a link folder


If we perform a right click on ‘define’ folder and select properties, resources, we would see the following:


Above shown it is the a link folder and the location is respective with a symbol of PROJECT_LOC. Use of PROJECT_LOC would enable create a project that is independant of project location in file system. When we want to move the project to another location in the file system, we just need to change this PROJECT_LOC to resolve to the correct path.

In attempt to create a link folder, I use ‘New‘ -> ‘Folder‘ -> ‘Advanced‘ -> ‘Link to alternate location (Linked Folder)‘ -> ‘PROJECT_LOC/../define‘.

This give an error of : “Internal error: Must specify a URI scheme:define

I ended up create a workaround as below:

  1. Create a link folder with fix path
    1. New‘ -> ‘Folder‘ -> ‘Advanced‘ -> ‘Link to alternate location (Linked Folder)‘ -> ‘Browse‘ -> Select the target folder
  2. Change the link folder from dependant path to independant path
    1. Right click on link folder -> ‘Properties‘ -> ‘Resources‘ -> ‘Edit‘ -> Replace with ‘PROJECT_LOC/../define’

With above sequence, Eclipse will be able to find the headers file inside ‘define’ folder


Browsing Source Code Efficiently in Vim: ctags

I have been using vim for my development for several years. All these while I am settle with my F4 custom function, which will perform recursive search of the source code for a particular symbol, as shown below:

map <F4> :execute “vimgrep /” . expand(“<cword>”) . “/j **/*.c **/*.C **/*.h **/*.H” <Bar> cw<CR>

It works well and I have never further explore for better tools. Until recently there is a need for search of large source code. That’s where I bump into ctags. Ctags will preindex all the symbol. When using it to ‘jump’ to function definition is instant. Founding about this is like one of those moment I told myself – I should have know about this long time ago.

Quick setup of ctags

  1. Package install in ubuntu
    1. apt-get install exuberant-ctags
  2. ‘cd’ to source folder and perform indexing. A file name ‘tags’ will be generated end of this command
    1. ctags -R *
  3. Open any source file, for example
    1. vi ./Source/main.c
  4. ctags shortcut key:
    1. ctrl + ]  : To go to function definition, move the cursor to the function
    2. ctrl + t  : go back to location before performing ‘ctrl+]’

I am sure there have more command, but for now, the above 2 is good enough for me.

Building TI SensorTag Project With CCS Linux Under Ubuntu


*During the setup, sometimes when the errors message appear to be weird, a rebuild of project may help to remove such error.

Installation setup

  1. The Ubuntu using is 12.04.
  2. CCS installed path
    1. CCS installed path ~/program/ti-ccs/ccsv6
  3. BLE Stack: 2.01
    1. BLE stack installed path: ~/program/ti-ccs/ti/simplelink/ble_cc26xx_2_01_00_44423
  4. TI-RTOS
    1. TI RTOS installed path: ~/program/ti-ccs/tirtos_simplelink_2_13_00_06
    2. XDC tools installed path: ~/program/ti-ccs/xdctools_3_31_00_24_core

Import Project

  1. Launch CCS
  2. Right Click on Project Explorer empty area, then ‘Import’ –> ‘CCS Project’
  3. Browse to path : program/ti-ccs/ti/simplelink/ble_cc26xx_2_01_00_44423/Projects/ble/SensorTag/CC26xx/CCS
    1. Under ‘Discovered projects’, tick both ‘SensorTag’ and ‘SensorTagStack’
    2. Click ‘Finish’ to import project

Building SensorTag

Build Folder Path Modification

  1. Right click on ‘SensorTag’, select ‘Properties’
  2. Click on ‘Resource’ –> ‘Linked Resources’, change path below, you need to modify below absolute path according to your installation location:
    1. CC26XXWARE : /home/cheng/program/ti-ccs/tirtos_simplelink_2_13_00_06/products/cc26xxware_2_21_01_15600
    2. TI_RTOS_DRIVERS_BASE : /home/cheng/program/ti-ccs/tirtos_simplelink_2_13_00_06/packages
  3. Build and there should be some warning about as below:
    1. Invalid project path: Include path not foundSensorTagBuildInvalidPath

Invalid Project Path

  1. All above errors is due to name case is not match, we can perform one of the below method
    1. folder rename
    2. create link file (I use this in below)
  2. Browse to respective folder and start changing creating the symbolic link
    1. ln -s Include include
    2. ln -s cc26xxST CC26xxST
    3. ln -s CC26xx cc26xx
    4. ln -s Devices devices
    5. ln -s interfaces interfaces
  3. In menu bar ‘Project’ –> ‘Clean’
  4. In menu bar ‘Project’ –> ‘Rebuild All’
  5. Another error statingas as shown below
    1. cannot open source file “sensortag.h”
    2. SensorTagFileOpenFail
  6. To solve this:
    1. Browse to: ~/program/ti-ccs/ti/simplelink/ble_cc26xx_2_01_00_44423/Projects/ble/SensorTag/CC26xx/Source/Application
    2. ln -s sensorTag.h sensortag.h
    3. ln -s sensorTag.h SensorTag.h
  7. More error on naming
    1. Browse to: ~/program/ti-ccs/ti/simplelink/ble_cc26xx_2_01_00_44423/Projects/ble/SensorTag/CC26xx/Source/Application
    2. ln -s SensorTag_ConnCtrl.h sensortag_connctrl.h
    3. ln -s SensorTag_IO.h sensorTag_IO.h

Building SensorTagStack

Build Folder Path Modification

  1. Right click on ‘SensorTag’, select ‘Properties’
  2. Click on ‘Resource’ –> ‘Linked Resources’, change path below, you need to modify below absolute path according to your installation location:
    1. CC26XXWARE : /home/cheng/program/ti-ccs/tirtos_simplelink_2_13_00_06/products/cc26xxware_2_21_01_15600
    2. TI_RTOS_DRIVERS_BASE : /home/cheng/program/ti-ccs/tirtos_simplelink_2_13_00_06/packages
  3. After rebuild, there will be errors on:
    1. ble/SensorTag/CC26xx/CCS/SensorTagStack/../../IAR/Stack/CC2650/../../../../../../tools/LibSearch/libSearch.exe: Command not found

Wine Setup (running LibSearch.exe and Boundary.exe)

  1. Below Window executables is being use during build process, in Linux, we have to use wine to run these executables
    1. libSearch.exe
    2. Boundary.exe
  2. Refer to internet on wine installation as well as wine-mono
  3. Preparation
    1. Ensure LibSearch.exe is at: ~/program/ti-ccs/ti/simplelink/ble_cc26xx_2_01_00_44423/Projects/tools/LibSearch
    2. Ensure Boundary.exe is at: ~/program/ti-ccs/ti/simplelink/ble_cc26xx_2_01_00_44423/Projects/tools/Boundary
  4. Right click Project ‘SensorTagStack’ –> ‘Properties’
    1. ‘Build’ –> ‘Steps’
    2. Change Pre-build steps to:
      1. wine “${ORG_PROJ_DIR}/../../../../../../tools/LibSearch/libSearch.exe” ${ORG_PROJ_DIR}/buildConfig.opt ${ORG_PROJ_DIR}/../../../../../../tools/LibSearch/parameters.xml ${ORG_PROJ_DIR}/../../../../../Libraries/CC26xx/IAR/ ${ORG_PROJ_DIR}/../../Lib/CC2650Stack.a FlashROM
    3. Change Post-build steps to:
      1. “${CG_TOOL_HEX}” -order MS –memwidth=8 –romwidth=8 –intel -o “${ProjName}.hex” “${ProjName}.out”
        mono “${ORG_PROJ_DIR}/../../../../../../tools/Boundary/Boundary.exe” -prj “ccs” -chip “CC2640” -lcf “${ORG_PROJ_DIR}/../../../../../common/cc26xx/CCS/cc26xx_ble_stack.cmd” -map “${PROJECT_LOC}/${ConfigName}/${ProjName}.map” -xml “${ORG_PROJ_DIR}/../../../../../../tools/Boundary/BoundaryConfig.xml” -cc “${ORG_PROJ_DIR}/../../../CCS/Config/ccsCompilerDefines.bcfg” -lnk “${ORG_PROJ_DIR}/../../../CCS/Config/ccsLinkerDefines.cmd”
  5. ‘Project’ –> ‘Build Project’
  6. Errors on:
    1. cannot open source file
    2. SensorTagOpenFileFail2
    3. After perform a ‘Project clean’ and project rebuild everything works