Alohomora!

In which we enable WiFi on the Wandboard Dual and Quad.

I have come to the time in a project where my glorious BeagleBone Black is sturggling to keep up.  What to do?  Fire up the Wandboard Quad!  As with the BeagleBone Black, I prefer to run Arch Linux Arm. And as before, WiFi does not immediately work (despite WiFi being built into the Wandboard Quad).  Luckily getting WiFi running is much easier than on the BeagleBone Black.

The WiFi chip on the Wandboard Dual and Quad is a Broadcom BCM4329 connected via SDIO and requires both a firmware and nvram in order to work.

First, we will load the nvram.  The command below will fetch the nvram from Freescale's github (Freescale is the maker of the processor used on the Wandboard) and place it in the proper directory.

wget -c https://raw.github.com/Freescale/meta-fsl-arm-extra/master/recipes-bsp/broadcom-nvram-config/files/wandboard/nvram.txt
sudo mv -v nvram.txt /lib/firmware/brcm/brcmfmac-sdio.txt

Next we need to rename the firmware already present in Arch Linux Arm.  This is required because the kernel Arch uses for the Wanboard is v3.0.35-3 and for kernels older than v3.13, the SDIO driver used generic firmware names[2].

cp -v /lib/firmware/brcm/brcmfmac4329-sdio.bin /lib/firmware/brcm/brcmfmac-sdio.bin

Now reboot the Wandboard.  When it comes back up, the output of ip link should list wlan0 as an option.

With the WiFi adapter recognized, we can connect to the router.

Install WPA

pacman -S wpa_actiond

Create a base config file

cp -v /etc/netctl/examples/wireless-wpa-configsection /etc/netctl/wireless_wpa_configsection

Generate the required wpa_supplicant config data

wpa_passphrase SSID PASSWORD

Insert the config section into your config file

nano /etc/netctl/wireless_wpa_configsection

Now test out the connection

netctl start wireless_wpa_configsection

Assuming no errors, set WiFi to load at boot

systemctl enable netctl-auto@wlan0.service

Note 1: Loading the firmware and nvram is not necessarily specific to Arch Linux Arm. If your flavor of Linux does not recognize the WiFi adapter, give it a go.

Note 2: Since the adapter is connected using SDIO, it will not show up in the output of lspci -k or lsusb -v

[1] Wandboard
[2] Broadcom Linux drivers

time-y wimey... stuff

it's more like a big ball of wibbly wobbly... time-y wimey... stuff

In which we get a Dallas Semiconductor real time clock (RTC) working on the Beagle Bone Black over the I2C bus under Arch Linux Arm.

The Beagle Bone Black has a real time clock (RTC from now on); however, the RTC does not have a battery to allow it to maintain the time when the board is powered off.  This will generally not pose a problem if your board is always connected to the Internet over the wired interface, but may be a stumbling block otherwise.  Luckily for you, it is easy enough to add a RTC.

Arch Linux Arm has the I2C bus enabled by default, and Arch Linux Arm has the driver for the DS1307 compiled into the kernel as can be seen below in the screenshot of the config file.  This may not be absolutely critical but should prevent any timing issues others have experienced when loading kernel modules at boot.

One great thing about the DS1307 driver is that the driver actually works with several different RTCs.  The below screenshot shows the RTCs listed in the driver source.  This tutorial uses the ChronoDot based on the DS3231; however, you should be able to use any listed.

More information on the ChronoDot can be found at [1], and it was purchased from [2].  It is essentially a break out board for the DS3231, an extremely accurate real time clock.

Connecting the ChronoDot to the Beagle Bone Black requires just four wires.  All you need to do is connect GND, Vcc, SCL, and SDA.  By default you can find all the pins needed on expansion header P9.

GND    pin 1 or 2
Vcc      pin 3 or 4
SCL      pin 19 (I2C2)
SDA     pin 20 (I2C2)

You will want to use the I2C2 bus as I2C1 is used by the board itself.

Power off your board and connect the corresponding pins on the ChronoDot to the pins on the Beagle Bone Black as listed above.  You can safely ignore the other pins on the ChronoDot as they are not needed for adding a RTC to the Beagle Bone Black.

Power on the Beagle Bone Black and you are almost done.

