Picking up from our previous session, it’s time to hack some more.
A quick couple scripts so we can bridge network through the USB interface.
On the host machine, we create /usr/local/src/usbnet_gate
like so:
#!/bin/bash
case "$1" in
up)
ifconfig usb0 172.17.0.254 netmask 255.255.0.0
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X
iptables -t nat -X
iptables -t mangle -X
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
iptables -A FORWARD -i usb0 -j ACCEPT
echo 1 > /proc/sys/net/ipv4/ip_forward
if ( ifconfig wlan0 | grep -q DOWN ); then
echo "Don't forget to put up the wlan0 interface!"
fi
;;
down)
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X
iptables -t nat -X
iptables -t mangle -X
ifconfig eth0 down
;;
*)
echo "Usage: $0 {up|down}"
exit 1
;;
esac
exit 0
On the target board, /usr/local/src/usbnet_route
looks like this:
#!/bin/bash
case "$1" in
up)
# fix routing table
for i in $(route -n | grep UG | sed 's/ */,/g'); do
$(echo $i | awk -F , '{print("route del -net",$1,"netmask",$3,"gw",$2);}');
done
route add default gw 172.17.0.254
;;
down)
# fix routing table
for i in $(route -n | grep UG | sed 's/ */,/g'); do
$(echo $i | awk -F , '{print("route del -net",$1,"netmask",$3,"gw",$2);}');
done
;;
*)
echo "Usage: $0 {up|down}"
exit 1
;;
esac
exit 0
If you don’t regularly connect an ethernet cable to your BBK at boot, you could run this script automatically by adding
post-up /usr/local/src/usbnet_route up
in the usb0
stanza in /etc/network/interfaces
. Otherwise, just go in via serial or SSH and enable it.
One of the coolest features of the AM335x SOC on the BBK is the pair of Programmable Realtime Units (PRUs), 200 MHz RISC cores that run independently of the ARM core and with access to GPIO, peripherals, private memory, and system memory. These are really cool for making high-speed hardware interfaces or communications busses.
More background info on the PRUs is available from
am335x_pru_package
from the BeagleBoard.org teamam335x_pru_package
The first goal is to get the latter package working with the Debian Wheezy image we installed last time. Grabbing the am335x_pru_package
, we follow the build process that boxysean describes (see the “First Steps” link above). If you grab boxysean’s fork of the package you get a couple LED blinking tests as well.
Sadly, it doesn’t work right out of the box: once we’re ready to run the test code, it turns out that the uio_pruss module shipped with our image apparently doesn’t work right.
INFO: Starting PRU_memAccessPRUDataRam example.
prussdrv_open open failed
A little strace
ing reveals the problem:
open("/dev/uio0", O_RDWR|O_SYNC) = -1 ENODEV (No such device)
open("/sys/class/uio/uio0/maps/map0/addr", O_RDONLY) = -1 ENOENT (No such file or directory)
Apparently something about the uio implementation is broken. Let’s see if we can’t figure out what.
My first inclination is to investigate how it works with the default Ångstrom image (aren’t you glad we kept our install on a microSD card? I am!).
First things first: you should be sure your Ångstrom image is up-to-date.
After looking into it, it turns out that my board already has the latest image. However, before figuring this out, I set about coming up with a way to update the onboard Ångstrom image directly from our Debian install. I’ve recorded it here for posterity.
On the target board, download the latest image:
cd /usr/local/src
wget https://s3.amazonaws.com/angstrom/demo/beaglebone/Angstrom-Cloud9-IDE-GNOME-eglibc-ipk-v2012.12-beaglebone-2013.04.13.img.xz
Note: if wget
complains about certificates, it’s probably because the date on your machine isn’t set. ntpdate -s time.mit.edu
will fix you right up.
Decompress it:
xz -d Angstrom-Cloud9-IDE-GNOME-eglibc-ipk-v2012.12-beaglebone-2013.04.13.img.xz
Now we have an .img file that’s actually a disk with a partition table and two partitions. Using fdisk
(yes, you can run fdisk
on a regular file!) we can see that the two partitions start at offsets 63 and 144585, both expressed in units of 512 bytes. With this information, we can mount the partitions like so (note the offset we provide is 144585*512):
mkdir -p /mnt/Afiles
mount -o loop,offset=74027520 BBB-eMMC-flasher-2013.04.13-DDR3-400MHz.img /mnt/Afiles
In /mnt/Afiles/build
we find the actual scripts that are used to flash the drive. Simply running emmc.sh
should perform the update. Since I haven’t actually done this, your mileage may vary.
I booted the Ångstrom system expecting things to work, but no love here. modprobe uio_pruss
still resulted in an empty /sys/class/uio
directory!
A little more research turned up this thread, How to reliably activate PRUSS on beaglebone? (from today!). Apparently there are some troubles with PRUSS under 3.8 kernels; until they’re fixed, we can use Jacek Radzikowski’s magical hack. Create /usr/local/src/pruss_magic_jr
, like so:
#!/bin/bash
progress_and_delay () {
echo -n "."
sleep 1
}
SLOTS=/sys/devices/bone_capemgr.*/slots
echo -n "Installing uio_pruss module ."
/sbin/modprobe uio_pruss
progress_and_delay
rmmod uio_pruss
progress_and_delay
echo cape-bone-nixie > $SLOTS
progress_and_delay
/sbin/modprobe uio_pruss
progress_and_delay
echo cape-bone-nixie > $SLOTS
progress_and_delay
rmmod uio_pruss
progress_and_delay
/sbin/modprobe uio_pruss
progress_and_delay
( [ -L /sys/class/uio/uio0 ] || [ -d /sys/class/uio/uio0 ] ) && echo ' Success!' && exit 0
# shouldn't get here if things worked
echo 'Failed.'
exit 1;
After executing this, the PRUs work!
[root@charm]# ls /sys/class/uio/uio0/
total 0
drwxr-xr-x 4 root root 0 Jan 1 00:09 .
drwxr-xr-x 10 root root 0 Jan 1 00:09 ..
-r--r--r-- 1 root root 4096 Jan 1 00:22 dev
lrwxrwxrwx 1 root root 0 Jan 1 00:22 device -> ../../../4a300000.pruss
-r--r--r-- 1 root root 4096 Jan 1 00:22 event
drwxr-xr-x 4 root root 0 Jan 1 00:22 maps
-r--r--r-- 1 root root 4096 Jan 1 00:22 name
drwxr-xr-x 2 root root 0 Jan 1 00:22 power
lrwxrwxrwx 1 root root 0 Jan 1 00:09 subsystem -> ../../../../../class/uio
-rw-r--r-- 1 root root 4096 Jan 1 00:09 uevent
-r--r--r-- 1 root root 4096 Jan 1 00:22 version
[root@charm]# ./PRU_PRUtoPRU_Interrupt
INFO: Starting PRU_PRUtoPRU_Interrupt example.
AM33XX
AM33XX
INFO: Initializing example.
INFO: Executing example on PRU0.
File ./PRU_PRU0toPRU1_Interrupt.bin open passed
INFO: Executing example on PRU1.
File ./PRU_PRU1toPRU0_Interrupt.bin open passed
INFO: Waiting for HALT command.
INFO: PRU0 completed transfer.
INFO: Waiting for HALT command.
INFO: PRU1 completed transfer.
Example executed succesfully.
Well, that’s all the time I’ve got today. My goal in the near term is to use the PRUSS to do high-speed data capture and waveform generation. After that, I hope to wrap the whole thing in a nice web interface so that we can use the board as a pattern generator / logic capture card via a web browser.
Stay tuned!
Questions? Comments?
@kwantam | <kwantam@gmail.com> | github