首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IAR初始化器函数放置

IAR初始化器函数放置
EN

Stack Overflow用户
提问于 2012-12-07 02:27:41
回答 1查看 16.7K关注 0票数 4

有人知道如何处理以下问题吗?

我有一个IAR嵌入式工作台。这个项目使用SDRAM来运行它的代码和Flash。SDRAM的代码是从SD卡加载的。但是,SDRAM中也存储了一些数据,比如全局变量或静态变量。其中一些必须初始化。初始化步骤iar_data_init3函数调用在low_level_init函数之后。因此问题在于,对于SDRAM中某些变量的初始化,初始化程序函数是从iar_data_init3调用的,其代码位于SDRAM本身内。这是错误的,因为SDRAM代码从SD卡还没有完成。

我尝试了C/C++开发指南中描述的手动初始化,但这并没有帮助。

调用的函数是__sti__routine,它提供变量的初始化。所有这些函数都是由IAR生成的。有什么方法可以告诉链接器将初始化函数放到Flash中?

编辑1:这里是C/C++的IAR手册中的信息。这是如何使用手动初始化的一个示例。

在链接器配置文件中:

代码语言:javascript
复制
initialize manually { section MYSECTION };

然后IAR文件说:

可以使用此源代码示例初始化该节:

代码语言:javascript
复制
#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有什么区别?另外,如果我有一个全局变量:

代码语言:javascript
复制
SomeClass myclass;

它应该放在SDRAM中,那么初始化是如何完成的呢?我想手动初始化变量,并将初始化函数放置到闪存ROM中。(问题是,通过将变量放入SDRAM,它的初始化功能也被放置到SDRAM中)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-12-07 12:47:35

您可以通过使用pragma预处理指令来指定变量和函数的位置。您需要使用预定义的部分之一或定义您自己的部分。

你没有提到你正在使用的IAR的特殊味道。下面的内容来自Renesas编译器参考指南,但是您应该检查正确的参考指南,以确保语法完全相同,并了解预定义的部分是什么。

使用@运算符或#pragma位置指令将函数组或全局变量和静态变量放置在命名段中,而无需对每个对象进行显式控制。变量必须声明为__no_initconst。例如,段可以放置在特定的内存区域,也可以使用段开始和结束操作符以受控的方式初始化或复制。如果您希望在单独链接的单元(例如,应用程序项目和引导加载程序项目)之间建立接口,这也很有用。如果不需要对单个变量的位置进行绝对控制,或者没有用,请使用命名段。 在命名段中放置函数的示例 void ( void )@ "FUNCTIONS";void (Void)@ "FUNCTIONS“{}#实用主义location=函数”void(Void)“; 若要覆盖默认段分配,可以显式指定一个内存属性,而不是默认的: __code32 void (Void)@“函数”;

编辑

根据您的注释,您应该有一个名为generic_cortex.icf的链接器文件,它定义了您的内存区域。其中应该有一些类似于以下内容的说明:

代码语言:javascript
复制
/* 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中使用place in来放置命名的section

在各区域放置各节 place atplace into指令将具有相似属性的部分集合放置到以前定义的区域中。

并告诉链接器您想要用initialize manually覆盖它的部分初始化

初始化应用程序 initializedo not initialize指令控制应用程序的启动方式。使用这些指令,应用程序可以在启动时初始化全局符号,并复制代码片段。

最后,在您的C文件中,告诉编译器哪些部分属于哪些部分,以及如何初始化声明为manually的部分。

代码语言:javascript
复制
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();
}

为了自定义多个不同内存设备之间的启动初始化,您需要非常仔细地研究ARM发展指南。同时,试着打开--log initialization选项,研究日志和地图文件,以确保您得到了所需的东西。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13756058

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档