如何把变量或者数组ios定义全局变量 数组到SDRAM及任意位置

21ic官方微信-->
后使用快捷导航没有帐号?
查看: 2910|回复: 3
ADS1.2如何把数组定义在外部SDRAM某特定位置开始处?
&&已结帖(0)
主题帖子积分
主题帖子积分
专家等级:结帖率:3%
主题帖子积分
例如想把&CHAR&XX[1056]定义在外部SDRAM&&0x开始处。让编译器知道,不会产生覆盖问题!
主题帖子积分
资深技术员, 积分 458, 距离下一级还需 42 积分
资深技术员, 积分 458, 距离下一级还需 42 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
资深技术员, 积分 458, 距离下一级还需 42 积分
资深技术员, 积分 458, 距离下一级还需 42 积分
使用scatter loading技术可以搞定这个问题
建议LZ看一下分散加载相关的书籍。
主题帖子积分
主题帖子积分
专家等级:结帖率:3%
主题帖子积分
在KEIL ARM
RAV下这样,告诉要在SCT文件修改!?
char&this_main_arry[1056]&__at(0x);K1.axf:&Error:&L6985E:&Unable&to&automatically&place&AT&section&.ARM.__AT_0x&from&main.o&with&required&base&address&0x.&Please&manually&place&in&the&scatter&file&using&the&--no_autoat&option.&SCT文件;&*************************************************************;&***&Scatter-Loading&Description&File&generated&by&uVision&***;&*************************************************************LR_ROM1&0x&&&&&&&&&{&&&&;&load&region&&ER_ROM1&0xx&&{&&;&load&address&=&execution&address&&&*.o&(RESET,&+First)&&&*(InRoot$$Sections)&&&.ANY&(+RO)&&}&&RW_RAM1&0xx&&{&&;&RW&data&&&.ANY&(+RW&+ZI)&&}&&RW_IRAM1&0xx&&{&&&.ANY&(+RW&+ZI)&&}}
主题帖子积分
主题帖子积分
专家等级:结帖率:3%
主题帖子积分
还是KEIL ARM,IAR也好方便!
&&.ARM.__AT_0x&&&&&&&&&&&&&&&&&&&&&0x&&&Section&&&&&1056&&main.o(.ARM.__AT_0x)&&&this_main_arry&&&&&&&&&&&&&&&&&&&&&&&&&&&0x&&&Data&&&&&&&&1056&&main.o(.ARM.__AT_0x)
热门推荐 /2#pragma section(&sdram_bank1&)
---here your vari or func----
注意,只有紧跟后面的一行有效
[通过 QQ、MSN 分享给朋友]
欢迎访问 TI 热门产品应用指南嵌入式软件(11)
一 基础知识
半字&&16位
字&&&&32位
Code, RO-data,RW-data,ZI-data
Code为程序代码部分
RO-data 表示 程序定义的常量
RW-data 表示 已初始化的全局变量
ZI-data 表示 未初始化的全局变量
Program Size: Code=&18248& RO-data=320 RW-data=260 ZI-data=3952
Code, RO-data,RW-data ............flash
RW-data, ZIdata...................RAM
三 详细分析
初始化时RW-data从flash拷贝到RAM
生成的map文件位于list文件夹下 (KEIL)
&&&&Total RO&&Size (Code + RO Data)&&&&&&&&&&&&&&&&18568 (&&18.13kB)
&&&&Total RW&&Size (RW Data + ZI Data)&&&&&&&&&&&&&&4212 (&&&4.11kB)
&&&&Total ROM Size (Code + RO Data + RW Data)&&&&&&18828 (&&18.39kB)
ARM指令的长度刚好是1个字(分配为占用4个字节),Thumb指令的长度刚好是半字(占用2个字节)
R0-R15 (R15-PC,R14-LR,R13-SP) 32位
每个异常模式还带有一个程序状态保存寄存器 (SPSR),它用于保存在异常事件发生之前的CPSR
LDMIA R1!,{R2-R7, R12} ;将R1单兀中的数据读出到R2-R7,R12,&&R1自动加1
STMIA RO!,{R3-R6,R10}&&;将R3-R6,R10中的数据保存到RO指向的地址,RO自动加1
在数据传送之前,将偏移量加到Rn中,其结果作为传送数据的存储地址.若使用后缀“!”,则结果写回到Rn中,且Rn值不允许为R15.指令举例如下:
LDR&&&Rd, [Rn, #Ox4]!
LDMFD&&SP!,{R0-R3,PC}^ ;中断返回
“^”符号表示这是一条特殊形式的指令。这条指令在从存储器中装载PC的同时(PC是最后恢复的),CPSR也得到恢复
大端格式(Big-endian)
小端格式(Little-endian)
数据0x存储格式
&&&&&&大端格式
低地址&----0x12|0x34|0x56|0x78----&高地址
&&&&&&小端格式
低地址&----0x78|0x56|0x34|0x12----&高地址
ARM微处理器支持7种运行模式,分别为: CPSR M[4:0]
1.用户模式(usr):ARM处理器正常的程序执行状态。&&&&&&&10000
2.快速中断模式(fiq):用于高速数据传输或通道处理。&&&&10001
3.外部中断模式(irq):用于通用的中断处理。&&&&&&&&&&&&10010
4.管理模式(svc):操作系统使用的保护模式。&&&&&&&&&&&&10011
5.数据访问终止模式(abt):当数据或指令预取终止时进入该模式,可用于虚拟存储及存储保护。10111
6.系统模式(sys):运行具有特权的操作系统任务。&&&&&&&&11111
7.定义指令中止模式(und):当未定义的指令执行时进入该模式,可用于支持硬件协处理器的软件仿真。 11011
ARM正常工作一般工作在用户模式和系统模式,复位的时候进入管理模式。
对于ARM指令集来说,PC指向当前指令的下两条指令的地址,
注意pc,在调试的时候显示的是当前指令地址,而用mov lr,pc的时候lr保存的是此指令向后数两条指令的地址
假设反汇编代码:&&0x000001 :&&mov lr pc&&&
(此时查看PC寄存器的值是0x000001,但实际PC值是0x000003, lr里面保存的就是0x000003)
fields 指定传送的区域(psr&&CPSR或SPSR)
c 控制域屏蔽字节(psr[7..0])
x 扩展域屏蔽字节(psr[15..8])
s 状态域屏蔽字节(psr[23..16])
f 标志域屏蔽字节(psr[31..24])
例如:MSR cpsr_c, #0xD3 ;&&CPSR[7...0] = 0xD3
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:46465次
排名:千里之外
转载:36篇
(2)(1)(5)(2)(4)(2)(1)(1)(3)(4)(1)(2)(4)(1)(5)(6)如何把变量或者数组定义到SDRAM及任意位置
如何把变量或者数组定义到SDRAM及任意位置
发布时间: 16:46:40
编辑:www.fx114.net
本篇文章主要介绍了"如何把变量或者数组定义到SDRAM及任意位置",主要涉及到如何把变量或者数组定义到SDRAM及任意位置方面的内容,对于如何把变量或者数组定义到SDRAM及任意位置感兴趣的同学可以参考一下。
我们开发软件的时候,经常会遇到到一个问题,就是内存不够,这个时候就纠结了,怎么办,有两种方法,第一种是扩展内存,外加SRAM或者SDRAM;第二种应该就是优化代码,也就是通常所说的把数组大小减一减,代码量缩一缩,变量啥的能少就少。两种方法都不错,但是我觉得一般情况下采用第二种方法最终会以功能减弱为代价完成的,这是以我的水平来看的,因为我觉得要在不影响功能的情况下进行比较大的缩减,确实比较困难,这需要对该系统了解比较深入,要不然很难做到。
&&&&&& 这两天我也遇到了这个问题,没怎么想,就打算用第一种方法,因为刚好板子上已经有SDRAM,然后就忙着驱动SDRAM,了解它的原理,然后写,读,这在我上一篇博客里面说了,把SDRAM裸奔了,发现还是很纠结,我怎么把数组变量定义到SDRAM里面啊,之前一直都是直接操作地址存取,没做过,而编译器默认我们编写的东西都放在内部RAM,然后我就开始到网上找资料,弄清了一些原理吧。现在就作为学习笔记放在这里。
&&&&&& ARM程序包含3部分:RO,RW和ZI
&&&&&& RO是程序中的指令和常量;
&&&&&& RW是程序中一初始化的变量;
&&&&&& ZI是程序中定义但未初始化的变量。
&&&&&& 由以上3点说明可以理解为:
RO就是readonly,
RW就是read/write,
ZI就是zero
ARM映像文件的组成
所谓ARM映像文件就是指烧录到ROM中的bin文件,也成为image文件。以下用Image文件来称呼它。
Image文件包含了RO和RW数据。
之所以Image文件不包含ZI数据,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。包含进去反而浪费存储空间。
Q:为什么Image中必须包含RO和RW?
A:因为RO中的指令和常量以及RW中初始化过的变量是不能像ZI那样“无中生有”的。
ARM程序的执行过程
从以上两点可以知道,烧录到ROM中的image文件与实际运行时的ARM程序之间并不是完全一样的。因此就有必要了解ARM程序是如何从ROM中的image到达实际运行状态的。
实际上,RO中的指令至少应该有这样的功能:
1. 将RW从ROM中搬到RAM中,因为RW是变量,变量不能存在ROM中。
2. 将ZI所在的RAM区域全部清零,因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零。ZI中也是变量,同理:变量不能存在ROM中
在程序运行的最初阶段,RO中的指令完成了这两项工作后C程序才能正常访问变量。否则只能运行不含变量的代码。
说了上面的可能还是有些迷糊,RO,RW和ZI到底是什么,下面我将给出几个例子,最直观的来说明RO,RW,ZI在C中是什么意思。
看下面两段程序,他们之间差了一条语句,这条语句就是声明一个字符常量。因此按照我们之前说的,他们之间应该只会在RO数据中相差一个字节(字符常量为1字节)。
void main(void)
const char a = 5;
void main(void)
Prog1编译出来后的信息如下:
================================================================================
Code RO Data RW Data ZI Data Debug
948 60 0 96 0 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 1008 ( 0.98kB)
Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)
================================================================================
Prog2编译出来后的信息如下:
================================================================================
Code RO Data RW Data ZI Data Debug
948 61 0 96 0 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 1009 ( 0.99kB)
Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1009 ( 0.99kB)
================================================================================
以上两个程序编译出来后的信息可以看出:
Prog1和Prog2的RO包含了Code和RO Data两类数据。他们的唯一区别就是Prog2的RO Data比Prog1多了1个字节。这正和之前的推测一致。
如果增加的是一条指令而不是一个常量,则结果应该是Code数据大小有差别。
同样再看两个程序,他们之间只相差一个“已初始化的变量”,按照之前所讲的,已初始化的变量应该是算在RW中的,所以两个程序之间应该是RW大小有区别。
void main(void)
char a = 5;
void main(void)
Prog3编译出来后的信息如下:
================================================================================
Code RO Data RW Data ZI Data Debug
948 60 0 96 0 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 1008 ( 0.98kB)
Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)
================================================================================
Prog4编译出来后的信息如下:
================================================================================
Code RO Data RW Data ZI Data Debug
948 60 1 96 0 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 1008 ( 0.98kB)
Total RW Size(RW Data + ZI Data) 97 ( 0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1009 ( 0.99kB)
================================================================================
可以看出Prog3和Prog4之间确实只有RW Data之间相差了1个字节,这个字节正是被初始化过的一个字符型变量“a”所引起的。
再看两个程序,他们之间的差别是一个未初始化的变量“a”,从之前的了解中,应该可以推测,这两个程序之间应该只有ZI大小有差别。
void main(void)
void main(void)
Prog3编译出来后的信息如下:
================================================================================
Code RO Data RW Data ZI Data Debug
948 60 0 96 0 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 1008 ( 0.98kB)
Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)
================================================================================
Prog4编译出来后的信息如下:
================================================================================
Code RO Data RW Data ZI Data Debug
948 60 0 97 0 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 1008 ( 0.98kB)
Total RW Size(RW Data + ZI Data) 97 ( 0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)
================================================================================
编译的结果完全符合推测,只有ZI数据相差了1个字节。这个字节正是未初始化的一个字符型变量“a”所引起的。
注意:如果一个变量被初始化为0,则该变量的处理方法与未初始化华变量一样放在ZI区域。
即:ARM C程序中,所有的未初始化变量都会被自动初始化为0。
1; C中的指令以及常量被编译后是RO类型数据。
2; C中的未被初始化或初始化为0的变量编译后是ZI类型数据。
3; C中的已被初始化成非0值的变量编译后市RW类型数据。
程序的编译命令(假定C程序名为tst.c):
armcc -c -o tst.o tst.c
armlink -noremove -elf -nodebug -info totals -info sizes -map -list aa.map -o tst.elf tst.o
编译后的信息就在aa.map文件中。
ROM主要指:NAND Flash,Nor Flash
RAM主要指:PSRAM,SDRAM,SRAM,DDRAM
&&&&&&&有些人可能看到这些感觉我已经跑题了,但是我觉得你要做到把变量定义到任意位置就必须了解这些,都不了解它怎么用好它。
&&&&& C中指定段:
#pragma arm section [sort_type[[=]&name&]] [,sort_type=&name&]*
sort_type: code、rwdata、rodata、zidata
如果“sort_type”指定了但没有指定“name”,那么之前的修改的段名将被恢复成默认值。
#pragma arm section // 恢复所有段名为默认设置。
#pragma arm section rwdata = &SRAM&,zidata = &SRAM&
static OS_STK SecondTaskStk[256]; // “rwdata”“zidata”将定位在“sram”段中。
#pragma arm section // 恢复默认设置
重点看下下面代码就会对#pragma arm section有更深一步的认识了。
内联函数(及其局部静态变量)
模板实例(及其局部静态变量)
消除未使用的变量和函数
将定义写入目标文件中的顺序
该编译指示完整语法为:
#pragma arm section [sort_type[[=]“name”]][,sort_type=&
此处name用于段名称,sort_type可为如下之一code, rwdata, rodata
和zidata。若指定sort_type,没有指定name,则sort_type的段名被
重新设置为默认值。单独输入#pragma arm section,则所以对象段的
恢复为其默认值
int x1 = 5; // in .data (default)
int y1[100]; // in .bss (default)
int const z1[3] = {1,2,3}; // in .constdata (default)
#pragma arm section rwdata = &foo&, rodata = &bar&
int x2 = 5; // in foo (data part of region)
int y2[100]; // in .bss
int const z2[3] ={1,2,3}; // in bar
char *s2 = &abc&; // s2 in foo, &abc& in bar
#pragma arm section rodata
int x3 = 5; // in foo
int y3[100]; // in .bss
int const z3[3] ={1,2,3}; // in .constdata
char *s3 = &abc&; // s3 in foo, &abc& in .constdata
#pragma arm section code = &foo&
int add1(int x) // in foo (code part of region)
return x 1;
#pragma arm section code
&& 一般而言,一个程序包括只读的代码段和可读写的数据段。在ARM的集成开发环境中,只读的代码段和常量被称作RO段(ReadOnly);可读写的全局变量和静态变量被称作RW段(ReadWrite);RW段中要被初始化为零的变量被称为ZI段(ZeroInit)。对于嵌入式系统而言,程序映象都是存储在Flash存储器等一些非易失性器件中的,而在运行时,程序中的RW段必须重新装载到可读写的RAM中。这就涉及到程序的加载时域和运行时域。简单来说,程序的加载时域就是指程序烧入Flash中的状态,运行时域是指程序执行时的状态。对于比较简单的情况,可以在ADS集成开发环境的ARM
LINKER选项中指定RO BASE和RW BASE,告知连接器RO和RW的连接基地址。对于复杂情况,如RO段被分成几部分并映射到存储空间的多个地方时,需要创建一个称为“分布装载描述文件”的文本文件,通知连接器把程序的某一部分连接在存储器的某个地址空间。需要指出的是,分布装载描述文件中的定义要按照系统重定向后的存储器分布情况进行。在引导程序完成初始化的任务后,应该把主程序转移到RAM中去运行,以加快系统的运行速度。
什么是arm的映像文件,arm映像文件其实就是可执行文件,包括bin或hex两种格式,可以直接烧到rom里执行。在axd调试过程中,我们调试的是axf文件,其实这也是一种映像文件,它只是在bin文件中加了一个文件头和一些调试信息。映像文件一般由域组成,域最多由三个输出段组成(RO,RW,ZI)组成,输出段又由输入段组成。所谓域,指的就是整个bin映像文件所处在的区域,它又分为加载域和运行域。加载域就是映像文件被静态存放的工作区域,一般来说flash里的 整个bin文件所在的地址空间就是加载域,当然在程序一般都不会放在
flash里执行,一般都会搬到sdram里运行工作,它们在被搬到sdram里工作所处的地址空间就是运行域。我们输入的代码,一般有代码部分和数据部分,这就是所谓的输入段,经过编译后就变成了bin文件中ro段和rw段,还有所谓的zi段,这就是输出段。对于加载域中的输出段,一般来说ro段后面紧跟着rw段,rw段后面紧跟着zi段。在运行域中这些输出段并不连续,但rw和zi一定是连着的。zi段和rw段中的数据其实可以是rw属性
本文标题:
本页链接:

我要回帖

更多关于 matlab定义数组变量 的文章

 

随机推荐