-
Notifications
You must be signed in to change notification settings - Fork 2k
How to install 6LoWPAN Linux Kernel on Raspberry Pi
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
http://elinux.org/RPi_Low-level_peripherals
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.
- Then we Plug the SDCard and boot our Raspberry Pi.
- Note, if you login the first time, the username is
pi
and the password israspberry
- Additional note, watch out if you have a german keyboard layout, the keys
y
andz
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 bysudo apt-get upgrade
.
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 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 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.
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
followed by:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2835_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.
We load the arch/arm/boot/dts/bcm2835-rpi-b.dts
file 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-tpio = <&gpio 25 1>;
spi-max-frequency = <6000000>;
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.
- 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.
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
.
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, append
device_tree=bcm2835-rpi-b.dtb
device_tree_address=0x100
at the end and save it.
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.
sudo apt-get install libnl-3-dev libnl-genl-3-dev wireshark
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
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
- 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
- Checkout RIOT
- Change to the examples/ng_networking folder
cd examples/ng_networking
- Add cross-compiler toolchain to the environment ```export PATH=~/Downloads/gcc-arm-none-eabi-4_9-2014q4/bin/:$PATH````
- Connect SAM R21 to your desktop
- Build
env BOARD=samr21-xpro make
- Flash to SAM R21
sudo env BOARD=samr21-xpro make flash
- Follow the build and setup instructions from above
- Configure IP of the RaspberryPi
- Insert SD card into reader
- Append your IP configuration (
ip=121.211.112.121
) in the first line of cmdline.txt on the boot partition - Return SD card to the RaspberryPi
- Connect the RaspberryPi to network and power
- Connect to the RaspberryPi via SSH
ssh [email protected]
- For easy of reconnection add your public key to
~/.ssh/authorized_keys
(in case it does not exist yet, just create folder and file) - Quit potentially running system deamon
sudo kill -s KILL `pgrep ifplugd`
- Set a PAN_ID
sudo iwpan dev wpan0 set pan_id 0xbeef
- Create monitoring interface ```sudo iwpan phy phy0 interface add monitor%d type monitor````
- Bring monitoring interface up
sudo ifconfig monitor0 up
- Set the correct channel, the RIOT example/ng_networking uses channel 17 by default
sudo iwpan phy phy0 set channel 0 17
- Start local Wireshark and feeding it remote live capture data from the RaspberryPi 802.15.4 interface
wireshark -k -i <( ssh [email protected] "sudo dumpcap -P -i monitor0 -w -")
- if this doesn't work for you can alternatively try:
ssh [email protected] 'sudo dumpcap -P -i monitor0 -w -' | sudo wireshark -k -i -
- Change to the examples/ng_networking folder
cd examples/ng_networking
- Open terminal to Atmel SAM R21
sudo env BOARD=samr21-xpro make term
- Run network command
ping6 fe80::ff:fe00:c07f
- You should see packets in Wireshark.
- Laptop (Linux)
- Raspberry Pi with a Linux as decribed above
- 801.15.4 openlabs adapater for Pi
- Sensor node running RIOT (ng_networking example)
- NID: 0x23
- Channel: 12
- More sensible prefix length should be possible.
###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
ifconfig eth0 inet6 add fd2d:0388:6a7b:0001:0000:0000:0000:0002/120
# 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
# configure 6LoWPAN interface for channel 12 and PAN ID 0x23
kill -s KILL `pgrep ifplugd`
modprobe ipv6
ifconfig wpan0 down
ifconfig 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
ifconfig wpan0 up
ifconfig lowpan0 up
# gateway scenario setup
sysctl -w net.ipv6.conf.all.forwarding=1
# set ULA on eth0
ifconfig eth0 inet6 add fd2d:0388:6a7b:0003:0000:0000:0000:0001/120
# set ULA on lowpan0
ifconfig lowpan0 inet6 add fd2d:0388:6a7b:0002:0000:0000:0000:0001/120
# add route for remote host
ip -6 route add fd2d:388:6a7b:1::/120 dev eth0
# 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
# 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