Thursday 1 July 2010

England In Despair

Well, it gives me no pleasure to have been proved right in my earlier predictions - on Sunday the English football team were indeed humiliated and sent home by a clearly superior Germany.  At least Germany had the grace to inflict a heavy defeat during normal time, without it having to go to penalties.  Indeed, at 4-1 it was England's heaviest ever World Cup defeat.

Yes, Lampard's goal was disallowed, and maybe in some alternate universe it proved a turning point, inspiring England on to victory.  But in this 'verse Germany weathered some pretty sustained pressure and then simply ran the length of the pitch and scored.  Twice.  The disallowed goal will give the disaffected fans something to whine about for the next few years (alright, for many, many years), but it finally makes up for England's disputed goal against Germany in the 1966 final.

Overall it was a lacklustre campaign.  This wasn't helped by the fact that the British press are both vicious and fickle, and having whipped up national hopes (as always) to near-hysterical levels, will now turn on the team, looking for blood.  The goalkeeping error against the USA was instantly (and rather brilliantly) dubbed 'The Hand of Clod', and Monday's headlines proclaimed 'Rout of Africa' and 'Fritz All Over Now'.  The fate of Fabio Capello's stint as boss must now be in the balance.

So what's a nation to do?  Why, turn to tennis, of course.  Andy Murray's through to the Wimbledon semi finals tomorrow.  He's Scottish, but that's near enough for the English papers, who conveniently refer to him as British while he's winning.  And the cricket's going rather well, although the prospect of a whitewash in the current one day series has been spoiled by Australia rather inconveniently winning the fourth test to bring the score to 3-1.

Oh, one more thing.  My wife has asked me to point out that, despite my previous snide comments, she does indeed understand the football offside rule.  And she gave a very convincing demonstration of this using the kitchen table, assorted condiments for players, and a handy hard boiled egg for a ball.  I most humbly apologise.

Enddianness and Neddiness

This is not an article about byte ordering

Nor is it a discussion of the correct way to eat your eggs

Rather, it is an exposition on the inability of the human brain to grasp the implications of statistics.

I'm writing this on a Saturday evening.  On Friday night, the last thing I did before leaving the office was to start a stress test running on one of my chip designs.  It's testing the chip communications.  I'm testing that under no circumstances will the chip lock up, or fail to respond correctly to communications.  I'm running the test because previous designs on other silicon have exhibited failure modes in which it was possible for the chip to stop responding to communications.

On Monday morning the first thing I will do on going into the office will be to see if the LED attached to the chip is still blinking, indicating that the test is still running, and no failures have occurred.  I've been running this same test every night and every weekend for about three weeks, and seen no failures yet.  Does this mean that the communications in this chip is bulletproof?  No, it does not. 

The highly recommended book The Black Swan, by Nassim Nicholas Taleb, talks about the nature of randomness, and in particular what the author dubs Black Swans - events deemed to be of very low likelihood, that have a devastating impact, and that can be explained away after the fact by experts with a little judicious hindsight.  (In this podcast, Taleb describes this as "a retrospective ability to weave a causal link", which is a rather wonderful turn of phrase).  These would be the self same experts who were completely blindsided by the events themselves, but who can confidently explain them away after the fact.  Events such as the two World Wars and the various economic disasters of the last century or so are all Black Swans. 

Taleb, in both this book and the earlier Fooled by Randomness, pours withering (and often entertaining) scorn upon such experts.  Economists, stock traders, MBAs, and indeed anyone having the temerity to make predictions about the future based on past trends, are all mercilessly ridiculed.  (He makes a few honourable exceptions - Karl Popper, George Soros, and Benoit Mandelbrot have all earned his respect.)

In one chapter of The Black Swan Taleb discusses the nature of human fallibility.  In it he talks about the medical acronym NED (No Evidence of Disease).  Apparently this is written on a patient's records after some tests have been run, and no sign of any malignancy or unusual activity has been found.

What, Taleb points out, doctors will never write is END - Evidence of No Disease. That is, they will happily say that they did not see any sign of a problem, but they will never say that there is no problem.

