I was how it's possible to test some specific C macros for embedded SW.
For example if I have the following macro:
/*
Set a pin as an input
port (B,C, D or E)
pin - pin to set (0-7)
*/
#define _SET_INPUT_PIN(port,pin) DDR ## port &= ~(1<<pin)
#define SET_INPUT_PIN(...) _SET_INPUT_PIN(__VA_ARGS__)
and I want to test it with two ports, one who exists (LED_OK) the other one no (LED_FAIL):
#define LED_OK D,3
#define LED_FAIL D,8
When I try to test it both LED_OK and LED_FAIL will work fine but some sort of warning/fail should alert that LED_FAIL doesn't exist since PORTD has only defined pins 0 to 7.
So, when I pass a LED how could I check "pin" is in range?
This is way too obscure. In general, I would strongly recommend not to hide super-trivial stuff like setting/clearing a pin behind abstraction layers.
Instead you should write something like:
#define LED_DDR DDRD
#define LED_PORT PORTD
#define LED_PIN (1u << 3)
LED_DDR |= LED_PIN; // set pin to output
LED_PORT |= LED_PIN; // set pin to 1
LED_PORT &= ~LED_PIN; // set pin to 0
LED_PORT &= (uint8_t)~LED_PIN; // set pin to 0 with pedantic type safety (MISRA-C etc)
LED_PORT ^= LED_PIN; // toggle pin
You can't really write clearer code so any abstraction layer beyond this is doomed to fail. It will not add clarity but it may add bugs. As seen from some thousands sketchy attempts on the SO/EE sites where people attempt to do just that. Or as seen in bloatware libs from silicon vendors.
A proper test would thus not test the obscure macro SET_INPUT_PIN
but question its existence. The name of the test is code review. Which would also point out the following issues:
_S
etc, it might collide with the compiler libraries.( (DDR ## port) &= ~(1 <<(pin)) )
with parenthesis both around macro parameters as well as around the final expression.1
signed integer constants which becomes a major hazard soon as we expand to 16 bit registers on what is likely a system with 16 bit int
. We'll then get undefined behavior bugs all over the place. Should have been 1u
.int
. Which is unhelpful and dangerous.