cmd文件 c语言的段,对于TMS320F2812的CMD文件的理解
1.COFF格式
要談CMD文件,首先不可避免的要談下COFF格式,COFF格式是通用目標(biāo)文件格式(Common Object File
Format)的縮寫,它是一種流行的二進(jìn)制可執(zhí)行文件格式,在DSP里二進(jìn)制可執(zhí)行文件包括庫文件(.lib)、目標(biāo)文件(.obj)和最終可執(zhí)行文件(.out)。詳細(xì)的COFF格式文件包括段頭、可執(zhí)行代碼、初始化數(shù)據(jù)、可重定位信息、行號入口、符號表、字符串。對于DSP的C語言編程我們只需要了解定義段和給段分配空間即可。采用COFF格式更利于我們對其進(jìn)行模塊化編程,我們可以自由的把哪些段分配到哪些空間。
2.Section
(1)其次,在編寫CMD文件得時候要碰到SectionS命令,SectionS命令的英文理解就有區(qū)域的意思,我們利用SectionS來將目標(biāo)文件的代碼放到指定的區(qū)域中。SectionS目標(biāo)文件中最小的單位我們稱之為塊,一個塊就是最終在存儲器映像中占據(jù)連續(xù)空間的一段代碼或者數(shù)據(jù)。COFF文件格式默認(rèn)有三個塊:
.text?存放可執(zhí)行代碼;
.data?存放已初始化數(shù)據(jù);
.bss?為未初始化數(shù)據(jù)留下的保留空間。
(2)匯編器對塊的處理和設(shè)置
未初始化塊的設(shè)置:
.bss?變量存放空間;
.usect?用戶自定義的未初始化段;
初始化塊的設(shè)置:
.text?匯編指令代碼
.data?常數(shù)數(shù)據(jù)(比如對變量的初始化數(shù)據(jù))
.sect?用戶自定義的已初始化段
.asect?類似于.sect,多了絕對地址定位功能,一般不用
(3)C語言對塊得的設(shè)置和處理
未初始化塊(data)
.bss?存放全局和靜態(tài)變量
.ebss?長調(diào)用的.bss(超過了64K地址限制)
.stack?存放C語言的棧
.sysmem?存放C語言的堆
.esysmem?長調(diào)用的.sysmem(超過了64K地址限制)
初始化塊
.text?可執(zhí)行代碼和常數(shù)(program)
.switch?switch語句產(chǎn)生的常數(shù)表格(program/低64K數(shù)據(jù)空間)
.pinit?Tables for global constructors (C++)(program)
.cinit?用來存放對全局和靜態(tài)變量的初始化常數(shù)值(program)
.const?全局和靜態(tài)的const變量初始化值和字符串常數(shù),(data)
.econst?長.const(可定位到任何地方)(data)
(4)C語言自定義塊
#pragma DATA_SECTION(函數(shù)名或者全局變量名,“用戶自定義在數(shù)據(jù)空間的段名”);
#pragma CODE_SECTION(函數(shù)名或者全局變量名,“用戶自定義在程序空間的段名”);
必須注意:不能在函數(shù)體內(nèi)聲明,必須在定義和使用前聲明。#pragma可以阻止對未調(diào)用的函數(shù)的優(yōu)化(優(yōu)化我也不太理解)。
3.2812的CMD文件
(1)在CMD文件中有兩個偽指令MEMORY和SECTIONS,其中SECTIONS的用法在上面已經(jīng)有了介紹,就是將生成的代碼或者數(shù)據(jù)分配到指定的存儲器的映射空間去。哪里是映射空間呢,這個就是由MEMORY這個偽指令來定義的,它的作用就是對整個存儲器進(jìn)行分區(qū),然后給每個存儲器進(jìn)行命名,DSP只認(rèn)物理地址(在我的第一篇日志里已經(jīng)詳細(xì)闡述了)。下面先寫下這兩個偽指令的語法格式:
MEMORY {
PAGE 0: name1[(attr)]origin=constant,
length=constant;
PAGE n: name1[(attr)]origin=constant,
length=constant;}
PAGE
n中頁號的最大值是255,每個PAGE代表一個完全獨(dú)立得地址空間,通常n=0為數(shù)據(jù)空間,n=1為程序空間,name是對存儲區(qū)間命名,attr規(guī)定了存儲器得屬性,R-讀,W-寫,一般我們不寫的??,origin,起始地址,length,該存儲區(qū)間的大小。
SECTIONS{
Name:[property,property,…]
Name:[property,property,…]
Name:[property,property,…]}
Name:源程序中的段名。如.text,Property:段的屬性參數(shù)。一個段的屬性參數(shù)包括下列五種:
(1)Load allocation,由它定義將輸出段加載到存儲器中的什么位置。
語法:load:
>allocation?(allocation是將邏輯段定位的地址說明)
例如:?.text:?load=0x1000?;將輸出段定位到一個特定的地址
.text:?load>ROM?;將輸出段定位到命名為ROM的存儲區(qū)
.text:?align=0x80?;關(guān)鍵詞align規(guī)定輸出段.text定位到從地址邊界0x80開始
.text:?block(128)?;關(guān)鍵詞bolck規(guī)定段必須在兩個地址邊界之內(nèi),如果段太
;大,就從一個地址邊界開始
.text:?PAGE0?;將輸出段定位到PAGE0
如果輸出段只定位一個位置,帽可省去關(guān)鍵字load。如:.text: >ROM
如果要用到一個以上參數(shù),可以將它們排成一行。如:.text:?>ROM align 16 PAGE 2
或.text: load(ROM align(16) PAGE(2))
(地址邊界是2的N次方冪的地址,如地址邊界定為16,則其地址為xxx0h。)
(2)Run allocation,由它定義輸出段在存儲器的什么位置開始運(yùn)行。
語法:run=allocation或run>allocation
鏈接器為每個輸出段在目標(biāo)存儲器中分配兩個地址:加載地址和執(zhí)行地址。通常這兩個地址是相同的。但如要先將程序加載到ROM,然后在RAM中以較快的速度運(yùn)行。則可兩次定位,如:
.fir:?load=ROM,run=RAM
(3)Input sections,由它定義哪些輸入段組成輸出段。
語法:{input_sections}
.text:?{*(.text)}
這樣就把所有的.text段鏈接成.text段輸出。也可以明確的用文件名和段名來確定輸入段:
.text:
{
F1.obj
(.text,sect)?;鏈接F1.obj的.text、.sect段
F2.obj
(sect)?;
F3.obj?;鏈接f3.obj的所有段
}
(4)Section type,用它為輸出段定義特殊形式的標(biāo)志
語法:Type=COPY、Type=
DSECT、Type=NOLOAD
(5)Fill value,當(dāng)初始化段中存在未初始化的存儲區(qū)間時,對其填充一指定值。
語法:fill:
value 或name:…{…}=value
4.2812的CMD文件的編寫
下面就來談?wù)勎覍?812在寫CMD文件的時候的一點(diǎn)理解,不足的地方希望各位看官撥冗指正
?。
(1)片內(nèi)存儲器分區(qū)MEMORY
先翻開相關(guān)芯片的存儲空間的資料,然后分配一下你得程序存儲空間和數(shù)據(jù)存儲空間,即PAGE0和PAGE1,程序存儲空間里通常放XINTF的ZONE0,1,2,6,7FLASHA-J,OPT,H0,bootROM,其中BOOTROM和XINTF得ZONE7是復(fù)用得,在不同得模式下選取不同的方式,MP/MC=0----BOOTROM,MP/MC=1----XINTFZONE7,在片內(nèi)數(shù)據(jù)空間上定義各個存儲器,這是也可以翻開你的書本,查下每章開頭,一般都有這一章所涉及的所以的寄存器的地址,然后根據(jù)這些地址分配一下存儲的單元的起始地址和空間的大小。
(2)SECTIONGS分塊
這里舉一個例子闡述一下分塊的方法,例如我們在數(shù)據(jù)存儲空間定義了SYSTEM塊,主要就是給系統(tǒng)的時鐘、看門狗、鎖存器等分的一個空間,這個空間的大小是0x0020H,也就是10進(jìn)制得32個字節(jié)單元,為什么要分32個字節(jié)單元呢,在書上我們可以查的系統(tǒng)得這一部分所對應(yīng)的寄存器的名稱和寄存器的字節(jié)數(shù)如下:
Reserved:10;HISPCP:1;LOSPCP:1;PCLCR:1;Reserved:1;LPMCR0:1;LPMCR1:1;Reserved:1;PLLCR:1;SCSR:1;WDCNTR:1;
Reserved:1;WDKEY:1;Reserved:3;WDCR:1;Reserved:6;計算一下,整個的存儲器空間的大小是10+1+1+1+1+1+1+1+1+1+1+1+1+3+1+6=32.這就是為什么是32個字節(jié)的原因。記住,此時這一塊的名字是SYSTEM(當(dāng)然你也可以另行定義)。在SECTIONS中我們定義輸出段的名字是SysCtrlRegsFile,其指向的就是SYSTEM.即
SysCtrlRegsFile:>SYSTEM,PAGE0
然后我們在自己的頭文件中定義結(jié)構(gòu)體和聯(lián)合體的時候,例如定義了一個SYSTEM_REGS的結(jié)構(gòu)體,里面包含了系統(tǒng)的控制寄存器的聯(lián)合體或者結(jié)合體,可以這么寫:
struct SYSTEM_REGS
{
Unit32?Reserved:10;
union?HISPCP_REGS
HISPCP;
union?LOSPCP_REGS
LOSPCP;
union?PCLKER_REGS
PCLKER;
Unit32?Reserved:1;
union?LPMCR0_REGS LPMCR0;
union ?LPMCR1_REGS LPMCR1;
Unit32 Reserved:1;
union PLLCR_REGS?PLLCR;
union SCSR_REGS?SCSR;?貌似這個是不用定義聯(lián)合體的,Unit32 SCSR:1;
union WDCNTR_REGS WDCNTR;
Unit32 Reserved:1;
union WDKEY_REGS WDKEY;
Unit32 Reserved:3;
union WDCR_REGS WDCR;
Unit32 Reserved:6;
}SysCtrlRegsFile;
這里面得聯(lián)合體都有其自己的定義,例如PLLCR_REGS
struct PLLCR_BITS
{
Unit16 DIV:4;
Unit16 Reserved:12;
};
union PLLCR_REGS{
Unit16 all;
struct PLLCR_BITS bit;
};
這樣我們要對PLLCR寄存器操作得時候就只需這么寫:SysCtrlRegsFile.PLLCR.all=0xXXXX;或者SysCtrlRegsFile.PLLCR.bit.DIV=0xXXXX;bit是結(jié)構(gòu)體的一個變量??,相信C語言得結(jié)構(gòu)體和聯(lián)合體(也叫共用體)大家都學(xué)得不比偶差吧。對其操作過程就是自動得找到了SysCtrlRegsFile對應(yīng)得那片空間0x00007010-0X0x702F,然后PLLCR就是就是里面的第18個空間即0x00007021,相信這么理解大家都應(yīng)該明白了撒。所有的寄存器都是這樣寫得哦。??。
成功源于共享!!!
總結(jié)
以上是生活随笔為你收集整理的cmd文件 c语言的段,对于TMS320F2812的CMD文件的理解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java final定义_Java中fi
- 下一篇: 单关闭功能_广告弹窗关闭