Silicon Labs Thunderboard Sense
The Thunderboard Sense board (or its newest incarnation, the Thunderboard Sense 2) from Silicon Labs has many attractive features for Farfalle.
- It contains most of the sensors we will need.
- It runs on a Cortex-M4 which is well supported by micca, et.al.
- It has a radio with Bluetooth capability.
Right now I'm exploring getting the bluetooth running. Like most hardware of this type, the bluetooth library is supplied by Silicon Labs. It is a typical hardware company's software effort. Documentation is adequate but not great. Things are oriented to examples rather than what is required to get a robust application running. The code is delivered as a binary blob so when things go wrong, debugging will be difficult.
Like many libraries supplied for bare-metal machines, it assumes it will control the world. Some provisions are made to integrate the bluetooth control into a different main loop, but it really wants to think it has control over everything. Also of interest is the resources the radio code uses. Those are not available to the rest of the system.
The first technical experiment is to determine if the bluetooth software can be integrated to the micca run-time in an effective way. It looks possible, but needs to be proven out so that we have a real micca runtime that can handle radio events.
Andrew Mangogna
17 Jan 2019
I received a Thunderboard Sense 2 board from Silicon Labs. This board has a newer version of the radio chip (EFR32MG12), but is otherwise very similar to the first generation board.
After a few days of pouring over manuals and looking at what needs to be done I have come to a few realizations.
- If the goal is to come up with a micca run-time that works in conjunction with the Silicon Labs bluetooth stack, then I will need some way to test that arrangement.
- We are talking Bluetooth LE (low energy), so that is a whole new unfamiliar technology that I need to understand. Oh boy!
- I will need some way to test the modified micca run-time, preferably from my Linux box (Doing this on Linux will get us a step ahead I hope. I'm guessing we will end up with some Raspberry Pi or BeagleBone like box somewhere in the system).
- On Linux, the "official" bluetooth code is called bluez. It consists of kernel stuff and userland programs. Key to the userland functionality is the bluez daemon. This daemon mediates between userland and the kernel to provide access to bluetooth functionality. You could program directly against the low level kernel interface, but that's a lot of lines of "C" code.
- The bluez daemon, as it turns out, is a D-Bus server. Oh boy! another big bit of technology I'm unfamiliar with.
With all this in mind, this is my plan of attack:
- Put together a simple script to attach to the Thundersense board using the provided demonstration application and make sure I can read and control the board by some programmable / scripting means.
- Build an empty application for the Thundersense board (there is an example empty app provided by SiLabs). Make sure I can control the few things that the empty application can do (i.e. connect and read manufacturer data, etc.).
- Make the modifications to the micca run-time to use it as the main event loop control and not the "native" loop provided by the SiLabs stack. There is hope in this area. SiLabs provides both a "native" API and has integrated the stack with the Micrium OS. The source code for the Micrium integration is available and shows how the bluetooth stack is serviced from OS threads. This should be enough to make it run with the micca run-time by supplying the necessary code. Although there are no OS threads in the micca world, we do have interrupt sync functions and a state machines that can do the same sort of work.
It seems a little backwards to work on test tooling first, but that is what I'm doing. To that end, I have D-Bus bindings to Tcl and can use those to talk to the bluez daemon. The bluez daemon will connect to the Thundersense board and can see all the services (a bluetooth concept) and characteristics (another bluetooth concept). The interfaces (a D-Bus concept) used by the bluez daemon are documented (sort of in some text files on git hub -- oh well) and it seems to behave according to its API's.
So it shouldn't be long before I have a simple Tcl application that can connect to the Thundersense board and see what types of services are there and obtain data from the board. I'll post something when I get to that point.
Andrew Mangogna
31 Jan 2019
After a couple weeks, I'm happy to report that I can now talk to the Thundersense2 board with a Tcl script. As is so predictable, it was more work than I thought it would be.
Turns out I ended up writing an entire client side Tcl package to deal with interfaces to the DBus daemon and handling the introspection and dynamic aspects of the DBus. Also, Bluetooth lives in the world of UUID's and it took a while to find the data needed to map UUID to reasonable names of things (at least find the data in a single collection that was machine readable). Unfortunately, all this stuff is in XML, so I had to brush off those skills.
In the end, I can now connect to the Thundersense2 board, find out all the "services" it offers and read the "characteristics" of the services and the "descriptors" of those characteristics. All through the DBus and all from a Tcl script. Using the debug output from the Thundersense2 board, I've been able to verify that the values I get in the Tcl script are the same as being sent by the board. Yeah!
So now it is on to the next step to repeat this with an empty or very minimal applications. Performing only a few things will clear a lot of crud out of the code. So this is still a preparatory step. Then, finally, I might get to the part where I make the bluetooth stack run with the micca run-time. That's the critical part.
Andrew Mangogna
10 Feb 2019
I've managed to convince the Silicon Labs bluetooth software to operate with the micca run-time. This is really significant as we now have a reasonable architectural basis onto which model translation can occur. As I had suspected, adding in some callbacks that were put in place to be able to run the BLE software with the Micrium RTOS gave me the hooks I needed to make it run with micca.
There seems to be three conditions that need to be met for the BLE software:
- A link level callback from IRQ needs to initiate giving the processor to the stack entry for handling link level things.
- When bluetooth events arrive from BLE stack, another callback from IRQ needs to schedule handling of the bluetooth event.
- Calls into the stack (commands in the terms of the docs) need to run single threaded.
The last is no problem since everything in micca is single threaded. The first is handled by having the link level IRQ callback do a sync request to the background which then directly executes the BLE stack link level handler. Sync functions in the background are all called as soon as there is no executing state action.
The stack event IRQ callback also requests a background synchronization, but in this case the background code just signals an event. A very simple state machine then handles the bluetooth stack requests (again called events in the docs just to make sure we overload the word "event" enough times to be confusing) one at a time. If it finds multiple requests to process, it signals itself an event to insure we get out of the state activity and allow any sync requests to run.
There is a timeout associated the BLE stack requests and we use a delayed event as a means of polling the stack, when the stack code itself deems it necessary, to determine if there is additional work. That timeout value is returned by the BLE stack itself and is sometimes zero which means the stack wants immediate service. A delayed signal in micca with a 0 delay time accomplishes a "yield" of the processor (this is by design). The yield happens because delayed events always start a new thread of control. Sync functions (and hence the link level processing required by the BLE stack) get executed in preference to any event dispatch. Another thread of control already in the event queue would have precedence over the 0 delay signal issued by the BLE stack request state machine. Nifty how that worked out.
Anyway, there are still some issues I can't explain and a bunch more architectural work to be done. However, this is the progress I was looking for since it is such a fundamental enabling step to be able to use the Silcon Labs chips. If I hadn't been able to make this work, we would have been off looking for other solutions since using the micca run-time is essential to all the other tools and techniques we intend to use on the project.
If you are wondering why I'm so focused on the Silicon Labs chips it's because their good low power performance and the fact I've used them in other contexts many times (when they were Energy Micro chips before Silicon Labs bought them). They all have built in Segger debuggers that you can access with a simple USB cable so you don't have to buy expensive dongles. They aren't quite as popular as some of the other ARM Cortex-M micros, but in combination with a radio on the same SOC, I haven't seen anything better. However, if anyone thinks we should look at some other chips, then speak up (or better yet, write up something here).
Andrew Mangogna