cancel
Showing results for 
Search instead for 
Did you mean: 

A simple question about READ_REG() macro and double layers of parentheses

laojian
Associate II

Hi,

It may seem simple to you, but it confuses me for a bit of time after I saw:

uint32_t isrflags  = READ_REG(huart->Instance->SR);

and

#define READ_REG(REG)     ((REG))

I have 2 questions here:

huart->Instance->SR should be an address, how does READ_REG(REG) get the data from it without using like:

#define READ_REG(REG)     (*(REG))

Why there are double layers of parentheses for REG as ((REG))? I searched but seems get nothing.

Thanks so much for your time!

Regards,

6 REPLIES 6
Uwe Bonnes
Principal II

Where did you find these defines?

laojian
Associate II

Hi Uwe,

I found this function in stm32f4xx_hal_uart.c:

/**

 * @brief This function handles UART interrupt request.

 * @param huart Pointer to a UART_HandleTypeDef structure that contains

 *        the configuration information for the specified UART module.

 * @retval None

 */

void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)

{

 uint32_t isrflags  = READ_REG(huart->Instance->SR);

 uint32_t cr1its   = READ_REG(huart->Instance->CR1);

 uint32_t cr3its   = READ_REG(huart->Instance->CR3);

 uint32_t errorflags = 0x00U;

 uint32_t dmarequest = 0x00U;

 /* If no error occurs */

 errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));

 if (errorflags == RESET)

 {

  /* UART in mode Receiver -------------------------------------------------*/

  if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))

  {

   UART_Receive_IT(huart);

   return;

  }

 }

……​

Then in stm32f4xx.h, near bottom:

#define READ_REG(REG)     ((REG))

Thanks!

Regards,

>> huart->Instance->SR should be an address, how does READ_REG(REG) get the data from it without using like: #define READ_REG(REG) (*(REG))

But it's not an address, huart->Instance is an address, SR is a field in a structure the that huart->Instance points too

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Pavel A.
Evangelist III

In C++ the argument of READ_REG would be a reference, for example:

 

inline uint32_t READ_REG(volatile uint32_t &reg)
{
  return reg;
}

 

but all we have there is plain old C.

Why  double layers of parentheses? Just because they did so.

 

So preprocessor treats like a function..

https://gcc.gnu.org/onlinedocs/gcc-4.7.4/cpp/Macro-Arguments.html

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Piranha
Chief II

There is a better question - why does such macro exist at all? With what are they planning to hypothetically redefine these "future proof" macros? PCI_BusWrite()?