As engineers, it behooves us to adopt the same approach.  If you have been working as an engineer for any length of time, you will have been caught out by the apparent absence of any problems in just the same way that I have in the past.  Just because we have run tests for a period of time and seen no bugs, this does not mean that there are no bugs - it just means that we have not seen any.  But even though I'm now on the lookout for feathery portents of doom, I'm still really hoping that that LED will be blinking on Monday morning.

Thursday 10 June 2010

England in Bloom

[Disclaimer: this post is completely unrelated to software, firmware, hardware, engineering or managerial practices, and in truth doesn’t really belong on this site.  Normal service will be resumed in due course.]

A quadrennial crop of Saint George's crosses are flowering across the nation.  Obviously every pub, white van, and lager lout seems to be bedecked with the emblem, but so are a surprising percentage of ordinary houses, shops, and cars.   The reason of course is the forthcoming football World Cup.

A quick note to any American passers-by: when I say 'football', I mean football - what you would call soccer.  What you call football is in fact American Football, which I am assured by sports-minded people is completely different.  I'm told this is similar to rugby, but they stop every time anything exciting looks like happening.  Also, when I say 'World', I actually mean the entire World - calling something a 'World Series' when it's only you that plays in the competition is charmingly parochial, but displays a shocking failure to grasp the basics of cartography.  Thank you for your time and attention ;)

Yes, the World Cup is coming, and even I have noticed it.  I don't watch television, don't read newspapers, and assiduously avoid news web sites.  But in this country the sport is so insidious, pervasive, and all-embracing, that even I know Beckham's not playing this time round, thereby dashing his hopes of playing in four consecutive World Cups, Rio Ferdinand is out with an injury, and Wayne Rooney was recently carded for swearing.  It's some form of weird cultural/sporting osmosis, I think.

I generally actively dislike watching sports, preferring to take part myself.  But there's something about the camaraderie and group experience of watching a high profile, high stakes match with complete strangers in a packed room that breaks down the normal barriers and leaves you high on the atmosphere of the situation. 

I vividly remember seeing Beckham sent off, Gazza in tears, and the hand of God.  (This last, in this country at least, shamefully overshadows the simply breath-taking other goal that Maradona scored in the same game - still one of the most awesome pieces of skill you will ever see on a football pitch.  I recently heard an interview with Gary Lineker, who was playing that day, in which he said that he wanted to simply stand up and applaud this goal at the time.)

It was before my time, but Kenneth Wolstenholme's commentary on the closing moments of the 1966 World Cup ('they think it's all over…') is completely legendary here.  I suspect that it's actually taught in schools.  Although any discussion about this game with German colleagues has inevitably ended in a dissection of England's controversial third goal...

In any case, if you can't stand football, good luck for the next month.  There's normally a few places around here advertising themselves as footy-free zones during World Cups and European Championships, but this time round they seem conspicuous by their absence.

English World Cup campaigns generally follow a well-worn path.  They start off with boundless enthusiasm and wildly optimistic self-belief on the part of the entire nation, to be followed inevitably by gut-wrenching disappointment, ignominy, and defeat.  Generally featuring Argentina or Germany, and probably a penalty shoot-out for good measure.  Yet the fire of hope burns forever bright.

I for one am looking forward to it.  Come 7.30 on Saturday evening when England kick off against the USA, I'll have found a pub or friend with a TV, will be clutching a pint, and will be loudly expressing my concerns with the manager's strategic choices, something about which I know absolutely nothing.  I do know I will be trying to explain the offside rule to my wife YET AGAIN. 

UPDATE: In the office sweepstake, I've managed to pick England as my team.  I tried to explain to the girl running it that I'm such a dead cert to win that she might as well hand over my winnings now, but unfortunately she too has known the heartbreak of following the Three Lions, and politely told me to naff off.

Wednesday 28 April 2010

Monitor Functions in the IAR Compilers for AVR

In AVR chips, game-changing actions like changing the clock prescaler or setting the watchdog are so important that they are afforded a protection mechanism all of their own. Timed write sequences are used to prevent accidental or rogue writes from fundamentally messing with your day.

These require you to perform a sequence of write operations within a defined time period - typically you need to do two writes within four clock cycles.

