如何访问外部SDRAM中的变量
我正在研究TM4C1294 + ccs 6.0.1 + TI 5.1.9(编译器)。
在8MB外部sdram中读/写变量工作正常,例如g_pui16EPISdram = (uint16_t *)0x60000000;
g_pui16EPISdram[SDRAM_END_ADDRESS ] = 0xdcba;
但是,因为我使用“属性指令”来访问外部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
在我的项目中,一些需要为extern
变量的“结构”在一个.h
中声明并在一个.c
定义;但是,对于测试我只是简单地使用了int abab[]
。 我试图在“属性指令”之前使用/不使用“extern”进行测试,简而言之,两者都不起作用。
如何访问/使用存储在外部sdram中的外部变量?
首先,我认为在C编程语言中使用外部存储介质读取/写入数据和使用extern关键字的概念存在误解。
这是一个简单的解释:
1)根据您的代码,您正在做的只是设置起始g_pui16EPISdram = (uint16_t *)0x60000000
并结束SDRAM模块的g_pui16EPISdram[SDRAM_END_ADDRESS ] = 0xdcba
地址以供内存映射使用,以供微处理器使用。 正如您在SECTIONS块中看到的那样, .data , .bss , .sysmem和.stack在SRAM ( 静态RAM )中定义。 因此,如果您尝试移动(或指向)微控制器执行的所需数据到外部介质,它甚至不会被执行。 因为,微控制器不知道在哪里找到它并执行它。 这类似于将USB记忆棒插入PC并期望在没有适当的BIOS设置的情况下从其启动。 由于BIOS不知道引导代码的位置,因此PC无法从该介质引导。 处理器必须知道要执行的目标二进制地址。 在您的情况下,它与extern关键字无关。 您可能只想将程序数据(例如int abab[20]
数组)移动到代码中的SDRAM部分,并使程序安全地到达外部存储器区域,由微控制器执行。
2) extern关键字用于声明从C语言中定义的文件以外的文件可见的外部变量。 此修饰符可用于所有数据类型,如char
, short
, int
, long
, float
, double
, 数组 , 指针 , 结构 , 函数等。基本上,此关键字通知编译器变量或函数具有外部链接并搜索所有传入源文件中的数据结构。 这也是另一种告诉编译器的方法“在某个地方声明了变量或函数,你,编译器,应该知道这个!(实际上,链接器执行脏工作,你说编译器让链接器找到它!) “。 作为类比, extern
可以被认为与static
关键字相反。
首先,应该静态分配要放入SDRAM的变量,通常是全局变量。
然后在源文件中将其声明为
#pragma DATA_SECTION(abab, ".abab_sect") int abab[20];
然后,如果将-m
添加到链接器选项中,将生成一个.map文件,并显示abab
符号放在.abab_sect
部分中,该部分分配在默认存储空间中,可能在SRAM中。
然后在您的cmd文件中添加
SECTIONS { ... ... .abab_sect : > SDRAM }
把它移到SDRAM
这个问题已经解决。 由于引导例程在调用main()之前尝试初始化全局变量,因此在boot routine
中需要为SDRAM EPI set-up
。 #pragma
和attribute
指令实际上不是使用外部sdram的问题。
感谢您对我的问题发表评论。