DSP

28335的程序到底是在哪里运行的。

2019-07-13 18:57发布

最近在研究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文件中写入相应的段名才行。