Friday 9 August 2013

Tutorial: Using the DSP on the BeagleBoard

Introduction


Hello! In this tutorial I'll be showing you how to utilise the BeagleBoard's TMS320C64x+ digital signal processor (DSP). I've recently started working on a project using the BeagleBoard and have been trying to use its DSP for a while now, but have found that most online resources are either hilariously outdated or contradict each other, making using the DSP rather arduous. Now that I've finally gotten it working, I've written this concise tutorial to help others that are struggling like I was.  

Requirements


+ An internet connection for downloading required files
+ A BeagleBoard; I used a BeagleBoard xM Rev. C
+ An x86/x86_64 host machine running GNU/Linux; I used Linux Mint 15 on my laptop
+ A micro-SD card reader compatible with your host machine
+ A micro-SD card, preferably with at least 4 GB capacity
~ (Optional) An ethernet connection to your BeagleBoard, allowing you to SSH into it over LAN

1 - Install Ubuntu 12.10 on the BeagleBoard


While you can probably get the DSP working with Angstrom, it's much much easier to use Ubuntu. Robert C Nelson maintains a number of Ubuntu images tailored to the BeagleBoard with a pre-configured DSP/Bridge-compatible kernel (this saves you building the kernel yourself and avoids a lot of the nitty-gritty). Download the latest version here, or to get the same version as me:

Host machine:
$ cd ~
$ mkdir dsp-stuff && cd dsp-stuff
$ wget http://rcn-ee.net/deb/rootfs/quantal/ubuntu-12.10-console-armhf-2013-07-22.tar.xz
$ tar xf ubuntu-12.10-console-armhf-2013-07-22.tar.xz
$ cd ubuntu-12.10-console-armhf-2013-07-22

Now you'll need to flash the Ubuntu image onto your micro-SD card. First, identify your card's device handle by inserting it into the card reader and running lsblk. USB card readers tend to show up as /dev/sdX whereas built-in card readers show up as /dev/mmcblkX. My card shows up as /dev/mmcblk0.

Once you've identified your card's device handle, run the setup_sdcard.sh script:

Host machine:
$ chmod +x ./setup_sdcard.sh
$ sudo ./setup_sdcard.sh --mmc /dev/mmcblk0 --uboot beagle_xm

There are two things to note here: first, you point the --mmc flag to the entire memory card, not just the first partition on the card (ie /dev/mmcblk0 as opposed to /dev/mmcblk0p1). Secondly, if you're using a normal BeagleBoard (not an xM) then change the --uboot flag to point to beagle instead of beagle_xm.

If everything went OK, the micro-SD card is now ready to be used in the BeagleBoard.

2 - Setup Ubuntu on the BeagleBoard


Login to the BeagleBoard (for example using serial communication) with username ubuntu and password temppwd.

First, update the system:

BeagleBoard:
$ sudo apt-get update
$ sudo apt-get upgrade

Change the root password:

BeagleBoard:
$ sudo -i
# passwd
# exit
# logout

Now log back into the BeagleBoard, directly into the root account using the password you just set. From here you can change the default username and password (replacing NEWNAME with your desired username):

BeagleBoard:
# passwd ubuntu
# usermod -l NEWNAME ubuntu

Now change the BeagleBoard's hostname (its name on your network). I chose to use 'bbxm':

BeagleBoard:
# echo bbxm > /etc/hostname

You'll also need to change your hosts file:

BeagleBoard:
# nano /etc/hosts

Change the 2nd line (127.0.1.1), replacing 'arm' with your chosen hostname. Since I chose to use 'bbxm', my /etc/hosts file looks like this:

127.0.0.1 localhost
127.0.1.1 bbxm

Now reboot the BeagleBoard:

BeagleBoard:
# reboot

While you can do everything over serial communication, or even plug a mouse/keyboard/monitor directly into the BeagleBoard, I find it's much cleaner and simpler to leave my board in a shoe box under the stairs with a wired ethernet connection to my router. This keeps my desk tidy and means I can SSH into it with my laptop from anywhere in the house.

