Manage Variation in C
Embedded systems evolve. Requirements, hardware, and software all change. Requirements change due to market (and marketing) forces. The hardware seems to change out from under the embedded software developer for a variety of reasons: manufacturing cost reductions, part obsolescence, and new capabilities to name a few. These hardware changes cause ripples through the software. Oh yeah, have you ever heard this requirement? The software has to be backward compatible with prior hardware versions. Of course you have. The software is pulled in many directions.
C is the most prevalent programming language for embedded development. The features of the C programming language are very limited for managing variation in a product. All these changes resulting in software that has to manage variations in the source code and likely at run time.
Suppose we are building a security/alarm system. (by the way, I have never designed an security system, so my apologies for my simplifying assumptions). The alarm system has a front panel. The front panel has a keypad, and a display. The system is designed to work with that front panel. We’ve sold and shipped a boat load of them. Life is good.
Then we hear the good news that the display we were using is being phased out. Why? A QZ4257 display component is now available, the new part is cheaper and we can save $92,471 in hardware cost over the 3 years. Unfortunately this component is not backward compatible with our software.
What are our options in C? We could use cut and paste to create a new display from the old display. We could have a variable that identifies the type of display installed. The code could use conditional logic to make sure it interacts with the installed display properly. Maybe we want the compiler to sort out the differences. We can use the C preprocessor and sprinkle#if QZ4257 in the necessary places. There will be other #if's as well. These are the ways C programmers deal with variation.
The conditional logic solution is OK for a variation or two. But the parade of changes does not stop with the QZ4257! Marketing wants the new color LCD. Next they want a PC hooked to a serial port to provide a virtual front panel. Then an Ethernet port is added and the virtual control panel is connected to the security system via TCP/IP. Oh! don't forget the USB port, 802.11b, and blue tooth! Did I forget to mention backward compatibility? Look at all this variation and all we have talked about is the changes to the user control panel!
This table summarizes some of the problems these solutions may lead to.
Manage Variation with C (oxymoron warning)
Options | Problems | Consequences |
Cut and Paste |
Duplication Later changes have to be made in multiple places Fix the same bug multiple times Forget to change all the necessary places Get to claim repair of the same bug multiple times ;-) |
|
Conditional logic | Complexity grows over time Everything is a special case |
|
Conditional compilation | Ditto above Added bonus: conditional compile side effects defects |
If I had a buck for every few year old C program that is now a mass of conditional logic that can not longer be safely or economically changed, how many dollars would I have? Is your C program one of them?
!commentForm -r
Good article!
Today, I am of the opinion that we are so very deep in the throw away society and that it continues to escalate in a geometric fashion. So, I think now a days, I would just go for duplication / copy / paste / patch and change / add / cut to fit the new because with the fast pace of new products, I really doubt that I would have to maintain the old stuff for very long anyway. I also wouldn't want to reinvent the wheel too much (so I copy / paste / rob existing functions).
It's great to be very specific as well because that way I no longer have to worry about guessing the future, supposed growth of the product (no way... it will simply be scrapped... and if you don't believe me, check out Sony as an example) and I no longer have to make any extra allowances on the harware I am working. I only have to deal with the (marketing) problem at hand; ...only.
A lot of code writing, I susupect, is just recycling of existing functions / ideas. You almost would be better off learning the company library and then pick and choose from exisiting stuff; drivers, etc. Or just take the code, as is, from Intel or AMD for their chips and make an interface to it.
Then, again... people don't like learning the other people's libraries and they seem to always want to put in their own two cents; no matter how many times they reinvent the wheel, huh?
Today, I am of the opinion that we are so very deep in the throw away society and that it continues to escalate in a geometric fashion. So, I think now a days, I would just go for duplication / copy / paste / patch and change / add / cut to fit the new because with the fast pace of new products, I really doubt that I would have to maintain the old stuff for very long anyway. I also wouldn't want to reinvent the wheel too much (so I copy / paste / rob existing functions).
It's great to be very specific as well because that way I no longer have to worry about guessing the future, supposed growth of the product (no way... it will simply be scrapped... and if you don't believe me, check out Sony as an example) and I no longer have to make any extra allowances on the harware I am working. I only have to deal with the (marketing) problem at hand; ...only.
A lot of code writing, I susupect, is just recycling of existing functions / ideas. You almost would be better off learning the company library and then pick and choose from exisiting stuff; drivers, etc. Or just take the code, as is, from Intel or AMD for their chips and make an interface to it.
Then, again... people don't like learning the other people's libraries and they seem to always want to put in their own two cents; no matter how many times they reinvent the wheel, huh?
Putting a nice face on function pointers is one of the good uses for C preprocessor macros. You push the really gnarly details down into a header file or two, and the rest of the project can use a reasonable API.
Yeah, funciton pointers give the same result. Odd that this technique is not used more. It does leads to code that is hard to read. Make sure your face is far from the gas when you ignite it, you can get burned :-)
Use function pointers aka poor man's polymorphism. Put a bunch of function pointers in a struct and then you're really cookin' with gas :-)
Add Child Page to ManageVariationInC