Using a “Run To Completion Task” model in embedded programming

This is about the architecture or high-level structure of an embedded app.  You don’t always need an RTOS, or you can implement a very simple one.

References

I read these sources prior to this post.   This post is largely a hasty summary of these links.

Super Simple Tasker

Real Time For the Masses

Fearless Concurrency in your microcontroller

Context

Embedded programming is event/interrupt driven.

Embedded programming is multiprocessing:  devices are processors too.

Some chips e.g. Nordic NRF52 chips have event and task notions implemented in hardware.

Most chips have a NVIC (Nested, Vectored Interrupt Controller).

Traditional advice about ISR’s:

Interrupt service routines (ISR) should be kept short.   The references above dispute that dictum.

Traditional, typical software architecture

Your ISR’s are short and set flags (events).  Your main loop is an event loop:

main() 
  while(true)
    if (eventFlagA)
        taskA()
    if (eventFlagB)
        taskB()
    wait for event (WEV or WFI instructions on ARM)

Tasks are just functions.  They run in the main context (not in an ISR) where interrupts are enabled but no interrupt is being serviced.  Tasks are interruptible by any interrupt.  Interrupts come from concurrent device operations that your software Tasks start.  (And some chips call device operations “tasks”, that eventually generate “events” that trigger interrupts.)

Another example might be:

main()
   while true
      taskA()
      sleep(duration)
      taskB()
      sleep(duration)

sleep(duration)
   start Alarm
   while()
      wait for event
      if event is Alarm event
          return
      else
          handle other event, set flags, etc.

Again, your code dispatches ( an if sequence) on events.  You might need several sleep functions, each anticipating a different set of possible events.

Run to completion task architecture

main()
   initialize things
   schedule(taskA)
   while (true)
       wait for Event

taskA()
    do something useful
    schedule(taskB)

taskB()
   do something useful
   start a task on a device  (to generate event for taskC)

taskC()
   service device event
   schedule(taskA)
   
etc....

Here each task runs to completion.  That means it doesn’t sleep.  It does not mean that it can’t be interrupted by a higher priority task.  Each task is-a  ISR for an event/interrupt.

Here, it is important that each task runs to completion and insures that some other task is scheduled or that some device task is running and will generate an event/interrupt that will in turn schedule another task.  I.E. you must insure that you don’t sleep forever.

As discussed above for SST, the NVIC (Nested, Vectored Interrupt Controller) is the dispatcher.  Your code does not dispatch, the HW does (or an “OS” scheduler.)

You can schedule many tasks to run at the same priority at the same time in the future.  When they run, they execute pseudo-concurrently.  One will run, to completion, when the interrupt triggers, from its scheduled alarm.  The interrupt from the other task’s scheduled alarm will trigger at the same time, but since it is at the same priority, will be pended and be serviced only when the first task completes.

Difference between this and SST

SST described above has a broader notion of Task:

  • implemented in an “OS” i.e. by a Scheduler
  • has-a priority
  • that other Tasks can schedule, i.e. put in a list of ready tasks
  • that does not run on events, only when the Scheduler jumps to it.

But the “OS” scheduler can often be simpler: just set an Alarm on a HW timer, arranging that the task runs in response the the alarm, as the ISR of the HW timer.  You can use such a simpler scheduler when you don’t need the notion of a set of prioritized, software tasks.  The HW interrupt priorities can still insure that time critical code is run (to service devices) but your lowest priority tasks (the logic of your main application) don’t need to be structured as a set, each having different priority.

When you want to schedule for immediate, next execution, you can just pend the Alarm interrupt, or use a SWI?

Wrapping your mind around it

In the traditional architecture, the code structure shows the most likely (anticipated) sequence of events, and code executed in response (e.g. taskA, taskB.)  It might be easier for readers to grasp.

In the RTC Task architecture, it is harder for readers to see the sequence.  But it is easier to interpret the code as the “actions” for state machine transitions.  You can label each task to indicate its event, e.g. “onEventA.”

When to use this architecture

As discussed above for SST, when your application is a state machine.

 

 

 

 

Upgrading tools for next version of a radio chip NRF52810

A log of process debugging when I started using a newer version of the Nordic radio SoC ship:  nrf52810.

I am using:

  • Eclipse
  • gnu arm compiler
  • gnu mcu plugin for eclipse
  • nrfjprog
  • JLink

I found the need to upgrade nrfjprog and JLink.  When a newer chip comes out, old versions of the tools don’t understand the new chip.

The first symptom is that nrfjprog doesn’t recognize the chip and says something like “the connected chip is not the right family” even though the nrf52810 is in the 52 family and you specified –family NRF52.  You need to upgrade to the latest nrfjprog version.

When I overwrote the existing nrfjprog directory, I seemed to have problems with nrfjprog not finding the “DLL”, meaning the JLink shared library .so.   I seemed to fix that by deleting the directory and installing fresh.

The next symptom might be, if you use an old debug configuration with device equal to nrf52832, is that the debugger flashes the chip, but then your target program crashes.  You need to specify the correct device in the debug configuration.

