純新手DSP程式設計 5 30 任務的通訊和同步

2021-06-06 20:00:20 字數 3906 閱讀 8134

dsp/bios中提供的用於執行緒之間協調的管理模組

1 mbx郵箱管理模組

mbx模組使用一組函式通過郵箱物件的控制代碼管理郵箱的訪問。

通常mbx_pend函式來等待信箱的資訊。這個函式可以帶乙個超時引數,以控制允許任務等待的時間。若引數設為sys_forever,則會引起呼叫的任務無限期地等待郵箱裡的資訊。如果超時值為0,則mbx_pend函式立即返回。其返回值給出了郵箱是否存有資訊。

函式mbx_post用來給信箱傳送資訊,如果有任務在等待該信箱的資訊,該任務會變為就緒狀態,同時mbx_post函式會根據優先順序產生任務切換。如果沒有任務處在等待狀態或者郵箱尚有空間,函式mbx_post會簡單的將資訊儲存在郵箱中並返回。

兩個任務執行緒可以通過郵箱來交換資料。

郵箱大小的單位是:字

(1)mbx_handle mbx = mbx_create(uns msgsize, uns mbxlength, mbx_attrs * attrs)

資訊大小、郵箱長度、目前郵箱引數沒有定義(保留),此函式將呼叫mem_alloc函式建立郵箱資料結構

struct mbx_attrs

(2)void mbx_delete(mbx_handle mbx)

刪除指定郵箱,呼叫mem_free釋放儲存空間

(3)bool status = mbx_pend(mbx_handle mbx, ptr msg, uns timeout)

msg是存放郵箱資訊的指標,如果等待時間大於timeout則返回。如果郵箱中有資訊,此函式將複製第一條資訊到msg所指的儲存空間,返回true,否則函式掛起當前任務,直到超時或呼叫mbx_post函式。

如果timeout取sys_forever,當前任務會一直掛起,直到mbx_post被呼叫,若timeout為0,直接返回。

(4)bool status = mbx_post(mbx_handle mbx, ptr msg, uns timeout)

此函式在將資訊寫入郵箱之前,需要檢查郵箱是否有容納新資訊的空間,若有,寫入並返回。呼叫函式時,若有更高優先順序的任務就緒,或者郵箱已滿且timeout不為0,則任務切換。

同理,如果timeout取sys_forever,當前任務會一直掛起,直到mbx_pend被呼叫,若timeout為0,直接返回。

2 sem旗語管理模組

sem旗語模組使用一組函式通過旗語物件的控制代碼來管理旗語的使用。

dsp/bios提供的旗語實際上是訊號量旗語,該旗語管理模組通過對旗語的計數來完成任務執行緒的同步和互相作用。

sem_post與mbx_post類似。不同的是,若沒有任務在等待旗語,則該函式簡單對旗語計數器加1,返回。

旗語是dsp/bios核心定義的資料結構,用於任務執行緒之間的通訊,同步以及訪問共享資料,當乙個任務執行緒在等待旗語訊號時,它將暫停執行,並產生任務切換。只有當其他任務傳送旗語訊號後,該執行緒任務將轉變為就緒狀態,等待執行。

(1)int count = sem_count(sem_handle sem)

返回sem制定的旗語計數器的當前值

(2)int count = sem_create(int count, sem_attrs * attrs)

傳入初始的旗語訊號量計數值和屬性引數(目前無定義,保留)成功則返回物件控制代碼,否則返回null

(3)void sem_delete(sem_handle sem)

刪除指定的旗語,並且呼叫mem_free函式釋放空間

(4)void sem_ipost(sem_handle sem)

使得處於等待旗語的任務由阻塞狀態(blocked)變為就緒狀態(ready).如果沒有等待旗語的任務,函式僅僅對訊號旗語計數器加1並返回。

此函式類似於sem_post函式,一般地在swi或者hwi中使用sem_ipost函式,在任務執行緒中使用sem_post函式。

(5)void sem_new(sem_handle sem, int count)

初始化指定旗語物件的計數器,只能用於靜態建立的旗語計數器進行初始化,調此函式不發生任務切換。

(6)bool status = sem_pend(sem_handle sem, uns timeout)

如果旗語計數器大於0,此函式對旗語減1返回true,否則會暫停當前任務的執行,直到該函式的旗語達到。

