Posts Tagged ‘programming’

RTOS Myth #1: Mutexes and Semaphores are Interchangeable

Monday, January 28th, 2008 Michael Barr

The Myth: Mutexes and semaphores are similar–even interchangeable–operating system primitives.

The Truth: Mutexes and semaphores should always be used for distinct purposes, and should thus feature distinct APIs. (My recommendations to RTOS vendors are at the end.)

The cause of the confusion between mutexes and semaphores is historical, dating all the way back to the 1974 invention of the semaphore by Djikstra. Prior to that date, the interrupt-safe task synchronization and signaling mechanisms known to computer scientists were not efficiently scalable for use by more than two tasks. Dijkstra’s scalable semaphore could be used for task synchronization (including mutual exclusion) as well as signaling.

After the introduction of commercial real-time operating systems (beginning with VRTX, ca. 1980) and the publication of a 1990 paper on priority inheritance protocols it became apparent that mutexes needed to be more than just semaphores with a binary value. Because of the possibility of unbounded priority inversion, which would break RMA assumptions, ordinary semaphores cannot be used for mutual exclusion.

Many bad sources of information add to the general confusion by introducing the alternate names binary semaphore for mutex and counting semaphore. The current wikipedia entry for semaphore is a prime example.

The correct and appropriate solution is a distinct set of RTOS primitives: one for semaphores and another for mutexes. Mutexes must prevent unbounded priority inversion. The APIs for semaphores and mutexes should be as distinct as possible, as their use is quite different.

Go on to RTOS Myth #2.

Compiler Quality and C’s volatile Keyword

Thursday, December 6th, 2007 Michael Barr

At at a meeting with a client yesterday, I was reminded of a conversation we’d had about eighteen months ago at an Embedded Systems Conference. At that time the client, I’ll call him John, was having a problem with C’s volatile keyword on a PIC microcontroller.

John had written a few lines of C code to swap the contents of two peripheral registers, perhaps something along these lines:


uint8_t temp;

temp = *pRegisterA;
*pRegisterA = *pRegisterB;
*pRegisterB = temp;

where pRegisterA and pRegisterB were pointers to memory-mapped I/O locations.

Since the data pointed to by pRegisterA and pRegisterB wasn’t being used anywhere else in the code, the compiler’s optimizer was completely ignoring the above code; outputting zero opcodes of machine code for that sequence.

As John and I discussed then, redeclaring the pointers as pointer to volatile integers (e.g., uint8_t volatile * pRegisterA = /* address */;), should have instructed the compiler to treat those lines of code as sacred and output corresponding machine instructions. Having tried this already, though, his compiler continued to output nothing.

Wow! John didn’t realize it at the time but he had just found a bug in his compiler.

I advised John to try another compiler, rather than the free compiler he was using. You generally do get what you pay for with C cross compilers. And, indeed, his problem went away with the new compiler.

Although it is common for embedded programmers to believe their compiler’s optimizer is broken when the flaw is really their failure to declare certain variables volatile, this was a genuine case of an internal compiler bug.

Public Course on Multithreaded Programming

Tuesday, November 6th, 2007 Michael Barr

This coming January, I’ll travel from chilly Baltimore to sunny Miami to teach an in-depth training course about the proper use of real-time operating systems to design multithreaded firmware. The aim of the class is to clarify the safe and correct use of RTOS primitives, such as mutexes, semaphores, and mailboxes.

The two-day course, called Multithreaded Programming with uC/OS-II, will be held January 22-23, 2008 at the Weston, Florida headquarters of RTOS vendor Micrium, just east of the Everglades. Registration is open to the public, but the total number of seats is limited.

The hands-on course involves a mix of lectures and a coordinated series of programming exercises. The target hardware is an ARM9 development board from STMicro. The increasingly popular uC/OS-II real-time operating system will serve as the reference API with compiler and debug tools from IAR Systems.

Full details, including registration instructions, are available at the Micrium website: http://www.micrium.com/support/training.html

MO/HO Market?

Friday, June 8th, 2007 Michael Barr

I was fascinated to receive the following message from a former colleague in e-mail yesterday:

Do you have any requirements for a Linux C++, Windows .NET, or embedded programmer who can work remotely? I have high speed (1.5 mbps) internet, a wireless router, and 3 laptops in my motorhome. I only need about $25/hr to support my new lifestyle.

Of course, it has become the norm that computer programmers and many other types of professionals can work from their countries of origin or even home offices. Some observers have gone so far as to call this the world is flat effect of the Internet.

But $25/hr for an experienced programmer living as a connected nomad somewhere in America? Could this be the end game for all of us in the computer services business?

Bad Code

Friday, September 20th, 2002 Michael Barr

Enough with the bad code already! While I’ve been discussing the subject of which language to use for embedded programming and how best to ensure a quality result the past few months, millions of lines of “bad code” have been newly written.

You’ve seen the kind of code I mean: modules and procedures carelessly divided (broken up as if to meet some arbitrary length limit, for example, rather than by purpose); variables randomly named, mostly global, and with a large percentage no longer in use; compiler warnings flagging a myriad of suspicious pointer and type conversions unheeded; comments—what few there are—mostly outdated and in conflict with the nearby code; other comments full of code that once did or meant something to somebody, but now doesn’t (or does it?).

Bad programmers can write bad code in any language. It’s time they and their code were dragged into the light. I’ve encountered bad assembly code, bad C code, and bad C++ code. I’m sure those who program regularly in Ada, Java, and every other language have uncovered bad code in those languages as well.

To achieve the best long-term results, it is often necessary to have the courage to discard such code and rewrite it. If an organization can accept that the existing code was never worth the money spent to develop it in the first place, they can move on and look forward to a brighter future. Ultimately, the costs (including the rewrite) will probably be much lower.

I’ve replaced bad assembly code with new C code that was smaller, more efficient, and easier to maintain. It was also developed more quickly and cheaply than the bad code and had far fewer bugs at integration. I’ve similarly replaced bug-ridden C code with new C++ code that required half the code and data memory—and was just as efficient.

I’m not trying to suggest that C is better than assembly, that C++ is better than C, or even that the original authors in these examples chose the wrong languages to begin with. (I’ve also rewritten bad code in the same language as the original.) I’m just trying to make the point that assembly doesn’t always result in the most compact code; there’s skill involved in achieving that result. And C++ code can be just as compact and efficient as C code—if you know what you’re doing.

That, of course, is the important part: The programmer must know what he is doing. Too often that isn’t the case. However they manage to get themselves hired, bad programmers seem to exist in every organization. The decisions they make and the code they write create more problems, hassles, and bugs than any interviewer can imagine. The costs are unbearable, particularly in real-time/embedded devices.

Well? Don’t just stand there. Do something. If it’s your own code that needs the fixing: read a book like Code Complete and start learning how to write well-structured easy-to-read code, obey the Ten Commandments for C Programmers, and get a copy of lint. The version control system you aren’t using should help you feel comfortable deleting no-longer needed code rather than commenting it out. If the fault lies elsewhere: tell someone who can do something about it before any more serious damage is done.