The next symptom is that you specify in an Eclipse debug configuration, under the Device tab, that the device is nrf52810_xxAA, but the debugger gives “Failed to set device (nRF52810_xxAA). Unknown device selected?”  You need to upgrade to the latest JLink version.  That involves:

  • download a JLink (say .deb) installer and run it
  • update Eclipse settings for JLink

See https://gnu-mcu-eclipse.github.io/debug/jlink/ for one way to do it (in Window>Preferences>SEGGER J-Link.

Change the jlink_path variable in Eclipse say from “JLink_v60i”to “JLinkv630f”.  In the Debug config>Debugger tab>Executable field, choose the “Variables” button.  Expect a list of variables.  Scroll to and select  “jlink_path” and choose “Edit variables” button.  Expect another list.  Scroll to an select “jlink_path” and choose “Edit…” button.  Change value, and choose OK, OK, etc.

Also, you might need to change the “jlink_gdbserver” variable from “JLinkGDBServer” to “JLinkGDBServerCLExe”.  The name has changed, by the addition of “CLExe”?  Note that JLinkGDBServerExe has a GUI, but the GNU MCU plugin says to use the command line version JLinkGDBServerCLExe

After you do all that, you should be able to execute a debug configuration and flash your app to the device.

My app still crashes.  Now I find that I need a different softdevice for this chip, S112 instead of S132.  I need to change my build config:

  • use headers for S112
  • use linker script for S112

 

Why change to nrf52810?

For me, because it is cheaper in dollars per unit.  Fanstel sells a module BT832A for less than $4, which is cheaper than the Waveshare nrf518122 that I was using.   I am already developing and testing on the nrf52DK which uses the NRF52 family nrf52832, and which is the dev kit that support nrf52810.

Here is a comparison of the family members.

For me, the main difference is: has less memory (192k or ROM instead of 256k.)  So I will need to change my build process to include optimization for small size, and to build for a different Softdevice.  That will be costly in development time for a new build process.

I can use the nrf52810 because my app is small, doesn’t use many periherals (none that are missing on the 52810), and doesn’t use many BT features (only one connection.)

 

 

 

Modern build systems for embedded (radios)

About

I ramble about my experiences with build systems for developing for embedded systems.  I use radio, ARM, SoC’s (Nordic NRF5x family), but the discussion might apply more generally.  I try to provide links, so you can explore.

Summary: I gradually migrated to CLI command line tools, using more recent tools instead of make.

Background

History of what build systems I have used:

Those tools are in order of age,  ease of use, and speed.

For example, make is:

  • ancient
  • hard to use
  • slow

while Meson is (?):

  • recent
  • easy to use
  • fast

 

Factors to consider for a build system in this context

  • supports cross compilation
  • integrated with your IDE
  • handles frequent changes to underlying SDK (Nordic’s)
  • handles very many target embedded systems (platforms)

You might have many targets if you  have a long-lived product that you will upgrade with new hardware:

  • different vendors e.g. Nordic vs Silicon Labs)
  • chip families NRF51x/52x
  • versions within a family e.g.  52832, 52810, 52840
  • devices and protocols that you use (i.e. Softdevice with Bluetooth, or other, or proprietary protocols.)

Makefiles

They get very large.  They are not easy to understand or modify.   But the ones Nordic provides are templates:  you will need to modify them, and re modify them whenever you change the SDK.

Eclipse CDT managed build

Eclipse projects are distinguished by kind:

  • “CDT managed build”: Eclipse generates makefiles.
  • “Makefile managed build”: you provide and edit a makefile

CDT managed build uses a GUI.  You must learn the structure of the GUI instead of the structure of a text configuration file (the makefile.)

Very few people seem to use it in the niche of embedded radios.

Nordic provides a tutorial for  using Eclipse IDE for development, but the examples don’t use Eclipse “CDT managed build”, just “makefile managed build.”  Again, that means you must edit the makefiles.

CMake and the Nordic SDK

Several people have implemented and published their own CMake scripts (macros) specific to the Nordic SDK:

Apparently Nordic realizes the benefit of newer build systems.  Nordic CMake macros:  IMO they are not very modular or extendable.

I found that my own scripts are fragile wrt SDK version.

There are a plethora of options for integration with the IDE:

The fact that there is a plethora is discouraging.  It requires much reading to decide which to choose.  It tells me there is no settled easiest way.

I disliked the projects generated by CMake.  They were too different from my usual way of structuring a project.

Often I just used Eclipse as an editor, debugger, and  version control wrapper, and built using the command line.

Meson

(I haven’t used Meson yet, I am still exploring it.)

One comparison of CMake and Meson.

Apparently Meson supports cross compiling: their documentation.

Meson is written in Python.  That is encouraging, that they used a high-level, modern language to implement what is a very complex task.  I would guess that one might even be able to understand any exceptions in the Meson implementation.

Apparently integration with IDE is in the future.

There is a Eclipse plugin editor for meson files.

The big picture