Care must be taken when performing such a write sequence that no other operations could take place that would violate the required timing. Typical candidates for such mischievous behaviour are interrupt service routines, which have an uncanny knack of firing at the most inconvenient times.

The obvious way to ensure that your timed write sequence is interrupt-safe is to disable interrupts around it, like so:

void do_timed_write_operation( void )
{
__disable_interrupt();
// timed write sequence goes here
__enable interrupt();
}

Unfortunately this contains a nasty little gotcha: if you call this function from code in which interrupts are disabled, they will be enabled on return from the function. This is almost certainly not what is intended, and can lead to late night debugging sessions.

A safer approach is to save the interrupt state on function entry, disable interrupts, do your business, and then put the interrupts back the way you found them:

void do_timed_write_operation_2( void )
{
uint8_t interrupt_state = __save_interrupt();
__disable_interrupt();
// timed write sequence goes here
__restore_interrupt( interrupt_state );
}

This approach is so common and idiomatic that the IAR compilers for AVR support it directly with the __monitor keyword. The following function is equivalent to the previous one:

__monitor void do_timed_write_operation_3( void )
{
// timed write sequence goes here
}

Unfortunately declaring a monitor function involves a code overhead - after all, even though you can't see it explicitly in the C, a quick squint at the list files will show that the interrupts are still being saved, disabled, and restored.

A saving grace here is that most such Big Important Things tend to happen during system initialisation, when interrupts are disabled anyway. In such circumstances you can perform your timed writes au naturel, without any interrupt protection. However you really need to convince yourself that it is safe to do so. It would be a brave man indeed who called the first function above once the system was up and running without spending a very long time looking at possible consequences.

In general I would suggest that all timed write sequences be protected by default. Such protection can be removed if you're convinced that it's safe to do so - and of course if you document this assumption in the comments.


Wednesday 21 April 2010

File Under Easy Listening

This is an excellent podcast by David Heinemeier Hansson (DHH) on Legacy Software.  It's a recording from a talk at RailsConf Europe, and the podcast (i.e., audio-only) format doesn't really work in the last third of the talk, in which he's refactoring some code on stage.  However, the gist of his argument is completely sound - if you wince in embarrassment/pain/surprise when you look at code you wrote a few years ago, it's nothing to be ashamed of.  The code hasn't got worse - you've got better.  In the interim you've learned new techniques and idioms, and the fact that the earlier you wasn't favoured with your current clear-sighted and visionary approach to writing code shows that you've progressed.

[The corollary of this is that the future you will be embarrassed/pained/surprised by what the current clear-sighted and visionary you is doing today, but what the hey, just appreciate the step change from yesteryear.]

Also highly recommended is this appearance by DHH on Jason Calacanis's This Week In Startups podcast.  Two successful and highly opinionated people with entirely different takes on business, money, and work slug it out.  Who's right?  They both are, of course.  They've figured out what works for them, and good luck to them.  You don't have to agree wholeheartedly with either to enjoy the debate.

Sunday 28 March 2010

Joel Spolsky and the Death of Blogging

Warning: this article contains meta material.  If you are easily offended by blogging about blogging, please stop reading now.

Still here?  Good, let's crack on then.

I personally am not a fan of metablogs - I read blogs for interest, entertainment, and education, and am not particularly interested in reading the authors' pontifications on the state of their respective navels.  One saving grace for blogs in this respect is that they are less susceptible to the curse of self-reference than tech podcasts.  These seem without exception to descend into an analysis of the microphones, headphones, software, and patch cables being used.  I suspect this is largely a by-product of putting geeks in close proximity to, you know, geeky stuff.  Perhaps blogging is slightly less prone to this phenomenon as it features fewer tools - after all, you just need a text editor.

And so it was with some surprise that I found myself writing this.  What prompted it was the recent announcement by Joel Spolsky that he's going to quit (actually, by the time this goes up it will be 'has quit') blogging.  He made the announcement in an Inc Magazine article, and his blog entry on distributed version control looks like being his last.

In case your universe hasn't intersected that of Joel's, he runs Fog Creek Software in New York.  They have several products in their portfolio, but I think it's fair to say that their FogBugz bug tracking application is their main calling card.  Joel has also run the Joel on Software blog for some time, and is a well known pundit and commentator on all things software.  More recently he co-founded the Stack Overflow website, a Q and A website for programmers that has very rapidly gained a huge chunk of mindshare.

