如何访问外部 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 和 .stack 在 SRAM (Static RAM) 中定义。因此,如果您尝试将微控制器显然需要执行的所需数据移动(或指向)到外部介质,它甚至不会被执行。因为,微控制器不知道在哪里找到它并执行它。这有点像将 USB 记忆棒插入 PC 并期望在没有适当的 BIOS 设置的情况下从它启动。由于 BIOS 不知道 bootstrap 代码在哪里,PC 将无法从该介质启动。要执行的目标二进制地址必须为处理器所知。在您的情况下,它与 extern 关键字无关。您可能只想将程序数据(例如 int abab[20]
数组)移动到代码中的 SDRAM 部分,并使您的程序在执行时安全地到达该外部内存区域微控制器。
2) extern 关键字用于声明外部变量,这些外部变量在 C 编程语言中定义的文件以外的文件中可见。此修饰符可用于所有数据类型,如 char
、short
、int
、long
、float
、double
、arrays, 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-up
在 boot routine
中需要用于 SDRAM,因为启动例程会在调用 main() 之前尝试初始化全局变量。 #pragma
和 attribute
指令与使用外部 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 和 .stack 在 SRAM (Static RAM) 中定义。因此,如果您尝试将微控制器显然需要执行的所需数据移动(或指向)到外部介质,它甚至不会被执行。因为,微控制器不知道在哪里找到它并执行它。这有点像将 USB 记忆棒插入 PC 并期望在没有适当的 BIOS 设置的情况下从它启动。由于 BIOS 不知道 bootstrap 代码在哪里,PC 将无法从该介质启动。要执行的目标二进制地址必须为处理器所知。在您的情况下,它与 extern 关键字无关。您可能只想将程序数据(例如 int abab[20]
数组)移动到代码中的 SDRAM 部分,并使您的程序在执行时安全地到达该外部内存区域微控制器。
2) extern 关键字用于声明外部变量,这些外部变量在 C 编程语言中定义的文件以外的文件中可见。此修饰符可用于所有数据类型,如 char
、short
、int
、long
、float
、double
、arrays, 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-up
在 boot routine
中需要用于 SDRAM,因为启动例程会在调用 main() 之前尝试初始化全局变量。 #pragma
和 attribute
指令与使用外部 sdram 无关。
感谢您对我的问题发表评论。