You need a mental model of the build process.  You acquire that mental model after long experience.  Learning and discarding build systems can help you form that mental model.  The newer build systems more clearly represent the model.  For example, using make you must remember what a “dependency” line looks like (foo: bar) while in newer build systems, a dependency might be labeled with text that says “dependency.”

 

 

 

 

 

Quick start Bluetooth BLE Swift iOS

This is a running commentary for a development session where I attempt to quickly build a Bluetooth app on an iOS iPhone using an example from Github (the Zero to BLE example.)

I already have Xcode installed on an iMac and know and like Swift language.

My goal is a simple app that scans for a BLE advertiser (a peripheral providing a service), connects to it, and writes one BT characteristic of the service.  The app has a simple GUI: one button that means: do the aforementioned.

I choose iOS because it is prevalent, and I have already developed other apps for it.  I can worry about cross-platform to Android later.

Here, I just want to establish the processes and validate the example project.  Later, I will modify the example to suit my app needs.

Getting an open source project

First I searched for open source.  I decided that a Cloud City example on GitHub is a likely candidate.

Clone the project into say ~/git/ using a terminal and command line.

Building and testing the project

Start Xcode.

Choose the button “Open another project” in the lower right corner of the “Xcode welcome” screen, which you can always get to by choosing “Window>Welcome to Xcode.”  Expect a file browser to open.  Navigate to the …xcodeproj file in your repository clone, select that file, and choose OK.  Expect for the project to open in Xcode.

Build and run it by choosing the Right-arrow icon in the upper left.  Expect the project to build and for an iPhone simulator window to open.  (There already exists a “scheme” of the project to build for the simulator.)

Unfortunately, the iPhone simulator does not support BLE, so expect a dialog box in the simulator saying to that effect.  IOW, you really won’t be able to test the app using the simulator.  Instead you need to download the app to real iPhone hardware.

Downloading to a real device

Choose the Square icon in the upper left (meaning “stop the running app”).  Expect the simulator window to remain, but to quit the simulated app and show you the iOS home screen.

Now plug in a real BLE capable (4s or later) iPhone or iPad (some early iPads are not BLE capable.)  Use a USB cable.  Expect more “schemes” to appear in the combo box for “Set the active scheme” in the upper left of Xcode.  Click on the combobox and choose “Device><foo’s>iPhone.  Expect the current scheme to change to that.

Now click the “Build and Run” icon.  Expect the app to download and run on your device.

Distraction: I get: "Could not find Developer Disk Image."  This is a mismatch between Xcode and iOS on the device.  Each version of Xcode requires a minimum version of OS X and supports a maximum version of iOS.  See the section below: Upgrading various tools
Another distraction: I get error messages about the provisioning profile which Xcode offers to fix, and apparently does by using my Apple ID.  Then I get "An App ID with identifier io.cloudcity.BLETemperatureReader is not available...".  See the section below: Fixing the bundle identifier

Finally, the app downloaded to my phone and began working, displaying debug messages in Xcode.

My next post might be about modifying the example project.

 

Upgrading various tools

A quick search shows this SO post suggesting a mismatch between Xcode version and iOS version on my phone.   Skip this section if you don’t have that problem.

Choose “Xcode>About Xcode” to see your current version.  Mine is 7.2.

Choose “Apple>About this Mac” to see your current OS X version.  Mine is 10.11.6  El Capitan.

Start the “App Store” app and choose the “Updates” tab.  Expect it to show you whether there are any updates available.  For me, none were.

On your iPhone, choose “Settings>General>About>Version”.  My installed iOS is version 9.3.5.

Searching showed that the latest Xcode is 9.2.  I don’t know why the App Store did not suggest it exists.  A quick search shows that in App Store you must search for “Xcode” and then click the “update” button from that result.   That didn’t seem to work, I got a spinning wheel but nothing seemed to happen.

The Xcode page on App Store says it is compatible with OS X 10.12.6 or later.  So I need to upgrade OS X first?  I think I have missed some updates so can’t updated directly from 10.11.6 to 10.12.6?  Anyway I went to this Apple page and downloaded a 10.12.6 update directly.  It takes several minutes.  When I clicked on the .dmg, etc.  I eventually got the message “… not supported on your system.”

Now a search reveals that 10.12 is “High Sierra” and that I need to “upgrade” not update.  But the upgrade page says I need an iMac later than 2009, while mine is circa 2007 as shown by “About this Mac.”  So I can’t upgrade to the latest Xcode.

But I can upgrade to a version that supports iOS 9.3.5  Wikipedia shows that Xcode 7.3.1 might support iOS 9.3.5 and run on my OS X.

So I downloaded and installed it (replacing my old installation) which took say an hour.

Fixing the bundle identifier

After Xcode complained about the provisioning profile and fixed it, Xcode did not like the original bundle identifier.  So I changed it by clicking on the project, choosing the “General” tab, and changing the field “Identity:Bundle Identifier” to <my apple id email address>.BLETemperatureReader.   The first part identities the developer or company building the app, the second part is the name of the app.