In his valedictory Inc Magazine article Joel states amongst other things that blogging is just too narrowly focused to be effective advertising for his company.  Which makes perfect sense if you're using it as a source of potential revenue.

In his penultimate Joel on Software article Joel lists some of the subject articles that have been written several kajillion times, by legions of pundits exploiting the whole democratisation of opinion made possible by the explosion of the Internet.  Which makes perfect sense if what you want to do is something truly original, especially in the narrowly-defined genre of geekerature.

All of which made my pause and consider - why am I doing this?  If someone as well known as Joel has had enough, doesn't see the point, and is getting out, why should I bother?  Why expend time and mental effort re-visiting subjects that other people have already addressed, more incisively and profoundly than I can?

Well:

  • I enjoy the act of writing.  I take pleasure in jotting down fleeting ideas or comments, and letting them germinate until they spring forth as fully-fledged articles.  It forces you to articulate and justify vaguely-held opinions and beliefs.  Under the weight of such scrutiny some ideas have self-imploded and got thrown out as blog fodder, but that doesn't diminish the importance of the process one whit.  In fact, if anything it increases it.
  • Joel's been doing this a lot longer than I have.  He's been there, done that, got the T-shirt, and it's time to move on.  Actually, he must have a whole wardrobe full of T-shirts.  For me the world of blogging is still new and shiny and pretty.  I'm enjoying it, so why stop?
  • There's a vague chance that some of my ramblings may be of some use to somebody, somewhere, some when.  Goodness knows I've learnt plenty from other people's blogs, and in some sense it's a little bit of repayment of accumulated karmic debt.
  • The articles act as a reference of techniques and ideas that I can easily find in the future.  If I want to do some fixed point arithmetic, or generate some random numbers, I've got ready-to-go code snippets and links back to original source material.  Of course I haven't actually written all that much yet, but I've already had reason to dip back into the archives a few times.  I've got a stack of blog ideas and sketched-out articles, so this blog will hopefully turn into a useful resource for the future me.
  • It is also of course partly self-aggrandising/self-serving.  The Internet has zeroed the cost of vanity publishing, so I may as well put something out there.  Something I can link to at some point in the future to flesh out my CV a bit.  Something that shows that I haven't spent the last several years just fulfilling a mandate as a corporate drone, but that I also think about and care about what I do.

My apologies for the brief digression into self-analysis.  Relatively normal service will be resumed in due course.

Sunday 28 February 2010

Backing Up Your Development Environment

Back in the good old bad old days, backing up an embedded project was simple.  You put the source files and makefile on a floppy disk.  And for good measure, you could put a copy of the compiler, assembler, linker, and any other tools on the floppy too.  The complete toolchain needed to recreate the shipped code, neatly wrapped up in its own little time capsule.

And that toolchain is an important detail.  The source code on its own is not enough to recreate a build, you have to factor in the tools too.  The output from a compiler can vary by a surprising amount between versions.

These days things are not so straightforward.  The compiler, assembler, and linker still exist, but they generally lurk behind the comforting facade of a glossy integrated development environment (IDE).  You don't need to figure out the arcane invocations needed to convince the command line tools to do your bidding, you just tick some checkboxes in an options dialog.  And I for one don't have a problem with this, I'm perfectly happy for such details to be sorted out behind the scenes.

However this ease of use can be a double-edged sword.  That sparkly shiny IDE is likely a significant chunk of code, and will be squirreling away information in all sorts of nooks and crannies on your PC - in the registry, in initialisation files, in configuration files, and down in the depths of your Documents and Settings folder.

Add in some vendor patch releases and user modifications, and suddenly keeping a snapshot of the state of your tools starts getting tricky.  Not only do you need to know that the code was built with v1.2.3.4 of the Acme Super Awesome IDE, but also that at that point you'd applied three vendor patches, and hand-modified a chip configuration file that you'd found a bug in.  You'd reported it to Acme MegaCorp technical support, but there hadn't been a bug fix release yet. 

