調試經驗--davinci特性
每一個硬體平台,都有別的平台所沒有的特性。
這裡,我把我調試dm6446過程中遇到的平台特性相關問題總結了一下:
1,硬體resize的使用;2,davinci的地址分析;3,共用記憶體CMEM的使用。
一,6446的resize調試:
6446的dvsdk中有兩個常式,一個是視頻環路loop,一個是編解碼encodedecode,而我需要一個結合了dsp調用的視頻環路程式,所以,將兩個常式進行了整合。
整合之後,DSP端演算法程式運行不起來。
首先簡化,將dsp演算法簡化為空白,可以執行。然後逐步添加功能模組,經過多次測試後發現,竟然是硬體resize的問題!
跟蹤查看應用程式,發現ARM端的smooth與resize,其實與DSP端的硬體resize用的是同一個硬體。
在arm端已經使用了硬體resize,然後在dsp端又使用了硬體resize,兩邊的配置不一致,根本問題可能是兩個核(arm與dsp)同時訪問了同一個硬體
(硬體resize),從而導致異常了。
在dsp端改用for迴圈實現resize,程式就可以正常運行了。
反過來,去掉arm端的resize配置,而dsp啟用硬體resize,程式也能運行,但是發現映像抖動加大,效果不好,未採用。
最終方案:改為在arm端resize,dsp端直接使用縮放後的映像。這樣,既保證了只有一個核訪問硬體resize,同時又兼顧了運行效率。
由於smooth並沒有改變映像的大小,嘗試使用memcpy代替resize。
在ARM端操作時:注意物理地址與虛擬位址的區別。
resize的buf地址參數,使用物理地址;
memcpy的buf地址參數,使用虛擬位址。
替換之後也能正常運行。但是考慮到smooth對映像有處理平滑的效果,最終沒有替換。
目前arm端使用了3次resize,1,capture,2,video中reduce,3,display 。
需要避免配置的衝突:在capture,display,video中都要先配置後執行。
嘗試正常化resize的配置函數Rszcopy_config_reduce():
統一到一個函數後,運行發現映像顏色異常(都使用縮小的過濾參數)。
結論:不同比例的resize,使用的過濾參數也不同,不能簡單統一到一個函數中。
6446對標清映像進行硬體resize的執行,每次耗時約6-7ms,運行時resize的調用線程阻塞,此時resize是由硬體執行的,而ARM轉移給其他線程。對比使用for迴圈實現的軟體resize,可以觀察到ARM佔用率明顯下降。
二,davinci的地址分析:
arm端的應用程式,使用虛擬位址;
dsp端演算法,使用物理地址。
arm給dsp傳遞參數時,若是指標,必須使用物理地址。
使用codec engine進行緩衝傳遞時,dsplink會有一個地址的轉換,編程時不用考慮差異。
在arm端應用程式中,若直接使用物理地址,賦值給指標,會導致系統異常。
三,共用記憶體CMEM的使用
對於共用記憶體CMEM的使用,需要非常的注意。首先,其總大小是有限的,一般分配為8M。對於視頻處理的演算法,總是需要傳遞整幀的映像進行處理,如果還要有多緩衝以進行並行的處理,很可能共用記憶體就不夠用了。其次,共用記憶體使用量容易出錯,必須有相應的保護。我們的經驗是:
(1) 儘早的提取映像中的有用資訊,以在後續的傳遞過程中減小記憶體的使用;
(2) 較多的使用控制標誌,以達到一塊記憶體地區實現多種使用功能的效果。
(3) 需要嚴格的將輸入變數與輸出變數分離,在ARM端將意義相同的變數值統一。
(4) 需要特別注意的是,必須將公開變數進行保護,在某一個時刻只允許ARM或DSP中的一個來進行訪問。
共用記憶體配置函數樣本:
buf = (char *)Memory_contigAlloc(bufSize, 128);
取物理地址樣本:
physaddr = Memory_getBufferPhysicalAddress((char *)buf,4,NULL);
關聯標頭檔:
#include "/root/dvsdk_3_10_00_19/codec_engine_2_25_05_16/packages/ti/sdo/ce/osal/Memory.h"
需要開闢連續記憶體,擷取物理地址,都與cmem相關,需要工具鏈的支援。 不能使用arm-gcc單獨編譯,需要使用dvsdk中的xdc。