跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

STM32中的assert_param函数浅析

学习STM32时,追踪源代码经常会在ST库函数中看到assert_param()函数,它的作用是什么呢?

上网了解一下之后便豁然开朗!

下面我将对它的作用及其用法进行简单的总结! 其实assert_param()是一个断言机制函数,它主要是用于调试代码。

比如我们在调用void USART_DMACmd()库函数时,追踪一下它的定义,会发现它是定义在stm32f10x_usart.c文件中再来看看它是如何定义的:

void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState)

{ /* Check the parameters */ assert_param(IS_USART_ALL_PERIPH(USARTx)); assert_param(IS_USART_DMAREQ(USART_DMAReq)); assert_param(IS_FUNCTIONAL_STATE(NewState)); if (NewState != DISABLE) { /* Enable the DMA transfer for selected requests by setting the DMAT and/or DMAR bits in the USART CR3 register */ USARTx->CR3 |= USART_DMAReq; } else { /* Disable the DMA transfer for selected requests by clearing the DMAT and/or DMAR bits in the USART CR3 register */ USARTx->CR3 &= (uint16_t)~USART_DMAReq; } } assert_param()函数在这里的作用是检查USART_DMACmd库函数传入的参数是否为真,如果为真,就什么也不执行,如果为假,就会在源程序编译的时候报错!

我们再追踪一下assert_param函数,发现它是在stm32f10x_conf.h中定义的,其本质是一个宏。

#ifdef USE_FULL_ASSERT

/** * @brief The assert_param macro is used for function's 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)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t* file, uint32_t line); #else #define assert_param(expr) ((void)0) 其实这个宏就是将一个条件判断语句((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))定义为assert_param(expr),英文也有注释,我就不多说了。

这位网友分析的还不错可以参考一下: 点击打开链接 下面自己来举个例子实验一下:

1 /*********************************************************************************

2 * Copyright: (C) 2017 zoulei 3 * All rights reserved. 4 * 5 * Filename: gg.c 6 * Description: This file i 7 * 8 * Version: 1.0.0(2017年07月13日) 9 * Author: zoulei 14 //#define NDEBUG 15 #include 16 #include 17 18 int main( void ) 19 { 20 FILE *fp; 21 22 /* fp = fopen( "test.txt", "w" );//以可写的方式打开一个文件,如果不存在就创建一个同名文件 23 assert( fp ); //所以这里不会出错 24 fclose( fp );*/ 25 26 fp = fopen( "noexitfile.txt", "r" );//以只读的方式打开一个文件,如果不存在就打开文件失败 27 assert( fp ); //这里会出错 28 fclose( fp ); //程序永远都执行不到这里来 29 return 0;

[zoulei@CentOS test]$ sudo vim gg.c

[zoulei@CentOS test]$ gcc gg.c [zoulei@CentOS test]$ ./a.out a.out: gg.c:27: main: Assertion `fp' failed. 已放弃 (core dumped) [zoulei@CentOS test]$ 上面编译测试我是在linux系统进行的,你会发现加上assert()函数之后,确实定位到具体的某一行以及文件,可能你会怀疑,那么我们再加上#define NDEBUG这段代码,这段代码它会禁用assert(fp)函数,我们再来看看效果。

[zoulei@CentOS test]$ sudo vim gg.c

[zoulei@CentOS test]$ gcc gg.c [zoulei@CentOS test]$ ./a.out 段错误 (core dumped) [zoulei@CentOS test]$ 看!

是不是没有出现错误是在哪个文件的哪一行的提示!

这就验证了assert()的作用是检测函数传入参数是否为真!

如果是大工程,这就为调式代码提高了效率。

相关文章