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

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

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:

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

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

  1. assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));

but:

  1. #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) 结构允许您调用宏并在其末尾加上 ;。也就是说,您想要能够使用:

  1. __HAL_RCC_GPIOC_CLK_ENABLE();

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

至于您提到的:

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

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

  1. #ifdef USE_FULL_ASSERT
  2. /**
  3. * @brief assert_param 宏用于函数参数检查。
  4. * @param expr 如果 expr 为 false,则调用 assert_failed 函数,
  5. * 该函数报告了失败调用的源文件名称和源
  6. * 行号。
  7. * 如果 expr 为 true,则不返回任何值。
  8. * @retval None
  9. */
  10. #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
  11. /* Exported functions ------------------------------------------------------- */
  12. void assert_failed(uint8_t *file, uint32_t line);
  13. #else
  14. #define assert_param(expr) ((void)0U)
  15. #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:

  1. __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:

  1. #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:

  1. #ifdef USE_FULL_ASSERT
  2. /**
  3. * @brief The assert_param macro is used for functions parameters check.
  4. * @param expr If expr is false, it calls assert_failed function
  5. * which reports the name of the source file and the source
  6. * line number of the call that failed.
  7. * If expr is true, it returns no value.
  8. * @retval None
  9. */
  10. #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
  11. /* Exported functions ------------------------------------------------------- */
  12. void assert_failed(uint8_t *file, uint32_t line);
  13. #else
  14. #define assert_param(expr) ((void)0U)
  15. #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:

确定