gpt4 book ai didi

c - 使用 IAR EWARM 手动将 .data 部分从闪存复制到 RAM

转载 作者:行者123 更新时间:2023-12-02 07:40:43 29 4
gpt4 key购买 nike

我为 Kinetis K24 Cortex M4 编写了一个引导加载程序。引导加载程序在运行时通过 USB 将附加功能加载到 RAM 中。该 ramcode 作为其自己的 EWARM 项目存在,生成二进制文件。该二进制文件的入口点必须始终为 0x20000000, vector 表必须始终位于 0x20007000,以便与我的 .NET 工具完美配合。 IAR 启动代码处理 .bss 和 .data 副本的清除,但它也做了一些我不想要的其他事情。我不知道如何强制 IAR 入口点到特定地址,所以我创建了自己的入口点,如下所示

#pragma section=".bss"

#pragma location=".init"
__interwork int __low_level_init(void)
{
char * from = __section_begin(".bss");
char * to = __section_end(".bss");

__DI(); // Disable interrupts

memset(from, 0x00 , (to - from));

memcpy(__vector_table, (unsigned char *)ROM_VECTOR_LOCATION, VECTOR_TABLE_SIZE);

SCB_VTOR = (unsigned int) & __vector_table;

main();

SCB_VTOR = (uint32_t)ROM_VECTOR_LOCATION;
}

当我调试代码时,我可以看到初始化为非零值的全局变量采用随机值。我相信这是因为我没有将 .data 部分从 LMA 复制到 VMA。

我的问题是如何将 .data 部分的副本从 LMA 复制到 VMA?

如果我能弄清楚如何分解它,但入口点不能是重置 vector ,我也会选择使用 IAR 启动代码。入口点必须是 0x20000000, vector 表必须位于 0x20007000

最佳答案

处理 .data 节副本的 IAR 函数称为 __iar_data_init3()。我曾考虑过直接调用它,但不敢相信它这么简单。 IAR 建议这是正确的解决方案。我还使用关键字 __root 来防止编译器删除我的“未使用”函数。这使我能够将其重命名为更合适的名称,例如startup()。调用它 __low_level_init() 只是一个防止编译器删除它的 hack。 __low_level_init() 不是作为启动序列的一部分调用的,而是作为我在引导加载程序中加载程序计数器的入口点调用的。这是我的最终解决方案

#pragma section=".bss"
#pragma location=".init"
__root void startup()
{
char * from = __section_begin(".bss");
char * to = __section_end(".bss");

memset(from, 0x00 , (to - from));

__iar_data_init3();

memcpy(__vector_table, (unsigned char *)ROM_VECTOR_LOCATION, VECTOR_TABLE_SIZE);

__DI(); // Disable interrupts

SCB_VTOR = (unsigned int) & __vector_table;

main();

SCB_VTOR = (uint32_t)ROM_VECTOR_LOCATION;

}

还有一个名为 __iar_zero_init3() 的函数可以处理 .bss 的归零,但是在第一次尝试时它导致我的程序崩溃。我无法想象需要做很多工作才能使其正常工作。

关于c - 使用 IAR EWARM 手动将 .data 部分从闪存复制到 RAM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48425861/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com