最近在研究28335的自升级问题,没想到自升级没结局,倒有了个新收获。
之前一直认为,程序在Flash中运行和在SRAM运行的主要不同点就在于以下的代码:
MemCopy(
&RamfuncsLoadStart,
&RamfuncsLoadEnd,
&RamfuncsRunStart);
InitFlash();
由于当初理解的并不全面,囫囵吞枣,看程序能在FLASH中启动了也就没有再审追究。直到今天才有了新的认识。Σ( ° △ °|||)︴
先来看看在RAM中运行的CMD文件是什么样子的:
codestart : > BEGIN, PAGE = 0
ramfuncs : > RAML0, PAGE = 0
.text : > RAML1, PAGE = 0
.cinit : > RAML0, PAGE = 0
.pinit : > RAML0, PAGE = 0
.switch : > RAML0, PAGE = 0
.stack : > RAMM1, PAGE = 1
.ebss : > RAML4, PAGE = 1
.econst : > RAML5, PAGE = 1
.esysmem : > RAMM1, PAGE = 1
IQmath : > RAML1, PAGE = 0
IQmathTables : > IQTABLES, PAGE = 0, TYPE = NOLOAD
可以看见所有字段均是在存储在RAM中,尤其注意.text(也就是程序存储运行位置),而固化到FLASH中的CMD文件又是什么样子嘞?
[code] .cinit : > FLASHA PAGE = 0
.pinit : > FLASHA, PAGE = 0
.text : > FLASHA PAGE = 0
codestart : > BEGIN PAGE = 0
ramfuncs : LOAD = FLASHD,
RUN = RAML0,
LOAD_START(_RamfuncsLoadStart),
LOAD_END(_RamfuncsLoadEnd),
RUN_START(_RamfuncsRunStart),
PAGE = 0
.stack : > RAMM1 PAGE = 1
.ebss : > RAML4 PAGE = 1
.esysmem : > RAMM1 PAGE = 1
.econst : > FLASHA PAGE = 0
.switch : > FLASHA PAGE = 0 [/code]
此时的函数存储运行空间已经变成了FLASH,也就是在无特殊声明的情况下,程序是在FLASH里面跑的。
此前一直错误的以为MemCopy() 函数时将flash中的所有程序均拷贝到内存中运行,现在可以比肩肯定的说:这完全是瞎扯。那真相是什么嘞?
真相就是,memcpy只是拷贝了FLASH中特定段内的内容到RAM中运行。在这里,拷贝的就是ramfuncs段中的函数。
通过查看.map文件可以得到:
ramfuncs 0 00320000 0000001f RUN ADDR = 00008000
00320000 0000001b DSP2833x_SysCtrl.obj (ramfuncs)
0032001b 00000004 DSP2833x_usDelay.obj (ramfuncs)
在ranfuncs中有两个函数,一个是usDelay();另外一个是InitFalsh();
在usDelay.asm文件中可以找到这么一句:
.sect "ramfuncs"
同样的,在DSP28x_usDelay.c中可以找到这句:
#pragma CODE_SECTION(InitFlash, "ramfuncs");
这两句就是对函数的运行空间做了具体的映射,也就是映射到ramfuncs段中。而在F28335.cmd文件中可以发现,这个字段是写在FLASHD里面的,通过memcpy函数的搬运,在运行时被加载到RAML0空间中去。
也就是说,在固化后,只有这两个函数是被放到RAM中运行的,其他函数还是跑在Flash里。
另,补充一下#pragma CODE_SECTION命令
格式 #pragma CODE_SECTION(func,"section")
其中func是函数名,section是此函数所存储的段名。如果要运用此命令,需要在CMD文件中写入相应的段名才行。