# 6LoWPAN on a RaspberryPi The aim is to get [6LoWPAN][1] running on a Rasberry Pi using a [Raspberry Pi 802.15.4 radio from openlabs][2] (based on the at86rf233) so we can later use it as a e.g. border router. The default Raspberry Pi kernel lacks support for recent [wpan-tools][3]. So we cross build a custom built kernel via tftp. In the following we assume the Raspberry Pi is at IP address 192.168.1.2 and does DHCP during boot. ## Setup the build environment and the RPi Since the kernel build would take a long time on the Rasberry Pi we're using a Debian System to crossbuild the kernel. ### Prepare cross toolhchain for Debian Jessie + Sid If you're running a RPi 2 you should be able to use the armhf toolchain provided by Debian already. $ dpkg --add-architecture armhf $ apt-get update $ apt-get install make ncurses-dev gcc-arm-linux-gnueabihf build-essential $ arm-linux-gnueabihf-gcc -v Using built-in specs. COLLECT_GCC=arm-linux-gnueabihf-gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/4.9/lto-wrapper Target: arm-linux-gnueabihf Configured with: ../src/configure -v --with-pkgversion=' 4.9.2-10' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,fortran --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --enable-multiarch --disable-sjlj-exceptions --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=arm-linux-gnueabihf --program-prefix=arm-linux-gnueabihf- Thread model: posix gcc version 4.9.2 ( 4.9.2-10) I don't have a Model 2 yet so I we have to grab the toolchain externally. ### Linaro For the Rpi 1 B and B+ use the Linaro toolchain. $ cd ~ $ git clone https://github.com/raspberrypi/tools $ export PATH=~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin:$PATH If you clone to another location be sure to adjusts the PATHs below too. ### The Linaro toolchain is 32bit and 64bit Lots of the examples are using the 32bit one so lets use this too: $ apt-get install lib32stdc++6 lib32z1 $ arm-linux-gnueabihf-gcc -v Using built-in specs. COLLECT_GCC=arm-linux-gnueabihf-gcc COLLECT_LTO_WRAPPER=/home/agx/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../libexec/gcc/arm-linux-gnueabihf/4.8.3/lto-wrapper Target: arm-linux-gnueabihf Configured with: /cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/src/gcc-linaro-4.8-2014.01/configure --build=i686-build_pc-linux-gnu --host=i686-build_pc-linux-gnu --target=arm-linux-gnueabihf --prefix=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/install --with-sysroot=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/install/arm-linux-gnueabihf/libc --enable-languages=c,c++,fortran --disable-multilib --enable-multiarch --with-arch=armv6 --with-tune=arm1176jz-s --with-fpu=vfp --with-float=hard --with-pkgversion='crosstool-NG linaro-1.13.1-4.8-2014.01 - Linaro GCC 2013.11' --with-bugurl=https://bugs.launchpad.net/gcc-linaro --enable-__cxa_atexit --enable-libmudflap --enable-libgomp --enable-libssp --with-gmp=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-mpfr=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-mpc=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-isl=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-cloog=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-libelf=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --enable-threads=posix --disable-libstdcxx-pch --enable-linker-build-id --enable-plugin --enable-gold --with-local-prefix=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/install/arm-linux-gnueabihf/libc --enable-c99 --enable-long-long --with-float=hard Thread model: posix gcc version 4.8.3 20140106 (prerelease) (crosstool-NG linaro-1.13.1-4.8-2014.01 - Linaro GCC 2013.11) ### Crossbuild an upstream kernel for the RPi For 6LowPAN the bluethoth-next true is a good starting point: $ git clone --depth=1 git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git $ export PATH=~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin:$PATH $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2835_defconfig $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- chrt -i 0 make -j 4 ### UBoot We want to boot the kernel using UBoot so we can conveniently swap out kernels using TFTP This is mostly copied from http://elinux.org/RPi_U-Boot . #### On the build host Crossbuild uboot $ git clone --deth=1 git://git.denx.de/u-boot.git $ export PATH=~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin:$PATH $ export CROSS_COMPILE=/home/agx/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf- $ export USE_PRIVATE_LIBGCC=yes $ make rpi_defconfig $ make -j4 -s #### On the RPI Configure the RPi to use the just built uboot $ PI_IP=192.168.1.2 $ echo "kernel=u-boot.bin" >> /boot/config.txt $ scp $PI_IP:u-boot/u-boot.bin /boot/u-boot.bin $ reboot #### On the tftp server Move the necessary files to the tftp server $ scp $PI_IP:bluetooth-next/arch/arm/boot/zImage rpi.img $ scp $PI_IP:bluetooth-next/arch/arm/boot/dts/bcm2835-rpi-b-plus.dtb . If you're using another PI model copy the corresponding device tree (dtb) file #### First Boot (Again mostly from http://elinux.org/RPi_U-Boot). Attach to the serial console, once uboot starts do a $ setenv fdtfile bcm2835-rpi-b-plus.dtb $ setenv bootargs earlyprintk console=ttyAMA0 console=tty1 root=/dev/mmcblk0p2 rootwait $ usb start $ dhcp ${kernel_addr_r} zImage $ tftp ${fdt_addr_r} ${fdtfile} $ bootz ${kernel_addr_r} - ${fdt_addr_r} #### Automate the boot Copy the above commands into a file called boot.src and do a mkimage -A arm -O linux -T script -C none -n boot.scr -d boot.scr boot.scr.uimg move that to /boot on your pi. Booting will from now on happen automatically. ## 6LoWPAN Now that we can quickly change and build kernels lets move to the 6LoWPAN part. ### Configuring the kernel and patching the DTS In order to enable support for the at86rf233 and 802.15.14 radio we need to change some kernel configuration. Since the board is connected vie API we change the DTS so it gets properly detected. This is readily done in this git repo: $ cd linux-wpan-next $ git remote add agx git://github.com/agx/linux-wpan-next.git $ git fetch rpi-6lowpan $ git co -b rpi-6lowpan -b agx/rpi-6lowpan Now lets reubuild DTS and kernel $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2835_defconfig $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- chrt -i 0 make -j 4 $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make dtbs Transfer the files to the TFTP server again as described above. ### Build the linxu-wpan tools Head over to your RPi. We build the wpan-tools there since they're small: $ git clone https://github.com/linux-wpan/wpan-tools $ sudo apt-get install autotools-dev libltdl-dev libnl-genl-3-dev $ cd wpan-tools && ./autogen.sh && make Now we have all the tools: $ src/iwpan list wpan_phy phy0 supported channels: page 0: 11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26 current_page: 0 current_channel: 13 cca_mode: 1 tx_power: 0 Upstream info on wpan-tools is at http://wpan.cakelab.org/ [1]: https://en.wikipedia.org/wiki/6LoWPAN [2]: http://openlabs.co/store/Raspberry-Pi-802.15.4-radio [3]: http://wpan.cakelab.org/