embedded software boot camp

Simplify, then add lightness

December 31st, 2011 by Nigel Jones

As 2011 draws to a close I have reason to be thinking about things automotive. As part of my musings, I was reminded of the famous mantra espoused by the late Colin Chapman of Lotus Cars – ‘Simplify, then add lightness’. I have always liked this aphorism for its idea of ‘adding lightness’ rather than ‘subtracting weight’.

So what’s this got to do with embedded systems you ask? Well, when it comes to embedded systems programming, I think Chapman’s concept is spot on. While most people would probably agree that simplifying an embedded system is a good thing, I wonder though how many actively work so as to achieve this? In my case I regularly hold conversations with my clients which can be summarized as: Yes I can do that, but it comes at the expense of complexity – and complexity leads to bugs – and bugs are very expensive. I have found that clients are quite appreciative of this as it forces them to evaluate what is truly important about the product. Incidentally, when I first started in the consulting business, I thought that it was my job to give the client whatever it was they asked for. The fact that in doing so I was often giving them a serious disservice was quite a revelation when the penny finally dropped.

So what about the ‘adding lightness’ directive? Well clearly this is an interesting concept when it comes to firmware. I take it to mean that the code should be simple, easy to read, and fast in execution – in other words not unlike a Lotus sports car. If I have cause to re-read the code many months or years later and I find that the code has stood the test of time and is a pleasure to read, then I think I have achieved the required lightness. If by contrast the code is out of date and ugly to read then I know I have failed. In short it’s the difference between designing a Lotus Elan and an AMC Pacer.

 

 

Novel uses for RTC registers

December 4th, 2011 by Nigel Jones

For obvious reasons, I usually write about things that are widely applicable. Today I’m going to deviate from this slightly and talk about the real time clock registers / RAM that are available on some (many?) ARM processors as well as I suspect a number of other architectures. An excerpt from the NXP data sheet is shown in the figure below.

NXP LPC17xx RTC registers

Of most interest is the column labeled ‘Reset Value’. You will notice that the values highlighted in red are ‘NC’. ‘NC’ means that the registers are unaffected by a reset condition. Furthermore, these particular registers may also be powered from an alternate power source such that they are also unaffected by loss of power. So why is this useful? Well I have found a couple of uses for them beyond the obvious and intended applications of maintaining date and time (for the RTC registers) and for providing non-volatile R/W storage for the General Purpose registers.

Communicating with the Bootstrap loader

Most embedded applications today contain a bootstrap loader (BSL). Although there are several ways of entering the BSL from the main application, the most common that I see is to force a watchdog reset, resulting in the CPU rebooting and starting up in the BSL. This technique is pretty good and I use it all the time. However I usually find it necessary for the main application to communicate some information to the BSL. For example, at a minimum the BSL needs to know that it has been intentionally entered for the purposes of performing a firmware update (as opposed to being entered as a result of a genuine watchdog failure). Under some circumstances I also need to pass other information to the BSL such as the port that initiated the update. In the past I have tended to pass this information via EEPROM. However with these registers available to me, I now use them for this task.

Debugging

If you are plagued with your system taking unexpected resets, then it’s a relatively trivial matter to write some debug code that writes context information to these registers. For example most RTOS provide mechanisms for calling user functions prior to performing a task switch. Within this function it’s trivial to write the task ID to one of these registers. Then it’s just a matter of putting a breakpoint on the entry into main() to discover which task was running when the reset occurred. Once you have it narrowed down to a task, you can then instrument functions in a similar manner.

I suspect I may find other uses for these registers in the future. Suffice to say I’d really like it if this feature became widespread across all processor families.

An open letter to the developers of the MPLAB IDE

September 27th, 2011 by Nigel Jones

