Raspberry Flavoured Goodness
I am working on a problem where I need to capture images with a camera and put them on a large screen. The raspberry pi with its optional camera board, and a large screen TV are the perfect elements to solve this problem. The program raspistill will take an image and put it on the screen for you which solves most of my problem. Thankfully the raspistill is open source software and so my attack plan was to examine that code then modify it to my needs.
Getting your hands on the source code for raspistill is easy
git clone https://github.com/raspberrypi/userland.git
Then I mostly used the instructions from http://thinkrpi.wordpress.com/2013/05/22/opencvpi-cam-step-2-compilation/
- cd userland
- sed -i ‘s/if (DEFINED CMAKE_TOOLCHAIN_FILE)/if (NOT DEFINED CMAKE_TOOLCHAIN_FILE)/g’ makefiles/cmake/arm-linux.cmake
- cmake -DCMAKE_BUILD_TYPE=Release
<Patience> <More patience> All compiles! If only most software was this well behaved.
Since my final goal is to make an executable like raspistillyuv, why not use raspistillyuv as a proxy to let me sort out the build environment. Using find for a while located the source code at userland/host_applications/linux/apps/raspicam/RaspiStillYUV.c. So I created a new directory /home/pi/raspicam and copied RaspiStillYUV.c to it. A bit of include chasing also showed that I needed to copy
RaspiCamControl.c RaspiCLI.h RaspiPreview.h RaspiCamControl.h RaspiCLI.c RaspiPreview.c
The simple plan was to compile and link the c files. On the Raspberry Pi its well known that you have to include some extra paths in order to make progress. So my first guess at a compile command was
g++ -I . -std=gnu++0x -isystem /opt/vc/include/ -isystem /opt/vc/include/interface/vcos/pthreads/ -isystem /opt/vc/include/interface/vmcs_host/linux/ RaspiStillYUV.c
and we promptly hit the following error
RaspiStillYUV.c:62:33: fatal error: interface/mmal/mmal.h: No such file or directory
Hunt for the missing headers
Now all the raspberry pi specific code is usually found under /opt/vc/include. Searching under here shows that there is no mmal.h installed. I did find /opt/vc/lib/libmmal.so. So how did this get onto the system? dpkg can do the reverse lookup for us
$ dpkg -S /opt/vc/lib/libmmal.so libraspberrypi0: /opt/vc/lib/libmmal.so
This would normally mean that the associated headers would be included in libraspberrypi0-dev which doesn’t exist. libraspberrypi-dev does exist but
$ dpkg -L libraspberrypi-dev |grep mmal
gives nothing. libraspberrypi-dev (1.20140618-1) now does contain these headers. Be careful of what you trust in the original blog entry (this update was written on 20140627) Also
$ apt-file search mmal.h
However, since the userland repository compiled up the camera binaries it must contain all the mmal code. And a find turns up
It would appear that the mmal headers would naturally go under the /opt/vc/include/interface directory. A tempting solution is to just copy the headers into the directory and declare the job done, however having been down that path I know it is the darkside (been free of the darkside since 2002) and always ends in tears/reinstall of OS. The correct solution is to make a package.
The fastest way I could think of to create a deb package is
$mkdir mmal-dev-20130909 && cd mmal-dev-20130909 $cp -r ~/userland/interface/mmal . $cat >Makefile <<EOF install: cp -r mmal /opt/vc/include/interface/ uninstall: rm -rf /opt/vc/include/interface/mmal EOF $sudo checkinstall
Back to the problem of compiling RaspiStillYUV.c
Rather than writing Makefiles, I use a program called cake that writes the Makefile and then calls make. The CFLAGS that cake uses on the raspberry pi are
-I . -fPIC -g -Wall -march=armv6 -mfpu=vfp -mfloat-abi=hard -isystem /opt/vc/include/ -isystem /opt/vc/include/interface/vcos/pthreads/ -isystem /opt/vc/include/interface/vmcs_host/linux/
which leads to the link error
undefined reference to `mmal_component_create'
Which means that we also need to specify the following link flags
-Wall -Werror -march=armv6 -mfpu=vfp -mfloat-abi=hard -L /opt/vc/lib -lbcm_host -lmmal
And then all is well.
1. Ha! On a proof read I discovered that I’ve outed myself as a C++ programmer not a C programmer. 🙂 Back to Post