• STM32 一种参数检查用法介绍


    STM32 一种参数检查用法介绍

    assert_param()是一个在代码中很常见的写法,这个函数的功能一般是对函数参数的合法性进行检查,这里以一个例子进行分析:

    assert_param(IS_GPIO_ALL_PERIPH(GPIOx))

    函数的参数是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) || 
                                        ((PERIPH) == GPIOH) || 
                                        ((PERIPH) == GPIOI) || 
                                        ((PERIPH) == GPIOJ) || 
                                        ((PERIPH) == GPIOK))
    

    这个宏定义的作用就是检查参数PERIPH,判断参数PERIPH是否为GPIOX(A...G)基址中的一个,只要有一个为真则其值为真,否则为假。由于这个是宏定义,因此并不是在编译的时候进行判断上的简化,而是将多行代码用宏定义代替了。

    下面再看看assert_param:

    assert_param

    函数原型如下:

    #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)
    #endif /* USE_FULL_ASSERT */
    
    

    这里有一个判断,如果是FULL ASSERT,则宏定义被展开为:((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)),否则则被展开为((void)0)

    先看第二种:
    如果被展开为((void)0),则相当于什么也没做,那么看第一种,如果expr为真,则跟第二种的处理一样,什么也不做,如果expr为假,则执行断言失败assert_failed((uint8_t *)__FILE__, __LINE__))

    既然如果选择了FULL ASSERT,那么就有断言失败的可能,因此,这里把断言失败的函数声明写上,即可避免编译错误。

    再看断言失败的处理:

    void assert_failed(u8* file, u32 line)

    官方给出的代码如下:

    void assert_failed(u8* file, u32line) 
    { 
    
        /* User can add his ownimplementation to report the file name and line number, 
    
           ex: printf("Wrong parametersvalue: file %s on line %drn", file, line) */ 
    
        /* Infinite loop */ 
    
        while (1) { } 
    
    } 
    

    这里可以使用串口打印出来,并将程序halt在这里。STM32的这种用法,可以推广至一般的嵌入式APP开发中,在不支持高级语言的场景下,使用C语言对输入参数进行检查也是一种很好用的手段。

    我们可以在应用开发时,建立一个参数检查的宏定义表,并在编写函数时使用上面的检查方式进行检查。

  • 相关阅读:
    弱省胡策 Magic
    CF917D Stranger Trees
    【弱省胡策】Round #5 Count
    【BZOJ2117】 [2010国家集训队]Crash的旅游计划
    「2017 山东一轮集训 Day5」苹果树
    【SDOI2017】天才黑客
    【JXOI2018】守卫
    小程序两种图片加载方式
    小程序之底部栏设计
    小程序之全局变量的设置及使用
  • 原文地址:https://www.cnblogs.com/RegressionWorldLine/p/12203747.html
Copyright © 2020-2023  润新知