I recently inherited a project that uses a Microchip PIC18 processor. Without going into too much detail, suffice it to say that I ended up using Microchip’s MPLAB IDE Version 8.73 together with Microchip’s C compiler. It had been a number of years since I last used MPLAB, in part because my experience back then was so painful. I was heartened to see that the version number had jumped from 6.X to 8.X and so I was fully expecting to find an IDE that was at the very least, decent. Boy was I disappointed. In no particular order, here are some of the head-slapping things I discovered. Disclaimer: I’m no MPLAB expert (and quite frankly after this experience I doubt I will ever become one). Thus it’s entirely possible that the issues listed below are a reflection of my incompetence.

No editor support for splitting the window

The title says it all. Text editors back in the DOS allowed you to open a file and look at various parts of the file at the same time via split windows. This is such a fundamental operation for text editors that I couldn’t believe it wasn’t supported. Do the developers of MPLAB use an editor with this limitation?

No single file compilation

There appears to be no way to simply compile a single file. Instead one is forced to perform a make. Not only is this really time consuming as make wades through all the files that aren’t relevant, it’s also a pain because:

  • It forces you to correct problems in the first file that make finds to process – rather than the one you are interested in.
  • If the compilation passes, it proceeds immediately to the link and download phase – regardless whether you want to or not.

A baffling debugger configuration interface

The first time I tried to download to the debugger, I received an error message telling me that there was a problem with the configuration bits. I beat my head against the issue for a few hours and in the end called a colleague who is a Microchip Consultant (Matt).  Matt told me that he avoided using MPLAB, but vaguely recollected that you had to configure the debugger to explicitly download to the target. Well Matt was spot on. I was just left wondering why anyone would want to debug code without having it downloaded first.

A joke of a simulator

While I was waiting to get hold of Matt, I experimented with the simulator. Despite the documentation saying that various peripherals were supported, I found that the simulator simply didn’t support them. Matt confirmed that the simulator was a piece of junk that no one bothered using.

Unnecessary variable scope limitation

I’m not sure if this is an IDE or a compiler issue. Anyway, when debugging within MPLAB, I discovered that if I had the temerity to declare a variable as static, then the only time I could examine its value was if the variable was in compiler scope. That is, if I was stopped in file foo.c, then the debugger would not let me see the values of static variables declared in bar.c. As a result, I was forced to declare variables as global simply so that I could look at them. Quite frankly, it blows my mind that in 2011 an IDE can force you to adopt lousy programming practices because of its limitations.

No pointer dereferencing

In a similar vein, I discovered that MPLAB only shows you the values of pointers, and not what they are pointing to. I thought that limitation disappeared at least ten years ago.

Limited support for ‘large ‘arrays

The PIC18 doesn’t handle arrays or structures greater than 256 bytes very well. However the Microchip compiler guys came up with a decent work around that is quite straight forward to use – until you want to look at the array in the debugger. In a nutshell all you seem to be able to do is examine the array / structure in the memory window. You can forget about looking at 16 bit integers, or other such ‘complex’ constructs.

Breakpoints that aren’t where I put them

I discovered that placing a breakpoint on a function call was highly problematic. In some cases the break would occur prior to the call, and in other cases it would occur after the call. If I wanted the breakpoint in the called function, I’d put it there myself, thank you.

Anyway, I could go on – but I think you get the picture. What I don’t get is this. Microchip is a big successful company. Why, after a decade of trying can’t they come up with a decent development environment? It has got to be costing them a lot of design wins when people such as myself cringe at the though of having to use their tools.

 

Effective C Tip #9 – use #warning

September 1st, 2011 by Nigel Jones

This is the ninth in a series of tips on writing effective C. Way back in 1999 I wrote an article for Embedded Systems Programming concerning the #error directive. If you aren’t particularly familiar with #error, then I suggest you read the article. While the #error directive has remained one of my most popular tools, I have become an equally big fan of #warning.

Before I delve into the uses of #warning, I must warn you (if you would pardon the pun) that #warning is a non standard directive. However it is supported by IAR, GCC, Microchip’s C18 compiler, Hi-Tech and probably a whole raft of other vendors. In other words, it’s pretty standard for a non-standard feature.

