Skip to content

How to install 6LoWPAN Linux Kernel on Raspberry Pi

Hauke Petersen edited this page Jun 14, 2017 · 53 revisions

How-to install and use 6LoWPAN on a Raspberry Pi with Linux Kernel rpi-4.1.y


NOTE: The installation guide on this page is largely outdated!

Please take a look at this guide for an updated version.


Table of Contents

Objective

This how-to will guide you to:

  • configure the Raspberry Pi Kernel for 802.15.4 and 6LoWPAN
  • patch in support for the openlabs Raspberry-Pi-802.15.4-radio device
  • compile a recent Linux kernel (rpi-4.1.y) for the Raspberry Pi
  • use the new built Kernel on your Raspberry Pi
  • and build WPAN tools to configure our 802.15.4 devices

Note: Further information and help to enable LoWPAN on a Raspberry Pi can be found in these guides and the associated repo.

Preparing the Raspberry Pi

For debugging, connect a UART adapter to the Pi, see for pinout:

http://elinux.org/RPi_Low-level_peripherals

Getting and installing Raspbian

To start off, we obtain the latest Raspbian image and flash it on our SDCard.

  • We download the official image from the Raspbian download site (scroll down a bit there),
  • and follow their provided guides to flash the downloaded Raspbian image to our SDCard.
    I suggest you to use a faster way than the command line way for installing (and make backups) Raspbian on RPI, like
  • WINDOWS: Win32diskimager https://sourceforge.net/projects/win32diskimager/
  • MAC-OSX: ApplePi-Baker http://www.tweaking4all.com/software/macosx-software/macosx-apple-pi-baker/
  • Then we Plug the SDCard and boot our Raspberry Pi.
  • Note, if you login the first time, the username is pi and the password is raspberry
  • Additional note, watch out if you have a german keyboard layout, the keys y and z are switched.
  • In the first run of our Raspberry, we set the filesystem to be expanded and set additional options for the system using the raspi-config tool. Then we let the Raspberry Pi reboot to finish the installation.
  • After the reboot we login and update the system by entering sudo apt-get update followed by sudo apt-get upgrade.

Get a new Raspberry Pi kernel (on a Linux Host)

We focus on cross compilation here, since we don't want to spend a night watching the build process ;).
To start, we need an appropriate and recent cross compiler (GCC for ARM) to build a new Raspbian kernel.
The Raspberry Pi requires a GCC for cortex a7 processors with hard fp (arm-gnueabihf) support.
So, our choice for a suiting GCC here is the Linaro GCC 4.9, which fulfills the requirements.
Note, you can use any other suiting GCC for the build process.
We download the appropriate tar.xz file and decompress it, e.g. directly in directory where we downloaded the file to.
To make the cross GCC ready to build things, we open a terminal and export the PATH to the newly decompressed GCC bin directory.
We enter:

export PATH=$PATH:/home/<myusername>/Downloads/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf/bin

Doing so we tell the environment (of the current terminal) the location of the cross GCC executables. (Please note, this may differ for your system).
To test if the export succeeded, we type arm-linux-gnueabihf-gcc --version, which should provides us with the version information of our cross GCC.
If not, the path export seems to be failed. You can check the export by entering $PATH in the terminal, which shows the content of the exported variable.
Please note, if you use a 64 bit Linux you may also need to install multilib support, i.e. i386 support.

Now we download the latest Raspberry Pi kernel sources from their Git repository.
We enter:

git clone --depth 1 https://github.com/raspberrypi/linux.git linux-rpi
cd linux-rpi
git checkout rpi-4.1.y
cd ..

Additionally we also obtain the latest firmware files.
We enter:

git clone --depth 1 https://github.com/raspberrypi/firmware.git firmware
cd firmware
git checkout next
cd ..

Now we have everything prepared to start configuring and building our new kernel.

Configure the new kernel

First we configure the sources with an appropriate configuration for the Raspberry Pi.
We switch in the kernel source folder, by entering cd linux-rpi. For the Raspberry 1, we use

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2835_defconfig

