对STM32库函数中 assert 函数的认知
> 本段代码取自 <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))