Create a generic Raspbian image with 6LoWPAN support

Sebastian Meiling edited this page Jun 5, 2018 · 48 revisions

Create a generic Raspbian image with 6LoWPAN support

Latest Notes and Known Issues

  • There seems to be a problem with the latest Kernel update 4.14.y, downgrade to 4.9.y as follows: sudo rpi-update 5c80565c5c0c7f820258c792a98b56f22db2dd03, see also blog entry and firmware commits
  • The current Raspbian (as of mid 2017) uses a Linux Kernel 4.9 which supports IEEE802.15.4 and 6LoWPAN
  • No issues reported for the OpenLabs IEEE802.15.4 transceiver, so far
  • But, there seem to be issues with the MRF24J40MA transceiver, while the device is correctly discovered and configured (even lowpan0) no frames can be send or received.

1. Objectives

This guide shows how to create a modified Raspbian Image that supports 6LoWPAN and runs on any variant of the Raspberry Pi, namely B, B+, 2B, and 3B. Step-by-step we will do the following:

  • prepare an initial Raspbian image for any Raspberry Pi
  • [optionally configure and build Linux Kernels for Pi B, B+, 2B, and 3B]
  • [install these WPAN capable Kernels into Raspbian]
  • install necessary WPAN tools
  • configure a 6LoWPAN device

2. Prepare Raspbian Image

2.1 Get and install Raspbian

  • First, we need the latest Raspbian Image, download here
  • there are 2 variants, namely Raspbian Jessie and Raspbian Jessie Lite, choose wisely:
    • if your Pi will be a server and a shell is all you need, go for the lite version
    • if you need a full fledged desktop GUI, e.g. with web browser, take standard Raspbian
  • under the hood they are basically the same, no worries here!
  • Second, we need to write the Image to a SDcard, OS specific guides are available here
  • for the impatient, it boils down to this:
# OSX, use diskutil to find right disk
sudo dd if=<path/to/raspbian.img> of=/dev/rdisk<N> bs=1m
# Linux, check 'ls /dev' for any new '/dev/sdX' 
sudo dd if=<path/to/raspbian.img> of=/dev/sdX bs=4M 
  • but, take a look at the guides!

2.2 Preconfigure Raspbian

  • plug the SDcard into your Pi and boot
    • login into the Pi with user pi and password raspberry
    • desktop GUI should login automatically
    • Note: standard keyboard layout is english so beware y and z!
  • first some initial configurations, run sudo raspi-config (open terminal in desktop GUI), and:
    • expand filesystem
    • change default password
    • fix keyboard layout, locals and timezone
    • if you need help
  • reboot and login again to resize root filesystem
  • if you have Internet connectivity, update Raspbian
sudo apt-get update && sudo apt-get upgrade
  • done, you may proceed ...

3. Enable support for IEEE 802.15.4/LoWPAN devices

3.1 transceiver specific device tree overlays

openlabs (AT86RF233)

  • there is an existing overlay for this transceiver shipped with Raspbian, should be here: /boot/overlays/at86rf233-overlay.dtb or /boot/overlays/at86rf233.dtbo
  • so just plug openlabs transceiver onto pinout interface of Raspberry Pi, see pinout image below.

microchip (MRF24J40MA)

Currently, there is no overlay for this transceiver available by default on Raspian, yet. So you need to build and install one yourself. But hey, that's pretty easy - no worries - just follow these steps:

  • install device tree compiler dtc:
sudo apt install device-tree-compiler
  • create file mrf24j40ma-overlay.dts
/dts-v1/;
/plugin/;

/ {
        compatible = "bcrm,bcm2835", "bcrm,bcm2836", "bcrm,bcm2708", "bcrm,bcm2709";

        fragment@0 {
                target = <&spi0>;
                __overlay__ {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "okay";

                        mrf24j40@0 {
                                compatible = "mrf24j40";
                                reg = <0>;
                                interrupts = <23 8>;
                                interrupt-parent = <&gpio>;
                                spi-max-frequency = <5000000>;
                        };

                        spidev@0 {
                                status = "disabled";
                        };

                        spidev@1 {
                                status = "disabled";
                        };
                };
        };
};
  • compile dst file and copy to /boot/overlays
dtc -@ -O dtb -o mrf24j40ma.dtbo mrf24j40ma-overlay.dts
sudo cp mrf24j40ma.dtbo /boot/overlays/.
  • plug microchip transceiver onto pinout interface of Raspberry Pi. Note with the overlay above, you have to connect RESET with pin 1 (alt.Reset) on the Pi pinout.

  • Alternatively, you can apply the patch to Raspberry Pi Linux-Kernel 4.7.y and use the device-tree overlay provided here. Before you compile the Kernel (see 4.) copy the dst file to arch/arm/boot/dts/overlays, this way it will be compiled together with the Kernel. Using the patch and this overlay allows for a simplified connection scheme, see figure above, and use only the pins/GPIOs in the pink box.