For the Raspberry 2, we first need to export KERNEL=kernel7, e.g. by using

export KERNEL=kernel7

and then call

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig

This provides us with an initial and basically complete configuration for the new kernel. In addition, we need to enable 802.15.4, 6LoWPAN and our specific transmission devices in the kernel, since its not provided in the default configuration.

We basically follow the openlabs guide, which instructs to setup an appropriate configuration for 802.15.4 and 6LoWPAN using an AT86RF233 SPI transceiver for a net-next kernel on a Raspberry Pi.
Contrary to the guide, we first patch the device tree, to enable support for the AT86RF233 SPI transceiver.
For the Raspberry 1 we load the arch/arm/boot/dts/bcm2835-rpi-b.dts, for the Raspberry 2 arch/arm/boot/dts/bcm2709-rpi-2-b.dts in our favorite editor and append the following part at the end:

&spi0 {
	status="okay";
	spidev@0{
		status = "disabled";
	};
	spidev@1{
		status = "disabled";
	};
	at86rf233@0 {
		compatible = "atmel,at86rf233";
		reg = <0>;
		interrupts = <23 4>;
		interrupt-parent = <&gpio>;
		reset-gpio = <&gpio 24 1>;
		sleep-gpio = <&gpio 25 1>;
		spi-max-frequency = <3000000>;
		xtal-trim = /bits/ 8 <0x0F>;
	};
};

This enables SPI on the Raspberry Pi and tells the kernel that our AT86RF233 SPI transceiver may be plugged over SPI (Pins 15-26) to it.

Now that we set-up the SPI connection for our AT86RF233 transceiver, we move on to configure our kernel for providing 802.15.4, 6LoWPAN and the transceiver device drivers.

We enter:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig

which provides us with the kernel configuration menu to configure/enable the above named features. If the menu does not appear, then we need to install a package by entering:

sudo apt-get install libncurses5-dev
  • First we enable 802.15.4 and 6LoWPAN support in our kernel.
    We traverse the menu to:
Networking support
  --> Networking options
    --> IEEE Std 802.15.4 Low-Rate Wireless Personal Area Networks support

enable the item if not already enabled, and enter the sub-menu of this item.
There we set all options either to be loaded as module <M> or as direct part of the kernel <*>.
We < Exit > back to Networking options and set 6LoWPAN Support if not already set.
Then traverse back to root menu.

  • Now we enable the drivers for our 802.15.4 devices (e.g. our AT86RF233 SPI transceiver).
    We traverse to:
Device Drivers
  --> Network device support
    --> IEEE 802.15.4 drivers

enable it if not already enabled, and enter the sub-menu.
There we set our driver(s) either to be loaded as module <M> or as direct part of the kernel <*>, e.g. <M> AT86RF230/231/233/212 transceiver driver.
Then we traverse back to root menu.

  • Finally we put in some default Boot options We traverse to:
Boot options
  --> () Default kernel command string

hit the enter key and type

console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait

in the "popped-up" input field.
Then we hit < Ok > and got back to the root menu.

There we hit < Save > and store the configuration in the proposed file (.config) followed by < Exit > to leave the kernel configuration menu.

Build our new kernel

After we finished our configuration, we fire the build process of our new kernel.
We enter:

CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm make zImage modules dtbs -j8

and have break.
When all is finished, we collect all built modules together in a .mods folder.
We enter:

CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm INSTALL_MOD_PATH=.mods make modules_install

which copies all .ko files to the provided directory, i.e. .mods.

Use the new kernel

Now that we built a recent kernel we need to copy with the modules and the firmware to our SDCard.
First the kernel:

