如何访问外部 SDRAM 中的变量

How to access variables in external SDRAM

我正在研究 TM4C1294 + ccs 6.0.1 + TI 5.1.9(编译器)。

Reading/Writing 8MB 外部 sdram 中的变量工作正常,例如 g_pui16EPISdram = (uint16_t *)0x60000000; g_pui16EPISdram[SDRAM_END_ADDRESS ] = 0xdcba; 但是,当我使用 "attribute directive" 访问外部 sdram 时,如下所示:int abab[20]__attribute__ ((section (".external")));,程序甚至没有执行。

".external" 定义为 .cmd :

SDRAM (RWX) : origin = 0x60000000, length = 0x00800000

SECTIONS
{
    .intvecs:   > APP_BASE
    .text   :   > FLASH
    .const  :   > FLASH
    .cinit  :   > FLASH
    .pinit  :   > FLASH
    .init_array : > FLASH

    .vtable :   > RAM_BASE
    .data   :   > SRAM
    .bss    :   > SRAM
    .sysmem :   > SRAM
    .stack  :   > SRAM
    .external : > SDRAM
}

这是我的 .map:

SEGMENT ALLOCATION MAP 60000000 60000000 00000050 00000000 rw- 60000000 60000000 00000050 00000000 rw- .external

全局符号:按名称字母顺序排序 address name -------- ----

60000000 abab

在我的项目中,一些 "structs" 需要是 extern 变量,在一个 .h 中声明并在一个 .c 中定义;但是,对于测试我只是简单地使用了int abab[]。 我已经尝试在 "attribute directive" 之前测试 with/without "extern",简而言之,两者都没有用。

如何access/use 外部变量存储在外部 sdram 中?

首先,我认为对使用external存储介质存储read/write数据和extern的用法存在误解 C 编程语言中的关键字。

这里有一个简单的解释:

1) 根据您的代码,您所做的只是设置SDRAM 模块的起始g_pui16EPISdram = (uint16_t *)0x60000000 和结束g_pui16EPISdram[SDRAM_END_ADDRESS ] = 0xdcba 地址以供微处理器使用的内存映射。正如您在 SECTIONS 块中看到的那样,.data.bss .sysmem.stackSRAM (Static RAM) 中定义。因此,如果您尝试将微控制器显然需要执行的所需数据移动(或指向)到外部介质,它甚至不会被执行。因为,微控制器不知道在哪里找到它并执行它。这有点像将 USB 记忆棒插入 PC 并期望在没有适当的 BIOS 设置的情况下从它启动。由于 BIOS 不知道 bootstrap 代码在哪里,PC 将无法从该介质启动。要执行的目标二进制地址必须为处理器所知。在您的情况下,它与 extern 关键字无关。您可能只想将程序数据(例如 int abab[20] 数组)移动到代码中的 SDRAM 部分,并使您的程序在执行时安全地到达该外部内存区域微控制器。

2) extern 关键字用于声明外部变量,这些外部变量在 C 编程语言中定义的文件以外的文件中可见。此修饰符可用于所有数据类型,如 charshortintlongfloatdoublearrays, pointers, structures, functions 等。基本上,这个关键字通知变量或函数具有外部链接的编译器,并在所有传入的源文件中搜索该数据结构。这也是告诉编译器 "There is a variable or function declared in somewhere and you, compiler, should know this! (actually, linker does the dirty job and you say to compiler that let the linker find it!)" . 打个比方,extern 可以被认为与 static 关键字相反的另一种方式.

首先,你要放入SDRAM的变量应该是静态分配的,一般是全局变量。

然后在你的源文件中,声明为

#pragma DATA_SECTION(abab, ".abab_sect")
int abab[20];

然后,如果您将 -m 添加到您的链接器选项,将生成一个 .map 文件并向您显示 abab 符号被放置在 .abab_sect 部分中,该部分被分配在默认内存中 space,可能在 SRAM 中。

然后在你的cmd文件中,添加

SECTIONS
{
    ...
    ...
    .abab_sect : > SDRAM 
}

移动到 SDRAM

问题已解决。 EPI set-upboot routine 中需要用于 SDRAM,因为启动例程会在调用 main() 之前尝试初始化全局变量。 #pragmaattribute 指令与使用外部 sdram 无关。

感谢您对我的问题发表评论。