This post explains you can develop and provision to real devices without becoming a paid member of Apple Developer Program.  You do need to have an Apple ID (but everyone does who uses an Apple product) but you don’t need to pay the annual fee to the ADP.

 

 

 

 

 

Nordic Timers

This is an overview of timers on Nordic radio SoC.

On the NRF52 family of radio SoC, there are these Timer devices:

  • RTC: low power, and low frequency
  • Timer: high power, and high frequency

The RTC is misnamed.  RTC is Nordic’s  acronym for “Real-Time Counter” but more generally RTC means “real time clock” and provides calender like functions: time measured in years and days.  The Nordic RTC is only 24-bit, so  it typically rolls over frequently, say in minutes.  Whereas most people expect a RealTimeClock to never roll over, practically speaking.

On the NRF52, there are three RTC’s, RTC0, RTC1, and RTC2.

  • RTC0 is used by the Softdevice
  • RTC1 is used by the Nordic app_timer module
  • RTC2 is not generally used by the Nordic SDK

So your app should use RTC2 as the first choice, so that if your app also uses Softdevice or app_timer, there is no conflict.

Nordic’s app_timer module implements virtual Timers.  That is, many Timers are implemented in software on one real Timer (i.e. one compare register of RTC1.)

Timers might better be called Alarms.  A Timer is implemented on a Clock and an Alarm, where a Clock is a counter that rolls over and an Alarm is a compare register that generates an event/interrupt when the compare register matches the clock.

Each of the RTC’s has a counter and multiple compare registers.  Thus you can implement many real Timers on each RTC.

A real Timer is implemented on hardware devices like the RTC.  It consumes no cpu cycles while it is running, and few cpu instructions to set it up.

Because virtual Timers are implemented partially in software, it takes a few more cpu cycles than a real Timer.  But that’s not important.  What is important is that the virtual Timers be implemented correctly.  There are outstanding bug reports on Nordic’s app_timer implementation.  And the test suite is no public.

Other software kits such as freeRTOS implement virtual Timers.  These might be more likely to be correct since they are open source and widely used?

Algorithms for setting an Alarm on a Clock are not trivial but are well understood.  It requires careful use of modulo arithmetic.  Modulo arithmetic is “clock like”: results of operations roll over, loosely speaking.  Correctly setting an alarm on a clock also requires use of Lamport’s rule.  Finally, a hardware implementation of a clock has limitations that the software (the Timer driver) must account for: a compare register cannot be set too near the current counter value, else the hardware event might not occur in a timely fashion.

 

 

Writing custom libraries for Energia (Arduino)

This is just about the pragmatics of: where do I put source files so that they are a shared library?

Custom: one you write yourself.

Library: a set of C++ source files (.h and .cpp) that you want to share among projects.

The simplified Energia/Arduino view

Outside the simplified Energia/Arduino world, libraries would be in a separate, shared directory and they would be pre-compiled into an object and separately linked into your projects.  In the Energia/Arduino world, that is all hidden.

Also, in the Energia world, a library seems to be a zipped directory of source files that follow some conventions that identify the version and documentation of the library.   So you can share the library.  I don’t know what the conventions are.  But if you are going to share your custom library, you should follow the conventions, and zip it up.  Then others can use the simplified user interface for installing zipped libraries.  Here, I don’t bother with the zipping.

Creating a custom library

Briefly, you just need to create your source files in the place that Energia looks.

Find where your sketchbook directory is:  In Energia choose “Sketch>Show Sketch Folder.”  Expect a file browser dialog (the Finder on the Mac) to show you the directory.

You will see a sub directory named “libraries”, and it will probably be empty.  (I don’t know where Energia keeps all the other pre-installed libraries.)

In that directory, create a directory with the name of your library e.g. “PWM”.

In the “PWM” directory, create your .h (and maybe .cpp) files, e.g. “pwm.h”

Now switch back to Energia and select “Sketch>Include Library>”   Expect a hierarchal menu to appear.  Expect to see “PWM” in the “Contributed libraries” section of the menu.

You can also choose “Sketch>Include Library>Manage Libraries”.  Expect a browser kind of window to open.  You should be able to browse to a line saying “PWM version unknown INSTALLED”.  (In my opinion, this should not be called “Manage Libraries” because it seems all you can do is view a list of the libraries.)

(Note that Energia expects at least one source file in your library directory.  Until then, Energia may give an error “Invalid library found in….”)

Referencing the library

In your main sketch “#include <pwm.h>”

Then define an instance of the PWM class and call its methods.

Developing and managing your library

You can just edit the files in place, using another editor.   When you use Energia to “verify” the main sketch that uses the library, it will recompile your changed library.

By managing I mean: copy the files out of the sketchbook folder to a safer, more shared place.  The sketchbook is in /Users/foo/Documents/sketchbook (on a Mac).  I prefer to put them under source control in a “git” folder, or in the “Dropbox” folder, so when I am done developing, I copy the library folder somewhere else.

