User login

Dan Collins's blog




Have a copy of ubiquiOS in hand. No further progress on the project.

Looking forward to integrating ubiquiOS and improving all the low-level OS functionality (software timers, memory allocation and debug output spring to mind!).




I have most of the association procedure implemented meaning nodes are able to associate with the coordinator. However I'm having problems with my custom OS. Rather than spend more time on that venture, the plan is to use ubiquiOS for now. I can always write a new OS later - or use something like Contiki.

I have a fair bit of experience with ubiquiOS so this will be the fastest path forward.

Not much will get done until at least the end of next week. The next step is to integrate ubiquiOS and make sure error states are handled with the association. Then it's on to security!




I've had MCPS going for a while now, however the structure I came up with initially made it difficult to pass frames between layers. For example it was up to the top layer to build the frame for sending - a bad way to do things!

The way it works now is that the MAC manages all of the frame memory and the upper layers simply pass in data. This is obviously a much nicer way to do things.

I also spend some time implementing some OS timers (which I am currently modifying to allow the addition of timers from an interrupt context). This allows the code to use callbacks, from a background context, to pass data around in a more event driven manner. While I like the idea of owning my own OS, ubiquiOS is available as an alternative which is likely to be far more stable. I'm still a little undecided but a few more bugs in my OS and I'm sure I'll jump ship. The intention will be to keep an OS abstraction layer so ubiquiOS can be swapped out and replaced as needed.

I've totally restructured the mac into several pieces - MCPS, MLME, coordinator and packet scheduler. The packet scheduler manages queues and timing of sending and receiving packets. MCPS is working, however no CCA is currently done so collisions are possible. I plan to implement beacons before I worry about CCA.

Patrick and I worked together to get 802.15.4 packets into wireshark. Patrick and Richard managed to get the full 6LoWPAN packet decoding going by ignoring the FCS in the MAC packets.




Woops. Missed a report last week...

Last week I wrote the radio driver which is able to send and receive 802.15.4 data packets. The Contiki software was useful to see which registers I needed to initialise to get data moving. There's plenty left to do but it's enough to get running.

This week I have started writing the MAC layer. I want to start with the PAN coordinator, specifically with beaconing. Once I have beacons, I can start work on the three scan types - active, passive and energy detection. This will allow the PAN coordinator to survey the site before starting a network.

Once I have the surveys and beacons working, I can get association working.




Dean lent me a Segger JLink which I was able to use to start tracing down the hardfault. I was unable to do this, as the newlib library doesn't contain debug symbols.

While I could build my own, I created a work around exploting the fact that vsnprintf works fine.

The JLink is still very useful as I'm very likely to need to debug other issues later on. The XDS100v3 is pretty useless for this task. The JLink also provides a way better (faster, CLI) way to program the device so I suspect I'll even become more productive.

The next step is to try and get some reliable radio sniffing going. I need to ensure I can see 802.15.4 frames so that when I'm developing my own MAC I can make sure the frames are correctly formatted. This should be a trivial task as the CC2538DK comes with a USB dongle which there is already sniffing software for. I'm just unsure if I'll be able to do the sniffing under Linux.

tl;dr: I have UART, printf and malloc working. Now I need to start radio dev.




After the last project meeting, we decided to ditch contiki as it does not offer much that will be useful to this project. Rather than trying to hack in a new mac controller and modify the existing mac data path, it is going to be easier to just write something from scratch. The future plan will be to add networking layers on top.

In order to facilitate a new platform, we're sticking with the CC2538DK. I've spent a bunch of time getting a linker script, start up file and some basic code running. So far I've got the LEDs, UART and LCD working fine. The next step is to try and get libc (specifically newlib) going to add support for things like printf, malloc and free. Printf is extremely useful for debugging and it makes the project much simpler to implement. Malloc will be useful for packet buffers and the like (although static memory could be used instead).

Unfortunately calling printf causes a hardfault. We don't even manage to get through newlib down to the stubs that are environment specific (the part that takes the characters from printf and passes them to the UART). Using GDB, we can examine what caused the hardfault and go about debugging from there.

I have no idea why, but I am unable to read any of the useful registers. It seems like the GDB server provided by TI (which gdb connects to) doesn't like hardfaults and somehow locks us out of some registers. This is a big problem, as I need to be able to debug the CPU in order to get anything done. I've lodged a support request with the TI forum: I don't have very high hopes as I haven't had very good support in the past.

I'm really hoping that Dean (as he has a lot of experience dealing with ARM Cortex M3 parts) is able to help me solve this. It's hard to debug without printf and without gdb!




Since the last report I've been reading through the 802.15.4 standard to get an idea of what to expect from silicon radios that say they are compliant.

Both Dean and Richard made the point that just because they use the 802.15.4 radios doesn't mean they follow the standard and as such I shouldn't expect to see a whole lot of structure from the standard. For example the standard is very vague when referring to a network not using PAN controller beacons which would allow the network designer to make whatever decisions they like. This is an issue when interoperability is desired as the IEEE802.15.4 standard really doesn't offer anything that would facilitate such interoperability - the application and the networking (in cases where it is not a star network with PAN controller beacons enables) are not defined by the standard.

