<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > DSP編程技巧之答疑解惑

DSP編程技巧之答疑解惑

作者: 時(shí)間:2016-10-15 來(lái)源:網(wǎng)絡(luò ) 收藏

1、 雖然可用的存儲空間看起來(lái)比section的長(cháng)度要大,但是鏈接器為何提示“placement fails for object”?

本文引用地址:http://dyxdggzs.com/article/201610/307292.htm

這種情況一般是因為段的空間的分配是并不是我們想象中的連續的一個(gè)緊挨一個(gè),而是被編譯器給“分塊”管理了。在內存地址分配時(shí),一個(gè)段需要完全適配到頁(yè)(page)中,或者從頁(yè)的邊界開(kāi)始連續分配;為了滿(mǎn)足這個(gè)要求,段在分配到頁(yè)中時(shí),可能無(wú)法完全利用某些頁(yè),導致內存地址中產(chǎn)生了間隙(hole),使得實(shí)際所需要的內存空間超過(guò)了根據變量大小計算出來(lái)的理論值。編譯器這樣做的目的是為了優(yōu)化數據頁(yè)(DP)寄存器的加載,達到減小代碼尺寸和優(yōu)化程序性能的目的。例如,針對一個(gè)數組,如果數組的長(cháng)度小于64字(words),則編譯器僅需安全地加載DP一次就可以訪(fǎng)問(wèn)數組的全部元素;如果數組長(cháng)度大于64字,則在訪(fǎng)問(wèn)每64字的數組元素時(shí),編譯器僅需加載一次DP,當然如果訪(fǎng)問(wèn)多個(gè)64字的數組元素則仍需要多次加載DP。

舉例說(shuō)明:

在cmd里定義:

RAMM1 : origin = 0x000400, length = 0x000400 /* on-chip RAM block M1 */

commbuf : > RAMM1 PAGE = 1

在main.c里定義以下幾個(gè)變量

#pragma DATA_SECTION(sendT, commbuf)

Uint16 sendT[260];

#pragma DATA_SECTION(receT, commbuf)

Uint16 receT[260];

#pragma DATA_SECTION(CntPPR, commbuf)

Uint32 CntPPR[250];

表面上共需260+260+250*2=1020,commbuf正好放得下.但ccs提示空間不夠:

(run placement fails for object commbuf, size 0x474 (page 1).

Available ranges: RAMM1 size: 0x400 unused: 0x400 max hole: 0x400)

產(chǎn)生錯誤的原因是根據DP加載的原則,page被劃分為64word的小單元,而數組被存儲在連續的、整塊的單元上,未使用到的空間不會(huì )再分配給其它數組或者變量使用。所以16位260長(cháng)度的數組實(shí)際占用了64*5=320 (64*4=256260),32位500的長(cháng)度實(shí)際占用了64*8=512,占用的總長(cháng)度為:320*2+512=1152=0x480。

按照CCS的提示,commbuf占用空間是320*2+500=1140=0x474,但是事實(shí)上32位數組占據的最后那個(gè)page已經(jīng)無(wú)法被別的變量使用了,所以如果還有新的變量出現的話(huà),會(huì )提示RAMM1塊缺少的地址更多。

根據我們的需要,可以在每次之間內存讀取操作之前都加載DP,這樣就可以禁用上面的“分塊”管理特性了。這樣做雖然可以減小內存地址空間中的“間隙”,但是每一次訪(fǎng)問(wèn)內存都需要加載DP,反而大大地增加了代碼的尺寸,實(shí)在是得不償失(看起來(lái)很少有人會(huì )這么做)。我們可以通過(guò)啟用編譯器的-disable_dp_load_opt,或者叫-md選項來(lái)實(shí)現這一方法。

確認某個(gè)段是否被編譯器給分塊管理的方法就是使用.bss和.usect指令。

2、 鏈接器提示“placement fails for object '.text'”,我們如何為.text分配更多的內存?

.text段中包含包含所有可執行的代碼,以及編譯器編譯產(chǎn)生的常量。如果我們的代碼比較大,超過(guò)了cmd文件中默認分配的空間,則.text無(wú)法適配到內存空間中,就會(huì )產(chǎn)生上面的錯誤。通常有三種方法可以來(lái)為其分配更多的空間。

方法一:修改cmd

方法二:分割.text,把它平均分配到多個(gè)內存區域中

這個(gè)方法比較直觀(guān),前提是幾個(gè)內存區域的總長(cháng)度要滿(mǎn)足要求。例如:

