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:
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
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
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 | | | | |
3 | GPIO 2 | I2C0_SDA | | | |
4 | 5 V | | | | |
5 | GPIO 3 | I2C0_SCL | | | |
6 | GND | | | | |
7 | GPIO 4 | | | | LED 0 |
8 | GPIO 14 | UART0_TXD | | | |
9 | GND | | | | |
10 | GPIO 15 | UART0_RXD | | | |
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 | | | | |
21 | GPIO 9 | SPI0_MISO | MISO | Green | |
22 | GPIO 25 | | FIFO (GPIO 1) | Red | |
23 | GPIO 11 | SPI0_SCLK | SCLK | Blue | |
24 | GPIO 8 | SPI0_CE0_N | CS | | |
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
BCM Drivers
Download bcm2835 drivers
./configure
make CC=“arm-linux-gnueabi-gcc -mcpu=arm1176jzf-s”
mkdir /opt/arm1176jzf-s
chown you:you /opt/arm1176jzf-s
cp src/bcm2835.h /opt/arm1176jzf-s
cp src/libbcm2835.a /opt/arm1176jzf-s
Troubleshooting