I also attempted to trace through the source for both RIOT OS and ContikiOS. RIOT OS is a microkernel meaning that messages get sent between different processes by the kernel. As such, I was able to trace the transmission of a TCP packet through the RPL routing, through the 802.15.4 framing to a call where the frame was sent to a transceiver. ContikiOS was far more complicated as they use a lot of preprocessor macros for various things which makes tracing a little more difficult. I wasn't interested in spending a lot of time tracing when my main interest was just figuring out how the 15.4 layer worked (PAN beacons? PAN controller elections? free for all?). I actually didn't figure out how either worked, but I imagine reading through the RPL routing document would give more information.

Finally I tried to evaluate both ContikiOS and RIOT OS. I like the RIOT OS source as it is very clean and readable. For this reason I was really hoping that I could use RIOT OS for this project. However, support for the CC2538 transceiver (distinct from the microcontroller core) is not in the mainline branch. I was able to checkout a branch that claimed support (and is in the process of a pull request) however it was hard to tell if it was actually working. ContikiOS on the other hand was ready to go out of the box. My sniffer seemed to have some kind of latency in showing me received packets (or it was rejecting them because they aren't using standard frame checksums?) which made it difficult to figure out how packets were flowing. In any case I was able to create a gateway running SLIP to a tap interface as well as a web server node that I could access over the air using the gateway.

I plan to continue evaluating both options but it appears that ContikiOS is more polished than RIOT OS in terms of CC2538 support. I find it interesting that RIOT OS claims support for the CC2538DK but doesn't support the radio (yet). RIOT OS is an embedded RTOS but I don't think I would choose it over FreeRTOS unless I wanted the networking and radio stack.




This report will cover the progress to date. I've also attached the proposal I submitted in case anyone is interested in reading that.

In order to make a start there are two areas that need to be considered. The first, and likely most important, is to consider how the provisioning flow is going to work. IEEE 802.15.4 has some build in AES security stuff as well as different channels (much like Wi-Fi has channels). At the link layer there needs to be a way to negotiate some kind of connection which will involve scanning for a channel both nodes can talk on as well as some kind of key exchange to encrypt the communication. Above that, in the networking layer, we probably want some kind of authentication and encryption to ensure that nodes are who they say they are. Finally, the application layer will need to support some kind of key store so users can add the new node before trying to connect it to the network.

The other side that needs to be considered is which platform the project should be built on. The CC2538 hardware has already been decided. Not only does it have IEEE 802.15.4 radios, it is also supported by all the major WS platforms I could find. The other convinient aspect is we already have development boards for it. The software, at this stage, will either by RIOT OS or ContikiOS. The issue with ContikiOS is that I've seen Brad and Isabelle working with it and it seems like there are a number of challenges along the way. RIOT OS is lacking a gateway software which would make it difficult to get any of the application layer stuff working. A gatteway is also useful for sniffing network traffic, but that can be done with any of the nodes and a serial port.

I think I'll start by reading through the IEEE 802.15.4 standard to gain some understanding of how the channels and encryption work. Those are likely to be key to the project. I may as well take the oppourtunity to draw some diagrams at the same time (which will help with report writing!).




I spent the week tidying the Linux format. This involved all of; making the code style consistent (with at least the DAG format), subclassing the ring format into another file and changing the format data to use the new list style format.

Tidying the code style was probably not needed as we can use an automated tool like astyle but I was just doing it as I went along with the other two tasks.

The new list style reduces the code duplication in the formats. The per thread format data and the main data format previously had some of the same parts. When using the threaded interface, there were a number of fields unused. By putting all of these per stream fields into a list, we can have a consistent interface for both the threaded and non-threaded API. This also simplifies the various API calls as the code is the same for both APIs.

Subclassing the ring format was needed to help maintainability. Ring really is a subclass of native, as a large number of the ring functions make use of the native functions. I moved the ring pieces into a new file, moved the format typedefs into a common header file and created a function to get a reference to the native format. The ring initialiser gets the native format and copies fields into the ring format.

I didn't manage to get the migration completed in the week, so I added the partial work to a branch and pushed that up to Richard's libtrace. The ring format compiles and needs to have the reading added back in. The rest of the functionality was copy-pasted and I assume that will work correctly. The native code needs more work to clean out the ring pieces and convert to the list format.

In hindsight, subclassing native as well as converting to the new list format might have been a bad idea. However, the way the format referencing was done in format_linux.c was not as easy to use as in format_dag25.c. Moving to the way it is done in format_dag25.c was going to be a large enough change anyway so I decided to just add in the list format style at the same time.




I haven't done a blog in ages! Oops.

Since my last blog, I have been refining the DAG format so the new cards work well. I wrote a bash script to configure the memory and hashing on the cards because that's a long process. Basically you tell the script how many streams you want, how much RAM you want to give them and which card to configure and it will go away and do just that.

I validated using ostinato and the dagsnap utility which showed a pretty good balance across all the streams.

The API between DAG 4 and DAG 5 changed slightly. I need to change how the configuration works by using the new CSAPI, and I also had to drop DUCK support. I really have no idea how DUCK works, and all references to the word DUCK have disappeared from the endace documentation. I left a helpful TODO message.

I also spent a bunch of time discussing how we're going to refactor the code base in the formats to better support using two different APIs - parallel and non-parallel libtrace. In the end we decided to use a linked list to hold per stream data. The non-parallel interface will get initialised and points to the first item in the list (FORMAT_DATA_FIRST). The parallel initialisation will add more entries to the end of the list. Any code that is common between the parallel and non-parallel code just get wrapped in a way that passes the correct data structure to the method.

Implementing this took a fair amount of time as there were a lot of references to modify. It compiled, and tracestats still counts the correct number of packets. I guess I should also make sure it performs well to be sure.