如何在 IAR 编译器中按特定顺序放置变量?

Posted

技术标签:

【中文标题】如何在 IAR 编译器中按特定顺序放置变量?【英文标题】:How to place variables in IAR compiler in specific order? 【发布时间】:2020-07-21 21:00:24 【问题描述】:

我正在尝试将一些变量放入特定的 ROM lication。

在链接器配置文件中:

define symbol __ICFEDIT_region_APP_ROM_start__  = 0x08070000 ;
define symbol __ICFEDIT_region_APP_ROM_end__    = 0x0807FFFF;

define region APP_ROM_region   = mem:[from __ICFEDIT_region_APP_ROM_start__   to __ICFEDIT_region_APP_ROM_end__];

place in APP_ROM_region  readonly section test_data;

在源文件中:

#pragma default_variable_attributes = @ "test_data"

const U8 testVar8 = 0;
const U8 testArray512[512];
const uint32_t testVar32 = 0x1234ABCD;
const U8 testArray500[500];

#pragma default_variable_attributes =

生成的 .map 文件:

test_data           const    0x08070000   0x200  source_file.o [1]
test_data           const    0x08070200   0x1f4  source_file.o [1]
test_data           const    0x080703f4     0x4  source_file.o [1]
test_data           const    0x080703f8     0x1  source_file.o [1]
testArray512            0x08070000   0x200  Data  Gb  source_file.o [1]
testArray500            0x08070200   0x1f4  Data  Gb  source_file.o [1]
testVar32               0x080703f4     0x4  Data  Gb  source_file.o [1]
testVar8                0x080703f8     0x1  Data  Gb  source_file.o [1]

它确实有效 - 变量位于正确的部分。

但是由于变量的大小,链接器已经把它整理好了。

有没有办法告诉链接器不要更改变量的顺序,以便它们在映射文件中出现的顺序与它们在源文件中声明的顺序相同?

目标是:

testArray8              0x08070000     0x1  Data  Gb  source_file.o [1]
testArray512            0x08070001   0x200  Data  Gb  source_file.o [1]
testVar32               0x08070201     0x4  Data  Gb  source_file.o [1]
testVar500              0x08070205   0x1f4  Data  Gb  source_file.o [1]

【问题讨论】:

使用struct不是更简单吗? @KamilCuk,不幸的是,一点也不。该文件将在项目外部生成,因此其外观是固定的。它由字符串组成:“类型名称 initial_value”。如果使用 struct,则 initial_values 应与声明分开设置。 C 编译器和链接器可以随意排序。您可能会了解您的工作方式,并尝试强制执行特定命令。但是,C 标准只为structs 定义了一个序列。 -- 链接器非常聪明地首先放置最大的对象以找到一些好的解决方案。它可能有也可能没有改变这种行为的选项。你读过它的所有手册吗?你问过 IAR 是谁提供了这个工具吗? @thebusybee,谢谢你的回答!是的,我浏览了完整的官方 IAR 指南 pdf 并没有找到合适的解决方案。我也会尝试从 IAR 支持人员那里得到答案,但如果我能在这里找到快速的解决方案或建议,那就太完美了:) 好吧,我没有真正回答,只是给出了提示。 ;-) 但是,如果手册没有显示任何选项,恐怕没有。你可能想回退到汇编程序来获得你想要的东西。 【参考方案1】:

有没有办法告诉链接器不要更改变量的顺序,以便它们在映射文件中出现的顺序与它们在源文件中声明的顺序相同?

我不知道有一个 选项 会强制链接器尊重源文件中的变量顺序。 但是有一种方法可以使用链接器配置文件中的block 指令来实现您的目标。

IAR C/C++ Development Guide 状态为 place in 指令:

place in 指令将部分和块放置在特定区域中。 部分和块将以任意顺序放置在该区域中。 要指定特定顺序,请使用block 指令。

因此,在源文件中,每个变量都需要进入一个单独的部分:

const U8       testVar8          @ test_data_1 = 0;
const U8       testArray512[512] @ test_data_2;
const uint32_t testVar32         @ test_data_3 = 0x1234ABCD;
const U8       testArray500[500] @ test_data_4;

在链接器配置文件中,我们按所需顺序添加带有test_data_* 部分的block 定义,并将其放在目标区域的开头:

define symbol __ICFEDIT_region_APP_ROM_start__  = 0x08070000 ;
define symbol __ICFEDIT_region_APP_ROM_end__    = 0x0807FFFF;

define region APP_ROM_region   = mem:[from __ICFEDIT_region_APP_ROM_start__   to __ICFEDIT_region_APP_ROM_end__];

define block TEST_DATA with fixed order  
  readonly section test_data_1,
  readonly section test_data_2,
  readonly section test_data_3,
  readonly section test_data_4
;

place at start of APP_ROM_region  block TEST_DATA ;

【讨论】:

以上是关于如何在 IAR 编译器中按特定顺序放置变量?的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 IAR ARM 编译器将函数表强制到特定地址

stm32项目到IAR

如何在 Kubernetes 中按特定顺序配置 Pod 初始化?

IAR 为自定义数据定义内存区域

如何使用 ARM 的 IAR 编译器编译 Google Test

如何配置 Visual Studio Code 以使用 IAR 编译器构建项目?