Laser cut acrylic cases for 96Boards Consumer Edition

TL;DR: There are some tried and tested CAD files and the DXF files can zipped and sent directly to the Seeed Studio laser cutting service.

Simple case for 96Boards Consumer EditionI have amassed a modest collection of 96Boards. They come as plain circuit boards with nothing to keep them safe from damage during handling. Its not just static discharge we have to worry about! Many of the boards have fairly large components on the underside and these can be knocked off by careless handling (I admit that I’m tempted to say “Hi” to a colleague at this point, but I won’t). Since, I’m at least as careless about handling as the next software engineer so I decided a case was needed.

I’m not aware of anyone selling cases for the 96Boards Consumer Edition so I decided to get my own laser cut. As it happens between ordering the boards and writing this post I have started to come across a couple of other folks at Linaro who are experimenting with cases but nevertheless I think I’m still the first to blog about it!

There is a hackspace in Bristol, UK where I live which could be a great place to get involved in laser cutting but it’s right on the other side of the city and I’ve not really found the time to get very involved there. Instead I decided to try out the Seeed Studio online laser cutting service: 100mm x 100mm, cut to your own design for $6 for five (plus postage).

Having something of a plan the only remaining problem is that I know absolutely nothing about CAD/CAM. The only information on the Seeed Studio website about file formats is that I must send in .zip or .rar files and the only blog posts I could dig up wanted me to use the Google Sketchup which is non-free and partially discontinued.

In the end I just asked myself, “How hard can it be?” and fired up LibreCAD. After working through a couple of tutorials I learned how to round off corners and how to add dimension information. Armed with this, and the 96Boards CE Specification which has very clear diagrams of the physical layout of the board, I draw a basic top/bottom plate. I wasn’t happy with the 35mm of “wasted” material due to the minimum panel size of the manufacturer so I added a half-top component as well. The half-top should work very nicely with the 96Boards UART board.

Combo case for 96Boards Consumer Edition

Influenced by this blog post I decided to export from LibreCAD as an SVG. This turned out not to be such a great idea. The resulting SVG uses curves that are quantized to pixelish boundaries. The friendly folk at Seeed Studio declined to use it and askeld me for DXF files instead. Since DXF is the native file format for LibreCAD this was not much of a hardship.

And that’s it… I got a bunch of cases made in a couple of colours. The glowing neon green in the photo above is sooooo my favourite. I’ve hurled my design files at github and, because I’ve had so much fun with this, I’ve given the project a nice generic name. Maybe there are more cases to come. If that happens, you’ll read about it here first!

Share

A USB relay controller from cheap off-the-shelf parts

This is an old project that I’ve been meaning to blog about for some time and, over a year later, am finally finding the time to write up. The project is a USB controlled (and powered) bank of relays assembled from cheap boards that can be purchased from ebay. The total cost a controller board and a bank of eight relays is about £6.50 (or $10 USD if you prefer to count like that).

stm32f103c8t6_dev_board
STM32F103C8T6 controller board

The controller board is an STM32F103C8T6 breakout board which provides the USB hardware and an ARM Cortex M3 CPU combined with enough FLASH and on-board RAM to make writing software fairly easy. These terrific little boards can be found on eBay for a whisker over £3 and are just perfect for hacking together all kinds of USB toys and tools (some of which may be the subject to further blog posts).

8 channel relay board
8 channel relay board

The only other components needed is the relay board and a bunch of jumper wires. Relay boards can be bought on eBay in single, dual, quad or octo configurations depending the complexity of your projects.

I use this project to automate things on my rather modest pool of development boards but definitely need all eight relays (and then some). My relays control power delivery and, for some boards, they are also used to automate changes to jumper configuration. The HiSilicon HiKey board (from 96Boards.org) is especially needy in this department. To automatically test its debrick/recovery process requires three relays. One for power control and a further two to manipulate the jumper configuration.

Both boards connected with jumper wires
Both boards connected with jumper wires

The completed system is fully USB powered with the relay board taking a 5V feed from the controller. Eight relays can be pretty hungry when they are all energised at once but we do just about manage to sneak in below the 500mA USB current limit.

So… the hardware in this build is very simple and can be assembled even by someone with no electronics knowledge. What about the software?

There is a complete firmware for the device which can be FLASHed to the controller board without much fuss. The firmware contains a simple command interpreter which is present to the host as a CDC/ADM class compliant device. This allows the device to operate without drivers on more or less any operating system.

> help
Available commands:
  echo
  id
  help
  reboot
  relay1
  relay2
  relay3
  relay4
  relay5
  relay6
  relay7
  relay8
  uptime
  version
