DSPLINK 介紹

 DSPLINK幾乎是DAVINCI平臺最重要的一個底層系統,它是ARM+DSP平臺上特有的。DAVINCI之所以能成爲現在的DAVINCI,有一大部分就是因爲有DSPLINK把GPP(General Purpose Processor, 即DM6446中的ARM)和DSP給連起來了。

TI期望大家使用的是它的CODEC ENGINE,因爲如果使用CODEC ENGINE,很多底層的細節對開發者就是透明的了。而爲了更深入地瞭解DAVINCI系統,爲了不做“不明真相”的高層代碼開發者,或者只是爲了追求GEEK的精神,我們應該去了解DSPLINK的結構和原理。BY THE WAY,這就是在學校裏的好處,不用去關心產品的上市時間,愛幹什麼幹什麼。

不過,這篇文章只是“佔座”性質的文章。我還沒有深入地去看DSPLINK的源碼,在這裏只是先把以前理解到的東西總結一下先。以後認真看了再補上。我想,DSPLINK的結構對於以後對異構多核間的通信是有借鑑意義的。

要使用DSPLINK的話,有下面那麼幾步:

  1. OF COURSE, 把環境給搭起來,重新編譯。
  2. OF COURSE, 把DEMO給跑起來。
  3. 理解DSPLINK的相關知識:內存分配及其他。
  4. 分析DEMO,修改DEMO爲已所用。
  5. 修改DSPLINK,爲已所用。最高境界也~

以下的內容主要是關於3,4兩步的。

系統結構

先上圖:

 

發現沒有,位於上層的幾個模塊都有PROC, CHNL, MSGQ等幾個小模塊,所以DSPLINK的縱向(就是從上層到下層)是用這幾個線貫穿的。

下面這是dsplink的目錄結構,可以看到和上圖中的模塊是大致對應的。每一個模塊都放在一個文件夾下。

.
./pmgr
./gen
./osal
./probe
./api
./ldrv

API

api文件夾裏是暴露給外部用戶使用的接口,放在這裏的接口才能被外界調用,所以說,要修改DSPLINK的源碼爲已用,得把增加的接口放在這裏。DSPLINK USER GUIDE(在DSPLINK的安裝目錄裏的DOC文件夾下)給出的接口都在這個api文件夾下定義。DSPLINK的每一個模塊都會暴露一些接口給它的上一層,api這一層就把接口暴露給用戶使用。

Processor Manager

pmgr文件夾裏就是Processor Manager的代碼。Processor Manager,顧名思義,提供對處理器的控制。這是核心的一個模塊,其他模塊對它進行支持。比如通過CHNL傳送數據時,Processor Manager作爲一個上層的“管理者”,Linux Driver層對其進行底一層的驅動支持。Generic Source Modules(GEN)對其進行一些常規的模塊的支持,比如要加載COFF格式的鏡像,就要使用GEN裏對COFF的支持。

Link Driver

Link Driver的代碼在ldrv文件夾下。如上圖所示,主要完成的是通信的工作。

通信有兩種:

一是CHNL,這種通信的DEMO是LOOP。這種通信是同步的,有ISSUE和RECLAIM兩種操作。流程大致是這樣(摘自USER GUIDE(dsplink 1.40)的Appendix, Issue reclaim model):

The steps for data transfer with issue reclaim model may be summarized below:

1.  Open a channel with defined buffer size & direction.

2.  Issue a buffer for IO on the specified channel

Empty buffer for receiving data

Filled buffer for sending data

3.  Attempt to reclaim the buffer. Reclaim will block until the IO operation completes

or a timeout occurs.

This wait can be postponed to a later point in time for asynchronous IO.

4.  A client must reclaim all the buffers issued to a channel.

二是MSGQ,也有個DEMO。這種通信是異步的。

反正這兩種通信都要driver的支持。

Link Driver還要包括對ZCPY和PCPY兩種傳輸模式的支持。ZCPY就是Zero Copy,就是不COPY,只傳指針。PCPY好像是Processor Copy,反正是要COPY數據。CHNL和MSGQ都可以選是使用ZCPY還是PCPY。

Operating System Adaptation Layer (OSAL)

這是DSPLINK和OS的“國界”,DSPLINK和操作系統之間的協作通過OSAL來進行。OSAL模塊使得DSPLINK具有可移植性。

Probe

還有一個文件夾叫probe,是用來在實際使用DSPLINK裏來評估其性能的。

內存管理