I suppose you could use git in that directory, and when you are done, commit and push that repository to a your shared (master) repository on github.

Brief Summary

A library is just a named directory in the directory “sketchbook/libraries”.  You can create a library yourself using a file browser and editor.

0xFFFFFFFE, reclaim_reent() error symptoms of embedded programming

This is a report of one cryptic symptom (and possible) fixes you might encounter when you are embedded programming.  I report it because I have experienced it more than once and always forget what it means.

When you are trying to flash your embedded mcu,  the debugger seems to download to the chip, the debugger starts  and then stops showing a stack trace something like this:

0xFFFFFFFE
reclaim_reent()

Usually you expect the debugger to stop at main() and wait for you to tell the debugger to run (but that depends on whether you have configured your IDE and debugger to breakpoint at main.)

It might mean (not a program bug, a process error):

  • your linker script <foo>.ld describes the memory of your chip incorrectly
  • you haven’t erased the chip’s ROM yet

About the latter.  I am not sure, but modules you buy might already be flashed with a program such as a DFU bootloader, and are configured to protect a debugger from overwriting that code in ROM.  For example, on the Nordic NRF51, to remove the protection and erase all of ROM so that you can then use the debugger:

 nrfjprog --recover --family NRF51

 

 

Patching (for Linux) lib_search tool in TI’s tool chain for embedded wireless development

Context

General

Trying to use CCS Desktop on Linux or OSX to build SimpleLink example programs for TI’s embedded wireless chips such as the CC26xx family of chips.

Specific

Fixing a Windows specific tool invoked by the projects of the examples.

References

A one-year old post on TI’s forum

TI’s wiki page for Linux

TI’s wiki page for OSX

TI’s wiki on Portable Projects

Why do you need the lib_search tool?

As far as I know, certain needed code is shipped as pre-built libraries ( .a files.) The example projects are not configured to build the libraries, only to link them in.

The lib_search tool does some sort of configuration.

Aside

I don’t understand what exactly the tool does, why all the libraries are not just in some directory that the linker searches for needed unresolved symbols.

The references seem to suggest that the libraries CAN be built on the Windows platform.  That seems to imply the library source code is not proprietary, i.e. not secret, only copyrighted and licensed.  It seems like it SHOULD be possible to build the libraries on any host system.

How so ever the libraries get built, they are hardcoded for a specific target chip, and possibly for other code such as a version of TI-RTOS?  Or does it pertain more to what the app image needs from the stack image of the embedded program?

Anyway, you don’t need to understand it to patch it.

Where in the project build is the tool invoked?

The example projects are configured to use the tool as a ‘pre-build’ step.  To see that, highlight a project in the Project Explorer pane of the CCS Desktop IDE, click on it with right mouse button, and choose ‘Properties.’  Expect a dialog.  Select ‘Build’ in the left pane of the dialog.  Expect the right pane to show many tabs. Look under the ‘Steps’ tab for a ‘Pre-build steps’ section.

Symptoms of non-portable tool use

When you build on a non-Windows platform you might get:

error #10234-D: unresolved symbols remain

that is, the linker could not find said certain libraries, because the linker command file was not built by the pre-build step.  The root cause is visible much earlier in the log of the build, the pre-build step (lib_search) failed and the build process ignores the failure (proceeds to compile and link.)

The non-portable aspects of the tool

The pre-build step invokes lib_search.exe.  That is a python program (and the interpreter) that has been packaged/bundled for Windows OS (so that python does not need to be installed onto the host.)

(Strange: the BT SDK developers don’t support non-Windows platforms, but they use the tool Python which Windows OS does not support, and they used the tool py2exe so they can ship the SDK portable to any stock/virgin Windows host.)

But as of BT SDK v2, the python source is shipped with the SDK.  So on any host where python2.7 is installed (most Linux/Unix and OSX hosts), and where certain other dependencies (the python package ‘lxml’) are installed, the tool will run as interpreted python.

Old patch for the problem

Some of the references suggest installing Wine and other tools that let Windows executables run on Linux/Unix hosts.

Then the fix is (roughly speaking) prepending wine to the command:

lib_search.exe ...     =>     wine lib_search.exe....

Another patch for the problem

Here we invoke the python interpreter on the python source.

Then the patch is (roughly speaking) prepending ‘python’ to the command and changing .exe to .py:

lib_search.exe ...     =>     python lib_search.py  ....

Here, we assume  “python” invokes python2.7 (which it often does, except if you have changed it to invoke Python 3 or later.)

