STM32--assert_param断言宏

1、基本概念 宏定义 在stm32f10x_conf.h头文件中,有如下定义:

/* #define USE_FULL_ASSERT    1 */
#ifdef  USE_FULL_ASSERT
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
  void assert_failed(uint8_t* file, uint32_t line);
#else
  #define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */

   如果定义了宏USE_FULL_ASSERT,assert_param(expr)宏展开就是((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
    如果没有定义宏USE_FULL_ASSERT,assert_param(expr)宏展开就是((void)0) 相当于什么也不执行
    ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))是C语言的一个双目运算符
    如果expr为TRUE,assert(expr)就是(void)0不执行任何动作。
    如果expr为FALSE, assert(expr)就是函数assert_failed((uint8_t *)__FILE__, __LINE__))
    void assert_failed(uint8_t* file, uint32_t line);只是在头文件中的函数声明,函数实体可以自己定义,例如使用printf查看。

void assert_failed(u8* file, u32 line) 
{ /* User can add his own implementation to report the file name and linenumber, 
ex: printf("Wrong parameters value: file %s on line %d\r\n", file,line) */ 
/* Infinite loop */ 
while (1) { } 
}


    注意__FILE__和__LINE__是标准库中的宏定义

例如:GPIO_Init函数的断言宏的使用:
 

assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \
                                    ((PERIPH) == GPIOB) || \
                                    ((PERIPH) == GPIOC) || \
                                    ((PERIPH) == GPIOD) || \
                                    ((PERIPH) == GPIOE) || \
                                    ((PERIPH) == GPIOF) || \
                                    ((PERIPH) == GPIOG))

判断输入参数GPIOx是否是GPIOA、B、C、D、E、F、G中的一个

2、C语言自定义断言函数实现断言

#include<stdio.h>

#define USE_FULL_ASSERT    1
#ifdef  USE_FULL_ASSERT
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((unsigned char *)__FILE__, __LINE__))
  void assert_failed(unsigned char* file, unsigned int line); /*函数声明*/
#else
  #define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */


int
main(int argc, char *argv)
{
    int a = 0;
    char str[10] = {0};

    printf("请输入一个大于10的整数:");
    scanf("%d", &a);

    assert_param(a > 10);
    printf("输入的整数是:%d\n", a);

    printf("请输入一个字符串,长度不要超过%d :", sizeof(str) / sizeof(str[0]));
    scanf("%s", &str);

    assert_param(str != NULL && strlen(str) < 10);
    printf("输入的字符串是:%s\n", str);

    return(0);
}

void
assert_failed(unsigned char* file, unsigned int line)
{
    printf("%s \r\n", file);
    printf("%d \r\n", line);

    while(1);
}

 运行平台:w7+codeblocks

3、C语言库函数实现断言

#include <assert.h>
#include <stdio.h>

int main()
{
    int a = 0;
    char str[10] = {0};

    printf("请输入一个大于10的整数:");
    scanf("%d", &a);

    assert(a > 10);
    printf("输入的整数是:%d\n", a);

    printf("请输入一个字符串,长度不要超过%d :", sizeof(str) / sizeof(str[0]));
    scanf("%s", &str);

    assert(str != NULL && strlen(str) < 10);
    printf("输入的字符串是:%s\n", str);

    return(0);
}

#include <assert.h>库中有如下定义:

#ifdef NDEBUG
/*
 * If not debugging, assert does nothing.
 */
#define assert(x)	((void)0)

#else /* debugging enabled */

/*
 * CRTDLL nicely supplies a function which does the actual output and
 * call to abort.
 */
_CRTIMP void __cdecl __MINGW_NOTHROW _assert (const char*, const char*, int) __MINGW_ATTRIB_NORETURN;

/*
 * Definition of the assert macro.
 */
#define assert(e)       ((e) ? (void)0 : _assert(#e, __FILE__, __LINE__))

#endif	/* NDEBUG */

从库函数中的定义可以看出,如果不需要使用C语言库函数中的断言功能

#define NDEBUG
#include <assert.h>

运行平台:w7+codeblocks 

猜你喜欢

转载自blog.csdn.net/tyustli/article/details/86475542
今日推荐