STM32 MDK编程中__weak的使用及避坑

时间:2023-12-15来源:欧工玩转嵌入式

 STM32 HAL库中有很多使用__weak修饰的函数。比如在"stm32f4xx_hal_spi.c"中有一处函数定义:

/**
  * @brief  Initialize the SPI MSP.
  * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
  *               the configuration information for SPI module.
  * @retval None
  */__weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi){  /* Prevent unused argument(s) compilation warning */
  UNUSED(hspi);  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_SPI_MspInit should be implemented in the user file
   */}

此处的函数修饰符__weak其实是一个宏定义,定义如下:

#define __weak   __attribute__((weak))

  __attribute__((weak))用于告诉链接器此处的函数为弱引用,这样一来,如果在其地方有同样的函数定义,则链接器会选择没用__attribute__((weak))修饰的那个函数来链接。这个特性对于需要使用回调函数的地方非常友好,可以在函数库中用__weak实现一个最小化的回调函数,这样用户可以根据是否需要回调而决定是否自己实现回调函数,在用户不需要实现自己的回调函数时,也不会因为缺少函数定义而报错。

  在使用__weak时,遇到过2个坑,下面给大家一个参考。

1.使用__weak和不使用__weak修饰的函数不能放在同一个源文件中,否则会报函数重复定义的错误。不过这个也好理解,因为__weak是给链接器做指示用的而非编译器 。当二者存在于同一源文件中,编译器会报错。

2.在__weak修饰的函数中,不能使用while(1)来阻塞程序。如果使用了while(1),编译能通过,但在存在非__weak修饰的函数情况下,程序也依旧无法继续向下执行。这应该是MDK的一个bug。解决方法是先定义一个值为1的局部变量,然后while这个局部变量。

uint8_t tmp = 1;while(tmp);


关键词: STM32 函数 编程

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW

或用微信扫描左侧二维码

相关文章

查看电脑版