日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

cmd文件 c语言的段,对于TMS320F2812的CMD文件的理解

發(fā)布時間:2025/3/11 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 cmd文件 c语言的段,对于TMS320F2812的CMD文件的理解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。