您好!
内存分配显示通过6个 pragma 语句将闪存函数的一部分移动到 RAM 后、编译的工程低于1兆字节。 但是、编译后的 bin 文件增加到了512MB、最初为106KB、而未通过#pragma 将函数从闪存移动到 RAM。 为什么*。out 文件大小934KB 相对较小、为什么内存 分配工具显示的 bin 文件大小要小得多?

This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
您好!
内存分配显示通过6个 pragma 语句将闪存函数的一部分移动到 RAM 后、编译的工程低于1兆字节。 但是、编译后的 bin 文件增加到了512MB、最初为106KB、而未通过#pragma 将函数从闪存移动到 RAM。 为什么*。out 文件大小934KB 相对较小、为什么内存 分配工具显示的 bin 文件大小要小得多?

尊敬的乔治:
为什么您没有回答这些问题或其中的任何部分?
我不需要介绍二进制文件。 该项目是相同的、只有部分器件通过#pragma 从闪存移至 RAM。 CPU 和堆栈指针应处理入栈/出栈跳转和调用 far 的返回地址。 在我看来、IP 比调用更容易、只需移动到不同的存储器地址。 这是 CPU 的函数、用于通过调用栈和 IP 来了解程序的一部分在存储器中的位置。 C2000 CPU 上没有创建的所有 ARM trampoline 是什么?
内存分配工具仅在 hex2bin.exe 运行后才不同意已编译的 bin 文件大小、该文件大小从106KB 增加到524MB。 其他情况出错了、没有警告这些段是 C2000编译器生成的无效 trampoline。 此外、添加了链接器命令--minimize_trampoline 无效、在以黑色文本添加的每个新段中都有50个或更多内容。 如映射文件中所示、一些空穴是可以接受的。
然而、闪存和 RAM 中的应用程序的大小与输出 bin 文件的大小完全不同。 只有在编译完成且没有错误的情况下、并且为闪存加载创建了 hex2bin.exe 后、内存分配工具才会反映编译。
请注意、甚至添加了一个 pragma (ISR 函数) bin 文件 、该文件的大小会增加到 524MB、其他段会返回到闪存。

