24. March 2014 · Categories: Software

I am currently busy adapting to the Cortex processor family, and I am amazed how ancient some of the coding practices have remained. A very typical case in point are the device header files used. Let us take as an example part of the definition of the interface to a DMA controller.

The relevant definitions for the destination width field look like this. First there is a normal struct definition without any structure:

and the definition of the width field is all done with macros for manual assembly:

Normal people would define this in proper C++, using something like

Unfortunately, you are basically forced to use these ancient methods, because the compilers, even the highly regarded one from Keil, do not properly optimize when you are changing multiple fields in such a struct. If one updates several fields with constants, the compiler strangely enough does not optimize them. For example, if you would update a byte:

then the compiler would even on highest optimization add the constants individually, even though there is no volatile forcing him to do so. And to top it off, the debugger is not even able to read enumerations in the bit field union, even though it can handle standard enums and plain int bitfields just fine.

This is really too bad, because using bitfields properly would allow a good editor to make completion suggestions for the relevant enum, and it would automatically catch any assignment errors.