I like everything about this except the hard coded mask, you can tell from my previous posts that I am sold on calculating it. It would be clearer to be able to just define the data field length numerically, and let the software make the mask:
struct BitExtractor
{
const uint8_t bitFieldLength;
const uint8_t offset;
};
...
const struct BitExtractor parameterAlfa = {5, 9};
const struct BitExtractor parameterBravo = {..., ...};
const struct BitExtractor parameterCharlie = ...;
The function getBits() can calculate a mask based on the math presented above.