Colin Walls has over thirty years experience in the electronics industry, largely dedicated to embedded software. A frequent presenter at conferences and seminars and author of numerous technical articles and two books on embedded software, Colin is an embedded software technologist with Mentor … More »
March 15th, 2017 by Colin Walls
I have frequently made the observation that a key difference between embedded and desktop system programming is variability: every Windows PC is essentially the same, whereas every embedded system is different. There are a number of implications of this variability: tools need to be more sophisticated and flexible; programmers need to be ready to accommodate the specific requirements of their system; standard programming languages are mostly non-ideal for the job.
I have written on a number of occasions about the non-ideal nature of standard programming languages for embedded applications. A specific aspect that can give trouble is control of optimization …
Optimization is a big topic. Broadly it is a set of processes and algorithms that enable a compiler to advance from translating code from (say) C into assembly language to translating an algorithm expressed in C into a functionally identical one expressed in assembly. This is a subtle, but important difference.
A key aspect of optimization is memory utilization. Typically, a decision must be made in the trade-off between having fast code or small code – it is rare to have the best of both worlds. This decision also applies to data. The way that data is stored into memory affects its access time. With a 32-bit CPU, if everything is aligned with word boundaries, access time is fast; this is termed “unpacked data”. Alternatively, if bytes of data are stored as efficiently as possible, it may take more effort to retrieve data and hence the access time is slower; this is “packed” data. So, you have a choice much the same as with code: compact data that is slow to access or a bit of wasted memory, but fast access to data.
Most embedded compilers have a switch to select what kind of code generation and optimization is required. However, there may be a situation where you decide to have all your data unpacked for speed, but have certain data structures where you would rather save memory by packing. Or perhaps you pack all the data and have certain items which you want unpacked either for speed or for sharing with other software. For these situations, many embedded compilers feature two extension keywords – packed and unpacked – which override the appropriate code generation options. It is unlikely that you would use both keywords in one program, as only one of the two code generation options can be active at any one time.