User Tools

Site Tools


Raspberry Pi - CC2520 Border Router

We want to create an 802.15.4 border router using a Raspberry Pi. This router will give greater visibility into 802.15.4 networks, allow for a more configurable border router that can store a practically infinite set of routes, and create a new platform for building IoT services.

More information can be found at:

Log (most recent event first)

Jan 13, 2013: LPL implementation is complete. Looks like right now we can't get super excellent duty-cycles because of the random collision avoidance. Tightening the initial backoff period will significantly increase packet reception rate. Right now with LPL it looks around 92-95% reception rates can be achieved with the “default” configuration. I'll add the ioctls to adjust these parameters.

  • One concern is the performance hit from LPL being enabled. It's not actually too bad. Brad had asked about whether it's a big deal that we can't selectively enable/disable it for specific packets. Well if we're sending to a non-LPL mote, as long as we request an ACK the packet will be echoed back immediately, which effectively terminates LPL, so I don't think it will be a big deal. Just avoid sending broadcast packets to a single, non-LPL host and you won't know the difference.
  • A better question is the performance hit from the random collision avoidance significant? We might need to create a way to disable this in the future, if we're doing large data dumps and stuff of that nature.

Jan 12, 2013: Implementing LPL, so far everything is going well. At some point we might need to add some sort of metadata information to

Jan 12, 2013: Added sample capture to GitHub repo for Salae.

Jan 11, 2013: All of the TX/RX functionality is now pretty much bullet-proof. I've implemented a couple disaster-mitigation strategies that recover the radio from race conditions. The two major ones are as follows:

  • TX Underflow Exceptions - Although the SPI driver runs in real-time mode, it (extremely) rarely will be interrupted by a scheduler activation after enabling TX, but before uploading the rest of the packet. When this occurs a TX underflow exception will occur and all further TX will be haulted until the exception is cleared, and the TX buffer is flushed. We now read the exception register at the end of each TX and check for this flag. If the flag is present we return a EBUSY error to the upper layers through the TXDONE callback and flush the buffers.
  • RX Overflow Excpetion - This happens primarily when the CC2520 accepts a stray RX packet. I think FitBit might actually be muddling the waters, not too sure. When the RX buffer fills up with an extremely large packet, usually a non 802.15.4-compliant packet transmitting using the same modulation scheme, it'll generate an RX overflow exception. We detect this by reading the length field, if the packet is too large for an 802.15.4 frame instead of reading it we simply flush the RX buffer.

Jan 7, 2013: Initial creation of this page. Goals are to better document the development and current status of the border router project. So far we've made really good progress:

  • The CC2520 chip has been successfully interfaced to by a kernel-mode driver.
  • Of interest is the work that has already been done in getting 802.15.4 support in the Linux kernel: here. It looks like they've done some really interesting work. I took a look at some of the code, a lot of it has even been mainlined into the Linux kernel. For some reason though they are missing some of the key pieces needed for a good 6LowPAN/RPL compliant interface that takes some of the innovations from TinyOS's world. I think they are focusing heavily on ZigBee. They don't provide for LPL or Soft-Acks, they don't discuss RPL or other routing protocols, and their IPv6 implementation seems to be very basic. They have an implementation of a CC2420 driver that will provide lower performance than the current implementation of the CC2520 driver I'm working on. The take-away is that they are creating a very general-purpose driver, and sacrificing a lot of functionality and performance because of this. Additionally development has stagnated as of March of last year. When we get closer to wanting to expose our driver as an actual network interface looking back at this work will be really valuable. They've fleshed out some of the hard parts of kernel-mode networking and at the very least the code serves as good contrast.

Jan 5, 2013: Some documentation on layering of the rx and tx laters.

  • The cc2520 driver will provide LPL support, Soft-Ack support, automatic retransmission (reliable link-layer emulation), filtering of duplicate packets, and automatic CSMA/CA algorithms. It starts to look a little monolithic, but it should also be very easy to understand the code. If we ever support more than one radio a lot of this code can be factored out into a common module. I don't know enough about the Linux kernel to do this right now, nor is it necessary to our primary goal at the moment.
  • The layers are separated along a pretty clearly defined interface, and I employed inversion of control in how they register each other. A interface struct accepts 3 function pointers, one for transmission, one as a callback for transmission being complete, and one callback when a packet is received.
  • These do resemble TinyOS's interfaces very closely. TinyOS has the benefit of creating an event abstraction, we use callbacks.
  • We need to be careful to keep things loosely coupled. It's going to get a little messy when the details of CMSA/CA (which needs to read the CCA flag) are implemented. I want to avoid too many direct function calls into the cc2520_* namespace. Ideally it will be possible to completely disable a layer with a recompile and only a line or two of code change.
  • I've noticed my code is a little more stratified than most Linux kernel drivers I've seen.

