IT技術互動交流平臺

多核DSP快速入門6.IPC的使用+實例分析

來源:IT165收集  發布日期:2016-04-28 21:40:23
IPC是SYS/BIOS處理核間通信的組件 IPC的幾種應用方式(下面中文名字是自行翻譯,旁邊有英文=_=||,另外下面的配圖中的藍色表示需要調用模塊的APIs,而紅色模塊表示僅僅需要配置(如在.cfg中配置),而灰色模塊表示是非必須的): (1)最小使用(Minimal use):這種情況是通過核間的通知機制(notification)來實施的,而一個通知所攜帶的信息是非常小的(一般是32bits),所以稱為最小使用。這種方式一般是用于處理核間的簡單同步,卻無法處理復雜的消息傳遞。
 這種情況下,需要利用到Notify模塊的APIs函數,比如通過Notify_sendEvent()函數給某個特定核傳遞一個事件,我們可以給特定事件動態注冊反饋函數。由于一個通知(notification)所攜帶的信息是極少的,所以只能給處理器發送一個事件號,而這個事件號所代表的反饋函數決定之后的動作。另外一些數據以函數參數方式,也可以被送出。 (2)增加數據通路(Add data passing):這種情況是在前面的最小使用機制下,在核間增加了一個傳遞鏈表元素的數據通路,這個鏈表的實施一般是使用共享內容并通過門(gates)來管理同步。
這種情況是在最小使用上,增加了一個ListMP模塊用于共享鏈表元素。 ListMP模塊是一個雙向鏈表,另外ListMP需要用到共離內存,所以SharedRegion模塊也需要被使用,另外ListMP通過NameServer模塊中來管理名稱/值,同時使用GateMP模塊來防止鏈表元素被多個處理器同時讀取。 (3)增加動態分配(Add dynamic allocation):這種情況下,增加了從堆中動態分配鏈表元素的功能。
這種情況在上種情況下,增加了一個Heap*MP模塊,這個模塊主要用于從堆中給鏈表動態分配內存 (4)強大但易用的消息機制(Powerful but easy-to-use messaging):這種情況下利用MessageQ模塊來傳遞消息。
除了Notify通知機制,還可以利用MessageQ來實現更為復雜的核間通信,在這種情況下,只需要配置MultiProc和SharedRegion模塊就可以了,而Ipc_start()函數將自動為我們實現上面灰色模塊的配置。 本節,我們暫時只以一個簡單的最小使用(Minimal use)情況為例,分析CCS自帶一個多核通信例子,這個例子在八核之間相互傳遞信息,之后我們總結核間傳遞方法實現步驟,實現一個主從核之間傳遞信息的功能。
一、打開CCS自帶例程 打開CCS自帶例程的方法和新建CCS項目是一致,只是需要在Project templates and examples中選擇我們需要的例子,這里的例子是在IPC and I/O Examples中選擇C6678 Examples中的Notify,然后輸入項目名稱后,CCS會自行將例子復制到項目下。
二、生成項目后,編譯調試查看運行結果 (1)點擊編譯后,查看有無出錯 (2)導入目標配置文件.ccxml,這里選擇的仍然是C6678 Device Functional Simulator, Little Endian. (3)點擊調試,選擇所有的核 (4)全選所有的核(通過Shift),然后Groups
(5)選中Group,點擊運行 三、分析運行結果 這個例程除了調用Notify模塊,在核間傳遞消息,通過反饋函數觸發核的動作,同時通過Semaphore模塊來保證核間依次執行,防止搶占,這里每個核都有一個信號量,來表明其當前是否執行或等待其它核執行完成。 (1)各核打印
這段是在main()中出現的結果,每個核都會執行各自的main()。
各核注冊事件,并表明其反饋函數
(2)核0執行同時釋放信號量,在核0釋放信號量semHandle之前,其他核都處理等待信號量釋放中
核0通過給核1發送事件,觸發反饋函數,在反饋函數中semHandle歸一,注意這個激活的信號量是在核1中的
激活核1的信號量后,核0打印結果,并等待其信號量的結果,所有核的信號量都初始為0
(3)以下是總共八個核,分別執行了NUMLOOPS次(這里設置的是10次)
下一個核信號被激活,開始執行
同時通過反饋函數將當前核的下一個核激活
完成發送事件
(4)退出任務循環,同時退出當前核的BIOS

