NOTICE: The Processors Wiki will End-of-Life on January 15, 2021. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.
WL1835 Cape on BeagleBone with Debian
Adding WL1835 Cape Support to Debian K3.8 Build[edit]
This page describes how to build a clean Debian K3.8 release that supports WL1835 Cape to add Wi-Fi and enable Bluetooth so that Bluez can be used. There are two points to note about it.
- The script is only for cross-compiling on a Linux Host (tested with 32 and 64 bit Ubuntu 12.04). See this link for possible additional packages that may need to be installed for the build script to run correctly.
- The WL1835 Cape uses the same MMC interface as the eMMC on BeagleBone and so if the cape is being used then eMMC is not available and so board must boot from microSD card.
History
Current version of code is v0.4.2. This updates build script to match wiki.
Previous Versions
- v0.4.1 This changes CONFIG_CRYPTO options to =y to allow wpa_supplicant to connect to secured APs and updates /opt/scripts to the latest versions to get the USB ethernet driver installing correctly on boot to allow SSH to work.
- v0.4. This picks up the migration to Debian filesystem 7.8 (as 7.7 has been removed) and u-boot 2015.01
- v0.3. This adds missing support for "fixed-regulator" in omap-hsmmc.c to drive WL_EN and corrects the gpio value in DTS file. This allows ifconfig wlan0 up and down to work correctly.
Building[edit]
Create a build directory and download and extract this patch set to this directory. Run the script wl8-build.sh which will download, patch and build the kernel and create a populated Debian Filesystem which can then be written to an SD card. This is basically scripting the build process described at https://eewiki.net/display/linuxonarm/BeagleBone+Black#BeagleBoneBlack-Debian7 with the addition of all the kernel patches and WL18xx Wi-Fi driver build steps.
A prebuilt version of u-boot and the filesystem are available here. Download them and then follow the instructions in the "Programming uSD Card" section to quickly get a system running.
Run script.
./wl8-build.sh
The content of the script is listed here and is hopefully self commented. When the script runs it calls a make menuconfig, select the exit option and then the save option. This does however mean that it is not possible to pipe the output of the build to a file.
#!/bin/bash #Copyright (c) 2014 Texas Instruments # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: #The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # This is a build script to create a Debian based Linux kernel 3.8 and filesystem based on debian 7.8 # that adds the TI WL18xx drivers and supplicant to support Wi-Fi for Wl1835 BeagleBone Cape # https://eewiki.net/display/linuxonarm/BeagleBone+Black#BeagleBoneBlack-Debian7 # version 0.4.2 # update debian to 7.8 and u-boot to 2015.01 following Robert Nelson's changes in April 2015 if [ ! -e fs-downloaded ] then if [ ! -e fs ] then mkdir fs fi cd fs || exit wget -c https://rcn-ee.com/rootfs/eewiki/minfs/debian-7.8-minimal-armhf-2015-01-20.tar.xz tar xf debian-7.8-minimal-armhf-2015-01-20.tar.xz cd debian-7.8-minimal-armhf-2015-01-20 if [ ! -e rootfs ] then mkdir rootfs fi cd rootfs FS=`pwd` sudo tar xf ../armhf-rootfs-debian-wheezy.tar . cd ../.. touch ../fs-downloaded cd .. else # just set FS FS=`pwd`/fs/debian-7.8-minimal-armhf-2015-01-20/rootfs cd fs/debian-7.8-minimal-armhf-2015-01-20 || exit sudo rm -r rootfs/ mkdir -p rootfs cd rootfs sudo tar xf ../armhf-rootfs-debian-wheezy.tar . cd ../../.. fi if [ ! -e dtc-compiler-downloaded ] then #upgrade dtc compiler wget -c https://raw.github.com/RobertCNelson/tools/master/pkgs/dtc.sh chmod +x dtc.sh ./dtc.sh touch dtc-compiler-downloaded fi #Download kernel and build it clean #part of the process is to download gcc 4.7 and so do this before uboot if [ ! -e kernel-built ] then if [ ! -e kernel-git-downloaded ] then sudo rm -r bb-kernel git clone https://github.com/RobertCNelson/bb-kernel.git touch kernel-git-downloaded else # remove bb-kernel patches cd bb-kernel git checkout patch.sh patches/defconfig system.sh.sample cd .. fi cd bb-kernel/ # Need to checkout the specific tag that the patch set was developed for - Dec 2014 # more recent commits/tags in the branch origin/am33x-v3.8 will break the patch set # to use a more recent tag you will need to manually update the patch sets (for patch.sh) # at least in this build package to be able to apply the wl8 cape patches git checkout 3.8.13-bone68 -b tmp # for a multi-core system set CORES unset CORES_SET CORES_SET=`grep -r CORES system.sh.sample` if [ -z ${CORES_SET} ]; then echo "CORES=8" >> system.sh.sample fi # the kernel must be built as is - trying to add wl8 defconfigs at this stage # will break the unsupported ti wifi drivers in the 3.8 kernel # we do apply the patches for device tree and wl12xx.h as they are needed and then patch defconfig # to not compile ANY TI wifi driver # all the patches are copied into bb-kernel/patches so they will be applied by patch.sh cp ../patches/kernel-patches/0001-change-device-tree-to-enable-BT-uart-enables-for-WL1.patch patches/capes/1001-change-device-tree-to-enable-BT-uart-enables-for-WL1.patch cp ../patches/kernel-patches/0016-update-wl12xx-h.patch patches/capes/1002-update-wl12xx-h.patch # these are relevant MMC patches for K3.8 from http://processors.wiki.ti.com/index.php/WL18xx_AMxxx_platform_integration_guide#Kernel_Patches cp ../patches/kernel-patches/0001-mmc-omap_hsmmc-add-DT-power-properties.patch patches/capes/1003-mmc-omap_hsmmc-add-DT-power-properties.patch cp ../patches/kernel-patches/0002-mmc-omap_hsmmc-Power-down-capable-mmc-slots.patch patches/capes/1004-mmc-omap_hsmmc-Power-down-capable-mmc-slots.patch cp ../patches/kernel-patches/0005-mmc-provide-a-standard-MMC-device-tree-binding-parse.patch patches/capes/1005-mmc-provide-a-standard-MMC-device-tree-binding-parse.patch cp ../patches/kernel-patches/0006-mmc-add-DT-bindings-for-more-MMC-capability-flags.patch patches/capes/1006-mmc-add-DT-bindings-for-more-MMC-capability-flags.patch cp ../patches/kernel-patches/0007-add-regulator-support-to-omap_hsmmc.patch patches/capes/1007-add-regulator-support-to-omap_hsmmc.patch # Modify defconfig to remove all TI wifi from kernel build patch -p1 < ../patches/kernel-patches/0012-defconfig-wl8.patch || exit # update patch.sh to apply these new patches patch -p1 < ../patches/kernel-patches/0015-add-dt-patch-to-patch.sh.patch || exit ./build_kernel.sh || exit cd .. #touch a file to say that kernel config is in no ti wifi configuration touch kernel-config-no-wilink touch kernel-built fi # work on principle there is a file bb-kernel/deploy/config-x.y.z-boneX cd bb-kernel/deploy export kernel_version=`find . -name config* | cut -d'-' -f 2,3` cd ../.. echo "kernel_version:${kernel_version}" # now that kernel is built copy the zImage and modules to rootfs sudo mkdir -p ${FS}/boot/dtbs/${kernel_version}/ sudo sh -c "echo 'uname_r=${kernel_version}' > ${FS}/boot/uEnv.txt" sudo sh -c "echo 'cmdline=quiet init=/lib/systemd/systemd' >> ${FS}/boot/uEnv.txt" sudo sh -c "echo 'cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN,BB-BONE-EMMC-2G' >> ${FS}/boot/uEnv.txt" sudo sh -c "cat ./patches/kernel-patches/uEnv.txt >> ${FS}/boot/uEnv.txt" sudo cp -v bb-kernel/deploy/${kernel_version}.zImage ${FS}/boot/vmlinuz-${kernel_version} || exit sudo tar xfv bb-kernel/deploy/${kernel_version}-dtbs.tar.gz -C ${FS}/boot/dtbs/${kernel_version}/ || exit sudo tar xfv bb-kernel/deploy/${kernel_version}-modules.tar.gz -C ${FS}/ || exit # set up file system table sudo sh -c "echo '/dev/mmcblk0p1 / auto errors=remount-ro 0 1' >> ${FS}/etc/fstab" # setup serial login sudo sh -c "echo 'T0:23:respawn:/sbin/getty -L ttyO0 115200 vt102' >> ${FS}/etc/inittab" # enable eth0 on beagle sudo sh -c "echo ' auto lo iface lo inet loopback auto eth0 iface eth0 inet dhcp iface usb0 inet static address 192.168.7.2 netmask 255.255.255.0 network 192.168.7.0 gateway 192.168.7.1 ' > ${FS}/etc/network/interfaces" # and ensure that eth0 is always used even if SD card used on another board already sudo sh -c "echo '# BeagleBone: net device() SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{dev_id}=="0x0", ATTR{type}="1", KERNEL=="eth*", NAME="eth0"' > ${FS}/etc/udev/rules.d/70-persistent-net.rules" # write /boot/SOC.sh so that /etc/init.d/generic-boot-script.sh will insert g_ether to enable SSH # access to 192.168.7.2 from PC sudo sh -c "echo ' #!/bin/sh board=am335x_evm' > ${FS}/boot/SOC.sh" # Get latest Robert Nelson boot scripts so that USB g_ether will be loaded correctly # which will allow SSH to be done to 192.168.7.2 over USB cd fs || exit if [ ! -e RobertCNelsonScripts ] then mkdir RobertCNelsonScripts else sudo rm -r RobertCNelsonScripts/* || exit fi cd RobertCNelsonScripts || exit git clone git://github.com/RobertCNelson/boot-scripts.git cd boot-scripts || exit git checkout master cd .. # move default /opt/scripts sudo mv ${FS}/opt/scripts ${FS}/opt/scripts-std || exit # and copy in updated ones sudo mkdir -p ${FS}/opt/scripts || exit sudo cp -r boot-scripts/. ${FS}/opt/scripts/ || exit cd ../.. # Clean out all obsolete TI connectivity fw from FS sudo rm -rf ${FS}/lib/firmware/ti-connectivity/* # now set gcc 4.7 downloaded by kernel build as the toolchain #extract the compiler name from the tar.xz file name to handle either 32 or 64 bit versions cd bb-kernel/dl COMPILER_NAME=`find . -maxdepth 1 -type f | cut -d'/' -f 2 | sed 's/.tar.xz//'` cd ../.. CC=`pwd`/bb-kernel/dl/${COMPILER_NAME}/bin/arm-linux-gnueabihf- if [ ! -e uboot-downloaded ] then git clone git://git.denx.de/u-boot.git || exit cd u-boot/ # update to latest tag git checkout v2015.01 -b tmp || exit # and patch it wget https://rcn-ee.com/repos/git/u-boot-patches/v2015.01/0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch || exit patch -p1 < 0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch || exit # as u-boot is rarely rebuilt just do it once after download make ARCH=arm CROSS_COMPILE=${CC} distclean || exit make ARCH=arm CROSS_COMPILE=${CC} am335x_evm_defconfig || exit make ARCH=arm CROSS_COMPILE=${CC} || exit touch ../uboot-downloaded cd .. fi sudo mkdir -p ${FS}/opt/backup/uboot/ sudo cp -v ./u-boot/MLO ${FS}/opt/backup/uboot/ sudo cp -v ./u-boot/u-boot.img ${FS}/opt/backup/uboot/ # Now that the kernel has been build with no TI wifi need to add the patches to Kconfig for WL18xx and # those to add Wl18xx to the defconfig file so that WL18xx drivers can be built against an updated # .config that will support it. The change in config does not affect anything built in the kernel. if [ -e kernel-config-no-wilink ]; then # first thing we do is patch kernel KConfigs and .config to now allow WL8 drivers # assume that kernel cd bb-kernel/KERNEL patch -p1 < ../../patches/kernel-patches/0013-update-Kconfig-to-wilink-platform.patch || exit patch -p1 < ../../patches/kernel-patches/0017-add-wl8-configs.patch || exit cd ../.. touch kernel-config-wilink rm kernel-config-no-wilink fi # ensure config and autogenerated /include files are updated cd bb-kernel/KERNEL make ARCH=arm CROSS_COMPILE="${CC}" oldconfig || exit cd ../.. # still need to build all the user space tools, wifi kernel drivers and download firmwares if [ ! -e wifi-downloaded ] then mkdir -p wifi-wl8 cd wifi-wl8 git clone git://git.ti.com/wilink8-wlan/build-utilites.git || exit cd build-utilites || exit cp ../../patches/wifi-build-patches/setup-env . || exit # Errors here referring to being unable to create directories are ok here. The filesystem is owned by root # and so user can't create some directories. This is not a problem as the actual build is run under sudo # We do not run the step as root as it would make root the owner of all the source files. ./build_wl18xx.sh update R8.5 touch ../../wifi-downloaded cd ../.. fi # now build and install wifi drivers cd wifi-wl8/build-utilites # do a clean and build . ./sudo_build_wl18xx.sh clean || exit cd ../.. # now tar up the rootfs cd ${FS} sudo tar -czf ../../tar-rootfs.tar.gz * cd ../.. echo "Build Successful"
Programming uSD card[edit]
The build process above will create the uboot files for the boot partition and a tar.gz file with the file system. The script programme-sd.sh will take these and programme an SD card. The script takes one argument which is the device name for the sd card. So if the card is mounted as /dev/sdc, then the argument passed is sdc.
$./programme-sd.sh sdc
The script is basically just an implementation of the instructions from https://eewiki.net/display/linuxonarm/BeagleBone+Black with some extra handling to automate the mounting of drives taken from SDK7
#!/bin/bash #Copyright (c) 2014 Texas Instruments # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: #The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # script to programme SD card following instructions from https://eewiki.net/display/linuxonarm/BeagleBone+Black if [ $# -eq 1 ]; then echo "will use drive /dev/$1" DEVICEDRIVENAME=$1 DISK=/dev/$DEVICEDRIVENAME NUM_OF_DRIVES=`df | grep -c $DISK` # This if statement will determine if we have a mounted sdX or mmcblkX device. # If it is mmcblkX, then we need to set an extra char in the partition names, 'p', # to account for /dev/mmcblkXpY labled partitions. if [[ ${DEVICEDRIVENAME} =~ ^sd. ]]; then echo "$DRIVE is an sdx device" P= else echo "$DRIVE is an mmcblkx device" P='p' fi if [ "$NUM_OF_DRIVES" != "0" ]; then echo "Unmounting the $DEVICEDRIVENAME drives" for ((c=1; c<="$NUM_OF_DRIVES"; c++ )) do unmounted=`df | grep '\<'$DEVICEDRIVENAME$P$c'\>' | awk '{print $1}'` if [ -n "$unmounted" ] then echo " unmounted ${DISK}$P$c" sudo umount -f ${DISK}$P$c fi done fi # erase it sudo dd if=/dev/zero of=${DISK} bs=1M count=10 # and write MLO & uboot sudo dd if=./u-boot/MLO of=${DISK} count=1 seek=1 conv=notrunc bs=128k sudo dd if=./u-boot/u-boot.img of=${DISK} count=2 seek=1 conv=notrunc bs=384k # now create partition sudo sfdisk --in-order --Linux --unit M ${DISK} <<-__EOF__ 1,,0x83,* __EOF__ DISK_IN_USE=${DISK}${P}1 echo "now try to format ${DISK_IN_USE}" sleep 2 # and format it sudo mkfs.ext4 ${DISK}${P}1 -L rootfs sync sync #mount rootfs sudo mkdir -p rootfs-sd echo "sudo mount -t ext4 ${DISK_IN_USE} rootfs-sd" sudo mount -t ext4 ${DISK_IN_USE} rootfs-sd || exit echo "successfully mounted" # Now extract rootfs cd rootfs-sd sudo tar -zxvf ../fs/tar-rootfs.tar.gz cd .. sync echo "sudo umount -f ${DISK_IN_USE} || exit" sudo umount -f ${DISK_IN_USE} || exit sudo rm -r rootfs-sd echo "successfully unmounted" else echo "must take argument of SD card device after /dev/, so /dev/sdd is sdd" fi
Running the System[edit]
Now that there is a programmed uSD card from either the pre-built files or just built it is time to boot the BeagleBoneBlack and WL1835 Cape. The WL1835MOD cape uses the same MMC interface as the eMMC memory on the BeagleBoneBlack. This means that switch S2 must be held down when the power is first applied to force booting from uSD. This is slightly awkward as S2 is under the cape so recommendation is to use something like a pen to hold it down. This is only required when power is applied, the boot mode is retained when reset button (S1) is pressed.
When the device tree file is loaded it should enable both the WL_EN and BT_EN signals which will illuminate LED1 and LED2 on the cape.
Currently when the BeagleBoneBlack first boots it is taking about 2 minutes for the USB ethernet port to install. So wait before trying to connect to 192.168.7.2 over SSH. Subsequent boots appear to be quicker, especially if the ethernet is working.
Configuring the system[edit]
On the first boot there are a couple of system configurations that need to be done.
- By default the Debian file system includes its own wpa_supplicant executable which is auto started by systemd. So to prevent this version of the supplicant being run on boot, disable it in systemd as follows
#systemctl disable wpa_supplicant.service
- The Debian filesystem does not include the udhcpc DHCP client used to request an IP address and so it needs to be downloaded and installed. At the same time install iperf to allow throughput testing. This needs to be done with an
ethernet cable connected.
#apt-get update #apt-get install udhcpc iperf
If there is an error about a database being out of date during the update it is because the system time is in the future. Update to the correct time with
#ntpdate pool.ntp.org
Connecting to an Access Point[edit]
wpa_supplicant is used to connect the BeagleBoneBlack as a station to an Access Point. The configuration of the Access Point to connect to is done via a file typically located at /etc/wpa_supplicant.conf. A Debian filesystem provides a generic version of this file with all the possible options in this location. To keep things simple for different configurations create new files for each connection.
Configuration for an Unsecured Access Point[edit]
Create a file /etc/wpa_supplicant-unsecuredAP.conf with the following contents to connect to SSID "MyAP"
ctrl_interface=/var/run/wpa_supplicant update_config=1 network={ key_mgmt=NONE ssid="MyAP" }
Configuration for a WPA2 secured Access Point[edit]
Create a file /etc/wpa_supplicant-securedAP.conf with the following contents to connect to SSID "MyAP" running WPA2 with password "password"
ctrl_interface=/var/run/wpa_supplicant update_config=1 network={ psk="password" ssid="MyAP" }
Connect to the AP[edit]
Run the supplicant passing the desired AP's configuration file to connect to the AP on interface wlan0
root@arm:~#wpa_supplicant -d -Dnl80211 -c/etc/wpa_supplicant-unsecuredAP.conf -iwlan0 -B
Check that the connection process was correct by running dmesg | grep wlan which should give following information
root@arm:/etc# dmesg | grep wlan [ 0.129013] wlan-en-regulator: 1800 mV [ 1677.205809] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready [ 1681.364364] wlan0: authenticate with a0:f3:c1:ac:af:ac [ 1681.374940] wlan0: send auth to a0:f3:c1:ac:af:ac (try 1/3) [ 1681.402398] wlan0: authenticated [ 1681.406715] wlan0: associate with a0:f3:c1:ac:af:ac (try 1/3) [ 1681.412420] wlan0: RX AssocResp from a0:f3:c1:ac:af:ac (capab=0x431 status=0 aid=1) [ 1681.432269] wlan0: associated [ 1681.432365] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
and then request an IP address from the AP.
root@arm:~#udhcpc -i wlan0
If there is a problem with the wpa_supplicant execution check that the version of the executable is the one built by the wl18xx drivers and not the default debian one. Check this by running which wpa_supplicant which should give following result
root@arm:~# which wpa_supplicant /usr/local/sbin/wpa_supplicant
Testing the Connection[edit]
The simplest way to test the connection and throughput is to use iperf. iperf transmits data in either TCP or UDP from a client to a server. So running a client implies transmission and running a server implies reception. The table below shows the performance achieved from the WL1835 Cape to a TPLINK TL-WR841N AP at a range of 1m in a typical office environment (~20 SSIDs in a scan). The other device in the test was a Ubuntu machine running iperf and connected to the AP via Ethernet so that WL183x cape had sole access to the Wifi port on the AP.
TCP (Mb/s) | UDP (Mb/s), %age loss | |
---|---|---|
Rx | 39.8 | 34.2, 2% |
Tx | 31.1 | 27.8, 0% |
In TCP mode iperf sends the maximum possible amount of data with 100% reliability.
The server (Receiver) is run as follows
#iperf -s
and the client command line used in the test for 60 seconds with a reporting interval of 10 seconds was:
#iperf -c <IP address of server> -t 60 -i 10
In UDP mode iperf sends a fixed data rate and then reports actual data rate received and the percentage of packets lost.
The server (Receiver) is run as follows with UDP mode specified
#iperf -s -u
and the client command line used in the test for 60 seconds with a reporting interval of 10 seconds was:
#iperf -u -b30M -c <IP address of server> -t 60 -i 10
In this case 30Mb/s was requested. Testing UDP throughput is an iterative process repeated at different increasing bandwidths (-b<bandwidth>) until the percentage packet error is unacceptable.