> relay1
Usage: relay1 on|off|toggle|pulse
> relay1 on
> relay1 off
>

Like any command interpreter the firmware can be automatically driven using an expect-like system. However on GNU/Linux (and I suspect any other Unix-like OS) it is sufficient just to hurl commands at the device node using shell scripts:

echo relay1 on > /dev/ttyACM0

The firmware has a couple of extra bits of polish to make it more practical. In particular the unique serial number embedded into all STM32 devices during manufacturing is extracted and persented as the USB serial number. This allows udev to be configured to recognise specific devices and give them stable device names regardless of any rearrangements of the USB bus topology. This allows a single host PC to (reliably) support a very large number of relays. Also included in the firmware package is a tiny shell scripted called targetctl which allows individual relays to be named, even across multiple usb-relay devices.

The firmware consists of a bootloader and the main image. The bootloader can be downloaded either using the UART bootloader included in the ROM of almost all STM32 devices. However I prefer to hook up an ST-Link (these are also easily found on eBay) to the controller boards JTAG pins to FLASH to bootloader. Once the bootloader is in place its easy to install the main image using a DFU programmer such as dfu-util. After the main image has been installed the device reboot and enumerate as a CDC/ACM device and is ready to use. With the main image installed the board will launch into it automatically. However pressing the reset button will force the device back into DFU mode ready for a firmware update.

For more information on how to install the firmware see http://github.com/daniel-thompson/usb-relay.git .

Finally to finish up I would really like to thank all the folks who work on libopencm3. The USB code in usb-relay comes from libopencm3 and without it then usb-relay probably wouldn’t exist in its current form.

Share

Debugging ARM kernels using fast interrupts [LWN.net]

I suspect that there are relatively few regular readers of this blog. However if you are one of them and are feed up with hastily written articles with inadequate proof reading then may I recommend you take a look at my recent article for lwn.net describing some of my recent Linux kernel work:

Debugging ARM kernels using fast interrupts

Not only did I proof read it, proof read it and proof read it again but the terrific folks over at lwn.net did the same resulting in an article I’m really proud of.

PS if you are not an lwn.net subscriber then you’ll have to wait until next week to read it…

Share

How loop optimization in GCC uses undefined behaviour to make inferences

There are many ways to try and understand how an optimizing C compiler might transform your code.

Lets start by thinking about the goal of an optimizing compiler. Its goal is to manipulate the code that it is presented with, making modifications to cause it to execute more quickly and without altering the observable behaviour of a correctly formed program.

It is very important when describing the effects of an optimizer to remember that its only obligation it to preserve the behaviour of a correctly formed program. If your program is not correctly formed (normally expressed by compiler writers as relying upon undefined behaviour) then the optimizer is allowed to make modifications. That’s it! These modifications need not  preserve observable behaviour. They don’t have to execute more quickly. They don’t have to try to guess the programmer’s intent. The compiler is allowed to make modifications of more or less any form.

Over the years optimizing compilers have come to make inferences based on undefined behaviour. One of the simplest ones occurs when a pointer is dereferenced. In this case the compiler knows that the pointer cannot be NULL (because it has already been dereferenced and dereferencing a NULL pointer results in undefined behaviour). As a result it can the treat any later checks for pointer validity as unreachable code and remove it.

Recently GCC gained a much more powerful mechanism to track undefined behaviour that occurs due to out of range loop indicies. Having read about this and looked at a few spurious compiler bug reports I settled down and wrote the following plausible but buggy code.

Note: If you like puzzles then don’t scroll down past the return 0; statement and closing brace. That way you can try and spot the bug yourself. As far as I know there is only one in there!

int is_whitespace(char c)
{
    const char lookup_table[] = { ' ', '\t', '\n' };

    for (int i=0; i<=sizeof(lookup_table); i++)
        if (c == lookup_table[i])
            return 1;

    return 0;
}

Spotting the error is hopefully the easy part.

If you need a clue then be reassured that the lookup table contains three elements (it is initialized from character literals rather than a string literal so it does not get nil-terminated).

If you just want to know what the bug is so you can keep reading this article then have a look at the loop exit condition. It uses <= rather than < meaning the loop exit condition is reached after four cycles round the loop. This results in reading after the end of the array leading to undefined behaviour.

Now for the hard bit. What do you expect to happen when you run this code?

One answer, and one that I might have given had I been asked this question instead of writing it is: “strictly speaking this is undefined so it needs fixing, however the padding put in by the linker means that on most systems lookup_table[3] will evaluate to ‘\0’ and so the function will work more of less as intended (assuming the caller never cares whether the ‘\0’ character is whitespace or not)”.

