【问题标题】:How to force IAR to keep linking interrupt related functions?如何强制 IAR 保持链接中断相关函数?
【发布时间】:2019-12-10 12:05:45
【问题描述】:

Clarification

我想从静态 C 库构建嵌入式软件。我的主要问题是软件链接,但由于最终产品的映射文件中缺少与中断相关的功能,因此无法运行。 (至少,这是我的假设)

我已经阅读了 IAR 的链接器手册,尝试了很多设置,但都没有成功。

你可以在下面找到一个 .map 文件比较,左边是应该的,右边是我从库中构建的结果。

.map compare

我的中断向量表:

Vector table

如果重要的话,目标处理器是 ARM。

提前致谢!

【问题讨论】:

  • “尝试了很多设置,但都没有成功。” 请列出您尝试过的那些应该有帮助但没有帮助的东西。
  • 如果您不引用某些内容,链接器将不会将其拉入。我的期望是您实际上并没有在代码中的任何地方引用您的中断函数。
  • @user694733 - 在 2 种静态库生成模式之间切换(静态库 C 和静态库 C (IAR) - 在自动运行时库选择之间切换 - 添加函数以保持符号列表 - 降低优化级别(我可以'不关闭,因为它不适合目标)
  • 请显示您项目的向量表。这是您指定中断处理程序的地方。即使它们是由库实现的,您仍然必须将它们映射到内存中的正确位置。
  • 请注意,您可能必须在链接器脚本或链接器中包含 vector table(不仅是函数)的 keep 指令设置以确保当 RussSchultz 提到的其他代码未引用符号时不会删除符号。

标签: c static linker embedded iar


【解决方案1】:

我并不特别熟悉 IAR,但一般来说,如果没有提供 stronger 链接,链接器将使用启动代码中提供的“弱链接”存根解析向量表符号。

阅读IAR documentation,问题是:

链接器不会仅仅为了满足弱引用而包含库中的模块

因此,如果您的所有“具体”中断处理程序都位于没有其他引用的非弱符号的单独模块中,则该模块将不会被链接。

您可以(可能)执行以下操作之一:

  1. 从启动代码中删除弱链接实现

  2. 实现对调用不同名称库代码函数的弱链接实现的覆盖。 (即,不要对库函数名称使用默认中断向量符号,而是使用调用库函数的默认名称实现函数。)

  3. 通过调用您的库代码而不是默认实现(通常是无限循环)来实现弱存根

  4. 在包含处理程序的一个或多个模块中创建一个符号并在代码中引用它以强制链接模块。例如,您可能有:

     const int library_isr_force_explicit_link = 0 ;
    

    在库中,然后在您的应用程序中:

    extern const int library_isr_force_explicit_link ;
    volatile int dummy = library_isr_force_explicit_link ;
    

    然后包含 ISR 的模块将被强制链接以解析 library_isr_force_explicit_link 引用,因此库 ISR 将解析其他弱符号。

如果库中没有任何已删除弱实现的实现,第一个选项将无法链接,这可能是一个有用的诊断而不是问题,但这确实意味着每个项目都会有自定义启动代码,这将仅与您的图书馆链接。

第二个会增加一定程度的函数调用开销,因此会稍微增加中断延迟和堆栈使用率。

第三个是 1 和 2 的组合,共享两者的优点/缺点。

第四个选项来自我对文档的理解——我认为它会起作用。

我个人会选择选项 2,只是为了避免修改提供的默认启动 - 将来可能会减少工作量 - 尤其是在应用供应商提供的更新时,并在移植代码时避免任何链接器特定问题到不同的工具链。

文档中的“保留模块”部分建议使用 iarchive 实用程序来提取对象模块并显式链接它,但这反而会破坏对象(不是双关语) 在第一个实例中将代码放入库中,如果您想自动化它,无论如何都会导致复杂的自定义构建步骤。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-14
    • 2016-12-25
    • 2017-01-29
    • 2013-01-09
    • 1970-01-01
    • 2015-04-09
    相关资源
    最近更新 更多