Road Map

Development has been scheduled to occur in a number of stages that will prove concepts and provide insight necessary to complete later stages:

  • Phase One: Proof of Concept Border Router
    • The goal of this phase is to prove that all the pieces needed to make this router possible are present. It is unclear whether the default Linux kernel will be able to support the real-time timing guarantees needed to interface directly with a radio chip. It's also unclear how TinyOS will fit into the whole picture, how it will interface with the chip, and what pieces of the device will be in user-mode or kernel-mode.
    • Deliverables at the end of this phase will look something like this:
      • A CC2520 kernel module that supports LPL, Soft-Acks, CSMA/CA, and auto retransmission.
      • A character driver interface that allows you to send and receive (more or less) raw 802.15.4 frames.
      • TinyOS interfaces to this character driver that run in user-land.
      • Documentation on the different parameters that can be controlled, such as channel, LPL intervals, and everything.
      • Sample applications that can send IPv6 frames from a TinyOS application, run in user-land.
  • Phase Two: Networking Exploration
    • With all the basics out of the way, we can start examining the networking aspects of this and how to integrate it cleanly with the Linux networking stack.
    • Deliverables:
      • A working RPL/IPv6 TinyOS router
      • Instructions and code that allow for PPP forwarding of packets from the TinyOS router to a PPP network interface running in Linux
      • Some data on the performance of the user-land TinyOS implementation. Does it need to move into the kernel? How does the scheduler mess with things? Should it be run as real-time?
      • More insight into how to increase the performance and cleanliness of the implementation.
  • Phase Three: Cleanup and Performance Work
    • We should know enough at this point to do some work on the performance of this thing, and general cleanliness of the implementation. Maybe pushing some things into the kernel, or working on a different way to present the network interface to Linux would be a good move.
    • Deliverables:
      • Instrumentation of the TinyOS code. It would be really cool to maybe integrate this with RabbitMQ so routing table adjustments and other stuff is pushed out as messages.
      • Performance updates. Identify bottlenecks and restructure code.
  • Phase Four: Above and Beyond
    • Web interfaces? CoAP implementation? Other services? Multiple border routers with a IPv6 Ethernet Backhaul? The sky is the limit!

Raspberry Pi Pins

For the Alpha board the GPIO pins of the CC2520 were not mapped to any specific RPi pins. You'll need to solder jumper wires.

Pin Function Bus Radio Function Saleae Color Leds
1 3.3 V
2 5 V
4 5 V
7 GPIO 4 LED 0
11 GPIO 17 RESET Orange
12 GPIO 18 LED 1
13 GPIO 27 LED 2
14 GND
15 GPIO 22 CCA (GPIO 3) Purple
16 GPIO 23 SFD (GPIO 4) Black
17 3.3 V
18 GPIO 24 FIFOP (GPIO 2) Brown
19 GPIO 10 SPI0_MOSI MOSI Yellow
20 GND
22 GPIO 25 FIFO (GPIO 1) Red
25 GND
26 GPIO 7 SPI0_CE1_N

Interface Board

We created a PCB interface board to attach the CC2520 evm module to the Raspberry Pi.

Low Level GPIO

Need to install bcm drivers.

BCM Drivers

  1. Download bcm2835 drivers
  2. ./configure
  3. make CC=“arm-linux-gnueabi-gcc -mcpu=arm1176jzf-s”
  4. mkdir /opt/arm1176jzf-s
  5. chown you:you /opt/arm1176jzf-s
  6. cp src/bcm2835.h /opt/arm1176jzf-s
  7. cp src/libbcm2835.a /opt/arm1176jzf-s


  • I see an 'Illegal Instruction' error!
    • You need to install the right cross compiler! apt-get install gcc-arm-linux-gnueabi make ncurses-dev
proj/rpibr/start.txt · Last modified: 2013/03/27 23:45 by bradjc