Friday, July 12, 2013

Moving to Google+

I'm trying my Google+ as a replacement for this blog from here on out.  Here's my first attempt: Semihosting on ARM Cortex-M with open-source tools and Using newlib-nano for MCU firmware -- please check it out and let me know what you think.

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)

CFLAGS += -DVERSION=\"$(VERSION)\"


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)

CFLAGS+=-DVERSION=$(VERSION)


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.

Wiring

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.

flyswatter

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"

openocd

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://openocd.git.sourceforge.net/gitroot/openocd
cd openocd

And build it:

./bootstrap
./configure --enable-maintainer-mode --enable­ft2232_libftdi
make
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


...save 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.

Thursday, June 23, 2011

Ubuntu 11.04 slowness and high CPU usage

I noticed extremely high CPU usage on my ThinkPad X40 after upgrading from Ubuntu 10.10 to 11.04 a while back.  This rendered the laptop nearly unusable, heated the system up quite a bit, and kicked the fan on all the time.  This was with the Unity interface disabled (it doesn't work on my hardware anyway) and almost nothing of interest running.

A bit of searching revealed that many others have the same problem: there seems to be an issue with the 2.6.28 series kernel provided with 11.04.  I decided to try a newer kernel to see if the problem goes away without me having to troubleshoot further.  There are a number of ways to do this, but I added the kernel PPA and upgraded the kernel packages:

sudo add-apt-repository ppa:kernel-ppa/ppa
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install linux-image-generic linux-headers-generic

and then rebooted.  This gave me the 2.6.39-0-generic which runs much better: the system is nice and cool, CPU usage is quite low, the fan is barely on, and applications run normally.

Hopefully this helps someone out.  As before, it seems that little to no testing was done on a large range of popular hardware.

Update

I had another case of 100% CPU usage and this time it was due to a process, "upowerd" taking nearly 100% CPU.  I don't know how to resolve this one yet but you can get the system back to being usable by simply killing that daemon:

sudo killall upowerd

Friday, April 29, 2011

setting up the finger print reader on a ThinkPad with Ubuntu

This works fine on my ThinkPad X61s (SGS Thomson Microelectronics reader) with Ubuntu 11.04 (and should be the same on the previous few versions).

I like the finger print reader even though it's not particularly secure.  My take on this is that it saves me time and prevents people from seeing my password over my shoulder.  You'd still need need physical access to my laptop to break in, at which point all bets (including the password, finger print reader or not) are off anyway.

To enable the finger print reader, first, install the thinkfinger packages:

sudo apt-get install thinkfinger-tools libpam-thinkfinger

Use tf-tool to acquire a fingerprint for your user account:

sudo tftool --acquire

And tell PAM to use thinkfinger as an authentication option:

sudo apt-get install thinkfinger-tools libpam-thinkfinger

From there on out, a finger swipe will be sufficient for things like "sudo" on the shell or logging in.  It won't let you unlock a locked screen (if you need that, you have to set a few things up for xscreensaver).  If you have multiple users and they want to use the fingerprint reader, you need to repeat the "tf-tool" step per user.

Enjoy your finger print reader while you still can, a whole new mess is coming soon.

Sunday, February 13, 2011

button (or other GPIO pin) debouncing

GPIO pin de-bouncing is a fairly common task and there are many good ways to implement it.  Here's how I handle it on most projects, I think that it's fairly clean and easy to adapt to small microcontrollers or for use in Linux kernel drivers.

Each pin that needs to be sampled and debounced can be represented with a state machine comprised of a state, value, and counter.  A pin is either idle (whether pressed or released) or in transition to being pressed or released.  To transition to the idle state, the pin must maintain the same level for a number of counts.

A pin can therefore be represented something like:

enum pin_state {
        PIN_IDLE       = 0,
        PIN_PRESSING   = 1,
        PIN_RELEASING  = 2,
};

struct pin {
        enum pin_state state;
        char pressed;
        unsigned char debounce;
        unsigned char debounce_threshold;
};

I use three states but with the combination of 'state' and 'pressed' and 'debounce' we really have four real states (idle-pressed, idle-released, pressing, and releasing).

At initialization time, the pin structure(s) should be set to zero.  The 'pin' structure should also contain information about the pin to enable a routine to check its value (for example the GPIO port and pin number).  We then poll the pin or pins in a thread or main loop.  For example, to check just one pin:

static struct pin;

void init(void)
{
        memset(&pin, 0, sizeof(pin));
        /* pick some reasonable threshold, this is a
           factor of your circuit and polling
           frequency */
        pin.debounce_threshold = 10;
}

void check_pins(void)
{
        /* invert this if the pin is active-low, as is common
           for buttons, we treat a '1' as 'active' */
        char cur = gpio_get_pin_value();

        switch (pin.state) {
              case PIN_IDLE:
                     if (cur != pin.pressed) {
                            pin.state = cur ?
                                    PIN_PRESSING : PIN_RELEASING;
                     }
                     break;
              case PIN_PRESSING:
                     if (cur) {
                            pin.debounce++;
                     } else {
                            pin.debounce = 0;
                            pin.state = PIN_IDLE;
                     }
                     break;
              case PIN_RELEASING:
                     if (cur) {
                            pin.debounce = 0;
                            pin.state = PIN_IDLE;
                     } else {
                            pin.debounce++;
                     }
                     break;
       }

       if (pin.state > PIN_IDLE &&
                      pin.debounce > pin.debounce_threshold) {
              /* report the pin press or release */
              report_pin(cur);
              /* and now the pin is idle */
              pin.state = PIN_IDLE;
              pin.debounce = 0;
              pin.pressed = cur;
       }
}

If there are multiple pins to check then I would replace the single 'struct pin' with an array and loop over them. In that case 'struct pin' should contain pin port and pin number information for your implementation of  'gpio_get_pin_value()'.

Thursday, January 20, 2011

inspecting USB HID descriptors in Linux

It's sometimes necessary to see the complete USB HID descriptor for a device, including the report descriptor.  On Debian-based systems like Ubuntu, you can do this with "lsusb".

To see all of the information with the report descriptor you must:
  1. unbind the HID device in question
  2. run "lsusb -vvv" as root
To see a list of HID devices:

$ ls /sys/bus/usb/drivers/usbhid


For example, for the device 3-1:1.0 you can:

$ echo -n 6-1:1.0 | sudo tee -a /sys/bus/usb/drivers/usbhid/unbind
$ sudo lsusb -vvv