Archive for September, 2011

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.

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:

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.