embedded - IAR 初始化函数放置

标签 embedded iar

有谁知道如何处理以下问题:
我有一个 IAR 嵌入式工作台。该项目也使用 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:
以下是 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 中)。

最佳答案

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

你没有提到你正在使用的 IAR 的具体风格。以下来自Renesas IAR Compiler Reference Guide但是您应该检查正确的引用指南以确保语法完全相同并了解预定义的部分是什么。

Use the @ operator or the #pragma location directive to place groups of functions or global and static variables in named segments, without having explicit control of each object. The variables must be declared either __no_init or const. The segments can, for example, be placed in specific areas of memory, or initialized or copied in controlled ways using the segment begin and end operators. This is also useful if you want an interface between separately linked units, for example an application project and a boot loader project. Use named segments when absolute control over the placement of individual variables is not needed, or not useful.

Examples of placing functions in named segments

void f(void) @ "FUNCTIONS";

void g(void) @ "FUNCTIONS"
{
}

#pragma location="FUNCTIONS"
void h(void);

To override the default segment allocation, you can explicitly specify a memory attribute other than the default:

__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 定义地址空间:

The maximum size of possible addressable memories

The define memory directive defines a memory space with a given size, which is the maximum possible amount of addressable memory, not necessarily physically available.



然后告诉它哪些芯片去哪里define region :

Available physical memory

The define region directive defines a region in the available memories in which specific sections of application code and sections of application data can be placed.



接下来链接器需要知道在什么 region放置命名 sectionplace in :

Placing sections in regions

The place at and place into directives place sets of sections with similar attributes into previously defined regions.



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

Initializing the application

The directives initialize and do not initialize control how the application should be started. With these directives, the application can initialize global symbols at startup, and copy pieces of code.



最后,在您的 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选项并研究日志和 map 文件以确保您获得所需的内容。

关于embedded - IAR 初始化函数放置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13756058/

相关文章:

c - C 中不允许使用类型名称

c++ - 使用虚函数调用时节省堆栈空间

embedded - fatal error ST-Link 未找到 MCU 设备

c - GCC -D 相当于 iarbuild.exe

filesystems - 如何使用 SD 卡以 48 ksamples/s 的速度记录 16 位数据?

c++ - 在 Windows CE 5 中的可见应用程序之间切换,Lang : C++

gcc - 如何从 C 代码引用段开头和大小

c - 在结构中使用 typedef 枚举并避免类型混合警告

c - 将外部静态库的段放置到特定位置