Now what do you do?

My current solution is to store a simple text file called 'build instructions.txt' or similar with each project.  It lists the IDE version, any applied patches, and any funnies such as the aforementioned modified chip configuration file.  This approach is not exactly high tech or complicated, but works fine. 

I can't help thinking that there must be a better way though - this is still a bit handraulic and error-prone.  I suggested to our IT guy that we could create a virtual machine (VM) image containing a bare bones XP install, plus the IDE, plus any 'non-standard' files (patches and the like).  That way we could simply specify which VM image to use with the source and project files hauled out of version control.  But that made him go a bit green and start shaking.  He was mumbling about licensing issues with that many Windows images. 

So - if anybody knows of a better way of doing this, do please let me know in the comments.

Sunday 14 February 2010

Zero Tolerance

This week I picked up some code from a colleague for review.  To me, part and parcel of the review process is rebuilding the code - I want to check that I get the same hex (i.e., output) file as has been checked in to our version control system for release.  And sure enough, this time I did. 

But I also got 16 warning messages.  The compiler spat out a variety of messages, including warnings of integer truncation, and what looked like notes the developer had written to himself - "This could be done faster with pointers" and the like.

What did this mean?  Was I using a different compiler version than the  developer?  Was my version smarter about flagging potential coding errors?  It seemed unlikely, as I got the same hex file.  This almost certainly indicated that we were using the same compiler.  Also, there was the matter or all those notes-to-self.  Those were clearly there for a reason.  How did he know it would be faster with pointers?  Presumably he'd coded that up to test it, as otherwise he couldn't know that it would be faster?  If he had, and it was, why hadn't he used it?

I spent a while scratching my head over this before going to see the developer.  "Oh yeah, I had a look at those, the real warnings are all fine.  Nothing to worry about.  And the others are just reminders to myself.".  And the comments about pointers and the like?  "It's always faster to do that code with pointers, I just didn't have the time.  That's just a reminder in case I look at this again."

Well, that was fine for him, as he'd written the code.  But at some point somebody else was going to look at it.  Maybe a customer would report a bug, and a colleague would be assigned to fixing it.  Maybe we'd want to add some new features.  Maybe we'd want to use this code as the basis for another product with similar functionality.  Or maybe, as in this case, a reviewer would pick up the code. 

In all of these scenarios, Joe Bloggs engineer would pick up some allegedly working code, hit build, be faced with a screenful of warnings, and freeze like a rabbit trapped in headlights.  Hampered as he would be by a lack of omnipotence, he wouldn't know that all the warnings are benign, and that a colleague knows a better way to write his own code.

The warnings might indicate real problems.  They might be the compiler being picky.  But our hypothetical engineer is going to have to assume that each is a land mine requiring individual attention and possible defusing.  All of which could have been avoided if the original developer had simply added some casts or whatever else was needed to placate the compiler.

The only acceptable number of warnings in a build is zero.  Anything else is going to waste people's time.  Any cost saving to the developer in not dealing with the issues as they crop up will be more than offset by the time wasted by a colleague (or possibly themselves) further down the line.

Possibly more importantly, a developer is fooling themselves if they think they can live with a raft of warning messages.

If you have 16 warnings every time you build, you are much less likely to notice the silent arrival of a seventeenth, this one a genuine harbinger of doom.  If however your build has always been clean, and is suddenly polluted by a warning - well, you'll see that.

This is indicative of a professional attitude to development, as well as saving time in the long run.  If all warnings are examined and addressed as they surface, the ongoing code quality and workmanship are high.  If attending to such items is left as a last-minute operation before release, or even worse pencilled in for the often mythical post-release clean-up, then it will either (a) be a huge job, or (b) not get done.

The same comments apply to writing code that is MISRA-compliant, or that gets a clean bill of health from Lint.  It's always faster and easier to do this as you go, rather than banging a keyboard for several days and then trying to impose some semblance of quality as an afterthought.

