有人知道如何处理以下问题吗?
我有一个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手册中的信息。这是如何使用手动初始化的一个示例。
在链接器配置文件中:
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中)。
发布于 2012-12-07 12:47:35
您可以通过使用pragma预处理指令来指定变量和函数的位置。您需要使用预定义的部分之一或定义您自己的部分。
你没有提到你正在使用的IAR的特殊味道。下面的内容来自Renesas编译器参考指南,但是您应该检查正确的参考指南,以确保语法完全相同,并了解预定义的部分是什么。
使用
@运算符或#pragma位置指令将函数组或全局变量和静态变量放置在命名段中,而无需对每个对象进行显式控制。变量必须声明为__no_init或const。例如,段可以放置在特定的内存区域,也可以使用段开始和结束操作符以受控的方式初始化或复制。如果您希望在单独链接的单元(例如,应用程序项目和引导加载程序项目)之间建立接口,这也很有用。如果不需要对单个变量的位置进行绝对控制,或者没有用,请使用命名段。 在命名段中放置函数的示例 void ( void )@ "FUNCTIONS";void (Void)@ "FUNCTIONS“{}#实用主义location=函数”void(Void)“; 若要覆盖默认段分配,可以显式指定一个内存属性,而不是默认的: __code32 void (Void)@“函数”;
编辑
根据您的注释,您应该有一个名为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中使用place in来放置命名的section
在各区域放置各节
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();
}为了自定义多个不同内存设备之间的启动初始化,您需要非常仔细地研究ARM发展指南。同时,试着打开--log initialization选项,研究日志和地图文件,以确保您得到了所需的东西。
https://stackoverflow.com/questions/13756058
复制相似问题