【问题标题】:How to keep unused function in firmware image use arm-none-eabi-gcc toolchain?如何使用 arm-none-eabi-gcc 工具链在固件映像中保留未使用的功能?
【发布时间】:2019-04-06 11:02:32
【问题描述】:

我现在尝试创建一个运行 STM32F0xx MCU 的固件映像。类似于flash算法,提供一些函数调用来控制STM32F0xx MCU Pins,但比flash算法复杂。所以它将使用 STM32 HAL 库和 Mbed 库。

编译器/链接器使用“-ffunction-sections”和“-fdata-sections”标志。

所以我使用“attribute((used))”尝试将功能保留到固件映像中,但失败了。
arm-none-eabi-gcc 工具链版本为 4.9.3。

我的代码是这样的:

extern "C" {
__attribute__((__used__))  void writeSPI(uint32_t value)
{
    for (int i = 0; i < spiPinsNum; i++) {
        spiPins[i] = (((value >> i) & 0x01) != 0) ? 1 : 0;
    }
    __ASM volatile ("movs r0, #0"); // set R0 to 0 show success
    __ASM volatile ("bkpt  #0");   // halt MCU
}

}

构建成功后,image中没有writeSPI符号。 我也尝试static 的功能,“-uXXXXX”标志,创建一个新部分。

问题:如何保留带有“-ffunction-sections”和“-fdata-sections”标志的writeSPI函数代码?

【问题讨论】:

  • 请包含完整的编译命令。我怀疑你还有--gc-sections 或类似的。顺便说一句,什么是“闪存算法”?
  • 请参阅:--gc-keep-exported,这可能会有所帮助。 __unused__ 属性适用于 compiler 而不是 LINKER。这意味着编译器将生成代码。另请参阅what does KEEP mean
  • “flash 算法”是在 Target MCU 中运行的一组函数。代码编译为与位置无关。
  • 因为我们需要的函数比较复杂,当编译为位置无关时,二进制代码会很大。包括许多未使用的功能(我们不需要)。 {我尝试使用 lib 来减小大小,它仍然很大}。简而言之,我们保留想要的未使用功能,并将不需要的功能移除到 ELF 映像中。
  • 对不起,忘了提,源代码编译为位置依赖。使用普通的 gcc 链接脚本文件。

标签: gcc attributes arm


【解决方案1】:

确保所需函数不会被垃圾回收的一种方法是在使用的方法中创建指向它的函数指针。您不必对函数指针做任何事情,只需对其进行初始化即可。

void(*dummy)(uint32_t)=&writeSPI;

另一种方法是从包含不应剥离的函数的编译单元中省略 -ffunction-sections 标志,但这可能涉及代码库的重大重组。

【讨论】:

  • 谢谢!作弊 gcc 编译器将工作。但是是否有任何编译器/链接器标志、#pragma、attribute ...强制将特殊未使用的函数链接到 ELF 映像中?
  • 我认为__attribute__ ((section (".text"))) 或类似的东西会起作用,但它对我不起作用。这个想法是你强制函数进入一个不能被垃圾收集的部分。
猜你喜欢
  • 2016-05-01
  • 2017-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-23
  • 1970-01-01
  • 1970-01-01
  • 2017-10-10
相关资源
最近更新 更多