×
单片机 > 单片机程序设计 > 详情

STM32中的assert_param函数浅析

发布时间:2020-09-03 发布时间:
|

下面我将对它的作用及其用法进行简单的总结!


其实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

 10  *      ChangeLog:  1, Release initial version on "2017年07月13日 15时42分36秒"

 11  *

 12  ********************************************************************************/

 13 #include

 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()的作用是检测函数传入参数是否为真!如果是大工程,这就为调式代码提高了效率。



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
实验八 交通灯控制(80C51单片机汇编语言编程)