四、多核IPC的配置 (1)IPC的啟動非常簡單,在導入Ipc頭文件后,在main()函數中調用Ipc_start()就能根據.cfg文件中配置啟動IPC所需要的模塊,比如默認情況下Ipc_start()會調用Notify_start()之類,不過要啟動這些模塊,需要保證提前在.cfg中添加了這些模塊(如右擊模塊,選擇Use) (2)IPC的配置是在.cfg中完成的,配置IPC首先需要申明,當前Notify等相關模塊也需要提前申明,這里如果不清楚IPC所需要的相關模塊,最好使用自帶IPC例程作為模塊。 var Ipc = xdc.useModule('ti.sdo.ipc.Ipc'); (3)設置同步的核數 Ipc.procSync = Ipc.ProcSync_ALL; 這里Ipc.ProcSync_ALL 表示Ipc_start會自動將所有的核都啟動了 Ipc.ProcSync_PAIR 表示只啟動部分核,需要啟動的核要通過Ipc_attach()來啟動,這個默認選項 Ipc.ProcSync_NONE 表示Ipc_start()不會同步任何核 (4)核間的連接方法Ipc_attach()及Ipc_detach() 這兩個函數的使用,需要.cfg文件中配置了Ipc.ProcSync_PAIR Ipc_attach的使用方法非常簡單,在Ipc_start()之后直接輸入: Ipc_attach(#coreID),#coreID表示需要連接的核ID號,如Ipc_attach(0)表示連接核0。 不過需要注意的是: a) 核的連接一定要按照ID號從小到大的順序進行,比如當前核必須先連接了核0,才能連接核1,之后才能連接核 b) 另外兩核之間的相互連接必須先滿足ID號小的先連接ID號大的,比如只有當核0連接核1后,核1才能連接到核0 c) 由于核的連接并不是一次就能成功的,所以一般需要加一個循環等待的過程,一般使用方法如下: while(Ipc_attach(#coreID)<0){ Task_sleep(1); } Ipc_detach()的使用方法同Ipc_attach()是類似的,不過它的功能是解除連接。
五、主從核之間的通信 前面介紹IPC核間通信例子,是每個核同所有核之間都有連接,而各核之間連接都是相同且雙向,而在很多情況下,我們并不需要如此多的核,或者許多核間連接也是不必要的,這些情況下使用Ipc.ProcSync_ALL未免太不高效。 下面我們介紹的例子是核間的主從通信,選擇三個核,選擇一個主核,另外兩個是副核,主核core0同副核之間有相互連接,而副核core1與副核core2之間沒有連接,這個主從通信主要完成以下事件 a) 主核向兩從核發送事件,激活從核,使其執行任務 b) 兩核完成任務后,向主核發送事件,主核繼續執行其任務。 這個例程主要有如下內容: (1)在.cfg文件中設置procSync 改為Ipc.procSync = Ipc.ProcSync_PAIR;
(2)定義主從核ID
(3)在main()函數Ipc_start()后增加如下代碼:
a) 這里主要根據主核和從核的角色分別添加連接任務:主核同兩個從核都有連接,而從核只與主核有鏈接 b) 在添加核間連接后,分別給核間連接注冊事件 (3)在任務函數tsk0_func內分別根據主核及從核的角色添加發送與接收函數,下面是以主核為例
主核在給從核分別發送事件后,通過Semaphore_pend等從核將主核的信號量激活,之后繼續主核任務。 同時只有當主核通過給從核發送事件,從核的注冊函數激活信號量,從核才能開始任務。 (4)仿真調試的結果
從結果上看,當從核分別收到了來自主核的事件時,同時開始任務,當從核任務全部完成后,主核才開始其任務
Tips: a) 這里需要注意的是在注冊函數內不要加System_printf()函數,這個函數會導致如下錯誤產生: ti.sysbios.gates.GateMutex: line 97: assertion failure: A_badContext: bad calling context. See GateMutex API doc for details. xdc.runtime.Error.raise: terminating execution b) 上面的代碼并不是全部 例程代碼下載地址:https://github.com/tostq/EasyMulticoreDSP/tree/master/6.IPC_notify
Tag標簽: 多核   實例分析  
  • 專題推薦

About IT165 - 廣告服務 - 隱私聲明 - 版權申明 - 免責條款 - 網站地圖 - 網友投稿 - 聯系方式
本站內容來自于互聯網,僅供用于網絡技術學習,學習中請遵循相關法律法規
香港最快开奖现场直播结果