首页 > 技术文章 > 对STM32库函数中 assert 函数的认知

skullboyer 2018-01-24 13:34 原文

> 本段代码取自 <stm32f4xx_gpio.c>

> 可以看出进入函数第一件事就是做 assert 输入参数检查,参数合法后,根据参数做相应操作

 1 /**
 2   * @brief  Initializes the GPIOx peripheral according to the specified parameters in the GPIO_InitStruct.
 3   * @param  GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices
 4   *                      x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices.
 5   *                      x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices.   
 6   * @param  GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that contains
 7   *         the configuration information for the specified GPIO peripheral.
 8   * @retval None
 9   */
10 void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
11 {
12   uint32_t pinpos = 0x00, pos = 0x00 , currentpin = 0x00;
13 
14   /* Check the parameters */
15   assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
16   assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));
17   assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
18   assert_param(IS_GPIO_PUPD(GPIO_InitStruct->GPIO_PuPd));
19 
20   /* ------------------------- Configure the port pins ---------------- */
21   /*-- GPIO Mode Configuration --*/
22   for (pinpos = 0x00; pinpos < 0x10; pinpos++)
23   {
24     pos = ((uint32_t)0x01) << pinpos;
25     /* Get the port pins position */
26     currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
27 
28     if (currentpin == pos)
29     {
30       GPIOx->MODER  &= ~(GPIO_MODER_MODER0 << (pinpos * 2));
31       GPIOx->MODER |= (((uint32_t)GPIO_InitStruct->GPIO_Mode) << (pinpos * 2));
32 
33       if ((GPIO_InitStruct->GPIO_Mode == GPIO_Mode_OUT) || (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_AF))
34       {
35         /* Check Speed mode parameters */
36         assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
37 
38         /* Speed mode configuration */
39         GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (pinpos * 2));
40         GPIOx->OSPEEDR |= ((uint32_t)(GPIO_InitStruct->GPIO_Speed) << (pinpos * 2));
41 
42         /* Check Output mode parameters */
43         assert_param(IS_GPIO_OTYPE(GPIO_InitStruct->GPIO_OType));
44 
45         /* Output mode configuration*/
46         GPIOx->OTYPER  &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pinpos)) ;
47         GPIOx->OTYPER |= (uint16_t)(((uint16_t)GPIO_InitStruct->GPIO_OType) << ((uint16_t)pinpos));
48       }
49 
50       /* Pull-up Pull down resistor configuration*/
51       GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2));
52       GPIOx->PUPDR |= (((uint32_t)GPIO_InitStruct->GPIO_PuPd) << (pinpos * 2));
53     }
54   }
55 }

> 本段代码取自 <stm32f4xx_conf.h>

> 可以看出函数 assert_param(expr) 由宏控制为两个情况, 当要检查的参数表达式为真,则 ((void)0) 什么也不干, 当要检查的参数表达式为假, 则调用函数 assert_failed((uint8_t *)__FILE__, __LINE__) 指出参数表达式错误发生的位置(所在文件, 所在行)

 1 /* Uncomment the line below to expanse the "assert_param" macro in the 
 2    Standard Peripheral Library drivers code */
 3 /* #define USE_FULL_ASSERT    1 */
 4 
 5 /* Exported macro ------------------------------------------------------------*/
 6 #ifdef  USE_FULL_ASSERT
 7 
 8 /**
 9   * @brief  The assert_param macro is used for function's parameters check.
10   * @param  expr: If expr is false, it calls assert_failed function
11   *   which reports the name of the source file and the source
12   *   line number of the call that failed. 
13   *   If expr is true, it returns no value.
14   * @retval None
15   */
16   #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
17 /* Exported functions ------------------------------------------------------- */
18   void assert_failed(uint8_t* file, uint32_t line);
19 #else
20   #define assert_param(expr) ((void)0)
21 #endif /* USE_FULL_ASSERT */

> 本段代码取自 <stm32f4xx_gpio.h>

> 可以看出作为函数 assert_param(expr)  参数表达式 IS_GPIO_ALL_PERIPH(PERIPH) 是一组判定相等的表达式来检查参数的合法性

 1 #define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \
 2                                     ((PERIPH) == GPIOB) || \
 3                                     ((PERIPH) == GPIOC) || \
 4                                     ((PERIPH) == GPIOD) || \
 5                                     ((PERIPH) == GPIOE) || \
 6                                     ((PERIPH) == GPIOF) || \
 7                                     ((PERIPH) == GPIOG) || \
 8                                     ((PERIPH) == GPIOH) || \
 9                                     ((PERIPH) == GPIOI) || \
10                                     ((PERIPH) == GPIOJ) || \
11                                     ((PERIPH) == GPIOK))

 

推荐阅读