In embedded C is quite natural to have some fixed/generic algorithm but more than one possible implementation. This is due to several product presentations, sometimes options, other times its just part of product roadmap strategies, such as optional RAM, different IP-set MCU, uprated frequency, etc.
In most of my projects I deal with that by decoupling the core stuff, the algorithm and the logic architecture, from the actual functions that implement outside state evaluation, time keeping, memory storage, etc.
Naturally, I use the C function pointers mechanism, and I use a set of meaningful names for those pointers. E.G.
unsigned char (*ucEvalTemperature)(int *);
That one stores temperature in an int, and the return is OKness.
Now imagine that for a specific configuration of the product I have a
unsigned char ucReadI2C_TMP75(int *);
a function that reads temperature on the I2C bus from the TMP75 device and
unsigned char ucReadCh2_ADC(unsigned char *);
a function that reads a diode voltage drop, read by an ADC, which is a way to evaluate temperature in very broad strokes.
It's the same basic functionality but on different option-set products.
In some configs I'll have ucEvalTemperature setup to ucReadI2C_TMP75, while on other I'll have ucReadCh2_ADC. In this mild case, to avoid problems, I should change the argument type to int, because the pointer is always the same size, but the function signature isn't and the compiler will complaint. Ok... that's not a killer.
The issue becomes apparent on functions that may need to have different set of arguments. The signatures won't ever be right, and the compiler will not be able to resolve my Fpointers.
So, I have three ways:
- use a global stack of arguments, and all functions are unsigned char Func(void);
- use a helper function to each implementation that lets me switch on the right assignment to make/call;
- use JMP / LCALL assembly calls (which of course is horrible), potentially causing major problems on the call stack.
Neither is elegant, or composed... what's your approach/advise?