0

I'm a newbie just starting to learn about stm32 and have some confusion with the HAL library, thank you so much for taking the time to help.

I used STM32 to generate code, in the MX_GPIO_Init() and then try to understand how these functions work but i don't fully understand. -Marco below initializes portC's clk, but why put it in a loop that is sure to run only once:

#define __HAL_RCC_GPIOC_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg; \
                                        SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPCEN);\
                                        /* Delay after an RCC peripheral clock enabling */\
                                        tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPCEN);\
                                        UNUSED(tmpreg); \
                                      } while(0U)

-i want to ask an other question, i understand this code is checking if the GPIOx is valid

assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));

but:

#define assert_param(expr) ((void)0U);

As I understand, assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); will be replaced by ((void)0U), where did I misunderstand?

i know it is important to understand and able to build project from scratch. But in companies, will project use libraries like HAL?

Russ Schultz
  • 2,545
  • 20
  • 22
Dhtruong
  • 3
  • 3
  • That is two separate questions, and the first does not relate to your title. You should post the questions separately. – Clifford May 11 '23 at 21:32

1 Answers1

2

The do { } while(0) construct is to allow you to invoke the macro and put a ; at the end of it. i.e. you want to be able to have:

__HAL_RCC_GPIOC_CLK_ENABLE();

There is a lot more information about that here: do { ... } while (0) — what is it good for?

As to your question about:

#define assert_param(expr) ((void)0U);

This is a disabled assert, because you have not defined USE_FULL_ASSERT. It basically does nothing. If you define USE_FULL_ASSERT in your project, assert_param() will be defined as an actual assert. From a random project I have open:

#ifdef  USE_FULL_ASSERT
/**
  * @brief  The assert_param macro is used for functions parameters check.
  * @param  expr If expr is false, it calls assert_failed function
  *         which reports the name of the source file and the source
  *         line number of the call that failed.
  *         If expr is true, it returns no value.
  * @retval None
  */
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t *file, uint32_t line);
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */

To enable USE_FULL_ASSERT, open your .ioc file in CubeIDE, click on the Project Manager tab at the top, click the Code Generator box on the left-hand side, and enable the Enable Full Assert tick-box.

pmacfarlane
  • 3,057
  • 1
  • 7
  • 24
  • the `do {} while (0)` construct doesn't just __allow you__ to add a semicolon at the end, it __forces you__ so it looks like a normal C/C++ line of code, and also doesn't give you a warning for a dead line of code if you have two `;` in a row. – Russ Schultz May 11 '23 at 15:03