IAR初始化函数放置

时间:2012-12-07 02:27:42

标签: embedded iar

有人知道如何处理以下问题:
我有一个IAR Embedded工作台。该项目正在使用SDRAM运行它的代码和Flash ROM。 SDRAM的代码是从SD卡加载的。但是,在SDRAM中还存储了一些数据,如全局变量或静态变量。其中一些必须初始化。初始化步骤iar_data_init3函数调用在low_level_init函数之后。所以问题是,对于SDRAM中某些变量的初始化,初始化函数是从iar_data_init3调用的,其代码在SDRAM本身内部。这是错误的,因为尚未完成从SD卡加载SDRAM代码。

我已尝试按照C / C ++开发指南中的描述进行手动初始化,但这没有帮助。

调用的函数是__sti__routine,它提供变量的初始化。所有这些功能都是由IAR生成的。有没有办法告诉链接器将初始化函数放到Flash 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中。)

1 个答案:

答案 0 :(得分:4)

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

您没有提到您正在使用的IAR的特定风味。以下内容来自Renesas IAR Compiler Reference Guide,但您应该查看正确的参考指南,以确保语法完全相同,并了解预定义的部分。

  

使用@运算符或#pragma位置指令进行放置   命名段中的函数组或全局和静态变量,   没有明确控制每个对象。变量必须是   声明为__no_initconst。细分可以,为   例如,放置在特定的内存区域,或初始化或   使用段开始和结束运算符以受控方式复制。   如果您需要单独的接口,这也很有用   链接单元,例如应用程序项目和引导加载程序   项目。在对展示位置进行绝对控制时使用命名细分   个别变量不需要或无用。

     

在命名段中放置函数的示例

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 };

实际的名称,地址和大小会有所不同,但看起来应该相似。我只使用datasheet中前两个动态内存区域的全部大小。这里发生的是你为不同类型的内存(即SD卡和SDRAM)分配地址空间的名称,以便编译期间命名的部分将被链接器放置在正确的位置。

首先,您必须使用define memory定义地址空间:

  

可能的可寻址存储器的最大尺寸

     

define memory指令定义了给定大小的内存空间,   这是可寻址内存的最大可能量,而不是   必然是物理上可用的。

然后告诉它哪些芯片与define region

一起去哪里
  

可用物理内存

     

define region指令定义可用内存中的区域   其中应用程序代码和部分的特定部分   可以放置申请数据。

接下来,链接器需要知道将regionsection放在一起的place in

  

在区域中放置部分

     

place atplace into指令放置了多个部分   类似的属性到先前定义的区域。

告诉链接器你要用initialize manually覆盖它的部分初始化:

  

初始化应用程序

     

指令initializedo 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选项并研究日志和地图文件,以确保获得所需内容。