C6000系列屬于高端DSP芯片,開發(fā)起來有一定的難度。在開發(fā)過程中難免遇到很多的困難和問題,下面就其中一些問題及解決辦法加以討論。
2.2.1 程序初始化問題 C6000 DSP程序的開發(fā)最好在TI提供的例子程序基礎(chǔ)上進(jìn)行相應(yīng)的修改,這樣不僅方便快捷,也可以避免很多意想不到的問題。我們的DM642用戶程序就以NDK的“client”例子為基礎(chǔ)修改而得。其中程序的初始化主要在DM642的初始化程序dm642init.c中和主程序client.c的開頭部分。在dm642init.c中,對(duì)緩存、網(wǎng)絡(luò)物理地址等進(jìn)行了初始化;而在client.c中,則是對(duì)中斷、EDMA等進(jìn)行初始化。 在dm642init.c中主要的初始化為以下幾行語句: CSL_init(); //初始化芯片函數(shù)庫 CACHE_clean(CACHE_L2ALL,0,0);//清緩存 CACHE setL2Mode(CACHE_128KCACHE);//將L2緩存設(shè)為128K CACHE_enableCaching(CACHE_EMIFA_CE00);//允許外存CEOO作為緩存 CACHE_enableCaching(CACHE_EMIFA_CE01);//允許外存CE01作為緩存 //Init the EVM //EVMDM642_init(); //EVMDM642_LED_init(); L2緩存即為DM642的內(nèi)部RAM,大小共256k,既可以設(shè)為緩存也可以設(shè)為內(nèi)存。網(wǎng)絡(luò)收發(fā)數(shù)據(jù)需要至少開辟64k的緩存,緩存越大性能越好。由于程序還要使用一部分內(nèi)存,因此以設(shè)128k緩存為宜。 CACHE_enableCaching (CACHE_EMIFA_CE00)和CACHE_enableCaching(CACHE_EMIFA_CE01)的作用是開辟外存空間作為緩存,CE00對(duì)應(yīng)外部RAM 的0x80000000~0x80FFFFFF空間,而CE01對(duì)應(yīng)外部RAM 的0x81000000~0x81FFFFFF空間。在我們的開發(fā)板上的實(shí)踐證明,這兩個(gè)函數(shù)是必須的,如果不用,網(wǎng)絡(luò)的性能要受到很大影響。 最后兩個(gè)函數(shù)EVMDM642_LED_init()和EVMDM642_init()只適用于DM642EVM板,與板上的FPGA有關(guān),而該FPGA的內(nèi)部邏輯沒有公開,所以在我們的開發(fā)板上這兩個(gè)函數(shù)不能夠正確運(yùn)行。實(shí)踐證明,在開發(fā)板上去掉這兩個(gè)函數(shù)對(duì)程序性能影響不大。
在主程序client.c中,主要對(duì)中斷、EDMA的通道等進(jìn)行初始化。 EMIFA_config(&emifaCfg0); //設(shè)置EMW IRQ_reset(IRQ_EVT_EDMAINT);//復(fù)位IRQ IER=0x303; //設(shè)置中斷寄存器 EDMA_config(hEdmaCha5,&edmaCfg0);//設(shè)置EDMA IRQ_enable(IRQ_EVT_EDMAINT);//允許IRQ HWI_enable(); //開硬件中斷 EDMA_intEnable(2); //允許EDMA中斷 EDMA_enableChannel(hEdmaCha5);//允許EDMA通道5 值得特別注意的是,DM642的網(wǎng)絡(luò)發(fā)送之后,需要重新將緩存初始化,否則下一次接收時(shí)就會(huì)有個(gè)別數(shù)據(jù)出錯(cuò)。具體原因有待研究。即將以下語句寫入到網(wǎng)絡(luò)發(fā)送程序之后: CACHE_clean(CACHE_L2ALL,0,0); CACHE_setL2Mode(CACHE_128KCACHE); CACHE_enableCaching(CACHE_EMIFA_CE00); CACHE_enableCaching(CACHE_EMIFA_CE01); 2.2.2 硬件中斷對(duì)網(wǎng)絡(luò)程序的影響 以太網(wǎng)協(xié)議屬于非實(shí)時(shí)網(wǎng)絡(luò)協(xié)議,其內(nèi)部實(shí)現(xiàn)機(jī)制也比較復(fù)雜。TI的NDK開發(fā)包中提供了符合berkeley socket標(biāo)準(zhǔn)的網(wǎng)絡(luò)函數(shù),如socket(),listen(),accept(),send(),recv()等等,但其內(nèi)部源代碼是不公開的。在實(shí)踐中,我們遇到的一個(gè)較為突出的問題是,在數(shù)據(jù)量較大的情況下,F(xiàn)IFO的中斷次數(shù)如果太頻繁,會(huì)影響到DM642的網(wǎng)絡(luò)發(fā)送。具體表現(xiàn)為程序運(yùn)行并非十分平穩(wěn),中斷較為頻繁的時(shí)候,網(wǎng)絡(luò)發(fā)送函數(shù)send()有時(shí)就會(huì)報(bào)錯(cuò),返回(-1),導(dǎo)致該幀數(shù)據(jù)發(fā)送失敗。 如果數(shù)據(jù)量較大且對(duì)數(shù)據(jù)信號(hào)處理實(shí)時(shí)性要求較高,那么該問題就會(huì)比較棘手,目前我們還未能夠完全解決。但根據(jù)目前我們的需要,可以將網(wǎng)絡(luò)發(fā)送的間隔時(shí)間延長。每次FIFO數(shù)據(jù)存滿后,通過EDMA傳輸?shù)酵獯嬷?,但卻不是每次存滿都進(jìn)行網(wǎng)絡(luò)發(fā)送。而是將數(shù)據(jù)累積起來,多次的傳輸數(shù)據(jù)一起發(fā)送。這樣的網(wǎng)絡(luò)發(fā)送出錯(cuò)率會(huì)小得多。在軟件編程上,也可以考慮雙buffer甚至3個(gè)buffer的方式。一個(gè)buffer滿后,進(jìn)行發(fā)送,而此時(shí)的FIFO數(shù)據(jù)導(dǎo)入另外的buffer中,如此循環(huán)。另外軟件上還需考慮容錯(cuò)機(jī)制,一次數(shù)據(jù)發(fā)送失敗后,需要將該數(shù)據(jù)包重新發(fā)送,從而保證不丟失數(shù)據(jù)。事實(shí)上,以太網(wǎng)的速度是很快的,如圖5所示,目前的DM642的網(wǎng)絡(luò)接口我們實(shí)測的速度可以達(dá)到10-11 Mbyte/S(百兆網(wǎng)即100 Mbit/s,換算成字節(jié)大約11~12Mbyte/s)。需要指出的是,同樣的數(shù)據(jù)流量條件下,大量的數(shù)據(jù)集合到一起一次發(fā)送,相比與分多次發(fā)送少量數(shù)據(jù),要穩(wěn)定得多。目前我們可以做到3 S發(fā)送一次,每次發(fā)送約5M 數(shù)據(jù)的較為穩(wěn)定地程序運(yùn)行,相信經(jīng)過改進(jìn),還有較大的提高空間。 2.2.3 其它常見問題 參考文獻(xiàn)[1]P44上提供了常見問題的列表,比如調(diào)用fdOpenSession()和fdCloseSession()的問題,PRD函數(shù)中設(shè)置100 ms周期的問題,內(nèi)存溢出問題(設(shè)置“SO_LINGER”選項(xiàng))等等,以及其他文獻(xiàn)[5]上提到的“dispatcher選項(xiàng)”問題,上述問題筆者在實(shí)踐中均遇到了,因此仔細(xì)閱讀文獻(xiàn)資料可以少走彎路。 3 結(jié)論 參考文獻(xiàn): |
|