pragma
您可以通过使用预处理器指令指定变量和函数的位置。您将需要使用任一预定义部分或定义您自己的部分。
您没有提及您正在使用的 IAR 的特定风格。以下内容来自Renesas IAR 编译器参考指南,但您应该查看正确的参考指南以确保语法完全相同并了解预定义部分是什么。
使用@
运算符或#pragma
位置指令将函数组或全局变量和静态变量放在命名段中,而无需显式控制每个对象。变量必须声明为__no_init
或const
。例如,可以将段放置在内存的特定区域中,或者使用段开始和结束运算符以受控方式进行初始化或复制。如果您想要单独链接的单元之间的接口,例如应用程序项目和引导加载程序项目,这也很有用。当不需要对单个变量的位置进行绝对控制或无用时,请使用命名段。
将函数放置在命名段中的示例
void f(void) @ "FUNCTIONS";
void g(void) @ "FUNCTIONS"
{
}
#pragma location="FUNCTIONS"
void h(void);
要覆盖默认段分配,您可以显式指定除默认值之外的内存属性:
__code32 void f(void) @ "FUNCTIONS";
编辑
根据您的评论,您应该有一个名为的链接器文件generic_cortex.icf
来定义您的内存区域。其中应该有类似于以下内容的说明:
/* Define the addressable memory */
define memory Mem with size = 4G;
/* Define a region named SDCARD with start address 0xA0000000 and to be 256 Mbytes large */
define region SDCARD = Mem:[from 0xA0000000 size 0xFFFFFFF ];
/* Define a region named SDRAM with start address 0xB0000000 and to be 256 Mbytes large */
define region SDRAM = Mem:[from 0xB0000000 size 0xFFFFFFF ];
/* Place sections named MyCardStuff in the SDCARD region */
place in SDCARD {section MyCardStuff };
/* Place sections named MyRAMStuff in the SDRAM region */
place in SDRAM {section MyRAMStuff };
/* Override default copy initialization for named section */
initialize manually { section MyRAMStuff };
实际名称、地址和大小会有所不同,但应该看起来相似。我只是使用数据表中前两个动态内存区域的完整大小。这里发生的是您为不同类型的内存(即您的 SD 卡和 SDRAM)分配名称到地址空间,以便在编译期间命名的部分将由链接器放置在正确的位置。
所以首先你必须定义地址空间define memory
:
可能的可寻址存储器的最大大小
该define memory
指令定义了具有给定大小的内存空间,这是可寻址内存的最大可能数量,不一定是物理可用的。
然后告诉它哪些芯片去哪里define region
:
可用物理内存
该define region
指令在可用存储器中定义了一个区域,其中可以放置应用程序代码的特定部分和应用程序数据的部分。
接下来,链接器需要知道region
将命名section
的内容放在什么位置place in
:
在区域中放置部分
place at
和指令将place into
具有相似属性的部分集合放入先前定义的区域中。
并告诉链接器您想要覆盖它的部分初始化initialize manually
:
初始化应用程序
指令initialize
和do not initialize
控制应用程序应该如何启动。使用这些指令,应用程序可以在启动时初始化全局符号,并复制代码片段。
最后,在您的 C 文件中,告诉编译器哪些部分包含哪些内容以及如何初始化声明的部分manually
。
SomeClass myClass @ "MyCardStuff";
#pragma section = "MyCardStuff"
#pragma section = "MySDRAMStuff"
void DoInit()
{
/* Copy your code and variables from your SD Card into SDRAM */
char * from = __section_begin("MyCardStuff");
char * to = __section_begin("MySDRAMStuff");
memcpy(to, from, __section_size("MySDRAMStuff"));
/* Initialize your variables */
myClass.init();
}
为了在多个不同的内存设备之间自定义启动初始化,您需要非常仔细地学习IAR Development Guide for ARM 。还可以尝试打开该--log initialization
选项并研究日志和地图文件,以确保您得到您想要的。