That answer might even have been adequate two years ago. However with modern compilers it is better to rely on the simpler answer regarding what can happen: “anything”.

Nevertheless, even knowing all of the above the transformation the compiler actually makes may still yet surprise you. Unconditionally the code comes out as:

int is_whitespace(char c)
{
    return 1;
}

If you don’t believe me look at the assembler (generated using gcc-4.8.2 with -O2 -std=c99 -S on x86-64).

        .file   "g.c"
        .text
        .p2align 4,,15
        .globl  is_whitespace
        .type   is_whitespace, @function
is_whitespace:
.LFB0:
        .cfi_startproc
        movl    $1, %eax
        ret
        .cfi_endproc
.LFE0:
        .size   is_whitespace, .-is_whitespace
        .ident  "GCC: (GNU) 4.8.2 20131212 (Red Hat 4.8.2-7)"
        .section        .note.GNU-stack,"",@progbits

What has happens is the compiler has realized that when i == 3 the code makes an undefined memory read. From this the compiler infers that i must always remain strictly less than three during execution of the function and that, for this reason, the end condition is unreachable. It can be optimized away and, because this change means the loop can never exit then we also know that the function can only return 1 so we can get rid of the loop itself as well.

As a further exercise imagine what happens if the loop contains a function call that is opaque to the optimizer (meaning that the compiler doesn’t know what side effects the function has and therefore cannot remove it). Now we still know that the end condition is unreachable but we need to call the function a data dependant number of times. Of course the compiler still believes the end condition is unreachable and can optimize it away. This results an infinite loop!

If you’re currently busy moaning about arrogant out-of-touch compiler writers who don’t understand the real world then please stop. Compiler writers tend to dog food (by compiling their compilers using their own compilers) and are just as in touch with the real world as every other working programmer. Perhaps instead you could thank them for transforming a rare, hard to tickle bug that could easily slip into production, into a deterministic one that should be caught by even the most simple of tests. That’s much easier to debug.

Of course the other thing you get out of the dedication of your compiler writer is faster code. In a system where there is heavy inlining of defensively written code (for example the C++ standard library) then, in principle, throwing away unreachable loop end conditions could pay significant dividends.

Share

Fifteen minutes using a Boss Micro BR

The fifteen minute figure is a slight poetic license. I did record this track during my first fifteen minutes playing about with the recorder. However after that it took me nearly twenty minutes to figure out how to master it into a format I can share with the world!

Recording is an Epiphone Dot plugged directly into a Boss Micro BR using the P01 “SuperCln” preset. The preset has been changed from the factory setting only by turning off the chorus.

To be honest the chorus effect sounds pretty terrific but, with such a naked guitar part it makes it sound like I have something to hide.

micro_br

Share

Use “#!/usr/bin/env hbcxx” to make C++ source code executable

#! C++I normally write some kind of personal toy during the holiday season. For example last year I wrote a toy fibre scheduler to go with a microcontroller project I was working on. This year however I’ve cooked up something and can’t quite decide if its a great idea, a pointless idea or a stupid idea. One thing is clear however, to find out which of the three possibilities it is, this bit of code needed packaging up properly as a product and shared with the wider world. Basically hbcxx uses the Unix #!/path/to/interpreter technique to make C++ source code directly executable.I’ve been taking a new look at C++. There is a palpable sense of “buzz” in the C++ community as they realize that, with C++11, they are sitting on something pretty special. The advocacy from the presenters at Going Native this year was remarkably effective (although if you take my advice you won’t watch Scott Meyer’s brilliant Effective C++14 Sampler until you know what std::move is for).
Quoting Bjarne Stroustrup: Surprisingly, C++11 feels like a new language. Considering its source it is not at all surprising that this quote is absolutely on the money: modern C++, meaning C++11 or later, does feel like another language. This is not because the language has been changed massively but because the new features encourage a different, and slightly higher level way to think about writing C++. It’s faster and more fun, supports lambdas, has tools to simplify memory management and includes regular expressions out-of-the-box.I was actually pretty amazed to see regular expressions in the standard C++ libraries, so that coupled with humane memory management (albeit humanity where you have to explicitly opt-in) and the auto keyword really got me thinking differently about writing C++. auto even encouraged me to write a template (generic programming is so much easier when you don’t have to explicitly declare the type of every expression). All this and without losing type safety…So my great/pointless/stupid idea (delete whichever is inappropriate) is a tool to keep things fast and fun by putting off the moment you have to write a build system and install script. For simple programs, especially for quick and dirty personal toys and scripts, the day you have to write a proper build system may never come. You no longer want the distraction of making a separate directory and a Makefile and you’ll find that pkg-config to just work.Instead I just copy your C++ source code into $HOME/bin. Try it. It works.Features include:

  • Automatically uses ccache to reduce program startup times (for build avoidance).
  • Enables -std=c++11 by defualt.
  • Parses #include directives to automatically discover and compile other source code files.
  • Recognises the inclusion of boost header files and, where needed automatically links the relevant boost library.
  • pkg-config integration.
  • Direct access to underlying compiler flags (-O3, -fsanitize=address, -g).
  • Honours the CXX environemnt variable to ensure clean integration with tools such as clang-analyzer’s scan-build.

