Thursday, September 27, 2012

Version strings in C or C++ code

This comes up every now and then and I have a hard time recalling the trick each time, so here goes: we have a revision control system (ex: git) and we'd like to include some useful version information (ex: the tag and hash via git describe) in our codebase for easy identification.  As such, we need to send that information down as a const string.

The simple way to do this is to escape the quotes around the string, something like:

VERSION=$(shell git describe)


Alternately, you can pass the raw output and stringify it via preprocessor macros as needed.  This is useful when you need both a string and raw version of something.  In the Makefile, that's just a matter of not putting the value in quotes.  For example:

VERSION=$(shell git describe)


Now in our C or C++ code, we need a macro that stringifies this, however it needs to stringify the value rather than literal name of the VERSION:

#define _STR(s) # s
#define STR(s) _STR(s)

/* then, somewhere... */
const char *version_string = STR(VERSION);

printf("version: %s\n", version_string);

The _STR macro stringifies via the '#' operator while the STR macro ensures that _STR acts on the result of a macro rather than the literal macro name. A huge thanks to my friend Andrey Smirnov for teaching me this macro.

Sunday, April 15, 2012

Getting started with LPCXpresso on Linux

Here are some notes about working with the LPC1769 on the LPCXpresso board, a reasonably cheap development kit from NXP.  I don't use the onboard JTAG/debug interface and Eclipse IDE integration (just follow their instructions if you'd like to try that).  Instead I connected a Flyswatter 2 JTAG interface (though many other ones would work fine) and used openocd.  Please check out Frank Sergeant's guide for further details.


My really quick a and dirty wiring.  You
can certainly do better with a custom ribbon cable!
Refer to the LPCXpresso schematics.  First, desolder the jumper resistors (R59 through R66) found between the columns of pins at J4. This effectively disconnects the JTAG/debug side of the LPCXpresso board.  Solder a header to J4 and wire the flyswatter JTAG interface (directly to its connector) as follows:
  • J4.2 ­to 1 (VTref)
  • J4.4 ­to 7 (TMS)
  • J4.6 to 9 (TCK)
  • J4.8 ­to 13 (TDO)
  • J4.10 ­to 5 (TDI)
  • J4.12 ­to 15 (nSRST)
  • J4.16 ­to any even pin 2 through 20 (GND)
Note that J4.14 is not connected. Power the target board by connecting J6.1 to GND and J6.2 to 3.3V on an external supply. J6.54 can also be used as GND.  Also please note that nTRST is missing, there's a way to tell openocd about that.


The Flyswatter 2 is just an FTDI 2232 FIFO device and therefore doesn't require any drivers.  It does need a udev rule though.  I created /etc/udev/rules.d/60-flyswatter2.rules with the following content:

SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", SYSFS{idVendor}=="0403", SYSFS{idProduct}=="6010", MODE="0666"


I'm using Ubuntu, but the following is similar for any distribution (package management aside).  I recommend building the latest version of openocd from source, with libftdi support for the Flywatter 2 (or similar JTAG interface).  To do this, first obtain some dependencies:

sudo apt-get install libftdi-dev
sudo apt-get build-dep openocd

Fetch the openocd source tree:

git clone git://
cd openocd

And build it:

./configure --enable-maintainer-mode --enable­ft2232_libftdi
sudo make install

From here we need the ./tcl directory from the openocd source tree.  Follow along with this helpful guide or the notes below.  The interface script for Flyswatter 2 is located in ./tcl/interface/flyswatter2.cfg.  The included ./tcl/target/lpc1768.cfg script is close enough for the LPC1769 on this board so we can use that.

Create a script tying the two together, for example this should work:

source [find interface/flyswatter2.cfg]
source [find target/lpc1768.cfg]

# tell gdb our flash memory map and enable flash programming
gdb_memory_map enable
gdb_flash_program enable

# we don't have nTRST
reset_config srst_only that to somewhere like ./tcl/board/lpcxpresso.cfg and use it to start openocd:

openocd ­s ./tcl ­f ./tcl/board/lpcxpresso.cfg

From another shell, connect to the openocd server:

telnet localhost 4444

Run the "help" command to see available options for the LPC176x.  GDB can connect via port 3333 for interactive debugging.