Thursday, January 1, 2015

Wifi on the BeagleBone Black with Systemd - An Addendum

So I go to all the trouble to write up a nice long blog post on how to get wifi going on the BeagleBone Black and what happens?  The 'Bone bites me in the ass, reinforcing the latter part of our Love / Hate relationship.  Here is the story, and the fix.

I posted my writeup to the BeagleBoard Google Group and one hour later, my wireless connection started acting up again.  I was always getting some DUP packets with my ZD1211 wifi adapter e.g.

64 bytes from ord31s22-in-f4.1e100.net (216.58.216.228): icmp_seq=3 ttl=50 time=71.4 ms
64 bytes from ord31s22-in-f4.1e100.net (216.58.216.228): icmp_seq=4 ttl=50 time=70.5 ms
64 bytes from ord31s22-in-f4.1e100.net (216.58.216.228): icmp_seq=4 ttl=50 time=75.6 ms (DUP!)
64 bytes from ord31s22-in-f4.1e100.net (216.58.216.228): icmp_seq=4 ttl=50 time=76.2 ms (DUP!)

that I couldn't figure out but otherwise things seemed to be working OK.  Then the ZD1211 stick just decided to drop the connection, take its ball, and go home.

I was pissed, but I also have one of those brains where the subconscious continues to crank away on the problem no matter now much you want to drive over your 'Bone with a car.  I was lying awake in bed when I remembered a post about someone else's problem being solved by changing the performance governor the 'Bone uses to set its clock speed.  The 'Bone is set up to go into "ondemand" mode when it isn't that busy, and it drops its clock speed all the way down to 300 MHz from its 1 GHz maximum when it does so.  Could changing this fix the problem?  Only one way to find out, but first I had to figure out how.

The Jessie snapshot I'm using on the 'Bone does not (yet) use the newer cpupower utility that the cool kids like Arch Linux are using these days.  Instead, Jessie still uses the older cpufreq-utils stuff.  So all you need to do to set the 'Bone to 1 GHz (and keep it at 1 GHz, dammit) is:
  1. Edit /etc/default/cpufrequtils (you might need to create it if it doesn’t exist).
  2. Specify the governor with the GOVERNOR variable by putting this line in the file:

    GOVERNOR="performance"
Then reboot the 'Bone with
root@beaglebone:~#  systemctl reboot
Once it has rebooted, check that the change is in effect by using the cpufreq-info command and verifying that the 'Bone is hanging out at 1000 MHz for 100% of the time.
root@beaglebone:~# cpufreq-info
cpufrequtils 008: cpufreq-info (C) Dominik Brodowski 2004-2009
Report errors and bugs to cpufreq@vger.kernel.org, please.
analyzing CPU 0:
  driver: generic_cpu0
  CPUs which run at the same hardware frequency: 0
  CPUs which need to have their frequency coordinated by software: 0
  maximum transition latency: 300 us.
  hardware limits: 300 MHz - 1000 MHz
  available frequency steps: 300 MHz, 600 MHz, 720 MHz, 800 MHz, 1000 MHz
  available cpufreq governors: conservative, ondemand, userspace, powersave, performance
  current policy: frequency should be within 300 MHz and 1000 MHz.
                  The governor "performance" may decide which speed to use
                  within this range.
  current CPU frequency is 1000 MHz (asserted by call to hardware).
  cpufreq stats: 300 MHz:0.00%, 600 MHz:0.00%, 720 MHz:0.00%, 800 MHz:0.00%, 1000 MHz:100.00%
The wifi on my 'Bone using the TP-Link TL-WN722N dongle has been rock solid since I did this a day or two ago.  No DUPs, no lockups.  I wasn't so lucky with my ZD1211 based dongle (the firmware for which will be appearing in future Jessie snapshots BTW), and I've decided not to pursue this any further.  There are some old bugs on this issue so it is unlikely that this is something I can do much about.  And I don't really care, because at least I have a setup now that works and is solid.

If you are interested, all the details can be found on this post to the BeagleBoard Google Group.  The explanation for using the "ondemand" governor is so that the 'Bone can be powered by USB.  But this doesn't make sense to me.  Nothing prevents the 'Bone in "ondemand" to clock up to 1 GHz for an extended period of time, and if USB won't cut this, you're screwed anyway.  And is it better to have mysterious failures like this happening to people and getting them so frustrated that they just want to run over their 'Bone with a car?  After all, there are other people besides me that burned off a bunch of hours thanks to this issue.

Want some take-aways to wifi on the Beaglebone Black?  Here are some take-aways.
  • Use an Atheros-based wifi dongle like the TP-Link TL-WN722N
  • Set up your wireless connection using NetworkManager and, if you are working from the command line, its nmtui interface
  • Set your CPU governor to "performance" or live to regret it
  • Don't power your 'Bone from USB.  Get yourself an external supply rated for 5 Volts at 2 Amps.  I use this one from the good folks at Adafruit.
Now, just like my last post, I'll toss in a few other tidbits that I've learned along the way.
Compiling your own kernel or wanting to use the SGX libraries?  Make sure that you have lzop installed.  I did not, and couldn't figure out why the kernel build wasn't producing a zImage and putting it into the deploy directory as noted in these instructions.  And if you are going to be doing that, might as well have ccache installed as well.  On Arch Linux:
root@beaglebone:~#  pacman -Sy lzop ccache
Want to turn off screen blanking not only for X-Windows, but for serial / SSH terminal sessions and the raw framebuffer (so that your OGLES2ChameleonMan demo doesn't blank after ten minutes)?  Edit /boot/uEnv.txt and add consoleblank to your cmdline, like so:
cmdline=quiet consoleblank=0
Did you flash your 'Bone with something containing the LXQT desktop or something similar?  What if you don't want LXQT to start on boot?  This awesome post shows to turn off LXQT in a running system:
root@beaglebone:~# systemctl isolate multi-user.target
and this starts it up again:
root@beaglebone:~# systemctl start graphical.target
To avoid starting up a graphical desktop at boot run:
root@beaglebone:~# systemctl set-default multi-user.target
and change back with:
root@beaglebone:~# systemctl set-default graphical.target
That's enough knowledge bombs for one post. See you next time here at Mad Scientist Labs.

2 comments:

  1. I just spent 4 hours mucking around with connmand, systemd, and classic ifup/ifdown scripts. Your article probably saved me 4 additional hours. Thank you.

    ReplyDelete
    Replies
    1. I bet it saved you more than that judging by the hell I went through!!!

      Delete