.text : >> FLASHA | FLASHC | FLASHD, PAGE = 0

方法三:完整分割法

這個(gè)名字有點(diǎn)古怪,它本質(zhì)仍然是把.text分割,目標區域也可以有多個(gè),但是當第一個(gè)區域就滿(mǎn)足要求時(shí),則只把它分配到第一個(gè)區域中,剩余的目前區域實(shí)際上未被使用到。

在實(shí)際編程實(shí)現時(shí),這些方法仍然存在一定的限制,包括:

1. 在包含控制律加速器CLA 的Piccolo器件中,只有特定的內存區域可被CLA所使用。

2. 在含有DMA的器件中,并不是所有的內存都可被DMA所訪(fǎng)問(wèn)。

3. 一般情況下,SRAM都是單個(gè)機器周期內只能訪(fǎng)問(wèn)一次,但是0等待狀態(tài)的。但在一些器件中,程序內存控制是包含等待狀態(tài)的,例如在某些2833x器件中,DMA可訪(fǎng)問(wèn)的數據空間是0等待狀態(tài)的,但是程序控制是1等待狀態(tài)的。這些SRAM空間更適合純數據訪(fǎng)問(wèn)類(lèi)型的使用。

3、在cmd文件中,可以把連續的Flash模塊組合為一個(gè)整體的區間嗎?

答案是可以的。在Flash的燒寫(xiě)中,可以在同一時(shí)間被燒寫(xiě)的Flash的最小長(cháng)度被稱(chēng)為扇區(sector),所以通過(guò)把我們的代碼進(jìn)行分區燒寫(xiě),就可以把它們對齊到扇區。

Flash模塊結合的方法一:直接合并法

以把兩個(gè)Flash扇區組和為一個(gè)段為例:

合并前,兩個(gè)扇區的定義是:

MEMORY

{

//

// Individual sectors E and F called out in the MEMORY description

//

...

FLASHF : origin = 0x310000, length = 0x008000 /* on-chip FLASH */

FLASHE : origin = 0x318000, length = 0x008000 /* on-chip FLASH */

...

}

合并之后的Flash區間為:

MEMORY

{

//

// Sectors E and F merged into one in the MEMORY description

//

...

FLASH : origin = 0x310000, length = 0x010000 /* on-chip FLASH F FLASH E */

...

}

方法二:反其道行之,把段分配到多個(gè)Flash模塊中,與問(wèn)答36的方法二是一致的,例如:

SECTIONS

{

.text: { *(.text) } >> FLASHE| FLASHH

}

4、 在cmd文件中,可以把相鄰的SARAM模塊組合為一個(gè)整體的區間嗎?

答案是可以的,方法與Flash組合的方法一樣。

雖然這樣做是完全沒(méi)有問(wèn)題的,但需要牢記SARAM模塊都是單個(gè)機器周期內只能訪(fǎng)問(wèn)一次的,所以為了優(yōu)化程序的性能,最好把代碼給分區到不同的物理SARAM模塊中,這樣可以減少大量讀/寫(xiě)操作中的資源沖突。

5、對于/BIOS的工程,如何了解鏈接的信息?

/BIOS 的配置工具生成一個(gè)cmd文件,規定如何連接所有 /BIOS 生成的程序段,并且默認鏈接至所有 C/C++ 語(yǔ)言編譯程序生成的程序段。 當從 RAM 運行程序時(shí),可能只需要這一個(gè)cmd文件就夠了。但在當從Flash中執行時(shí),很有可能需要生成且連接一個(gè)或多個(gè)自定義的程序段。

此外,任何配置片載Flash控制寄存器(例如,Flash等待狀態(tài))的代碼不能從Flash執行。我們也許需要從 RAM(而非Flash)中運行特定時(shí)間關(guān)鍵函數來(lái)大幅提升性能。 必須創(chuàng )建一個(gè)自定義cmd來(lái)處理這些我們定義的程序段??梢詤⒖糝unning an Application from Internal Flash Memory on the TMS320F28xx DSP這個(gè)文檔,其示例代碼在http://www.ti.com/general/docs/l ... 58fileType=zip。

需要注意的是,這些文檔和程序與新版本的CCS中所包含SYS/BIOS并不是完全兼容的。此外,如果我們想使用第三方的操作系統,例如VxWorks、us/OS、INTEGRITY等,則要根據這些RTOS的特點(diǎn)進(jìn)行內存的分配與管理。



關(guān)鍵詞: DSP 編程技巧 解惑

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>