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