To learn more about hbcxx take a look at:

Then have fun.

 

Share

How C++11, threads and lambda capture come together.

Somehow when I first read about C++ lambda functions I overlooked the way in which they capture variables. What can I say, I’m pretty familiar with python and just somehow expected variables to be automatically captured…

Be that as it may, I would like to present you with some broken code of the type I wrote when I first set out working on some of this stuff:

#include <atomic>
#include <iostream>
#include <thread>

using namespace std;

class threads_and_lambda_capture {
    thread worker;
    atomic<bool> running;

    void process()
    {
        while (running) {
            cout << "Process is running" << endl;
            this_thread::sleep_for(chrono::seconds{5});
        }
    }

public:
    threads_and_lambda_capture()
        : worker{}
        , running{true}
    {
    }

    virtual ~threads_and_lambda_capture()
    {
        // With thanks to Scott Meyers for making this topic the
        // subject of a presentation... if you forget to stop a
        // joinable thread then the threads destructor will
        // terminate the program.
        stop();
    }

    void start()
    {
        running = true;
        worker = thread{[]() { this->process(); }};  //  <== BUG!!!
    }

    void stop()
    {
        if (worker.joinable()) {
        running = false;
            worker.join();
        }
    }
};

Most of the class above is merely scaffolding to show you a little context. The focus of the rest of this post is exclusively the start() method:

void start()
{
    running = true;
    worker = thread{[]() { this->process(); }};  //  <== BUG!!!
}

The intent of the above code was to make a method belonging to the current class as the thread entry point. The bug in the above code is that the this pointer has not been captured by the lambda and is therefore undefined in the lambda’s body.

After a little time in the company of google I replaced my code with the following working code and moved on:

void start()
{
    running = true;
    worker = thread{&thread_and_lambda_capture::process, this};
}

Somehow this irked me slightly. For me, the real value of modern C++ (including C++11 and the soon to be released C++14) is that it takes down the level of expertise required to utilize its power.  For that reason the above just seemed too knowledge intensive to be modern C++.

Thankfully I was right! When I discovered, in a completely different context, more about lambda capture I revisited the code above (and decided to write a blog post about it).

void start()
{
    running = true;
    worker = std::thread{[this]() { this->process(); }};
    //                   ^^^^^^       ...and BUG is gone
}

To explain what’s happening here, lambdas in C++11 consist of the [] variable capture section, the optional () parameter list section and the {} body. With this added to the list of captured variables then the symbol in the lambda body resolves correctly. Note that I have captured this by value (making a copy of it) rather than by reference for the same reasons I would apply to method calls. As usual, objects that cannot (or should not) be copied are better captured by reference.

An short but information dense introduction to C++ lambdas can be found at: cppreference.com .

It is true that the above code is probably still not particularly pleasing to a novice (and I suspect it may also be slightly slower although I have not read the disassembly to check this). However the knowledge demonstrated is likely to be far more transferable to other problem domains than knowing the arcane behaviour resulting from taking the address of contains member functions. So much so that a novice tutored in modern way (meaning parts of STL are introduced on the first day) will probably already have come across the concept of variable capture long before multi-threading raises its head!

So… with my new found transferable knowledge I’m going to finish the lambda function I need to filter a list.

Share

Measuring a ’12 Nexus 7’s microphone to speaker latency

The recent release of patchfield for Android made me wonder whether Android’s audio system has developed sufficiently over the last three years to be suitable for real time signal processing. There have been a couple of developers at google working hard to reduce the output latency but their work does not yet encompass input latency.

However since patchfield allows the speaker to be digitally connected to the microphone it is easy to use patchfield itself to measure input to output latency of an Android system.

The following picture shows the test set up I used to measure it.

image

