__weak弱函数

__weak是KEIL编译器特有的关键字,用来指定一个函数为“弱函数”。

我们经常在STM32CubeMX生成的工程中见到它,例如外部中断处理函数中的外部中断回调函数。

__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(GPIO_Pin);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_GPIO_EXTI_Callback could be implemented in the user file
   */
}

在这个函数返回值类型void的前面,使用__weak指明了这个函数是一个弱函数。从这个函数中的语句和注释来看,这个函数其实什么都没有做。

我们需要在用户文件中,自己再定义一个一模一样的函数,只是我们自己定义的函数,不需要指明是弱函数。

理论上,一个工程中是不允许出现两个相同名称的函数的,这里使用__weak指明其中一个是弱函数,就可以了。

程序在编译的时候,如果发现有两个相同名称的函数,而且其中一个是弱函数,就会忽略弱函数,使用正常的函数进行编译;如果发现只有一个弱函数,那还是会使用弱函数参与编译。

在STM32CubeMX中生成的弱函数,寓意都是让我们自己再定义一遍。例如,我们可以把上面的函数自己重新定义一下,在函数中加入一些用户代码,把函数放到main.c文件中。

/* USER CODE BEGIN 0 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  switch(GPIO_Pin)
  {
    case GPIO_PIN_0: // WAKUP按键
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);// 熄灭D4
      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);// 熄灭D3
      break;
    case GPIO_PIN_13:// KEY1按键
      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);// 点亮D3
      break;
    case GPIO_PIN_3: // KEY2按键
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET);// 点亮D4
      break;
    default:break;
  }
}
/* USER CODE END 0 */