We are what we repeatedly do.  Excellence, then, is not an act, but a habit.  (I didn't say that, Aristotle did.  And according to Wikipedia, it's actually a misattribution.  But as misattributions go, it's got to be one of the best.)

Sunday 7 February 2010

Generating Random Numbers using LFSRs

On a recent project I needed a simple random number generator. It didn't need to be anything fancy, nothing mathematically pure or statistically valid, just a quick'n'dirty little generator that would spit out numbers that looked random to the casual eye.

In a previous incarnation I worked for a mobile radio consultancy. One of the things I came across in that particular life was the concept of Pseudo Random Binary Sequences (PRBSs).

These are sequences of 0s and 1s that are generated deterministically, yet are random enough for many practical purposes. They are used extensively in communications to spread the bandwidth occupied by a signal. This makes the signal more immune to jamming, as the signal is smeared across a bigger chunk of spectrum than would otherwise be the case. It is also more difficult to intercept, since any receiver must know and be synchronised to the spreading sequence at the transmitter. A more subtle usage is that multiple signals can be spread across the same spectrum by multiple PRBSs, yet be teased apart at multiple receivers by correlation with the correct individual spreading sequences.

PRBSs are typically generated using Linear Feedback Shift Registers (LFSRs). These are cheap and easy to build in hardware, and easy to code in software.

At any time, a function of the LFSR contents is generated as the output bit value. This is fed back into the shift register as the next input. The output bit sequence is essentially random, as is the sequence of states formed by the LFSR contents.

The 'function of the LFSR contents' mentioned above is called a generator polynomial. It determines which LFSR cells are combined and fed back to form the LFSR input for the next state.

For instance, the Wikipedia article on LFSRs lists the following generator polynomial for an 8-bit PRBS:

x^8 + x^6 + x^5 + x^4 + 1

We now need to know how to convert this into code.

As we are generating an 8-bit polynomial, we start off with the 8-bit unsigned value 0x00u as our feedback function. If a power of x, say m, is used in the polynomial, assign a 1 to polynomial bit (m-1). The +1 in the polynomial corresponds to the output bit, and does not appear in the feedback settings. Here we have an 8-bit generator polynomial with bits 7, 5, 4, and 3 set, giving a value of 0xB8u.

Given this, and also using the example code in the Wikipedia article, we can now write a function that returns the next value in a pseudo-random 8-bit sequence.

#define LFSR_8_INITIAL_VALUE 0x01u
#define LFSR_8_POLYNOMIAL 0xB8u

uint8_t next_lfsr_8( void )
{
/* seed LFSR */
static uint8_t lfsr = LFSR_8_INITIAL_VALUE;

/* get LFSR LSB */
uint8_t lsb = (uint8_t)( lfsr & 0x01u );

/* shift LFSR contents */
lfsr = (uint8_t)( lfsr >> 1u );

/* toggle feedback taps if we output a 1 */
if( 1 == lsb )
{
lfsr ^= LFSR_8_POLYNOMIAL;
}

return lfsr;
}

An n-bit PRBS is said to be maximal length if the number of distinct output values it generates is 2^n - 1. That is, a maximal length 8-bit PRBS consists of 255 values. Our generator polynomial is indeed maximal length, and so the values returned will start to repeat after 255 calls.

In the above code I have set the initial value of the LFSR to 0x01u. The LFSR will generate a fixed sequence of output values, and the initial value merely determines where in the sequence the reported values will start.

Note that because the feedback taps uses the XOR operator, the LFSR will get stuck in the all-zeros state if it ever gets there. Care must be taken that an LFSR is not initialised with this value.

The corresponding 16-bit function is as follows.

#define LFSR_16_INITIAL_VALUE 0x0001u
#define LFSR_16_POLYNOMIAL 0xB400u
uint16_t next_lfsr_16( void )
{
/* seed LFSR */
static uint16_t lfsr = LFSR_16_INITIAL_VALUE;

/* get LFSR LSB */
uint8_t lsb = (uint8_t)( lfsr & 0x0001u );

/* shift LFSR contents */
lfsr = (uint16_t)( lfsr >> 1u );

/* toggle feedback taps if we output a 1 */
if( 1 == lsb )
{
lfsr ^= LFSR_16_POLYNOMIAL;
}

return lfsr;
}
Using the above approach, you can generate PRBSs of arbitrary length, given tables of generator polynomials (your search engine of choice will unearth plenty).