我阅读了这篇文章、但它并未解决添加308字节单个 pragma 后的500兆字节空洞问题。 编译器似乎为单次 Far 调用添加了数千个字节、对于308字节 pragma 的每个8字节 trampoline、似乎都是这样。
您认为3个 trampoline (每个8字节)在二进制文件输出中可以等于500 MB 吗? 我们无法查看500MB 二进制文件、因为它会冻结十六进制查看工具。
是的。 该示例中有一个孔洞。 发生这种情况的原因是已初始化段之间的存储器中存在间隙。 您的空穴发生的原因相同。 这是二进制文件中可能出现空洞的唯一原因。 孔要大得多、因为已初始化段之间的存储器距离要大得多。 本文还讨论了如何避免此类漏洞。
谢谢、此致、
乔治
奇怪的是、当 CMD 文件末尾放置了其他 pragma 定义时、C2000没有此类问题。 移动 RAM 定义的其他部分上方的 ARM pragma 部分并不会阻止巨大的孔洞的形成。 另一个段定义与闪存相关。 为什么有人会考虑将 RAM pragma 移动到闪存写入固件的闪存部分上方?
BTW:引用的(*。out)文章文件大小不是 MkHex4Bin.exe 文件大小。 奇怪的是、最小尺寸的 pragma 始终显示在最大到最小尺寸 RAM 模块的内存分配末尾。 .out 文件仍然相当小、930KB。 编译器和链接器不会解析 --gap-fill 指令。
在 TM4C1294KCPDT 上、闪存从地址0开始、RAM 从地址0x20000000 (512MB)开始。 使用#pragma 将函数的加载地址设置为 RAM 会导致二进制文件变为512MB、因为二进制文件格式在地址范围内不能有空洞。
使用#pragma 将函数的加载地址设置为 RAM 的另一个问题是、在器件复位/下电上电时、没有机制将函数加载到 RAM 中。 因此、此类程序只能从 CCS 调试器运行。
要将函数放置在 RAM 中、请使用 TI ARM 编译器、而是在 源代码中的函数上使用__attribute (((ramfunc))。 例如:
__attribute ((ramfunc)) void UARTIntHandler(void)
在链接器命令文件中、声明 .binit 和 .TI.ramfunc 段。 例如:
/* Section allocation in memory */
SECTIONS
{
.intvecs: > APP_BASE
.text : > FLASH
.const : > FLASH
.cinit : > FLASH
.pinit : > FLASH
.init_array : > FLASH
.binit > FLASH
.vtable : > RAM_BASE
.data : > SRAM
.bss : > SRAM
.sysmem : > SRAM
.stack : > SRAM
#ifdef __TI_COMPILER_VERSION__
#if __TI_COMPILER_VERSION__ >= 15009000
.TI.ramfunc : {} load=FLASH, run=SRAM, table(BINIT)
#endif
#endif
}
这会导致运行时启动代码将函数从闪存中的加载地址复制到 SRAM 中的运行地址、而不会导致二进制文件变为512MB。
切斯特、您好!
我有多个 pragma 要加载到 RAM 地址中并将大量配置函数保留在闪存中。 ARM 编译器应该在 CMD 文件中处理适当的 pragma 段而不添加孔洞、因为没有包含此 conundrum 的文本。 C2000编译器可让我们了解 CMD 文件是否已使用 trampoline 创建段。
默认的 TM4C1294项目 CMD 文件在范围内非常通用、引导加载程序应用程序加载到闪存中、从0x4000开始甚至更高。 添加.binit > FLASH 可能有助于从各种函数加载多个 pragma。 引导加载程序会复制到 RAM 中指向闪存矢量表或沿这些行的内容、即使它有自己的矢量表。 这可能是*。bin 文件变得如此大的原因。
应用程序(main.c)应添加 mcopy()作为将.TI.ramfunc code_section 从闪存复制到 RAM。 ARM 编译器似乎应该在复制#pragma 函数后添加 pragma 偏移地址。 忘记添加 mcopy()命令,可能会导致内存大漏洞。
C2000 mcopy()、pragma 和 CMD 文件部分:
#include
device.h:
extern uint16_t RamfuncsLoadStart;
extern uint16_t RamfuncsLoadEnd;
extern uint16_t RamfuncsLoadSize;
extern uint16_t RamfuncsRunStart;
extern uint16_t RamfuncsRunEnd;
extern uint16_t RamfuncsRunSize;
// RamfuncsLoadStart、RamfuncsLoadSize 和 RamfuncsRunStart 符号
//由链接器创建。 请参阅 device.h CMD 文件。
memcpy (&RamfuncsRunStart、&RamfuncsLoadStart、(size_t)&RamfuncsLoadSize);
存储器
{
第0页:
RAMLS0_1 :origin = 0x008000、length = 0x001000 //4096KB
RAMLS2_3 :origin = 0x009100,length = 0x000F00 //4096KB -16个字,勘误建议读取内存组末尾会导致 CRC 错误。
}
#pragma CODE_SECTION (myISR、".TI.ramfunc")
部分{
codestart:>开始,align (4)
//仅需要第一个 pragma 的 RAM 地址位置、所有其他(DATA_SECTION) pragma 具有如下所示的简单段
.TI.ramfunc:load = FLASHB0_SA,
运行= RAMLS2_3、// RAM 组
Load_start (RamfuncsLoadStart)、
load_size (RamfuncsLoadSize)、
Load_End (RamfuncsLoadEnd)、
RUN_START (RamfuncsRunStart)、
run_size (RamfuncsRunSize)、
RUN_END (RamfuncsRunEnd)、
对齐(4)
}
置于函数上方:#pragma DATA_SECTION (MyParams、".params.ramdata");
部分{
params.ramdata:> RAMLS0_1 //将存储器定义为闪存页0或1
myvars.ramdata :> RAMLS0_1
}
我在第0页创建了更复杂的 tm4c1294 CMD 文件、其中包含4个 SRAM 65KB 段(262KB)。 与上述 C2000 CMD 文件语法类似、mcopy()放置位置为3、而 SRAM_0默认为:.bss、.stack、.vtable、.data 定义。 没有机会加载该文件、但在 main.c 断言 mcopy()命令后*。bin 文件大小为107KB。 请注意、闪存会在 mcopy()之后将3个 pragma 段保留到 C2000项目中也需要的 RAM 中。
