MSP430FR5969内存分配的问题
cmd文件里的具体内容我就不贴了,大家自己可以看一下。cmd文件主要由两部分构成,一个是MEMORY{};另一个是SECTIONS{}
本文引用地址:https://www.eepw.com.cn/article/201611/319189.htm其中MEMORY{}是定义内部所有寄存器及存储器的地址,在这里大部分内容都是厂家定义好的,一般不能修改。但是咱们今天要改的就是他,当然只能改其中允许该的地方,那就是FRAM的分配问题。根据数据手册里提供的内存分配情况(如下图)我们可以得知,59x9的内存从0x0000开始,一直到0x13FFF。对应着这个图和Cmd文件,我们可以了解内部的地址分配问题,如果做过总线扩展之类的同学肯定对这个不会陌生了,如果没有见过就需要理解一下。其实也很简单,就是对应的地址要对应上就可以了。有一些是固定好的不能变,比如各个中断向量的地址,各个寄存器的地址等。一般能变的就是程序存储空间和数据空间了,对应到59x9里面就是cmd文件里的三个部分,即RAM :origin = 0x1C00, length = 0x0800
FRAM : origin = 0x4400, length = 0xBB80
FRAM2 : origin = 0x10000,length = 0x4000
其中origin 表示起始地址,length 表示长度
这几个关键的起始地址和长度可以在上表以及msp430FR59xx69xx数据手册.pdf的21页22页找到,这两页是中断向量地址,也就是cmd文件下面的部分了。上面说到地址的和21页和22页上的地址是内部规定好的,用户不能自行改变。看到这里,我想大家应该明白了,其实这个芯片留给用户的地址有3部分。分别是0x1C00开始的2K空间,0x4400开始的46K空间以及0x100000开始的16K空间。那么这些空间都是放什么内容的呢?这就要说到CMD文件中的另一部分SECTIONS{}了。
顾名思义,SECTIONS就是选择的意思,当然就是选择程序编译过程中的每一部分数据的位置了。这一部分每一行的具体意义我也说不太明白。只是略知一二,与此帖有关的的有这样几句
- .cinit : {}> FRAM /* INITIALIZATION TABLES */
- .pinit : {}> FRAM /* C++ CONSTRUCTOR TABLES */
- .init_array : {}> FRAM /* C++ CONSTRUCTOR TABLES */
- .mspabi.exidx : {}> FRAM /* C++ CONSTRUCTOR TABLES */
- .mspabi.extab : {}> FRAM /* C++ CONSTRUCTOR TABLES */
- .const : {} >> FRAM | FRAM2/* CONSTANT DATA */
- .text:_isr : {}> FRAM /* CODE ISRs */
- .text : {} >> FRAM2 | FRAM/* CODE
- .bss : {} > RAM /* GLOBAL & STATIC VARS */
- .data : {} > RAM /* GLOBAL & STATIC VARS */
- .TI.noinit: {} > RAM /* For #pragma NOINIT */
- .stack : {} > RAM (HIGH) /* SOFTWARE SYSTEM STACK */
除了上面那样利用官方分好的区块重新定义之外,我们还可以自己重新划分地址。比如把46K的区块划分成两个或者多个区块,当然一般为了实用方便区块还是少一些比较好,把同一类型数据中的子类数据的地址分配权利给编译器会更简单一些,如果对数据的存放比较关心,比如我想单独拿出一块放参数,那么我们就可以单独定义一块地址作为参数,方便数据的管理。
从上图中,我们可以看到,字符串常量存储的位置上FLASH1区或者FLASH2区,可执行代码也是存储在FLASH1去或者FLASH2区。这里出现这个问题的原因可能是可执行代码存储在FLASH区,但是需要的字符串常量存在是FLASH2区,所以重定向时,由于存储的位置较远,导致无法定向到。
注:这样做可能还存在一个问题,因为FLASH1区的大小非常小,只有31K,按照目前这种做法,中断函数代码、变量初始化的值以及字符串常量都被存储在FLASH1区,部分执行代码也存在这个区域。如果前面三者的大小超过了FLASH1区的大小,这种情况不知道编译器是否会有提示。如果没有提示,但是溢出的话,可能是会出问题的。但是从目前调试的情况来看,一切正常。如果后续出现奇怪的现象,需要考虑是否是这里的问题。
评论