BeagleBone Black
Find below my experiences with the BeagleBone Black (BBB) revision 3.
Contents
First Boot
First boot with BeagleBone Black is best done by using a serial communication program like CuteCom or Putty.
Attach the USB connector to your PC and issue this command to find the tty-port that will be created:
$ ls -lart /dev
drwxr-xr-x. 2 root root 80 Aug 16 13:19 bsg crw-rw----. 1 root disk 21, 1 Aug 16 13:19 sg1 drwxr-xr-x. 2 root root 3900 Aug 16 13:19 char drwxr-xr-x. 22 root root 3560 Aug 16 13:19 . brw-rw----. 1 root disk 8, 16 Aug 16 13:19 sdb drwxr-xr-x. 6 root root 120 Aug 16 13:19 disk drwxr-xr-x. 2 root root 200 Aug 16 13:19 block crw-rw-rw-. 1 root dialout 166, 3 Aug 16 13:19 ttyACM3 crw-rw-rw-. 1 root tty 5, 0 Aug 16 13:20 tty crw-rw-rw-. 1 root tty 5, 2 Aug 16 13:21 ptmx
The above list show the devices created when attaching the USB cable. The line of interest here is the ttyACM3 - might differ on other systems.
Since normal users normally not are member of the dialout group the quickest way to gain access to the tty-port is to issue this command:
$ sudo chmod o+rw /dev/ttyACM3
This will give a normal user access to the port.
Alternatively modify the /etc/group to allow the login to be member of the dialout group.
Now open the CuteCom or Putty port on a serial line using /dev/ttyACM3 and 115200 bps as settings.
An output like this can be seen:
Login timed out after 60 seconds. \0x1b[r\0x1b[H\0x1b[J Debian GNU/Linux 7 kolles-beaglebone ttyGS0 default username:password is [debian:temppwd] Support/FAQ: http://elinux.org/Beagleboard:BeagleBoneBlack_Debian The IP Address for usb0 is: 192.168.7.2 kolles-beaglebone login:
Now login using the defaults given.
Also try to issue
$ ssh debian@192.168.7.2
This will open an ssh connection over the USB cable, which also supports networked traffic, to the BBB.
Yocto Project
The Yocto Project, see the home page for further details, can create a distribution for the BBB.
For instructions on how to build a personal Yocto Project Distribution see Yocto Project Build Instructions.
Creating the boot SD
There are several methods to create a bootable SD card.
The easiest way is to use a graphical interface, e.g. gparted
Create two partitions, one size 40, or more, megabytes for u-boot and one for the rest of the SD card - here 7+ GB.
Label the boot partition boot and the other partition root.
The boot partition shall be a primary partition of type FAT32 while the rest is a ext3 or ext4 file system. Format the partitions to the designated file system types and set the boot flag for the boot partition.
Alternative method
Here is an alternative method only using the console if no graphical environment is available:
$ export DISK=/dev/sdc $ umount ${DISK}1 #<<<Note the addition of the '1' $ sudo dd if=/dev/zero of=${DISK} bs=512 count=20 $ sudo sfdisk --in-order --Linux --unit M ${DISK} <<-__EOF__ 1,12,0xE,* ,,,- __EOF__ $ sudo mkfs.vfat -F 16 ${DISK}1 -n boot $ sudo mkfs.ext4 ${DISK}2 -L rootfs
Here's whats happening:
- Provided that the newly inserted SD card is /dev/sdc - could be another e.g. sdb depending on the disks in the PC - tell the rest of the script where the device is located (the DISK variable)
- unmount if automount mounted it
- dd is a very effective utility to create files and much more - here zeros is copied from /dev/zero (if=/dev/zero) to the disk (of=${DISK} i.e. /dev/sdc) with 512 bytes block size (bs=512) for 20 blocks (count=20)
- Next rather than calling the fdisk the sfdisk partition table manipulating program is used with a HERE script (the part from __EOF__ to __EOF__)
- With the partition the next is to make a file system with mkfs both vfat and ext4 file systems and at the same time labelling the partitions
Transfer binaries to the SD card
Mount the two SD card partitions. On some Linuxes it is easily done by removing the SD card and reinsert it and automount will automagically mount the disk partitions.
From the Yocto Project distribution copy the MLO and the u-boot.img files to the boot partition.
In order to populate the root file system to the root partition untar the compressed root file system that bitbake produced.
$ cd <the mounted root partition> $ sudo tar xf <path to poky>/beaglebone/tmp/deploy/images/beaglebone/core-image-sato-beaglebone.tar.bz2 . $ sync
This is what is happening:
- First change to the root partition on the SD card (on Fedora it is typically mounted /run/media/<username>/root)
- Then untar the compressed root file system from where bitbake built it (here it is the graphical core-image-sato distribution)
- Finally issue sync to let the kernel write everything to the SD card - when sync returns unmount the SD card.
Windows and Mac users
You will have to figure out from the descriptions above how to format and create the filesystems on the SD card and how to copy the files to the card.
Booting the BBB with Yocto Project
Insert the SD card into the slot for it on the BBB. Press and hold the button on top of the board near the SD card in order to boot from the SD (otherwise the BBB will boot from the built in eMMC). Apply power through the USB connector.
Monitor the boot process
Only if the u-boot causes problems a serial connection may be helpful, otherwise it is usually enough to wait until the USB interface becomes available in the boot process.
So if the u-boot messages should not be monitored, just connect the USB cable to the PC and start the favourite serial communication program, e.g. CuteCom, Putty or screen. Wait until the tty USB device becomes available. The USB interface will become available when the system is near the end of the boot process - and at that time the u-boot messages are long gone.
If, for some reason, the board won't boot, a serial cable need to be connected to the board. Get a PL2303 cable - or build one your self...
Connect the serial cable to the port to J1 as shown below.
PL2303 USB to serial cable
Board Wire Function Pin 1.....Black.....Ground Pin 4.....Green.....Receive Pin 5.....White....Transmit (Where pin 1 is the one near the white dot)
Connecting the pl2303 cable to the BeagleBone Black
Stop u-boot
Using a serial interface it is possible to monitor the boot process.
Here the command
$ screen /dev/ttyUSB0 115200
is used to connect to the serial line (use Ctrl-a+k to kill the window). Putty or CuteCom can show the same.
Immediately after applying power and e-boot presents it self on the serial interface, hit any key on the keyboard to stop the boot process.
This is a typical output from the early boot process:
U-Boot SPL 2014.04-00014-g47880f5 (Apr 22 2014 - 13:23:54) reading args spl_load_image_fat_os: error reading image args, err - -1 reading u-boot.img reading u-boot.img U-Boot 2014.04-00014-g47880f5 (Apr 22 2014 - 13:23:54) I2C: ready DRAM: 512 MiB NAND: 0 MiB MMC: OMAP SD/MMC: 0, OMAP SD/MMC: 1 *** Warning - readenv() failed, using default environment Net: <ethaddr> not set. Validating first E-fuse MAC cpsw, usb_ether Hit any key to stop autoboot: 0 U-Boot#
Here the u-boot has stopped and are awaiting a command.
Enabling the DS18B20 thermometer
The version of Debian that my board was supplied with uses the Flattened Device Tree in order to ease the access to GPIO's and other hardware. This are so for the most modern Linux distributions for the ARM processors. The reason for this is mainly because Linus Thorvalds did not want to include the large amount of device drivers for the ARM processor family in the kernel. Se more about the Flattened Device Tree (FDT) on this site.
From this site I was inspired to set-up the correct dts file enabling the usage of GPIO pin 2 for the 1Wire interface.
Create a file name DS1820-00A0.dts with this content
/dts-v1/; /plugin/; / { compatible = "ti,beaglebone", "ti,beaglebone-black"; part-number = "DS1820"; version = "00A0"; exclusive-use = "P9.12"; fragment@0 { target = <&am33xx_pinmux>; __overlay__ { ds1820_pins: pinmux_ds1820_pins { pinctrl-single,pins = <0x78 0x37>; }; }; }; fragment@1 { target = <&ocp>; __overlay__ { onewire@0 { status = "okay"; compatible = "w1-gpio"; pinctrl-names = "default"; pinctrl-0 = <&ds1820_pins>; gpios = <&gpio2 28 0>; }; }; }; };
Compile the specification into a dtbo binary file
dtc -O dtb -o /lib/firmware/DS1820-00A0.dtbo -b 0 -@ DS1820-00A0.dts
Finally in order to enable this part of the device tree perform at every boot this command
echo DS1820 > /sys/devices/bone_capemgr.*/slots
The thermometer should now show up in the /sys/bus/w1/devices folder
drwxr-xr-x 2 root root 0 Jan 1 2000 . drwxr-xr-x 4 root root 0 Jan 1 2000 .. lrwxrwxrwx 1 root root 0 Feb 21 10:49 28-000005a7ce64 -> ../../../devices/w1_bus_master1/28-000005a7ce64 lrwxrwxrwx 1 root root 0 Feb 21 10:49 w1_bus_master1 -> ../../../devices/w1_bus_master1
the 28-00000nnnnnnn is the thermometer - they are all uniquely identified, so the n's will vary.
Test with Python
To check that the thermometer work correct prepare this short test program in a file named test.py where you of course will adjust the thermometer ID to suit your set-up:
import time w1="/sys/bus/w1/devices/28-000005a7ce64/w1_slave" while True: raw = open(w1, "r").read() print "Temperature is "+str(float(raw.split("t=")[-1])/1000)+" degrees" time.sleep(1)
Execute the program
python test.py
you should get something similar to this
root@klaus-BBB:~/ds18b20# python test.py Temperature is 24.0 degrees Temperature is 24.0 degrees Temperature is 24.062 degrees Temperature is 24.062 degrees ^CTraceback (most recent call last): File "test.py", line 8, in <module> time.sleep(1) KeyboardInterrupt root@klaus-BBB:~/ds18b20#
Test using Bonescript
This source first locates the attached thermometer and then uses it for temperature reading.
This code is only able to handle one thermometer at a time, or in fact only one 1-wire device at at time.
// // Interface for the thermometer // Author : Klaus Kolle // Date : 2015 02 22 // Revision : 0.0.3 var b = require('bonescript'); var f = require('fs'); //console.log('Hello, Thermostate.'); var temperature; // Read from the 1-wire thermometer // The 28-00000nnnnnnn will change depending of the device connected // var oneWireDir; locateThermometer(); function locateThermometer() { var initialDir = '/sys/bus/w1/devices/'; var regExpr = '28-00000'; var dir = []; var i; // Get all files and directories in the dir var dirs = f.readdirSync(initialDir); // Did we gat anything - if not the cape manager is probably not initialised // with the dtbo compiled device tree if (dirs.length > 0) { for (i = 0; i < dirs.length; i++) { // Only select the directories matching the pattern if(dirs[i].match(regExpr)) { dir.push (dirs[i]); } } // Currently the code only accepts one thermometer oneWireDir = initialDir + dir + "/w1_slave"; } } function readTemp() { // Callback function for the timer b.readTextFile(oneWireDir, printTemp); } // The 1-wire returs this when reading the device // klaus@klaus-BBB:~$ cat /sys/bus/w1/devices/28-000005a7ce64/w1_slave // a5 01 4b 46 7f ff 0b 10 f7 : crc=f7 YES // a5 01 4b 46 7f ff 0b 10 f7 t=26312 // Therefore a split is needed. We need the string after the second = function printTemp(x) { // We receive the data i x if (x.data != '') { var stringToSplit = x.data; // Split at = - three resulting strings are returned var arrayOfStrings = stringToSplit.split('='); // We are only interesd in the last temperature = (arrayOfStrings[2]) / 1000; console.log("Temp: " + temperature); } } setInterval(readTemp, 5000);
Expect a readout like this
Temp: 24.687 Temp: 24.75 Temp: 24.75 Temp: 24.687 Temp: 24.75 Temp: 24.75 Temp: 24.75 Temp: 24.687
ARMv7 Cross Compiler on Fedora/Centos/RedHat
The Fedora package system does not contain a suitable compiler for the ARMv7 processor. Luckely Linaro, does maintain a toolchain suitable for us.
http://releases.linaro.org/14.11/components/toolchain/binaries
http://releases.linaro.org/14.11/components/toolchain/binaries/arm-linux-gnueabihf
On this page http://linux-sunxi.org/Toolchain maintains a list of compilers for the ARM architecture. Pick-up the newest version and copy the link. Then
$] wget http://releases.linaro.org/14.07/components/toolchain/gcc-linaro/4.9/gcc-linaro-4.9-2014.07-1.tar.xz
which will download the newest version on the time of writing this.
You will have to install a number of things on your Fedora in order to be able to compile the gcc compiler. I assume that you have the standeard development environment up running for the 64 bit version.
$] yum install gmp.i686 mpfr.i686 libmpdclient.x86_64 mpc.x86_64 \ gmp-devel.i686 gmp-devel.x86_64 mpfr-devel.x86_64 mpfr-devel.i686 \ libmpc-devel.x86_64 glibc-headers.i686 gmp-devel.x86_64 \
The .686 are for 32 bit versions of the compiler and the -devel typically contains the header and other important files. and maybe even more.
Run the configuration script
]$ ./configure
in the unpacked directory.
If everything configures without errors execute
]$ make all
and after a couple of hours or longer you may have a cross compiler compiled depending on your systems mileage.
[klaus@kko gcc-linaro-4.9-2014.07-1]$ START=`date` [klaus@kko gcc-linaro-4.9-2014.07-1]$ make all && END=`date` [klaus@kko gcc-linaro-4.9-2014.07-1]$ echo $START; echo $END Thu 9 Apr 09:06:25 CEST 2015 Thu 9 Apr 11:06:12 CEST 2015 [klaus@kko gcc-linaro-4.9-2014.07-1]$