3.3 enable transceiver

  • to enable either one of the transceivers add/uncomment line in /boot/config.txt
dtoverlay=at86rf233
  • or
dtoverlay=mrf24j40ma
  • and reboot, afterwards you should be able to configure a lowpan device using tools see below
  • to check run ip link, you should see a wpan0 device if successful
  • if you have any trouble sending or receiving data with any of these transceivers:
    • use sniffer such as tshark, if you see corrupted IEEE 802.15.4 frames or checksum fail for its payload, you likely have to adapt (lower) SPI speed in /boot/config.txt
    • for instance the Atmel was very unstable at 4-6MHz, but with 3MHz it worked fine
    • so modify overlay to dtoverlay=at86rf233,speed=3000000

4. New Linux Kernels for the Pi

Otherwise building your own Linux Kernel for the Pi is typically fully optional. Really you must not do that if you simply want to test stuff! However, if you still want to ... here is how to do it anyway.

As the Pi has not the fastest CPU we opt for cross compiling a new Linux kernel; so unplug the Pi, eject the SD card and put it into a card reader of a more powerful machine. The following software tools are required:

  • Ncurses, development version, for Kernel configuration
  • GCC compiler (arm-linux-gnueabi) for ARMv6/7 CPUs

If you are running a Debian based Linux, use the following command to install required packages:

sudo apt-get install libncurses5-dev gcc-arm-linux-gnueabi

4.1 Download sources

  • create a base directory and change owner to your user:
sudo mkdir -p /opt/src/rpi_wpan
sudo chown <your-username> /opt/src/rpi_wpan
cd /opt/src/rpi_wpan
  • clone Raspberry Pi Linux-Kernel version 4.14 from Github:
git clone --depth 1 https://github.com/raspberrypi/linux.git \
    --branch rpi-4.14.y --single-branch linux-rpi
  • we don't want to mix things between Pi B,B+ and Pi 2B/3B, so just do it again
git clone --depth 1 https://github.com/raspberrypi/linux.git \
    --branch rpi-4.14.y --single-branch linux-rpi2
  • Note: if you don't need a Raspberry Pi version agnostic image (i.e., runs on any Pi), you can build only one Kernel either for the Pi1 or Pi 2 and 3.

  • we also need latest firmware files

git clone --depth 1 https://github.com/raspberrypi/firmware.git \
    --branch next --single-branch firmware
  • and finally the build tools with the right arm gcc compiler:
git clone --depth 1 https://github.com/raspberrypi/tools.git
  • now we should have 4 (or 3, if you only build 1 Kernel) directories under /opt/src/rpi_wpan namely firmware, linux-rpi, linux-rpi2, and tools

  • Note: to clone a single branch you need git with version > 1.7 (check with git --version)

4.2 Configure the Kernel

Again, if you only want to use the Raspbian image for a certain Pi version, you may configure and build only 1 Kernel.

steps for Raspi B and B+

  • change directory to /opt/src/rpi_wpan/linux-rpi
  • set PATH environment variable for tools (if you running 32Bit system, omit suffix -x64):
export PATH=/opt/src/rpi_wpan/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64:/opt/src/rpi_wpan/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/:$PATH
  • initials Kernel configuration with:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcmrpi_defconfig

steps specific to Raspi 2B and 3B

  • change directory to /opt/src/rpi_wpan/linux-rpi2
  • initials Kernel configuration with:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig

Kernel menuconfig (all Pi variants)

With the previous steps we configured the SPI for the Atmel IEEE 802.15.4 transceiver, now we have add Kernel support for IEEE 802.15.4 and 6LoWPAN.

  • run Kernel configuration with
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
  • enable general support for 802.15.4 and 6LoWPAN, goto:
Networking support
  --> Networking options
    --> IEEE Std 802.15.4 Low-Rate Wireless Personal Area Networks support
  • check all boxes (submenu too) and set them to <M> to build the required Kernel module
  • go back to top menu using <EXIT> in the bottom menu
  • next we add the network driver support, i.e., for the Atmel transceiver; goto:
Device Drivers
  --> Network device support
    --> IEEE 802.15.4 drivers
  • again check all boxes with <M>, submenus too and go back to the top menu
  • finally we set some boot options, goto:
