Giter Club home page Giter Club logo

cmake-cpputest's Introduction

cmake-cpputest

Skeleton project for development in embedded C using the approach outlined in Test Driven Development for Emedded C with testing done via CppUTest and build done using CMake

The demo source code used here (e.g. LedDriver example) was taken from the code from the book Test Driven Development for Emedded C. There isn't very much code, but I just used it as a simple demonstration of a cross-platform build environment that promotes tdd in embedded c.

Goals

  • Support dual targeting local dev machine + raspberry pi embedded target...CHECK
  • Support cross-compiler builds...CHECK
  • Support build platform independence...works on Mac OS X and Linux (see below). have not tested Windows
  • Provide a good environment for getting started on a new project...SUBJECTIVE CHECK
  • Out Of Source Build...CHECK

Why? I'm going to build a Raspberry Pi project, and compiling on the target is painful for a lot of reasons. I'd prefer to develop, build, & test on a development machine, but still have the capability of building and running tests on the target. This setup ought to work similarly for any target - not just the Raspberry Pi. You can use it and modify it to suit your needs.

I typically use Mac OS or Linux (Ubuntu) to develop with. Technically this should port to Windows with something like Cygwin, but I haven't bothered to try.

pre-requisites

NOTE I'm using Mac OSX and homebrew which makes installation a bit simpler. I also use Sublime Text 2 as my editor along with the SublimeClang plugin. I've already configured the cmake-tddc.sublime-project file so stuff "should just work" in the editor (including intellisense and auto-compilation on save).

Assume the basic GNU toolchain (i.e. make, gcc, g++, etc.)

Install CMake

With homebrew (Mac): brew install cmake With aptitude (Ubuntu): sudo apt-get cmake

Useful links:

Install CppUTest

With git: git clone git://github.com/cpputest/cpputest.git && cd cpputest && make With homebrew: brew install cpputest

Now, create an environment variable that points to it. Add the following line to .bash_profile or similar: export CPPUTEST_HOME=/path/to/cpputest

Build

$ mkdir build && cd build
$ cmake ..
$ make

Run Tests

~/git/cmake-cpputest$ cd build && ./bin/RunAllTests

......!.........
OK (16 tests, 15 ran, 20 checks, 1 ignored, 0 filtered out, 0 ms)

These 16 tests are for LedDriver which is sample code from the book. There's even an example of using a stub via the linker (RuntimeErrorStub.c).

Cross-Compile for Raspberry Pi

I gave up trying to do this on the Mac. It might be possible, but I couldn't find anything decent on how to setup Gnu compiler toolchain for the Arm/Pi hardware like there is for Linux. So, the path I'm taking is to use Linux to cross-compile when I need to, but I can still develop and test on the Mac using tdd/mocks. Only if I want to cross-compile for the Pi and push the binaries will I need to switch.

So, this step is for Ubuntu only; I grab the pre-built toolchain for Pi:

$ mkdir -p ~/git/raspberrypi/ && cd ~/git/raspberrypi
$ git clone git://github.com/raspberrypi/tools.git

Now, create an environment variable that points to the tools. Add the following line to .bashrc or similar: export PI_TOOLS_HOME=~/git/raspberrypi/tools

this is my path, yours may be different

Now, edit the file Toolchain-raspberrypi-arm.cmake and make sure the paths are consistent with $PI_TOOLS_HOME. This is the cross-compiler configuration for CMake.

In order to build, you'll also need to cross-compile a version of CppUTest, and you'll have to override the environment variable $CPPUTEST_HOME with the Arm version of the library.

Build as follows (create a different build directory for the Arm stuff so we don't intermix them)

$ mkdir pibuild && cd pibuild
$ cmake -DCMAKE_TOOLCHAIN_FILE=../Toolchain-raspberrypi-arm.cmake ..

With fingers crossed, it will build ok.

Cross-Compile CppUTest for embedded target

Actually, instead of cross-compiling the CppUTest library, I chose to build it with the QEMU emulator. It seemed easier than messing with the cross-compiler. This is a one-time build, since the code for CppUTest will not change often. I wanted to setup the Emulator anyway with QEMU, so it kills two birds with one stone.

You might ask why not just build the whole source - including CppUTest in QEMU or on the Pi itself, and the reason is that it is slow. It took about 5 minutes to compile CppUTest. I want a dev. environment that is fast and allows me to mock the hardware and dependencies.

Install QEMU

$ sudo apt-get install qemu qemu-system

Download the Raspbian Wheezy Image

$ wget http://files.velocix.com/c1410/images/raspbian/2012-08-16-wheezy-raspbian/2012-08-16-wheezy-raspbian.zip
$ unzip ./2012-08-16-wheezy-raspbian.zip

Download the QEMU Kernel Image

$ wget http://xecdesign.com/downloads/linux-qemu/kernel-qemu

Launch the image. Consult QEMU docs or online tutorials for tweaks. I had to use the -cpu arm1136-r2 target.

$ qemu-system-arm -kernel ./kernel-qemu -cpu arm1136-r2 -m 256 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1" -hda ./2012-08-16-wheezy-raspbian.img

Now, in the emulator, grab the source for CppUTest from git and build it

$ mkdir ~/git && cd ~/git
$ git clone git://github.com/cpputest/cpputest && cd cpputest
$ make

Now, kill the emulator, mount the filesystem and copy the library to the host. Run fdisk to figure out the start sector.

$ mkdir -p /mnt/pi
$ fdisk -lu ./2012-08-16-wheezy-raspbian.img 

Disk ./2012-08-16-wheezy-raspbian.img: 1939 MB, 1939865600 bytes
255 heads, 63 sectors/track, 235 cylinders, total 3788800 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000108cb

                           Device Boot      Start         End      Blocks   Id  System
./2012-08-16-wheezy-raspbian.img1            8192      122879       57344    c  W95 FAT32 (LBA)
./2012-08-16-wheezy-raspbian.img2          122880     3788799     1832960   83  Linux

$ sudo mount -t ext4 -o loop,offset=$((512*122880)) ./2012-08-16-wheezy-raspbian.img /mnt/pi

Now, create a directory on the host to hold the Arm library and include files.

$ mkdir ~/cpputest-arm
# Assume you git cloned the ccputest source to ~/git/cpputest
$ cp -R ~/git/cpputest/include ~/cpputest-arm
$ mkdir ~/cpputest-arm/lib
$ cp /mnt/pi/home/pi/git/cpputest/lib/libCppUTest.a ~/cpputest-arm/lib
$ sudo umount /mnt/pi

Now, if you want to build for the Pi target, including the test binary, you update CPPUTEST_HOME and use the CMake toolchain file for the Pi.

$ export CPPUTEST_HOME=~/cpputest-arm
$ cd ~/git/cmake-cpputest/pibuild 
$ cmake -DCMAKE_TOOLCHAIN_FILE=../Toolchain-raspberrypi-arm.cmake ..
$ make

Outputs in bin and lib directories. You can re-mount the Pi filesystem, copy them over, restart emulator and validate that they work ok (they do for me).

cmake-cpputest's People

Contributors

davisford avatar tiborsimon avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.