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.
WL1835MODCOM8 on iMx6SL EVK with MainLine Kernel Debian Filesystem
How to Build WL1835 Support in Mainline Linux[edit]
As of Kernel 4.1 the WiLink8 Wi-Fi drivers are now in the mainline Linux. This means that it is no longer required to build the Wi-Fi drivers out of tree using the TI script or patch up the Shared Transport Layer for Bluetooth in your chosen kernel. Additionally there is now device tree support for i.Mx6SL EVK plus MMC2COM adapter board plus WL1835MODCOM8 as a supported platform in Robert Nelson's Linux on ARM build system.
The hardware required is listed here and the connections to be made between boards are described here
This page provides a script that is based on the BeagleBoneBlack build steps described at https://eewiki.net/display/linuxonarm/BeagleBone+Black which have been modified to build for the i.Mx6SL EVK. This creates a K4.1rc4 based kernel running on a Debian 8.0 file system. This was the latest tag at the time of writing.
There are several 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 device tree patch applied to the tag is an optional one to reduce the driver strength on the MMC bus to the WL1835. This has been seen to be required on some boards only and so may be optional.
- The uboot patch is a variation on the SABRE one.
- In this example bluez is used as the Bluetooth stack as this is the stack available in Debian. There is no reason why the TI Bluetopia stack cannot be used as it is compiled with a gcc armhf toolchain.
History
Current version of script is v0.2.
Building[edit]
Create a build directory and download and extract the build script 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.
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 # 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 4.1rc4 and filesystem based on debian 8.0 # for Wl1835 on i.Mx6SL EVK. Based on BeagleBone at # https://eewiki.net/display/linuxonarm/BeagleBone+Black # version 0.2 # May 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-8.0-minimal-armhf-2015-04-27.tar.xz tar xf debian-8.0-minimal-armhf-2015-04-27.tar.xz cd debian-8.0-minimal-armhf-2015-04-27 if [ ! -e rootfs ] then mkdir rootfs fi cd rootfs FS=`pwd` sudo tar xf ../armhf-rootfs-debian-jessie.tar . cd ../.. touch ../fs-downloaded cd .. else # just set FS FS=`pwd`/fs/debian-8.0-minimal-armhf-2015-04-27/rootfs cd fs/debian-8.0-minimal-armhf-2015-04-27 || exit sudo rm -r rootfs/ mkdir -p rootfs cd rootfs sudo tar xf ../armhf-rootfs-debian-jessie.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.9 and so do this before uboot if [ ! -e kernel-built ] then if [ ! -e kernel-git-downloaded ] then sudo rm -r armv7-multiplatform git clone https://github.com/RobertCNelson/armv7-multiplatform touch kernel-git-downloaded else # remove bb-kernel patches cd armv7-multiplatform/ git checkout patch.sh system.sh.sample cd .. fi cd armv7-multiplatform/ git checkout 4.1-rc4-armv7-x0 -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 # Add this new patch to build system cp ../patches/kernel/0013-reduce-driver-IO-strength-to-50ohms-from-90-ohms.patch patches/dts/0013-reduce-driver-IO-strength-to-50ohms-from-90-ohms.patch # update patch.sh to apply these new patches patch -p1 < ../patches/kernel/0001-add-patch-to-reduce-SDIO-drive-strength.patch || exit ./build_kernel.sh || exit cd .. touch kernel-built fi # work on principle there is a file bb-kernel/deploy/config-x.y.z-boneX # if version is a release candidate cut the sections 2-5 separated by'-' cd armv7-multiplatform/deploy export kernel_version=`find . -name config* | cut -d'-' -f 2,3,4,5` 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 cp -v armv7-multiplatform/deploy/${kernel_version}.zImage ${FS}/boot/vmlinuz-${kernel_version} || exit sudo tar xfv armv7-multiplatform/deploy/${kernel_version}-dtbs.tar.gz -C ${FS}/boot/dtbs/${kernel_version}/ || exit sudo tar xfv armv7-multiplatform/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" # enable eth0 and wlan0 sudo sh -c "echo ' auto lo iface lo inet loopback auto eth0 iface eth0 inet manual auto wlan0 iface wlan0 inet manual ' > ${FS}/etc/network/interfaces" # and ensure that eth0 is always used even if SD card used on another board already sudo sh -c "echo '# EVK: 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" # Clean out all obsolete TI connectivity fw from FS sudo rm -rf ${FS}/lib/firmware/ti-connectivity/* # And download the latest wifi fw wget http://git.ti.com/wilink8-wlan/wl18xx_fw/archive-tarball/R8.5 tar -xvf R8.5 wilink8-wlan-wl18xx_fw/wl18xx-fw-4.bin sudo mv wilink8-wlan-wl18xx_fw/wl18xx-fw-4.bin ${FS}/lib/firmware/ti-connectivity/ rm -r wilink8-wlan-wl18xx_fw rm R8.5 # and the latest bluetooth firmware wget http://git.ti.com/ti-bt/service-packs/blobs/raw/7783edec65c91e0112961bdb7acad6db6a050092/initscripts/TIInit_11.8.32.bts sudo mv TIInit_11.8.32.bts ${FS}/lib/firmware/ti-connectivity/ # now set gcc 4.9 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 armv7-multiplatform/dl COMPILER_NAME=`find . -maxdepth 1 -type f | cut -d'/' -f 2 | sed 's/.tar.xz//'` cd ../.. CC=`pwd`/armv7-multiplatform/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/ # git checkout v2015.04 -b tmp || exit # and patch it for sl EVK with WL1835 added patch -p1 < ../patches/u-boot/0001-imx6slevk-wl1835-uEnv.txt-bootz-nfixes.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} mx6slevk_defconfig || exit make ARCH=arm CROSS_COMPILE=${CC} || exit touch ../uboot-downloaded cd .. fi # 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.
Configuring the system[edit]
On the first boot there are a couple of system configurations that need to be done. This process was done while logged in as root with the password root. The minimal Debian filesystem does not contain the Bluez tools to run the Bluetooth stack, crda to handle Wi-Fi regulatory details or some utilities to test performance. These can be installed as follows with an ethernet cable connected. The first step is to request an IP address on the ethernet.
# dhclient eth0
then install the required tools
#apt-get update #apt-get install iperf iw crda bluez bluez-tools
Once these have been installed it is necessary to reboot the board. This allows Wi-Fi to start correctly with CRDA running.
Connecting to a Wi-Fi 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:~#dhclient wlan0
Testing the Wi-Fi 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 WL1835MODCOM8 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 | 31.4 | 34.4, 2.4% |
Tx | 37.0 | 20.4, 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 -c <IP address of server> -b30M -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.
Starting the Bluetooth[edit]
The first step for running Bluez is to load the firmware to the WL1835. This is done with the utility hciattach. The arguments specify that bluetooth is connected to UART /dev/ttymxc3, that it is a Texas Instruments Bluetooth device and that the communication should switch to 3Mbaud
#hciattach /dev/ttymxc3 texas 3000000 &
Once this has completed the hci0 interface can be brought up
#hciconfig hci0 up
The scan is carried out with bt-adaptor which will give an output similar to this with a list of all the devices advertising
#bt-adapter –d Searching... [00:0D:FD:47:54:AF] Name: Nokia Play 360° Alias: Nokia Play 360° Address: 00:0D:FD:47:54:AF Icon: (null) Class: 0x0 LegacyPairing: 0 Paired: 1 RSSI: -33 Done
Connecting to the selected device is done with
# bt-device -c 00:0D:FD:47:54:AF
And then set as trusted, so subsequent connects will be automatic
# bt-device --set 00:0D:FD:47:54:AF Trusted 1