On the left is my 2012 Nexus 7. This is connected to the earphones sitting in top of the (red) sound card. Using earphones prevents feedback between the mic and speaker. Finally a microphone rests on top of the earphones. Critically the microphone picks up both the environment and the output of the earphones.

If you are particularly eagle eyed you might have notices a few missing cables in the above picture. Specifically the earphones are not actually plugged into the Nexus and the microphone is not plugged into the soundcard! I haven”t faked the photo however I only decided to blog about it after I had starting taking things apart again. In may haste to get a picture of it I forgot to plug it all back together.

Latency is measured simply by knocking in the table surface. This creates a short burst of noise that is captured both by the microphone in the picture and by the Nexus’ internal microphone. Patchfield captures the sound and replays it to the earphone which the microphone also picks up. The latency can then by calculated by looking at the waveform of the signals picked up by the microphone.

And the results are… 132ms from input to output. Just to put this number into perspective a piano, which is one of the highest latency musical instruments, takes about 25ms from the start of a keypress to the hammer striking a string. Another way to express it is that it is way too much for any musical application. The brain doesn’t just hear it as an echo… it hears it as a LOOONNNGG echo!

I repeated the same test on my Nexus 4 and that was better but not by enough to make much difference. That “only” took 124ms.

I guess there remains lots of very good reasons by iRig is not available for Android. There is one remaining ray of hope: the latest Samsung Mobile SDK includes a professional audio API based on jack and dedicated to handling low latency. It looks like Samsung really do want to take the fight to apple.

Share

Faking try/catch/finally in bourne shell (and jenkins)

When Bourne shell was first release in 1977 it turned out that, for several very good reasons, Steven Bourne had designed a nice simple language with no need for exception handling. That is, it did not need exception handling until Jenkins, also for very good reasons started using it with the -ex that causes the shell to bail out on the first error in encounters.

Normally Jenkins’ behaviour is is exactly what you need. Scripts stop as soon as something goes wrong. However a typical glue script to run a test suite overnight on a shared development board might look like the following pseudo-code:

lock $MY_DEVELOPMENT_BOARD
make test TARGET=$MY_DEVELOPMENT_BOARD
unlock $MY_DEVELOPMENT_BOARD

This problem with the above code is run using jenkins, or any other tool that runs the shell with the -ex argument, then the unlock command is not run if the test suite fails and make returns the error to us and the board is never unlocked. A simple fix might be:

lock $MY_DEVELOPMENT_BOARD
if make test TARGET=$MY_DEVELOPMENT_BOARD
then
    unlock $MY_DEVELOPMENT_BOARD
else
    unlock $MY_DEVELOPMENT_BOARD
    false
fi

If you favour compactness (and only having to type out the unlock command once) then perhaps:

lock $MY_DEVELOPMENT_BOARD
make test TARGET=$MY_DEVELOPMENT_BOARD && res=$? || res=$?
unlock $MY_DEVELOPMENT_BOARD
[ 0 -ne "$res" ] && false

However what about the following. Note that the “unlock” command is similar to a  a “finally” operation in some languages but will be executed before the catch statement:

lock $MY_DEVELOPMENT_BOARD
try make test TARGET=$MY_DEVELOPMENT_BOARD
unlock $MY_DEVELOPMENT_BOARD
catch echo "System tests failed! Please see logs"

The above can readily be implemented aided by a couple of simple shell functions:

try () {
        if [ -z $exception_has_been_thrown ]
        then
                "$@" || exception_has_been_thrown=1
        fi
}

catch () {
        if [ ! -z $exception_has_been_thrown ]
        then
                "$@"
                false   # If "sh -ex" then exit at this point
                unset exception_has_been_thrown
        fi
}

These scripts don’t make a big difference for the simple script above. However what if you are running multiple test suites sequentially under lock?

lock $MY_DEVELOPMENT_BOARD
try make smoke_test TARGET=$MY_DEVELOPMENT_BOARD
try make heavy_regression_test TARGET=$MY_DEVELOPMENT_BOARD
unlock $MY_DEVELOPMENT_BOARD
catch echo "System tests failed! Please see logs"

Now at last the benefits of these wrapper functions really make sense. Because all the test suites are run using the try function then they will be skipped if previous try blocks have reported an error. This gives us behaviour similar to -e but delays the reporting of the error until the unlock has been performed.

To close, and for the historians amoung you, despite my starting this post with a reference to 1977 the code presented wouldn’t have run in the original Bourne shell because it uses features that were added later. However I think that by 1986 (SVR3) then all the features used here would have been available. Certainly if you know different then please let me know… I’d be interested.

Share