If you want to be able to SSH into the BeagleBoard, log in (as your username or root, it doesn't matter) and find the board's local IP address:

BeagleBoard:
# ip addr

You're looking for the inet address of eth0. My BeagleBoard's local IP address is 192.168.0.18, as shown below:


To SSH into the BeagleBoard:

Host machine:
$ ssh 192.168.0.18

You may receive a warning about the server's key/certificate, just click Yes.

3 - Install DSP/Bridge drivers on the BeagleBoard


If your host Linux machine is 64-bit, you'll need to ensure you have a multiarch system. To check whether your machine is 32-bit or 64-bit, do the following:

Host machine:
$ dpkg --print-architecture

If the output is amd64 then you'll need the 32-bit libraries. You can check if you already have them by entering:

Host machine:
$ dpkg --print-foreign-architectures

If you see an i386 then you're already multiarch. If not, install the 32-bit libraries:

Host machine:
$ sudo apt-get install ia32-libs

You can now download and run the create_dsp_package.sh script from Robert C Nelson's github repository:

Host machine:
$ cd ~/dsp-stuff
$ wget https://raw.github.com/RobertCNelson/tools/master/x86/ti_omap/create_dsp_package.sh
$ chmod +x ./create_dsp_package.sh
$ sudo ./create_dsp_package.sh

If the script encounters a connection timeout when attempting to download a file from gforge.ti.com, you can download the required file from here instead. Place the file in your ~/dsp-stuff/dl folder and run the script again; it should work now.

The script will have created a DSP_Install_libs.tar.gz archive, which you should move over to the BeagleBoard:

Host machine:
$ scp ./DSP_Install_libs.tar.gz ash@192.168.0.18:~/DSP_Install_libs.tar.gz

Now SSH into the BeagleBoard and install DSP/Bridge:

BeagleBoard:
$ tar xf DSP_Install_libs.tar.gz
$ chmod +x ./install-DSP.sh
$ sudo ./install-DSP.sh

Next build the DSP-side drivers:

BeagleBoard:
$ sudo /boot/uboot/tools/update.sh
$ sudo /boot/uboot/tools/pkgs/ti-tidspbridge.sh

Start DSP/Bridge:

BeagleBoard:
$ sudo /etc/init.d/dsp_init start

And finally, check that DSP/Bridge is working:

BeagleBoard:
$ sudo dsp-test

If everything went OK, you should see the following:



4 - Install DSP for Dummies


DSP for Dummies (DFD) is a "framework designed to allow programmers to easily interface their programs to the DSP". It really does make using the DSP rather simple!

Before you can install DFD, you'll need some pre-requisite tools. First, install the ARM Linux cross compiler on your host machine:

Host machine:
$ sudo apt-get install gcc-arm-linux-gnueabi

Next, download the Texas Instruments C6000 Code Generation tools. You'll need to register for a free Texas Instruments account, and if you're outside of the US you'll need to fill out a short export form too. You can get the latest Linux version here.

I ran into issues with the installer crashing Cinnamon over and over again (I use Linux Mint 15). I found that by dropping into a TTY (Ctrl-Alt-F3 for example) and running the .bin directly from there instead worked just fine.

When asked for an installation directory, I chose /opt/dsp-tools, but you can install it wherever you want.

Next, you'll need the DLLcreate tool (copy the whole wget command in one go, it will work!):

Host machine:
$ sudo -i
# cd /opt
# wget -q "http://dev.omapzoom.org/?p=tidspbridge/userspace-dspbridge.git;a=blob_plain;f=source/dsp/bdsptools/bridge-tools.tar;hb=HEAD" -O - \
    | tar xf - --strip-components 3 --wildcards ti/dspbridge/dsp/doffbuild/bin/*
# exit

Now you're ready to install DFD. First, grab the source code:

Host machine:
$ cd ~/dsp-stuff
$ wget http://processors.wiki.ti.com/images/c/c3/Dsp-for-dummies.tar.gz
$ tar xf Dsp-for-dummies.tar.gz
$ cd dsp-for-dummies

Before you can compile the matrix multiplication example, you'll need to make a slight alteration to the Makefile:

Host machine:
$ nano Makefile

Ensure that Line 2 reads:

CROSS_COMPILE ?= arm-linux-gnueabi-

Also, if you installed the Texas Instruments C6000 Code Generation tools to a directory other than /opt/dsp-tools, you'll need to change Line 21 accordingly. For example, if you installed the tools to /home/ash/c6000, Line 21 should read:

DSP_TOOLS := /home/ash/c6000

You're now ready to compile!

5 - Test DFD


Compile the matrix multiplication example:

Host machine:
$ make clean
$ make

This will generate two files in the dsp-for-dummies directory, dummy and dummy.dll64P. The first of these is the GPP-side binary executable and can be placed anywhere on the BeagleBoard. The second file is the DSP-side binary which needs to be placed in the BeagleBoard's /lib/dsp directory.

SSH into the BeagleBoard and navigate to where you copied the dummy file:

BeagleBoard:
$ ./dummy 128 0 3



You should see lots of numbers be printed to the screen. If so, everything is working! :)
If not, see below.

6 - Troubleshooting


When you try to run the dummy example, you may see something like this:

-bash: ./dummy: No such file or directory

This is most likely due to a hardware/software-float ABI mismatch with the particular ARM Linux cross compiler you're using on your host machine. There are two solutions to this. The first is a bit hackish, and is to simply install the ARMEL libraries on the BeagleBoard:

BeagleBoard:
$ sudo apt-get install libc6-armel

The "better" solution is to explicitly use a hardware-float ARM Linux cross compiler on your host machine:

Host machine:
$ sudo apt-get gcc-arm-linux-gnueabihf

Note the hf at the end of gnueabi. You'll also have to modify ~/dsp-stuff/dsp-for-dummies/Makefile again so that Line 2 now reads:

CROSS_COMPILE ?= arm-linux-gnueabihf-

Again noting the hf at the end of gnueabi. Remake the example and copy it over to the BeagleBoard again; it should work now.

Closing Words


Hopefully after following this tutorial you have a working DSP/Bridge and DSP for Dummies installation on your BeagleBoard and can now successfully communicate between the GPP and DSP!

Feel free to leave comments, especially if you spot any errors :)

Thursday 17 January 2013

Installing OpenCV on Linux (Ubuntu) with FFMPEG support

Introduction


Hello and welcome to my blog! A lot of the content I'll be adding here in the future will involve the OpenCV library, so I thought what better a way to begin than with a handy installation guide for setting it up on your Linux (Ubuntu) system.

This guide will be split into three sections as follows:
  1. Install all prerequisite libraries
  2. Compile and install FFMPEG
  3. Compile and install OpenCV
So, let's begin.

1 - Install all prerequisite libraries


First of all it's a good idea to update your package lists. You can do this by opening a terminal and simply typing the following:

     sudo apt-get update

Next, install Synaptic Package Manager from the Ubuntu Software Centre (or your distribution's equivalent). Synaptic will automatically add a package's dependencies and the dependencies of those dependencies (and so on) to your system, which can massively simplify the installation process.

To mark a package for installation simply search for its name in the "Quick filter" box and click the box to the left of the relevant search result, choosing "Mark for Installation" as shown below:


(Click to Enlarge) - Searching for packages using Synaptic
You'll want to search for each of the following packages using Synaptic and mark each for installation - I've included a short description of what each package is doing but for more information check out their Synaptic pages yourself:

  • build-essential              For building debian packages
  • cmake                        For generating configured makefiles
  • libeigen3-dev                C/C++ lib for matrix/vector maths
  • libfaac-dev                  Audio encoder
  • libgtk3-dev                  For building GUI interfaces
  • libjasper-dev                For general image manipulation
  • libjpeg62-dev                For handling JPEG images
  • libopencore-amrnb-dev        Speech codec - Narrow band
  • libopencore-amrwb-dev        Speech codec - Wide band
  • libopenexr-dev               For handling EXR images
  • libtbb-dev                   Multi-core performance lib
  • libtheora-dev                For handling Ogg Theora videos
  • libtiff5-dev                 For handling TIFF images
  • libvorbis-dev                For handling Ogg Vorbis audio
  • libxvidopencore-dev          Video codec
  • libx264-dev                  Video codec
  • python3.3-dev                For building Python modules etc
  • python-numpy                 Extras for Python
  • yasm                         Assembler

Note that you can get away with not installing some of these if you know you're not going to be using them with OpenCV / FFMPEG, it's your call. This also goes the other way - If you know you're going to be using a file format or codec that hasn't been listed above, you'll want to search for its development package (the -dev suffix) and install it.

Once you've marked all of the above files for installation, click the "Apply" button and then expand the "To be Installed" drop-down that appears. Check that all of the above packages are on the list (there will be a lot more than just them - those are the dependencies). I've done the list in alphabetical order to make it a bit easier - If you've missed one simply click cancel, mark that package for installation and then click "Apply" again.

After checking that all of the packages are on the list, confirm that you wish to install them.


2 - Compile and Install FFMPEG


Now for FFMPEG. At the time of writing, FFMPEG is on version 1.1 - To get the latest version go here and scroll to the bottom, downloading the corresponding .tar.bz2 file. Alternatively to get the same version as me type the following into a Terminal window:

     cd ~
     wget ffmpeg.org/releases/ffmpeg-1.1.tar.bz2
     tar -xvf ffmpeg-1.1.tar.bz2
     cd ffmpeg-1.1

If you downloaded a different version you'll need to extract it yourself and navigate to the created folder. If you didn't install some of the prerequisites or added some extra file formats and codecs yourself you should now type this and look for the relevant options to toggle:

     ./configure --help

However, if you did the same prerequisites as me you can simply add each of the following options:

     ./configure --enable-gpl --enable-version3 --enable-nonfree
                 --enable-shared --enable-x11grab --enable-libfaac
                 --enable-libopencore-amrnb --enable-libopencore-amrwb
                 --enable-libtheora --enable-libvorbis --enable-libx264
                 --enable-libxvid

Regardless, the most important option here is the --enable-shared - If you don't have this enabled, OpenCV will not be able to use FFMPEG for opening and closing video files! You can check that FFMPEG will be shared by scrolling up after running the configuration script and ensuring it says "shared yes" as shown below:

(Click to Enlarge) - Ensure FFMPEG is shared
With FFMPEG correctly configured, type this into the Terminal:

     make
     sudo make install

Assuming there were no errors FFMPEG has now been installed.  If something went wrong, check you've set the ./configure options correctly, especially if you added/removed some of them as discussed earlier.

3 - Compile and Install OpenCV


Finally it's time to install OpenCV. As with before there may be a newer version available than what I'm using (2.4.3) - You can get the latest version here. Alternatively to get the same version as me type the following into a Terminal window:

     cd ~
     wget sourceforge.net/projects/opencvlibrary/files/opencv-unix/2.4.3/OpenCV-2.4.3.tar.bz2
     tar -xvf OpenCV-2.4.3.tar.bz2
     cd OpenCV-2.4.3

Once inside the extracted archive you'll want to create a new folder that will contain the compiled code:

     mkdir build
     cd build

Now to configure OpenCV for installation - You may have to tailor these options to suit your needs (removing -D INSTALL_PYTHON_EXAMPLES=ON if you're not interested in using OpenCV with Python, etc). Type this:

     cmake  -D CMAKE_BUILD_TYPE=RELEASE -D INSTALL_C_EXAMPLES=ON
            -D INSTALL_PYTHON_EXAMPLES=ON -D BUILD_EXAMPLES=ON
            -D WITH_TBB=ON -D WITH_FFMPEG=ON ..

Note the .. at the end of that command. Also, if you want to build OpenCV to have OpenCL support (assuming you've already installed OpenCL) then you should add the option -D WITH_OPENCL=ON after -D WITH_FFMPEG=ON.

Check the output of cmake to ensure your options have been set correctly (notably that the entry FFMPEG says YES) as shown below:

(Click to Enlarge) - Ensure FFMPEG is being used
If everything looks OK, type the following:

     make
     sudo make install

Once OpenCV has been installed there's still a few things left to do. Firstly, you'll need to tell the system where to find the OpenCV library:

     sudo nano /etc/ld.so.conf.d/opencv.conf

With the file open (it might be empty, don't worry) add the following line and save: (press Ctrl-O to save, hit enter to confirm the file name and then hit Ctrl-X to exit)

     /usr/local/lib

And finally configure the shared libraries:

     sudo ldconfig

Now you'll need to restart your machine. Once you're back open a Terminal window and type the following:

     echo $(pkg-config opencv --cflags --libs)

You should see something like this:

(Click to Enlarge) - Make sure you get something similar
If you do, you've now successfully installed OpenCV with FFMPEG support! If not you'll want to reconfigure, remake and reinstall OpenCV before checking again. You won't be able to compile your code properly until you see an output like above.

In order to compile your code, you'll want to use that same string as a compiler argument. For example, to compile the file main.cpp that includes the file #include <cv.h> you would type the following into a Terminal window:

     g++ -o EXAMPLE main.cpp $(pkg-config opencv --cflags --libs)

That concludes this guide - Thanks for reading and feel free to leave a comment if you need anything clarifying or explaining.