Optional
If you would like to verify that your Beagle Bone Black can see the ChronoDot, you can install the I2C-tools package with
pacman -S i2c-tools
Once installed, you can issue the following command
i2cdetect –y –r  1
This will scan I2C bus 1 (bus 1 in software corresponds to I2C2 on the hardware) for connected devices.  If you have connected the ChronoDot correctly, you should see an entry for 68 as in the image below.  68 is the bus address of the DS3231.  If you do not see a 68, verify your connections and/or the location of the I2C2 bus pins as they can be changed in software.


 

In order to register the new I2C RTC, you need to issue the command

echo ds3231 0x68 >/sys/bus/i2c/devices/i2c-1/new_device

After this you should see an entry for /dev/rtc1 as well as /sys/class/rtc/rtc1 – both point to the same device.

To verify you have the right rtc, check the name with

cat /sys/class/rtc/rtc1/name

and to check the time

cat /sys/class/rtc/rtc1/time

Most likely the time is wrong, and you should correct it before proceeding.  The easiest way to do this is to update the system time using ntpd and then synchronize the RTC.

If ntpd is running, you can either wait for it to eventually update the system time or stop it and force an update with

systemctl stop ntpd
ntpd –dqg

Once the system time is correct, synchronize the RTC with

hwclock -f /dev/rtc1 –w

Notice we are specifying the hwclock to use in the command above.

Now that the RTC has been set to the correct time, we can use it at boot to set our system time.

The first thing you need to do is create a script to recreate the I2C RTC device at boot and synchronize the system clock with it.  Once that is done, you can configure the system to run the script at boot.

Create the script with

nano /usr/lib/systemd/scripts/rtc

and type or copy and paste the following into the script

#!/bin/bash
echo ds3231 0x68 >/sys/bus/i2c/devices/i2c-1/new_device
hwclock -f /dev/rtc1 –s

As promised, this will recreate the I2C RTC and synchronize the system clock to it.

Next you will need to make the script executable with

chmod 755 /usr/lib/systemd/scripts/rtc

Now to make it run at boot.

Create the systemd file with

nano /etc/systemd/system/rtc.service

and type or copy and paste the following into the script

[Unit]
Description=RTC clock
Before=netctl-auto@wlan0.service
[Type]
Type=oneshot

[Service]
ExecStart=/usr/lib/systemd/scripts/rtc

[Install]
WantedBy=multi-user.target

Test it out by issuing

systemctl start rtc

If you receive no errors, you can enable this to run at boot with

systemctl enable rtc

Otherwise review the error messages to determine the issue.

You might have noticed the line Before=netctl-auto@wlan0.service in the systemd file. This instructs systemd  to bring up the RTC before starting the wireless LAN adapter.  This should prevent any wpasupplicant issues concerning timestamp validation.

You should now have a working battery backed RTC on your Beagle Bone Black.

[1] docs.macetech.com/doku.php/chronodot_v2.0
[2] www.evilmadscientist.com

The fruits of my labor

In which we try to get the 802.11n wifi module (RTl8192cu Chipset) from Ada Fruit running on a Beagle Board Black under Arch Linux Arm

Please note:  This guide assumes you already have Arch Linux Arm running on your Beagle Bone Black.

First things first, let’s get your installation up to date and install a few needed packages.

You will need the following:

  • iw – command line interface to manage wireless devices (replaced iwconfig)
  • wpa_actiond – needed to automatically connect to wifi networks on boot
  • netctl – used to control the state of the system services for the network profile manager (replaced netcfg)
  • ifplugd – needed to automatically connect to wired networks on boot

 

Getting started, install iw and wpa_action

pacman -S iw wpa_actiond 

Next, you need to remove netcfg as it conflicts with netctl.  If you fail to remove netcfg first, you will likely receive errors when you attempt to install netctl.

pacman -Rs netcfg

You need to update the system before installing netctl and ifplugd.  If you try to install them first, you will receive a message that the packages cannot be found.

Update you system with

pacman -Syu

With the system up to date, install netctl and ifplugd with

pacman -S netctl ifplugd

All required packages are now installed and up to date, and you are ready to configure the networks.

The first thing you want to do is ensure the system will bring up the wired network.  Otherwise, if there is no wifi connection, you will need a keyboard, mouse, and monitor plugged into the Beagle Bone Black in order to issue commands1.