For this step to work, you must install the python packages that lib_search uses, and the package’s dependencies (lib_search depends on python package lxml which depends on C libraries libxml2 and libxslt.

To install those dependencies:

pip --upgrade pip
pip install wheel
pip install lxml

More exactly, in the build step change:

"${TOOLS_BLE}/lib_search/lib_search.exe"

to

python "${TOOLS_BLE}/lib_search/src/lib_search.py"

More to the patch

Define and redefine certain project path variables:

In the project’s Properties>Resources>Linked Resources>Path Variables  redefine

TOOLS_BLE  <= ${BLE_SDK_ROOT}/tools

and define

BLE_SDK_ROOT <= /home/<you>/ti/simplelink/ble_sdk_2_02_00_31

Change the .xml configuration file

(e.g. in TOOLS_BLE/lib_search/params_split_cc2640.xml)

Use a text editor to change “\” to “/” everywhere in file paths.  (Windows uses backslash in paths, other OS’s use forward slash.)

If you haven’t done this step, you see an error message that lib_search emits, saying

Cannot match   <foo> to any library .opt file in <bar>

where bar is a file path like “…./.\host….”

Setting Up a Linux Development System for Embedded Wireless using TI LaunchpadXL-CC2650 EVM

About

A record of my learning experience.  Discusses general, high-level considerations. Gathers many links that I followed.

Audience

For advanced, C programmers who are new to TI’s tool chain for programming embedded devices.

Similar documents

CC26xx Family SW Quickstart Guide also covers this material.

This blog shows a similar process for an older EVM (SensorTag), but using Windows OS and CCS Desktop.

The Narrow Subject

Here I assume the CC2650 target (an mcu and radio system on a chip) but only discuss:

  • Bluetooth (the chip allows other protocol choices i.e. WiFi or Zigbee)
  • TI-RTOS (other RTOS choices might be various free OS’s)

This might apply to other TI chips such as CC13xx, CC2640, and other earlier chips.

The Broader Subject

Wireless networks, not necessarily IoT development.  My use case is not serious IoT: I don’t want to connect to the Internet and I don’t even want to talk to standard Bluetooth devices, just between two of my own.  I don’t even want Bluetooth protocol, it just happens to be what I studied first.

Disclaimer

I could be wrong.  You should follow links to original sources.

Other target, IoT, and wireless network ecosystem choices

ARM mBed ecosystem also offers an online IDE, desktop development tools, an RTOS, and bluetooth stack.

The CC26xx target uses the ARM ISA.  You might be able to use the ARM ecosystem, but I think the bluetooth stack in the ARM ecosystem might not work on the CC26xx?  The CC26xx has two processors, a host (ARM M3) and a network (ARM M0) processor.  A Bluetooth stack should have an interface at the HAL layer between the upper layers of the BT stack and a network processor’s implementation of the lower layers.  I don’t know whether either the ARM bluetooth stack upper layers, or the TI network processor lower layers (in firmware on the M0), conform to any HAL interface standard.

(Note that TI also has much documentation on implementing “network processors”.  There, they are treating the CC26xx as a server for yet another processor, the application processor, say a powerful cpu of a desktop PC.)

ARM does not make chips (only the design IP for them).  You might consider whether using TI tools locks you into their chips, and whether using the ARM ecosystem would give you a choice of chips.

TI’s IDE Choices

CCS Cloud – “online IDE” or “online compiler”: browser and cloud based: few files stored or installed on your development system (host)

CCS Desktop – installed on your host computer, based on Eclipse IDE

Energia – (Arduino clone) does not support the CC26xx family target.

Dev System OS Choices

For CCS Cloud, shouldn’t matter, but it does: to burn to the EVM requires setting up communication via USB to the EVM, which is host OS dependent (drivers and permissions.)  CCS Cloud requires installation of TI Cloud Agent on your desktop.  All three major OS’s are supported.

For CCS Desktop, all three major OS’s are supported, but Windows seems to be favored.  E.g. installing the Bluetooth stack is biased: requires Wine on Linux.

TI’s instructions  for Building BLE Projects on Linux.  It acknowledges that TI does not officially support their BT stack on a Linux dev system (but they do support their IDE and RTOS.)

Overview

To develop, you need three components:

  • IDE (CCS Desktop or Cloud)
  • TI-RTOS
  • Bluetooth stack (or another wireless stack, i.e. library)

Using CCS Cloud, all three components come easy, automatically.

Using CCS Desktop, you must know the steps.

Installing CCS Cloud

Installation is minimal.  Search for “CCS Cloud Tools”.  Click on “CCS Cloud>Click to Start Developing”.  It will open in your browser.  When you first try to “Run” your target app, it will give you further instructions for installing:

  • a browser plugin
  • TICloudAgent

You must install TICloudAgent, and on Linux it depends on installing certain 32-bit libraries.  It’s web page seems out of date, it doesn’t show support for Ubuntu 16.4 or for this EVM (Launchpad.)

CCS Cloud is intended for starting programmers or small trials, i.e. for education and evangelism.  I don’t think the user base is large, yet.

I want to use it ( I have used Energia for small projects.)  But so far, I have had a fitful experience.  In other words, it seems somewhat fragile: requires refresh or restarting things.  Maybe slow.  But at least you can quickly experiment and learn the scope of your project (what might work, what else you need to learn.)

For example, at first ‘Run’ (burning to target) didn’t work for me, and after rebooting my dev system the next morning and plugging in the EVM after CCS Cloud was started, it did work.

For example, at first a project built successfully.  Then subsequent builds failed even though I had not changed a line of code.  The fix may be to delete a project and redownload it (using TI Resource Explorer.)  Maybe it is a consequence of changing between my two host computers.

Sometimes it fails to login (“too many logins”).  I guess there are limits on their servers?

The browser connection times out at inconvenient times (say every 30 minutes.)

Run (download to target)

“Failed to connect to target” : you don’t have the target plugged into a USB port on your desktop.

“Firmware update required” : the debugging interface half of the EVM board requires flashing.  This seems to be a warning, as download to the target seemed to proceed.

Installing CCS Desktop

Linux instructions.

A training video.

Additional notes

CCS Desktop is based on Eclipse IDE.  It is not a plugin that you can download from within Eclipse, but is downloaded and installed(?) separately (thats weird.)  If you are an Eclipse user, the overall look-and-feel is familiar, but specifics might not be.

The installer is 32-bit, but TI  says to use 64-bit Linux (that’s weird.)  You MUST follow the instructions for installing 32-bit library dependencies. (a 64-bit host will run 32-bit apps if the needed 32-bit libraries are also installed.)

The installer won’t run by double clicking it (because “>file *.run” shows it is 32-bit ELF?) but will run from the command line.  The installer is a .run instead of a .bin (thats weird?) but see this explanation of what a .run file is (essentially, an installation tool outside the approved Debian process.)

If you the installer starts but shows an error dialog “Failed to locate …libgcrypt…” you didn’t follow the instructions for installing that component.  You follow the link and click on “32-bit” (which points to ftp for a .deb file)  and expect to continue to install libgcrypt using “Ubuntu Software” installer app.

When the CCS Desktop installer runs, expect a wizard to run, that downloads and installs.

CCS Desktop: Installing TI-RTOS

You install TI-RTOS (development libraries) from within CCS.  Navigate to the TI App Center and choose “TI-RTOS for CC13xx and CC26xx”.

CCS Desktop: Installing Bluetooth Stack

TI’s instructions  for Building BLE Projects on Linux gives specifics for installing the BT stack on Linux using Wine (Windows emulator.)  Those instructions seem to be out-of-date.  I needed these changed instructions:

sudo apt-get install wine
sudo apt-get install winbind
(Download the Windows .exe installer.)
cd ~/Downloads
wine ble_cc26xx_setupwin32_2_01_00_44423.exe  (expect installer dialog)
cd ~/ti
cp -r ../.wine/drive_c/ti/simplelink/ . 

My changes to the instructions:

  1. Once you install the BLE SDK, I suppose it creates files in the proper place, and then you can uninstall Wine from your Linux computer?
  2. When I tried “>wine ble….exe”  it yielded errors about “ntlm” and needing package “winbind.”  And failed to create ~/<me>/.wine/drive_c/ti  (where it should be installing files.)  So I also installed package winbind.
  3. The installer did not seem to create .wine/drive_c/Program Files(x86\)/Texas Instruments/Boundary/  so I omitted the step of copying it.

(I haven’t successfully built a project yet.)

CCS Desktop: Importing Example Projects

I tried the TI Resource Explorer and did not have much luck finding

TI’s instructions  for Building BLE Projects on Linux also gives instructions for importing example projects.

CCS Desktop: Tweaking Example Projects

The instructions there for changing the linked resources (paths, capitalization of fileNames, and fileName wording) are slightly dated but generally accurate: you will need to use the principle and tweak the exact changes yourself.  For example, the filename “RF.c” seems to have changed in the latest release of BLE SDK.

If you get:

error: can't create session manager: can't find a JVM;
 the environment variable 'XDCTOOLS_JAVA_HOME' is set,
 but does not appear to be a directory containing a 64-bit
 Java Runtime Environment

Then see this post on TI Forum .

 

What are Images?

For the CC26xx, burning the target comprises two steps:

  • the app
  • the bluetooth stack

These are two different projects in the IDE.

TI calls them “images”.  I suppose that means they are loaded in different addresses of target ROM, and that the app on the target knows where to find the BT stack.  You only need to burn the BT stack once (unless it changes upstream, a new version.)

What are the symptoms of failing to burn both?  The app and not the BT stack:  does the app complain somehow?  The BT stack and not the app: nothing whatsoever happens, there is no app to boot?

Test Projects, CCS Cloud

How to use TI’s example projects to test your dev system.  These were written while I was using CCS Cloud; they might not apply to CCS Desktop.

Project Zero for CC2650

A demo app to burn onto your SimpleLink LaunchPad.   Essentially it sets up the Launchpad as a BT peripheral that a central device (a phone, etc.) can poll (see advertisements), connect to, and change attributes (to blink LED’s.)    This describes the demonstration, what a user sees.

As near as I can tell, this is NOT the app that is burned into a LaunchPadXL-CC2650 out of the box.  At that time, pushing the upper right button on the LaunchPad causes it to BT advertise, and for the green LED to blink.

This can be a test case for your development system.  If you successfully build and burn it, it should behave as described, talking to a BT scanner on another device.  Unfortunately, to see the results you need to use some of the free BT scanner apps, you need another BTLE enabled device, Android 4.3 or greater, or a recent iPhone or iPad that supports BT Low Energy.

 BigTime

This project prints “debug messages” once per second for a few seconds. It doesn’t use the radio.  It is intended to teach how to code semaphores etc.

CCS Cloud:  When you click the Debug icon, expect a dialog to open (the dialog that shows progress).  It should say, in order, paraphrased:

  • Building…
  • Loading…
  • Initializing…

The red/green led on the top half of the EVM should blink as the program is burned.

CCS Cloud: Then the dialog goes away and the debug panels of the IDE show new information, and a marker appears across from “main()” in the panel that shows the code.  The debugger is waiting for you to start the app.

Press the “Resume” icon in the debugger panel (looks like the standard “Play/Pause” icon on VCR’s).  Expect the program to run and print some messages into the Debug tab of the panel across the bottom of the IDE.  The final message should be “bigTime ended.”

 SimpleBLEPeripheral

This example project is configured for another EVM.  When you try to “Run” it on the LaunchpadXL-CC2650 EVM, you get the error “….Failed to connect….”.

To fix it, click right mouse button on the project in the Project Explorer Pane of CCS Cloud.  Expect a menu to pop up.  Choose “Project Properties”.   Expect a dialog to appear.  In the “General” section, in the “Connection” textbox, click.  Expect a pulldown menu to appear.  Choose “XDS110” (the type of interface on the upper half of this EVM.)  Choose OK and build again.

Repeat for the other half of the project, the …App… versus the ….Stack….

Other Notes

It seems like a few “Run” errors in red while burning, such as “Failed Device Reset”, are ~normal~ and that CCS Cloud retries and eventually succeeds.

Sometimes Ubuntu displays “You have just opened  a digital audo device” dialog meaning it has seen the Launchpad on the USB port somehow.  Choose “Do nothing” and “Do this always.”  Maybe it interferes with CCS Cloud if you don’t?

Cloud IDE for programming

About this post

The subject is software development environments that are easy to set up and use from anywhere.

This post’s quality is low:

  • written quickly
  • more questions than answers
  • from my limited experience, not exhaustive
  • it discusses programming embedded micro controllers, not programming in general

The problem

You want:

  • to minimize effort administering your development environment, and maximize time spent writing software (SetupEase)
  • to work from any physical location (Mobility)
  • to use version control (Versioning)
  • not to lose work (Backup)
  • to share (OpenSource)

Some software developers work in a single development environment in a single location.  Others may switch between many environments and many locations.  For example, software developers for embedded systems might switch environments for each brand of microprocessor they use.  They may develop at home and at work.

The State of the Art

AFAIK, there is not currently a development environment that gives you all of the above.

Solution Pieces

  • Github
  • Dropbox
  • Containers or virtual machines
  • IDE’s in the cloud

Github

Github the software provides you Versioning and Github.com the website gives you some Mobility.  But it only gives you Mobility for your source and some parts of your development environment ( such as makefiles), not for your total development environment (such as what compiler you are using.)  And the Mobility is clunky, you can’t work in your open master repository, you must work in a clone and remember to push to origin master after each work session, so that your work will be available tomorrow from another location.

Dropbox

Dropbox gives you Mobility for your source files: anywhere you work, your files will be automatically synchronized (with slight lags.)  And you can put Github clones inside Dropbox.  But you still don’t have Mobility for your complete development environment, since your IDE or compiler is installed locally, not in Dropbox.

Containers

Containers or virtual machines give you SetupEase.  Someone else can install and configure your development environment, and you download and use the whole.  For example, a development environment for open source OS Mynewt is available in a container.

But containers don’t give you Mobility.  You must set up distinct (but identical) container instances in every location.  Any files you create in a container instance, and any modifications to the development environment, are local to the container instance.   Your container could include Dropbox having a Github clone, but you still must remember to push after each session, and that might not mobilize any modifications to the environment in the container instance.

IDE’s In the Cloud

Also known as “IDE as service.”  Here, you run your development environment in a browser.  A server:

  • stores your source files
  • stores your environment
  • does all the compilation
  • runs and debugs your app (with help from an agent to the target device)

An example is Texas Instrument’s CCS Cloud.  My knowledge is limited.  AFAIK it give you SetupEase, Mobility, and Backup.  It doesn’t seem to give you Versioning and Share.  It seems to let you clone Github repositories, but not commit in the clone, or push to the origin.

TI admits in the FAQ for CCS Cloud that for advanced work you probably will need to use CCS on the desktop.  In other words, CCS Cloud is only for experimenting or trials.

CCS Cloud does let you download any files from it, so you could use a manual process in which after every session, you download, commit, and push any files you have changed in CCS Cloud to your master Github repository in Dropbox.

Other examples might be “Particle online” and “mbed online.”  (I don’t know these.)

References

EmbeddedWeekly  blogs a little about this subject.  I read that before writing this post.