Escolar Documentos
Profissional Documentos
Cultura Documentos
int add(int a, int b) { #if __DEBUG // Debugging output printNumber(a+b); #endif return a+b; } Notice that the comment f or the f unction 'add' is at the top of the listing while the actual f unction is f urther down. T his can happen over time if there is a space between the comment and the f unction. T he likely cause was the addition of the printNumber f unction between 'add' and its comment description. Later, someone saw that there was an addition f unction and it seemed logical to put multiply next to it " the comment creep has resulted in disjointed documentation within the code. To f ight this problem, try keeping code inside the f unction it documents, or make the comment block very obvious by putting lines above and below the comments. Tip #3: Don't optimize prematurely. One of the cardinal sins in programming is premature optimisation. However, the rule is of ten broken in practice due to time constraints, sloppy coding, or overzealous engineers. Any program you write should start out as simple as it can possibly be and still provide the desired f unctionality " if perf ormance is a requirement, try to implement the program simply, even if it does not match the perf ormance. Once you have tested and debugged your complete unit (be it a program or a component of a larger system), then go back and optimise. Haphazardly optimising code can lead to a maintenance nightmare since optimised code is usually harder to understand, and you might not get the perf ormance results you need. Ideally, use a prof iler (such as gprof , which works with GCC, or Intel's VTune) to see where your bottlenecks are and f ocus on those areas " what really is slow may surprise you. Tip #4: ISRs should be simple Interrupt Service Routines (ISRs) should be as simple as possible, both f or perf ormance and maintenance reasons. ISRs, being asynchronous in nature, are inherently more dif f icult to debug than "regular" program code, so keeping their responsibility to a minimum is important f or the overall maintainability of your application. Try to move any data processing out of your ISR and into your main program " the ISR can then be responsible only f or grabbing the data (f rom hardware, f or example) and placing it in a buf f er f or later use. A simple f lag can be used to signal the main program that there is data to be processed. Tip #5: Leave debugging code in the source f iles During development, you will likely add a great deal of code that is designed f or debugging " verbose output, assertions, LED blinking, etc. When a project is over, it may be tempting to remove those sections of code to clean up the overall application, especially if the debugging code was haphazardly added. While cleaning up the application is a noble pursuit, taking out the debugging code creates problems later. Anyone attempting to maintain that code will likely reproduce many of the steps created in the original development " if the code is already there it makes maintenance a whole lot easier. If the code needs to be removed in production builds, use conditional compilation or put the debugging code in a central module or library and don't link it into production builds. Initial development of the application should include time to document and clean up debugging code; the extra time spent will be well worth it. Tip #6: Write wrappers f or system calls Try to separate low-level I/O routines f rom the higher-level program logic through interf aces, because a program can be made very dif f icult to manage by developing monolithically. Putting all of the f unctionality of an application into a f ew large f unctions makes code dif f icult to understand and much harder to update and debug. T his is especially true with hardware interf aces. You may have direct access to hardware registers or I/O, or even an API provided by the platf orm's vendor, but there is a lot of motivation to create your own 'wrapper' interf ace.
You usually do not have control over what the hardware does and if you have to change platf orms in the f uture, having hardware-specif ic code in your application (API or direct manipulation, it doesn't matter which) will make it much more dif f icult to port. If you create your own wrapper interf ace, which can be as simple as creating macros that are def ined to the hardware API, your code can be consistent and all the updates needed f or porting will be in a centralised location. Tip #7: Break up f unctionality only as needed Embedded applications will dif f er f rom PC applications in that a lot of the f unctionality will be specialised to the hardware you are working with. Splitting up f unctional units into the smallest pieces possible is not advisable - keep the number of f unction calls in a single scope (f unction) to less than 5 or 6, and make f unctional units of the hardware correspond to f unctional units in the sof tware. Breaking up the program any f urther will create a spider web of a call graph, making debugging and comprehension dif f icult. Tip #8: Documentation Keep all documentation with the code and, ideally, a copy of the hardware too. When documenting your application, try to put as much of the design and application model directly into the source code. If you have to keep it separate, put it in a source f ile as a giant comment and link it into the program. At the very least, if you use a version control system (such as CVS or Microsof t Source Saf e), check the documentation into the same directory as your source " it is really easy to lose the documentation if it is not located with the source. Ideally, put all the documentation and source on a CD (or your choice of portable storage device) seal it in a bag with the hardware and development tools you are using and put that bag in a saf e place " your successors will thank you. Tip #9: Don't be clever! Similar to premature optimisation, clever coding can lead to big trouble. Since C and C++ are still dominant languages in the embedded world, there is a huge number of ways to solve a single problem. Templates, inheritance, goto, the ternary operator (the "?"), the list goes on and on. Really clever programmers can come up with extremely compact and elegant ways to use these tools to solve problems. T he problem is that usually only the programmer understands the clever solution (and will likely f orget how it worked later). T he only solution is to avoid cleverness and keep the use of esoteric language f eatures to a minimum " f or example, don't rely on short-circuit evaluation in C statements or use the ternary operator f or program control (use an if -statement instead). Tip #10: Put all def initions in one place T his one is easy; if you have a lot of constant def initions or conditional def ines, keep them in a central location. T his could be a single f ile or a source code directory, but if you bury a def inition deep within your implementation, it will come back to bite you.