Copy the default dhcp ethernet connection from the examples2 directory to /etc/netctl/

cp /etc/netctl/examples/ethernet-dhcp  /etc/netctl/

Now set it to start when the system starts

systemctl enable netctl-ifplugd@eth0.service

If you were to reboot now, you should at least be able to establish an ethernet connection.

On to wifi!

My network is configured to use WPA to secure the wireless connection, and for security sake, I hope yours is too.  WPA is handled by wpa_supplicant.  The Arch Linux Wiki indicates nl80211 is the preferred driver for use with wpa_supplicant instead of the older wext.  Unfortunately, I could not get the wifi module to connect if wpa_supplicant was using the nl80211 driver.

To ensure wpa_wupplicant uses wext edit fi.epitest.hostap.WPASupplicant.service and add -D wext

nano /usr/share/dbus-1/system-services/fi.epitest.hostap.WPASupplicant.service

Another issue I encountered was the need to have the system clock set so wpa_supplicant can validate timestamps.  If the system clock is too far off, validation will fail, and it will not connect (more on this later).  By default, Arch Linux Arm runs OpenNTP to correct the system time.  Depending on how long your board has been running, your system time may or may not be correct.

Issue the command date to check the system time.

If your system time is off, you have a couple options for setting the system clock

Setting is manually with something like

timedatectl set-time "2012-10-30 18:17:16"

Setting it automatically with NTP

I prefer the second choice.

Optional

Arch Linux Arm comes with OpenNTP by default.  This package is not maintained for Linux, so let’s switch it out for regular old NTP.

pacman -S ntp

When asked, allow pacman to remove OpenNTP.

Now you can set the time from the internet with

ntpd -dqg

Leave out the d if you do not want to see diagnostic output.

Finally, set the hardware clock to the updated time with

hwclock –w

You can set ntp to run at boot with

systemctl enable ntpd

 

Now make a config file for wifi in /etc/netctl/ by copying the wireless_wpa_configsection configuration from the examples directory

cp /etc/netctl/examples/wireless-wpa-configsection /etc/netctl/wireless_wpa_configsection

There are other wpa config files in the examples directories, but the configsection configuration is the only format that can be loaded automatically at boot.

Also, please notice the hyphens in the copy to name have been replaced with underscores.  If you do not change the hyphens, you may get cryptic errors and your wifi configuration will not work.  Apparently this has to do with how hyphens are (mis)handled.

You can use wpa_passphrase to generate the required wpa_supplicant config data like so

wpa_passphrase SSID PASSWORD

This will output the required configuration.   I hope your password is better than the one in the screenshot.

Copy this data and place it in wireless_wpa_configsection

nano /etc/netctl/wireless_wpa_configsection

Note the single quotes around the configuration keys in the screenshot.

To test your configuration, issue the following commands

netctl start wireless_wpa_configsection
ifconfig

If you receive an error, check the status as instructed in the message.  The first time I tried to connect, it timed out; however, attempting to start netctl again worked.

If all goes well, you should see an entry for wlan0 with an ip address.  If not, double check the configuration file and ensure your SSID and password are correct.  If you have a router that broadcasts on both 2.4 Ghz and 5 Ghz, be sure and use the SSID in use on the 2.4 Ghz spectrum as the Ada Fruit adapter is 2.4 Ghz.

With everything working, you can set wifi to start at boot with

systemctl enable netctl-auto@wlan0.service

As long as you do not fully power off the board (ie by holding the power button for greater than 8 seconds, by issuing the poweroff command, or by losing power) wifi will automatically reconnect.  In other words, if you reboot the board everything will be fine.  If the power is interrupted, wifi most likely will not automatically reconnect.

This is because the real time clock (RTC) on the Beagle Bone Black does not have a battery backup.  When you power off the board, the RTC is reset.  This causes wpa_supplicant to fail timestamp checks.  I am currently looking at two solutions to this problem.

  1. Using fake hardware clock to periodically save the time to a file and reload it at boot
  2. Using a battery backed RTC over SPI or I2C to maintain the time when the board is powered off

 

Depending on your needs, solution 1 may not be an option.  I will update these instructions after I have tested both.

1Unless you have installed and configured USB Gadet, but that is a topic for another post.
2In this post, I assume you are using DHCP.  If not, use the static IP address config files.