我不理解STM32 HAL库中的这个宏:#define assert_param(expr) ((void)0U)

huangapple go评论49阅读模式
英文:

I don't understand this marco in stm32 HAL library: #define assert_param(expr) ((void)0U)

问题

I'm here to provide translations, as requested. Here's the translated content:

"我是一个刚开始学习STM32的新手,对HAL库有些困惑,非常感谢您抽出时间来帮助。

我使用STM32生成代码,在MX_GPIO_Init()函数中,然后尝试理解这些函数如何工作,但我不完全明白。
-Marco在初始化portC的时钟,但为什么要将它放在只会运行一次的循环中:

#define __HAL_RCC_GPIOC_CLK_ENABLE() do {
__IO uint32_t tmpreg;
SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPCEN);
/* RCC外设时钟启用后延迟 */
tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPCEN);
UNUSED(tmpreg);
} while(0U)

我想问另一个问题,我理解这段代码是检查GPIOx是否有效:

assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));

但是:

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

据我理解,'assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));' 将被替换为 '((void)0U)',我理解错了吗?

我知道理解并能够从零开始构建项目很重要。但在公司里,项目会使用类似HAL这样的库吗?"

英文:

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?

答案1

得分: 2

The do { } while(0) 结构允许您调用宏并在其末尾加上 ;。也就是说,您想要能够使用:

__HAL_RCC_GPIOC_CLK_ENABLE();

有关此方面的更多信息,请参考这里:do { ... } while (0) — 有何用途?

至于您提到的:

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

这是一个禁用的断言,因为您没有定义 USE_FULL_ASSERT。它基本上什么都不做。如果在您的项目中定义了 USE_FULL_ASSERT,则 assert_param() 将被定义为一个实际的断言。从我打开的一个随机项目中:

#ifdef  USE_FULL_ASSERT
/**
  * @brief  assert_param 宏用于函数参数检查。
  * @param  expr 如果 expr 为 false,则调用 assert_failed 函数,
  *         该函数报告了失败调用的源文件名称和源
  *         行号。
  *         如果 expr 为 true,则不返回任何值。
  * @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 */

要启用 USE_FULL_ASSERT,在 CubeIDE 中打开您的 .ioc 文件,点击顶部的 Project Manager 选项卡,在左侧点击 Code Generator 框,并启用 Enable Full Assert 复选框。

英文:

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.

huangapple
  • 本文由 发表于 2023年5月11日 18:11:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76226488.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定