在timeout時間之後,暫停的任務會變為就緒,若timeout等於sys_forever,則必須有sem_post函式才能取消。

若超時,函式返回false。若旗語計數器為0,而超時引數不為0,則任務切換

(7)void sem_post(sem_handle sem)

類似於sem_ipost函式。

(8)void sem_reset(sem_handle sem, int count)

復位旗語計數器並重新開始計數,調此函式不發生任務切換。

3 que佇列管理模組

概述:que模組通過佇列控制代碼的訪問來管理一系列佇列操作函式。

每個佇列包含0個或者多個有序的元素項,其中每個元素項都是乙個結構體變數。

它的第乙個成員是型別為que_elem的變數,該結構體成員用作內部指標。

(1)que_handle queue = que_create(que_attrs * attrs)

佇列屬性引數目前保留。成功返回新佇列物件控制代碼,失敗返回null。

(2)void que_delete(que_handle queue)

刪除佇列

(3)ptr elem = que_dequeue(que_handle queue)

刪除佇列最前面的元素項並返回該項的指標,此指標是乙個指向結構體的指標,該結構第乙個成員必須是

que_elem型別的成員。

注意:多工共享佇列時:使用que_get函式,此函式取元素時禁止中斷。

(4)bool empty = que_empty(que_handle queue)

判定佇列是否為空

(5)void que_enqueue(que_handle queue, ptr elem)

在隊尾插入乙個元素項,引數elem是乙個指向結構體的指標。

注意:多工共享佇列時:使用que_put函式,此函式取元素時禁止中斷。

(6)void * elem = que_get(que_handle queue)

如果佇列不為空,則此函式刪除最前面元素項,並返回指向其的指標,如果隊列為空,返回此佇列本身。

判定佇列是否為空的方法:

if( (que_handle)(elem = que_get(q))!=q )//佇列非空

(7)que_elem * elem = que_head(que_handle queue)

返回乙個指向佇列中最靠前元素的指標,隊列為空,返回此佇列本身。

(8)void que_insert(ptr qelem, ptr elem)

在原佇列的qelem前面插入新元素項elem,多工共享佇列時,此函式應和一些避免衝突的函式配合使用。

(9)void que_new(que_handle queue)

初始化指定的佇列物件,使佇列變空。

當使用變數說明方法靜態建立佇列時,初始化此佇列。若佇列原來為空,其元素不被處理,而是遺棄。

(10)ptr elem = que_next(ptr qelem)

返回元素qelem的下乙個元素項的指標,多工共享佇列時,此函式應和一些避免衝突的函式配合使用。

(11)ptr elem = que_prev(ptr qelem)

返回元素qelem的前乙個元素項的指標,多工共享佇列時,此函式應和一些避免衝突的函式配合使用。

(12)void que_put(que_handle queue, void * elem)

在隊尾新增元素項,自動禁止中斷

(13)void que_remove(ptr qelem)

刪除佇列中的元素項,由於佇列是雙向鍊錶,所以不要刪除頭結點。

任務之間的共享資源與同步

併發程式設計7 任務取消

通常如下情況會取消 1.使用者發起取消請求 2.現實的活動 3.分解任務其中一條發現了解決方案,其他的就可以取消了 4.分解任務其中一條發現了對於其他任務都有影響的錯誤,比如磁碟空間已滿,其他的可以取消了 5.關閉,當執行器關閉的時候,必須對正在處理及等待處理的任務進行優雅的關閉。乙個最簡單的方式是...

純新手DSP程式設計 5 15 CCS簡述

從昨天開始,自己從vc開發轉向的dsp程式設計,工作需要,呵呵,知識還是自己的,認真學習。ccs最早是由go dsp公司為ti公司的c6000系列開放的,後來ti收購了go dsp,並將其擴充套件到它的其他系列。c3x中沒有dsp bios功能,因此為了區別,將c3x稱作cc。折騰了兩天,乙個編譯環...

RTAI的使用者空間程式設計(一) 任務建立

實時任務的建立主要完成對代表實時任務實體的任務結構變數的初始化操作,包括分配任務棧 初始化任務棧 初始化鍊錶指標等。1.函式 rt task rt task init unsigned long name,int priority,int stack size,int max msg size rt...