Embedded IAR初始值设定项函数布局
有人知道如何处理以下问题吗:Embedded IAR初始值设定项函数布局,embedded,iar,Embedded,Iar,有人知道如何处理以下问题吗: 我有一个IAR嵌入式工作台。该项目正在使用SDRAM来运行其代码和闪存ROM。SDRAM的代码是从SD卡加载的。然而,在SDRAM中也存储了一些数据,比如全局变量或静态变量。其中一些必须初始化。初始化步骤,即iar_data_init3函数调用,在low_level_init函数之后进行。因此,问题在于,对于SDRAM中某些变量的初始化,初始化函数是从iar\u data\u init3调用的,其代码在SDRAM本身内部。这是错误的,因为从SD卡加载SDRAM代码尚
我有一个IAR嵌入式工作台。该项目正在使用SDRAM来运行其代码和闪存ROM。SDRAM的代码是从SD卡加载的。然而,在SDRAM中也存储了一些数据,比如全局变量或静态变量。其中一些必须初始化。初始化步骤,即
iar_data_init3
函数调用,在low_level_init
函数之后进行。因此,问题在于,对于SDRAM中某些变量的初始化,初始化函数是从iar\u data\u init3
调用的,其代码在SDRAM本身内部。这是错误的,因为从SD卡加载SDRAM代码尚未完成
我曾尝试过C/C++开发指南中描述的手动初始化,但没有帮助
调用的函数是\uu sti\uu例程
,它提供变量的初始化。所有这些函数都是由IAR生成的。有没有办法告诉链接器将初始化器函数放入闪存ROM
编辑1:
以下是IAR C/C++手册中的信息。
这是一个如何使用手动初始化的示例
在链接器配置文件中:
initialize manually { section MYSECTION };
然后IAR文件说明:
您可以使用此源代码示例初始化该节:
#pragma section = "MYSECTION"
#pragma section = "MYSECTION_init"
void DoInit()
{
char * from = __section_begin("MYSECTION_init");
char * to = __section_begin("MYSECTION");
memcpy(to, from, __section_size("MYSECTION"));
}
但我不明白,首先,
两者的区别是什么
MYSECTION_init和MYSECTION。
同样,如果我有一个全局变量:
SomeClass myclass;
它应该放在SDRAM中,
那么如何对其进行初始化呢?我想手动初始化变量,
并将初始化函数放在闪存ROM中。(问题是,通过将变量放在SDRAM中,它的初始化函数也放在SDRAM中)。您可以通过使用预处理器指令指定变量和函数的位置。您需要使用其中一个预定义的部分或定义自己的部分 你没有提到你正在使用的IAR的具体味道。以下内容来自,但您应该检查适当的参考指南,以确保语法完全相同,并了解预定义的部分是什么 使用
@
运算符或#pragma
位置指令放置
命名段中的函数组或全局和静态变量,
没有对每个对象的显式控制。变量必须是
声明了\uu no\u init
或const
。这些片段可以,例如
例如,可以放置在内存的特定区域,或者初始化或
使用段开始和结束操作符以受控方式复制。
如果您希望在两个应用程序之间建立接口,这也很有用
链接单元,例如应用程序项目和引导加载程序
项目在绝对控制放置时使用命名线段
不需要或不有用的单个变量
在命名段中放置函数的示例
要覆盖默认的段分配,可以显式指定
默认值以外的内存属性:
__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 region
指令定义可用内存中的一个区域
应用程序代码的特定部分和
可以放置应用程序数据
接下来,链接器需要知道在哪个区域
中放置带的命名部分
:
在区域中放置截面
放置在
和放置到
指令放置具有
将类似属性转换为以前定义的区域
并告诉链接器您想用手动初始化覆盖部分初始化:
初始化应用程序
指令初始化
和不初始化
控制
应该启动应用程序。有了这些指令,应用程序
可以在启动时初始化全局符号,并复制代码片段
最后,在您的C文件中,告诉编译器什么进入了哪些节,以及如何初始化手动声明的节
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();
}
为了在多个不同的内存设备之间自定义启动初始化,您需要非常仔细地研究。还可以尝试打开--log initialization
选项并研究日志和映射文件,以确保您得到了所需的内容。在上面的示例中,您正在处理函数,但是如果有需要在开始时初始化的变量,则可以使用上面的方法将变量放置到某个位置,但是初始化这些变量的函数呢?我想控制初始化函数的位置。@maximus我举的例子是专门针对函数的,因为这就是你在问题中所问的。
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();
}