CMD各段定义与分配方法指引
DSP28335—CMD文件中的各個(gè)段解釋
CMD文件里有兩個(gè)基本的段:初始化段和非初始化段。初始化段包含代碼和常數(shù)等必須在DSP上電之后有效的數(shù)。故初始化塊必須保存在如片內(nèi)FLASH等非易失性存儲(chǔ)器中,非初始化段中含有在程序運(yùn)行過(guò)程中才像變量?jī)?nèi)寫(xiě)數(shù)據(jù)進(jìn)去,所以非初始化段必須鏈接到易失性存儲(chǔ)器中如RAM。
已初始化的段:.text,.cinit,.const,.econst,.pinit和.switch…
.text:所有可以執(zhí)行的代碼和常量
.cinit:全局變量和靜態(tài)變量的C初始化記錄,包含未用const聲明的外部(extern)或靜態(tài)(static)數(shù)據(jù)表
.const:包含字符串常量和初始化的全局變量和靜態(tài)變量(由const)的初始化和說(shuō)明
.econst:包含字符串常量和初始化的全局變量和靜態(tài)變量(由far const)的初始化和說(shuō)明,與.const不同的是.const分配范圍被限制在低64K 16位數(shù)據(jù)區(qū),而.econst的分配范圍是4M 22位數(shù)據(jù)區(qū)
.pinit:全局構(gòu)造器(C++)程序列表
.switch:包含switch聲明的列表
非初始化的段:.bss,.ebss,.stack,.sysmem,和esysmem.(更好的理解就是,這些段就是存儲(chǔ)空間而已)
.bss: 為全局變量和局部變量保留的空間,在程序上電時(shí).cinit空間中的數(shù)據(jù)復(fù)制出來(lái)并存儲(chǔ)在.bss空間中。
.ebss:為使用大寄存器模式時(shí)的全局變量和靜態(tài)變量預(yù)留的空間,在程序上電時(shí),cinit空間中的數(shù)據(jù)復(fù)制出來(lái)并存儲(chǔ)在.ebss中,與.bss不同的是.bss分配范圍被限制在低64K 16位數(shù)據(jù)區(qū),而.ebss的分配范圍是4M 22位數(shù)據(jù)區(qū)
.stack:為系統(tǒng)堆棧保留的空間,用于和函數(shù)傳遞變量或?yàn)榫植孔兞糠峙淇臻g。
.sysmem:為動(dòng)態(tài)存儲(chǔ)分配保留的空間。如果有宏函數(shù),此空間被宏函數(shù)占用,如果沒(méi)有的話,此空間保留為0
.esysmem:為動(dòng)態(tài)存儲(chǔ)分配保留的空間。如果有far函數(shù),此空間被相應(yīng)的占用,如果沒(méi)有的化,此空間保留為0.
編譯器生成的包含代碼和數(shù)據(jù)的多個(gè)部分,稱為段。這下段被分為兩個(gè)不同的組:初始化了的和沒(méi)被初始化的,初始化的部分是由所有的代碼,常量和初始化表組成的。下表列出了由編譯器產(chǎn)生的初始化段。
初始化段
段名 內(nèi)容 限制
.cinit 顯式初始化的全局變量和靜態(tài)變量表 代碼
.const 顯式初始化的全局和靜態(tài)的const變量和字符串常量 不超過(guò)64K長(zhǎng)度
.econst 長(zhǎng)調(diào)用的常量 數(shù)據(jù)中的任何地方
.pinit 全局對(duì)象的構(gòu)造函數(shù)表 代碼
.switch switch語(yǔ)句產(chǎn)生的表 代碼或者數(shù)據(jù)
.text 可執(zhí)行代碼和常數(shù) 代碼
沒(méi)初始化的段是由未初始化的變量,堆棧和malloc產(chǎn)生的內(nèi)存。下表列出了由編譯器產(chǎn)生的沒(méi)初始化段。
沒(méi)初始化段
段名 內(nèi)容 限制
.bss 全局和靜態(tài)變量 不超過(guò)64K長(zhǎng)度
.ebss 長(zhǎng)調(diào)用的全局或靜態(tài)變量 數(shù)據(jù)中的任何地方
.stack 堆棧空間 不超過(guò)64K長(zhǎng)度
.sysmem malloc函數(shù)產(chǎn)生的內(nèi)存 不超過(guò)64K長(zhǎng)度
.esysmem far_malloc函數(shù)產(chǎn)生的內(nèi)存 數(shù)據(jù)中的任何地方
一旦編譯器生成的這些段,連接器會(huì)從各個(gè)源文件中取出這些段,并結(jié)合它們來(lái)創(chuàng)建一個(gè)輸出文件。連接器命令文件(.cmd)就是用來(lái)告訴連接器去哪里找這些段的。初始化段必須分配到非易失性存儲(chǔ)器,如flash/ ROM,當(dāng)電源被撤除時(shí),程序不會(huì)消失。未初始化的段可以被分配到RAM中,因?yàn)樗鼈兪窃诖a執(zhí)行期間被初始化的。
當(dāng)需要把程序從flash復(fù)制到RAM里時(shí),各個(gè)段分配參考如下:
.cinit Flash
.cio RAM
.const Flash
.econst Flash
.pinit Flash
.switch Flash
.text Flash
.bss RAM
.ebss RAM
.stack Lower 64Kw RAM
.sysmem RAM
.esysmem RAM
.reset RAM1
具體應(yīng)用實(shí)例:
(一)#pragma DATA_SECTION 利用CCS進(jìn)行DSP編程時(shí),如果不指定變量的存儲(chǔ)位置,那么編譯器會(huì)自動(dòng)給變量分配存儲(chǔ)位置,但是,有些時(shí)候,需要將某個(gè)變量存放到某個(gè)特定的位置,這個(gè)時(shí)候就可以利用#pragma DATA_SECTION指令了。
第一步,利用#pragma DATA_SECTION指令將變量xxxCmdBuf關(guān)聯(lián)到SECTIONS“ramdata”;
#pragma DATA_SECTION(xxxCmdBuf,“ramdata”); uint16_t xxxCmdBuf[4];12
第二步,修改CMD文件使得“ramdata”映射到指定的地址空間。
MEMORY { PAGE 0 : /* Program Memory */ …
PAGE 1 : /* Data Memory */ … RAML_XXXCMD : origin = 0x00BFF0, length = 0x000004 } …
SECTIONS { … ramdata : > RAML_XXXCMD, PAGE = 1 … }1234567891011121314151617
只需完成上述簡(jiǎn)單的兩步就可以將某個(gè)變量指定到特定的位置,一些博文指出采用這種方法時(shí),需要先利用#pragma DATA_SECTION開(kāi)辟一個(gè)空間,然后在定義該空間的大小,即第一步中的兩行代碼是有先后順序的。
TI 的技術(shù)文檔《Programming TMS320x28xx and 28xxx Peripherals in C/C++》(SPRAA85D–November 2005–Revised January 2013)對(duì)該方法也有相應(yīng)的描述,如下所示。
(二)#pragma CODE_SECTION 利用#pragma CODE_SECTION指令可以將程序從Flash搬到RAM中運(yùn)行,從而提高程序執(zhí)行速率,該方法需要完成以下四步。
第一步,利用#pragma CODE_SECTION指令關(guān)聯(lián)程序和SECTIONS;
#pragma CODE_SECTION(mainISR,“ramfuncs”);1
第二步,為鏈接創(chuàng)建相關(guān)變量;
// Used for running BackGround in flash, and ISR in RAM extern uint16_t *RamfuncsLoadStart, *RamfuncsLoadEnd, *RamfuncsRunStart;12
第三步,復(fù)制時(shí)間關(guān)鍵代碼以及Flash設(shè)置代碼到RAM;
// Copy time critical code and Flash setup code to RAM // The RamfuncsLoadStart, RamfuncsLoadEnd, and // RamfuncsRunStart symbols are created by the linker. // Refer to the linker files. memCopy((uint16_t *)&RamfuncsLoadStart,(uint16_t *)&RamfuncsLoadEnd,(uint16_t *)&RamfuncsRunStart);1234
第四步,修改CMD文件。
SECTIONS { /* Allocate program areas: */ … ramfuncs : LOAD = FLASHD, RUN = RAML0_1, LOAD_START(_RamfuncsLoadStart), LOAD_END(_RamfuncsLoadEnd), RUN_START(_RamfuncsRunStart), PAGE = 0 1234567891011
上面代碼中, LOAD = FLASHD, //指定了要加載程序在Flash里的地址段 RUN = RAML0_1, //指定了在RAM里運(yùn)行程序的RAM地址段 LOAD_START(_RamfuncsLoadStart), // 所要加載程序在Flash里的初始地址 LOAD_END(_RamfuncsLoadEnd), // 所要加載程序在Flash里的結(jié)束地址 RUN_START(_RamfuncsRunStart)
總結(jié)
以上是生活随笔為你收集整理的CMD各段定义与分配方法指引的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: CAN总线抗干扰的六种解决方案
- 下一篇: 子网掩码及网络号路由表的匹配方法