Home > database >  What is the logic of "#ifdef" lines in the embedded if condition?
What is the logic of "#ifdef" lines in the embedded if condition?

Time:01-13

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.

  • Related