sudo cp arch/arm/boot/dts/*.dtb /media/<myusername>/boot/
sudo cp arch/arm/boot/dts/overlays/*.dtb* /media/<myusername>/boot/overlays
sudo scripts/mkknlimg arch/arm/boot/zImage /media/<myusername>/boot/kernel.img

After this, we copy the modules:

sudo cp -r .mods/lib/* /media/<myusername>/<SDCardpatitionname>/lib

and the prebuilt firmware files for hard fp:

cd ..
cd firmware
sudo rm -rf /media/<myusername>/<SDCardpatitionname>/opt/vc
sudo cp -r hardfp/opt/* /media/<myusername>/<SDCardpatitionname>/opt

As last step we need to tell the bootloader which device configuration it should use, i.e. bcm2835-rpi-b.dtb. We fire our favorite editor open the /media/<myusername>/boot/config.txt file and for the Raspberry 1 append

device_tree=bcm2835-rpi-b.dtb
device_tree_address=0x100

for the Raspberry 2, we append

device_tree=bcm2709-rpi-2-b.dtb
device_tree_address=0x100

Finally we save the changes to the file. That's it :D our SDCard is prepared to run the new kernel.

So, we unmount the SDCard, plug it in the Raspberry Pi and let it boot. If everything went fine, we should see the usual boot process. If you see a colored screen permanently (in case you plugged a monitor to your Raspberry Pi) something went wrong.

Install some needed packets on the Pi:

sudo apt-get install libnl-3-dev libnl-genl-3-dev wireshark

Build and install the WPAN tools

After logging in, we need the WPAN tools to setup and use one of our 802.15.14 devices. First we need to install the dh-autoreconf package to be able to build the recent WPAN tools. We type

sudo apt-get install dh-autoreconf

Then we clone the latest wpan-tools sources

git clone https://github.com/linux-wpan/wpan-tools
cd wpan-tools

build them

./autogen.sh
./configure CFLAGS='-g -O0' --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib
make

and finally install them

sudo make install

Configure your WPAN device

Please note: Before we can begin to setup our connected device with the previously built wpan-tools, we need to put the connected interface, e.g. wpan0, down. (Be cautious, it might be that the at86 adapter will get assigned a different name, e.g. wpan1 if another wireless interface is connected.) To check if the device is up and active we enter ifconfig and should be presented with a list of running interfaces including our wpan0.
Now usually the ifplugd daemon is active in Raspbian. Basically it activates connected interfaces automatically.
So before we can set our wpan0 interface down, we need to prevent that the ifplugd daemon reactivates the device back immediately.
So we enter:

ps -ax | grep ifplugd 

look for the line with our WPAN device, and kill the corresponding daemon.
For instance entering the above may present us with (or similar):

...
1706 ?    S   0:07 /usr/sbin/ifplugd -i wpan0 -q -f -u0 -d10 -w -I
...

then we kill this specific daemon instance be entering

sudo kill -KILL 1706

After this we can set our wpan0 interface down, and it stays down. Now we can start to configure our device.

For testing, follow some of the instructions at http://wpan.cakelab.org/#_how_to_8217_s

802.15.4 Monitoring Example

Prerequisites

  • Hardware
  • Desktop running Wireshark
  • RaspberryPi
  • OpenLabs Raspberry Pi 802.15.4 radio
  • Atmel SAM R21 (used as testing device sending 802.15.4 packets)
  • Software
  • RaspberryPi setup as described above
  • RIOT example/ng_networking

Setup

Atmel SAM R21

  1. Checkout RIOT
  2. Change to the examples/ng_networking folder cd examples/ng_networking
  3. Add cross-compiler toolchain to the environment ```export PATH=~/Downloads/gcc-arm-none-eabi-4_9-2014q4/bin/:$PATH````
  4. Connect SAM R21 to your desktop
  5. Build env BOARD=samr21-xpro make
  6. Flash to SAM R21 sudo env BOARD=samr21-xpro make flash

RaspberryPi (with OpenLabs Raspberry Pi 802.15.4 radio)

  1. Follow the build and setup instructions from above
  2. Quit potentially running system deamon sudo kill -s KILL `pgrep ifplugd`
  3. Set a PAN_ID sudo iwpan dev wpan0 set pan_id 0xbeef
  4. Create monitoring interface sudo iwpan phy phy0 interface add monitor%d type monitor
  5. Bring the wpan interface down sudo ip link set wpan0 down
  6. Bring monitoring interface up sudo ip link set monitor0 up
  7. Set the correct channel, the RIOT example/ng_networking uses channel 26 by default sudo iwpan phy phy0 set channel 0 17

Monitoring

Desktop

  1. Start local Wireshark and feeding it remote live capture data from the RaspberryPi 802.15.4 interface wireshark -k -i <( ssh pi@<Raspberry_PI_IP> "sudo dumpcap -P -i monitor0 -w -")
  • if this doesn't work for you can alternatively try:
    ssh pi@<Raspberry_PI_IP> 'sudo dumpcap -P -i monitor0 -w -' | sudo wireshark -k -i -
    Note, on the command line you may be prompted with:
    [sudo] password for <username>: pi@<Raspberry_PI_IP>'s password:
    It requires to enter the [sudo] password for your local <username> first, which fires wireshark, and to enter the password for the RaspberryPI afterwards which starts passing the dumpcap to wireshark.
  1. Change to the examples/ng_networking folder cd examples/ng_networking
  2. Open terminal to Atmel SAM R21 sudo env BOARD=samr21-xpro make term
  3. Run network command ping6 fe80::ff:fe00:c07f
  4. You should see packets in Wireshark.

Example Gateway Configuration using ULAs (Unique Local Addresses)

Requirements:

  • Laptop (Linux)
  • Raspberry Pi with a Linux as decribed above
  • 801.15.4 openlabs adapater for Pi
  • Sensor node running RIOT (ng_networking example)

802.15.4 Settings:

  • NID: 0x23
  • Channel: 12

Notes

  • More sensible prefix length should be possible.

External Host

###OS X Remote Host

Tried it. It doesn't like /120 prefixes and manual static IPv6 routes. Could work with /64 prefixes but I didn't try that yet.

or

###Linux Remote Host # Load ipv6 kernel module modprobe ipv6

# Set ULA address
ip address add fd2d:0388:6a7b:0001:0000:0000:0000:0002/120 dev eth0

# Add route for gateway
ip -6 route add fd2d:388:6a7b:3::1/120 dev eth0

# Add route for IoT devices
ip -6 route add fd2d:388:6a7b:2::/120 via fd2d:388:6a7b:3::1

Raspberry Pi: Border Gateway

# configure 6LoWPAN interface for channel 12 and PAN ID 0x23
kill -s KILL `pgrep ifplugd`
modprobe ipv6
ip link set wpan0 down
ip link set lowpan0 down
iwpan phy phy0 set channel 0 12
ip link add link wpan0 name lowpan0 type lowpan
iwpan dev wpan0 set pan_id 0x23
ip link set wpan0 up
ip link set lowpan0 up

# gateway scenario setup
sysctl -w net.ipv6.conf.all.forwarding=1

# set ULA on eth0
ip address add fd2d:0388:6a7b:0003:0000:0000:0000:0001/120 dev eth0

# set ULA on lowpan0
ip address add fd2d:0388:6a7b:0002:0000:0000:0000:0001/120 dev lowpan0

# add route for remote host
ip -6 route add fd2d:388:6a7b:1::/120 dev eth0

# disable 6LoWPAN UDP header compression
#rmmod nhc_udp # this is now supported in RIOT

SAM R21: IoT Device

# Set 802.15.4 channel
ifconfig 7 set channel 12

# Set ULA address
ifconfig 7 add fd2d:0388:6a7b:0002:0000:0000:0000:0003/120

    # Set default route
    fibroute add :: via <RPi link-local address on lowpan0>

Testing from RIOT

# The first ping the gateway
ping6 3 fd2d:0388:6a7b:2::2 3 2000
      | |                   | |
      | |                   | +------- Timeout in milliseconds
      | |                   +--------- Size in bytes
      | +----------------------------- Target address
      +------------------------------- Number of pings
      
# Ping the remote host
ping6 3 fd2d:0388:6a7b:1::1 3 2000
Clone this wiki locally