Beruflich Dokumente
Kultur Dokumente
absolutely no cost in resources like overloaded f unctions, f or example, which are just a compiler/linker symbol issue; these may be used f reely as required. Other f eatures can cause signif icant overhead and should be used with care or avoided all together. A good example is the exception handling system (EHS). T his f acility enables the construction of very robust code, with very little ef f ort required by the programmer to accommodate a wide range of exceptional events smoothly. T he downside is that, behind the scenes, a lot of code has been silently generated to accommodate this f unctionality. Although avoiding the EHS entirely may not be necessary, using it in a simple way minimizes unwelcome surprises. It's worth noting that the EHS overhead code may be generated, even if EHS is not being deployed; EHS support is switched on, by def ault, in many compilers. Good Idea #4: Encapsulate expertise in objects. An embedded sof tware team has a diverse set of skills. Dif f erent members of the team have dif f erent areas of expertise. Endeavor to encapsulate that expertise into classes so that it can be utilized saf ely by other members of the team. For example, a hardware device may have some very precise requirements associated with its access; representing the device by an object means that not every user needs to understand its eccentricities. A similar approach can be used to hide the specif ics of a real-time operating system. Good Idea #5: Use tools that are optimized for embedded. It's a known f act that embedded sof tware development is dif f erent f rom desktop programming. T his is widely recognized and a great many companies of f er tools f or embedded programming, but tread caref ully here. Some tools are much more oriented towards the needs of embedded developers than others; some vendors simply adapt desktop development tools. Five things to avoid #1: Writing "clever" code is never smart. C++ gives you the opportunity to write very clear, concise code. It also provides the means to write very convoluted, arcane code which does nothing except illustrate how clever you think you are. Do not give in to this temptation. For example, in C++ you can def ine your own operators. Always ensure that their f unctionality will not surprise a reader of the code. For example, you could def ine a new class and include a def inition of the + operator, such that an expression may be written like this: a + b; T he above example adds the value of the object b to the object a. T his is unwise, as the + operator does not normally f unction in this way. Redef ining the += operator would be much better. If they do not serve to clarif y the logic of the sof tware, do not use overloaded operators; just use member f unctions with meaningf ul names instead. Neither language f eature introduces any hidden overheads into the resulting code. #2: Do not treat an embedded system like a desktop computer. If you're programming a PC, you can assume that memory is inf inite (and f ree) and that you will always have enough CPU power. With embedded sof tware, you need to be more circumspect as both memory and CPU power are limited. T he best approach is to write some code, then measure its size and its execution perf ormance. Only when you are satisf ied that these measurements are within reasonable bounds should you move on. #3: A purely top down implementation may be dangerous. It may be attractive to build a sof tware application by starting at the high level and including just stubs f or lower level f unctions. T hen, when that structure is debugged, you can start implementing the next level down.
T he drawback to this strategy is that a nasty surprise may be waiting just around the corner. You can f inish coding and f ind that the whole program is too big and/or too slow. And you have no idea where you acquired the additional overhead. A better approach is to start at the other end. Encapsulate the lower level f unctionality in objects and build the application up f rom there " f ollowing the previous advice of measuring as you go. With this approach you will not encounter any surprises. #4: Avoid the use of deeply nested inheritance. Part of the point behind object-oriented programming is the ability to def ine classes in terms of others (base classes) that have been previously created (by you or by another developer) without the need to f ully understand the inner workings of the base classes. T his is inheritance. T he downside is that objects instantiated f rom such derived classes may carry some overhead " not much, but some. And this overhead may mount up as the depth of inheritance increases. So, f or an embedded application, where overheads may really count, you need to be vigilant. #5: It is not logical to avoid language features just because your tools do not handle them well. Some language f eatures can be very usef ul, but will carry an overhead if not handled in an appropriate way f or embedded applications. An obvious example is f unction templates which if badly implemented, can cause an enormous code bloat. A common implementation of templates results in instantiations which are local to a module. T his can lead to numerous copies of identical code that could waste an enormous amount of memory. If your tools do not handle such constructs well, do not eschew good programming practice. Get some tools that will enable you to program productively. Conclusion As code size and complexity increases relentlessly, C++ is becoming an excellent programming language of choice f or embedded applications. Past f ailures have deterred many developers f rom adopting the language choosing instead to continue using C. T he key to success with C++ is to use it intelligently, f ocus on the problems that it addresses, and pay attention to its implementation on an embedded system.