The use of #warning is simple enough:

#warning This is a warning

This will result in the compiler issuing a warning with the text ‘This is a warning’ printed to stderr. Please note that, just as for #error, there is *no* requirement that the text be in quotes. If you insist on putting quotes around the text, then they will be printed to stderr as well.

With the syntax out of the way, here’s some of the ways that I use #warning.

Protecting Incomplete Code

Very often when I’m coding, I like to get the big picture in place without worrying about the minutiae of the implementation details.  As a result I end up with functions or loop bodies that are incomplete. In these cases I simply add a #warning to alert me to the issue. For example

void foo(void)
{
#warning To be completed
}

Thus what happens now is that whenever I compile the module, I get a warning (i.e. reminder) that there is something important still to be done.

Commenting Out Code

I *never* comment code out anymore as part of the debugging process, as it is simply too easy to forget that the code has been removed. Instead I use this construct:

void foo(void)
{
# if 0
   /* Code to be temporarily removed is here */
#else
#warning Temporary debug construct. Fix me!
   /* Experimental code goes here */
#endif
}

In this case whenever I compile the module, I get a warning (i.e. reminder) that I have some experimental code in the image.

The Key Final Step

While the above are useful constructs, the real power of #warning comes if you configure your compiler to treat warnings as errors for the release build. If you do this and you have inadvertently left incomplete or debug code in the image, then your compilation will fail. In short, this technique will guarantee that you never release code that includes / excludes code that shouldn’t / should be there. That’s effective C.

Previous Tip

 

 

Rabbit patches and embedded systems

August 29th, 2011 by Nigel Jones

You may think from the title that I’m writing about Rabbit microprocessors – but no I’m actually intending to talk about bunnies. What you ask do rabbits have to do with embedded systems? Well read on and find out…

If you have ever had a vegetable garden then you will know that they are magnets for rabbits. Furthermore, you will soon find out that it takes extraordinary efforts to keep the rabbits out, as they have a tremendous ability to circumvent all sorts of fences.  When faced with such a problem, it is sometimes advisable to build a rabbit patch. The basic idea is this – you plant your garden and put a fence around it, and then on the outside of the fence you plant a second vegetable garden that is purely for the rabbits – i.e. a rabbit patch. The rabbits feed on the rabbit patch and leave your real garden alone because they would have to exert effort to get to it – and they don’t need to as their needs are satiated by the rabbit patch.

So what has this to do with embedded systems? Well let me describe a scenario to you that is almost certainly all too familiar to anyone that has been doing this for a few years.

It’s dog and pony show time and marketing is coming to pronounce judgement on your latest creation. Now if you are fortunate, the folks in marketing are a pleasure to work with. However from time to time, you run into someone who is incapable of attending a dog and pony show without offering criticisms / complaints. (I’m talking about the sort of person who would have criticized Michelangelo’s David at its unveiling). When faced with such an individual, I have found that the answer is to build the embedded system’s equivalent of a rabbit patch. It works like this. You intentionally put into the demonstration something that obviously isn’t quite right. Come time for the dog and pony show, the complainer latches on to the ‘problem’, and proceeds to explain in detail why it is wrong. You sit there and graciously accept the pearls of wisdom dispensed to you. You can then proceed to the meat of the presentation and get some useful work done.  The meeting ends and our protagonist walks away happy – and you have managed to actually have a useful and productive meeting. Naturally the fix to the ‘problem’ is a flick of a compilation switch.

So now you know what a rabbit patch is. I encourage you to use it sparingly. I also encourage you to watch out for it being used on you! I have sat in on a couple of presentations where I’m pretty sure a rabbit patch has been deployed. Fortunately I’m also pretty sure the rabbit patch wasn’t for my benefit…

On a personal note, I’m expecting to return to my normal blogging schedule. The long awaited hardware test may actually make an appearance soon.