In the code below I have an push button example of efr32fg14 evalution board.
They use the #ifdef
command which checks if the BSP_GPIO_LED1_PORT
variable is defined.
BSP_GPIO_LED1_PORT
is the port number neccesary for the command.
What if the logic of using #ifdef
in the code below?
#include "em_device.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "bsp.h"
// Push-buttons are active-low
#define PB_PRESSED (1)
/**************************************************************************//**
* @brief GPIO initialization
*****************************************************************************/
void initGPIO(void)
{
// Enable GPIO clock
CMU_ClockEnable(cmuClock_GPIO, true);
// Configure PB0 and PB1 as input
GPIO_PinModeSet(BSP_GPIO_PB0_PORT, BSP_GPIO_PB0_PIN, gpioModeInput, 0);
GPIO_PinModeSet(BSP_GPIO_PB1_PORT, BSP_GPIO_PB1_PIN, gpioModeInput, 0);
// Configure LED0 and LED1 as output
GPIO_PinModeSet(BSP_GPIO_LED0_PORT, BSP_GPIO_LED0_PIN, gpioModePushPull, 0);
#ifdef BSP_GPIO_LED1_PORT
GPIO_PinModeSet(BSP_GPIO_LED1_PORT, BSP_GPIO_LED1_PIN, gpioModePushPull, 0);
#endif
}
/**************************************************************************//**
* @brief Main function
*****************************************************************************/
int main(void)
{
// Chip errata
CHIP_Init();
// Initializations
initGPIO();
while (1)
{
// Set the state of LED0
if (GPIO_PinInGet(BSP_GPIO_PB0_PORT, BSP_GPIO_PB0_PIN) == PB_PRESSED)
{
// LED0 On
GPIO_PinOutSet(BSP_GPIO_LED0_PORT, BSP_GPIO_LED0_PIN);
}
else
{
// LED0 Off
GPIO_PinOutClear(BSP_GPIO_LED0_PORT, BSP_GPIO_LED0_PIN);
}
#ifdef BSP_GPIO_LED1_PORT
// Set the state of LED1
if (GPIO_PinInGet(BSP_GPIO_PB1_PORT, BSP_GPIO_PB1_PIN) == PB_PRESSED)
{
// LED1 On
GPIO_PinOutSet(BSP_GPIO_LED1_PORT, BSP_GPIO_LED1_PIN);
}
else
{
// LED1 Off
GPIO_PinOutClear(BSP_GPIO_LED1_PORT, BSP_GPIO_LED1_PIN);
}
#endif
}
}
I have tried to look for the #ifdef
definition to see the logic of this command in the code.
CodePudding user response:
#ifdef
is a pre-processor directive (rather then a "command"), and is used for conditional compilation.
If the condition (in this case defined BSP_GPIO_LED1_PORT
) is false, the code between the condition and the corresponding #endif
is removed from the compilation so that no code is generated for that section of source.
In this case the "logic" appears to be to conditionally build code that supports either one or two LEDs. That is code related to LED0
is always included, and that for LED1
is excluded unless BSP_GPIO_LED1_PORT
.
So to support LED1
, you might either have a header that has (for example):
#define BSP_GPIO_LED1_PORT gpioPortA
or you might use a command line swithc such as -D BSP_GPIO_LED1_PORT=gpioPortA
in GCC, CLANG and many other compilers. Note that defined
/!defined
are Boolean states, the macro need not itself have a value, but here it is actually the port identifier for the GPIO.
Note that there is a corresponding #ifndef
(if-not-defined), and both can have a #else
section and zero or more #elif
(else-if) sections.
#ifdef
/#ifndef
are however rather inflexible. In C89 the more useful defined
operator was added so that you can use #if
and more complex expressions such as:
#if defined BSP_GPIO_LED1_PORT && defined BSP_GPIO_LED1_PIN
#if
expressions allow Boolean expressions to control conditional compilation, rather then just defined
/!defined
. #ifdef
has been largely redundant since C89, but it seems to not be going away.