內存管理是使用DSPLINK時一定要理解的一個東西。這些內存是怎麼分配,怎麼用的,在哪些地方管理它的屬性。要了解了這些才能看懂DEMO的代碼,才能修改代碼爲已所用。

BUFPOOL/SMAPOOL的結構如圖所示。有一個BUFPOOL的結構體,在其中可以設定有多少個MPBUF,每一個MPBUF對應一個Buffer POOL,每一個Buffer POOL有一些BUFFER,這些BUFFER的大小是相同的。

DSPLINK中有一個結構體是SmaPoolAttrs,這個結構體用於指定上圖中結構的屬性。其中numBufPools指的是number of buffer pools,即Buffer POOL的個數,上圖中可以看到的個數是3。bufSizes是一個數組,每一個元素存儲的是上圖中淺色部分BUFFER的大小,如{2,3}指的是第一個Buffer POOL中的buffer的大小爲2,第二個Buffer POOL中的buffer大小爲3。numBuffers是指number of buffers,即一個Buffer POOL中所含的buffer的個數,如numBuffers的值爲{6,8},那麼第一個Buffer POOL中有6個buffer,第二個buffer POOL中有8個buffer。還有一個屬性是exactMatchReq,如果此值爲true的話,則實際分配內存時,請求的內存大小一定要和buffer的大小一樣,即爲bufSizes,不然的話不會分配;如果此值爲false,那麼系統就會去找大於所請求的大小的內存。這裏有個規則的,我忘了…好像DSPLINK的安裝文件夾裏的POOL或者SMA POOL文檔中有寫。

瞭解了結構之後,Demo中的關於內存配置的宏就能看懂並修改了。

這裏有TI給的pool的overview.

下面給出幾個使用POOL時的注意事項和troubleshooting。

Troubleshooting

1

在Demo Loop裏,傳輸的大小隻能是128的倍數,但64, 129就不能傳,這是因爲數據對齊的關係。具體我也記不得是怎麼樣了,可以看看源碼裏DSPLINK_ALIGN這個宏的說明。

2

Demo Loop的debug版本在內存分配時會有問題,不要使用make出來的debug版本的loop。

3

錯誤現象

Encodedecode Debug: POOL0: Buffer Size of each Buffer = 691200.

Encodedecode Debug: POOL0: Number of Buffers in a buffer Pool = 1

POOL_Open () failed. Status = [0x80008013]

解決方案:

主要是buffer開得不夠大的問題

http://wiki.davincidsp.com/index.php/DSPLink_POOL_FAQs

http://wiki.davincidsp.com/index.php/Changing_DSPLink_POOL_size

解決這個問題要修改一個配置文件,上面的網頁指示的文件可能是新一點的版本里的,在我所使用的dsplink 1.30中,實際應該修改的是$(DSPLINK)/config/all/CFG_Davinci.TXT

4

錯誤現象

DEMO LOOP 中DSP端無法接收GPP端發送來的數據

原因

loop.c中將


/** =============================================

*  @name   NUMBUFS

*

*  @desc   Number of buffers in pool.

*  ====================================== */

#define NUMBUFS        4

改成了1。

Debug過程及解決

loop.absClean將傳691200的數據後,將NUMBUFS改成1,出現下面的錯誤。

=============== Sample Application : LOOP ==========

Entered LOOP_Create ()

Leaving LOOP_Create ()

Entered LOOP_Execute ()

Before CHNL_Issue() out

Before CHNL_Reclaim() out

即在CHNL_Reclaim裏停了下來

將其改回4後,可正常傳送。

5

錯誤現象

[email protected]:/opt/ttroot# ./loopgpp loop.out 691200 1

=============== Sample Application : LOOP ==========

Entered LOOP_Create ()

POOL_Open () failed. Status = [0x80008013]

Leaving LOOP_Create ()

Entered LOOP_Delete ()

CHNL_FreeBuffer () failed (output). Status = [0x80008000]

CHNL_Delete () failed (input). Status = [0x80008000]

CHNL_Delete () failed (output). Status = [0x80008000]

POOL_Close () failed. Status = [0x8000800b]

Leaving LOOP_Delete ()

====================================================

原因與解決

這也是因爲dsplink的sma pool不夠大,但是隻是把pool設爲691200*4(*4是因爲loop中的num of buffers的值是4)是不夠的,因爲還有其他的結構體什麼的東西要用內存。當我把sma pool size的值設爲691200*8時,運行成功。

以上內容多爲回憶或潦草的筆記轉化而來,一定得用批判的眼光看…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章