Boot options
  --> () Default kernel command string
  • in the popup box enter:
console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait
  • go back to the top menu again and exit, saving the configuration with ```
  • do this for both Pi configurations

4.3 build Kernel and modules (all Pi variants)

  • compile the modified Linux Kernels by running the following commands in both directories:
CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm make zImage modules dtbs -j4
  • you can modify parameter -j to match number of cpu cores of your system: the more, the better

4.4 release the Kraken ... aehm Kernels

  • plug the SD-card with the prepared Raspbian Image into a card reader of your Linux system
    • likely your system will automount the boot and root partition somewhere, check where
    • if not, create 2 directories as mount points and mount the partitions, look for new devices named /dev/sdX{1,2} likely the one with the highest number, and run:
    sudo mkdir -p /tmp/mnt/boot
    sudo mkdir -p /tmp/mnt/root
    sudo mount /dev/sdX1 /tmp/mnt/boot
    sudo mount /dev/sdX2 /tmp/mnt/root
    
  • first we deploy the Kernel for Pi B and B+
cd /opt/src/rpi_wpan/linux-rpi
sudo cp arch/arm/boot/dts/*.dtb <path/to/boot-mount>/
sudo cp arch/arm/boot/dts/overlays/*.dtb* <path/to/boot-mount>/overlays
sudo scripts/mkknlimg arch/arm/boot/zImage <path/to/boot-mount>/kernel.img
  • next install the Kernel modules to the root partition (not boot!):
sudo CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm \
  INSTALL_MOD_PATH=<path/to/root-mount> make modules_install
  • now, we copy the Kernel for Pi 2B:
cd /opt/src/rpi_wpan/linux-rpi2
sudo cp arch/arm/boot/dts/*.dtb <path/to/boot-mount>/
sudo cp arch/arm/boot/dts/overlays/*.dtb* <path/to/boot-mount>/overlays
sudo scripts/mkknlimg arch/arm/boot/zImage <path/to/boot-mount>/kernel7.img
  • Note: the Kernel image name is kernel7.img!
  • next install the Kernel modules again for Pi 2B to the root partition (not boot!):
sudo CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm \
  INSTALL_MOD_PATH=<path/to/root-mount> make modules_install
  • finally we copy the new firmware files to the root partition:
cd ..
cd /opt/src/rpi_wpan/firmware
sudo rm -rf <path/to/root-mount>/opt/vc
sudo cp -r hardfp/opt/* <path/to/root-mount>/opt
  • that's it, now unmount both partitions an eject the Raspbian SD-card

4.5 Prevent Kernel Upgrades

To ensure that your custom kernel will not be overwritten by some system upgrade when running

sudo apt-get update && sudo apt-get upgrade

You should mark the kernel and bootloader packages as hold using the following commands:

sudo apt-mark hold raspberrypi-kernel
sudo apt-mark hold raspberrypi-bootloader

This should do the trick, but still be carefull when upgrading check the package list first!

4.6 Cutting edge Kernels

If you want to have (or need) an even newer Linux kernel with the latest 6LoWPAN development state, you have to compile from the bluetooth-next Kernel branch. There are already some guides to help you out on that, so we don't want to rewrite this here again. Check the following links, they should get you started:

  • for the MRF24J40 transceiver look here
  • and for the openlabs AT86RF233 transceiver here
  • also look at the website of the bluetooth-next development link

The drawback with these approaches is, that you likely loose device tree overlay support which the Raspbian bootloader provides. Thus, you have to use uboot and modify and compile full device tree files - no dynamic overlays on boot anymore :(

5. Install WPAN tools and configure 6LoWPAN devices

  • fire up you Raspberry Pi with the new kernel and login as user pi and open a terminal if you're using the desktop version
  • clone wpan-tools from Github, we'll put everything into /opt/src, todo so:
sudo apt install git
sudo mkdir /opt/src
sudo chown pi /opt/src
cd /opt/src
git clone https://github.com/linux-wpan/wpan-tools 
  • install some dependencies and packages, before building the wpan-tools:
sudo apt install dh-autoreconf libnl-3-dev libnl-genl-3-dev
  • next configure
cd /opt/src/wpan-tools
./autogen.sh
./configure CFLAGS='-g -O0' --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib
  • and afterwards build and install them
make
sudo make install
  • if everything worked fine, run a test command:
iwpan list
  • if any LoWPAN devices are present, they should be listed

  • if you haven't attached a device yet, the tool will print nothing - as long as no error occurs, that's fine

  • Well done, we are through with the basic steps - however, there is more

Acknowledgments

This guide borrows from and builds upon an older howto, see here