打印
[其他ST产品]

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

[复制链接]
1072|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
elephant00|  楼主 | 2024-2-19 12:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
 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);

使用特权

评论回复
沙发
梅花香自123| | 2024-2-22 18:28 | 只看该作者
关于你提到的两个坑,特别是第一个坑,确实需要注意。在实际的工程中,如果需要用户进行自定义回调函数的实现,最好将相关函数放在用户自己的源文件中,以避免和库函数中的__weak修饰的函数冲突。

第二个坑也是一个很实用的经验

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

930

主题

2551

帖子

5

粉丝