基礎類的DSP/BIOS API調用
一、時鐘管理CLK
(1)Uns ncounts = CLK_countspms(void)
返回每毫秒的定時器高解析度時鐘的計數值
(2)LgUns currtime = CLK_gethtime(void)
返回高解析度時鐘的計數值 超過32bit歸零
高解析度時鐘是DSP時鐘除以(TDDR+1)
(3)LgUns currtime = CLK_getltime(void)
返回低解析度時鐘的計數值 超過32bit歸零
高解析度時鐘是DSP時鐘除以(TDDR+1)再除以(PRD+1)
(4)Uns period = CLK_getprd(void)
返回CLK管理器周期寄存器的值
二、周期函數PRD
(1)LgUns num = PRD_getticks(void)
返回32位周期函數管理計數值
(2)void PRD_start(PRD_Obj* period)
啟動PRD模組計數器,一般地,mode=one-shot
(3)void PRD_stop(PRD_Obj* period)
關閉PRD模組計數器
(4)void PRD_tick(void)
對周期模組的計數器加1,以便周期模組管理器確定哪個周期性函數得以運行
三、軟體中斷管理SWI
(1)void SWI_andn(SWI_Obj* swi, Uns mask) mask 屏蔽字參數
將郵箱值與mask做與運算,並用結果代替以前的郵箱值,若為0,啟動軟體中斷,恢複郵箱初始值
(2)void SWI_andn(SWI_Obj* swi)
將郵箱值減1,並用結果代替以前的郵箱值,若為0,啟動軟體中斷,恢複郵箱初始值
(3)void SWI_disable(Void)
禁止軟體中斷
(4)void SWI_enable(Void)
使能軟體中斷
(5)Uns num = SWI_getmbox(void)
返回當前SWI對象在被執行的郵箱值,若中斷已經開始執行,DSP/BIOS會先儲存此值
(6)Uns key = SWI_getpri(SWI_Obj * swi)
返回指定的SWI對象的優先順序
(7)void SWI_inc(SWI_Obj * swi)
將指定的SWI對象的郵箱值加1,同時啟動軟體中斷,就算使用者調用多次,最終執行一次。
(8)void SWI_or(SWI_Obj* swi, Uns mask) mask 屏蔽字參數
將啟動指定的軟體中斷,並將此軟體中斷的郵箱值與mask做與運算,並用結果代替以前的郵箱值,
等到中斷完成之後,郵箱值恢複為初始值,一般地,調用SWI_getmbox獲得觸發此軟體中斷的郵箱值
(9)void SWI_post(SWI_Handle swi)
啟動指定的SWI對象的軟體中斷,此函數不受郵箱值的影響,也不影響郵箱值。
一般地,周期性低啟動一個軟體中斷,將_SWI_post填入PRD對象的函數設定欄,啟動軟體中斷的參數寫入arg0
(10)Uns key = SWI_raisepri(Uns mask)
提高SWI軟體中斷的優先順序,一般地
key = SWI_raisepri(SWI_getpri(&swi_1));
--access shared resouces--
SWI_restorepri(key)
(11)void SWI_restorepri(Uns key)
恢複原來的優先順序
(12)SWI_Obj * swi = SWI_self(void)
當前執行的SWI對象的軟體中斷的地址
四、資訊輸出管理LOG
(1)void LOG_disable(LOG_Obj * log)
關閉指定對向的日誌功能
(2)void LOG_enable(LOG_Obj * log)
開啟指定對向的日誌功能
(3)void LOG_error(String format, Arg arg0)
void LOG_message(String format, Arg arg0)
前一個函數可以將一個事件、資料或出錯資訊按照指定的格式串寫入系統日誌,不受TRC跟蹤管理模組的影響
後一個函數類似於前一個函數,但是受到TRC跟蹤管理模組的影響
(4)void LOG_event(LOG_Obj * log, Arg arg0, Arg arg1, Arg arg2)
將未格式化的事件訊息寫入日誌中
(5)void LOG_printf(LOG_Obj * log, String format, int arg0, int arg1)
指定的LOG視窗顯示訊息 %d %x %o %s
(6)void LOG_reset(LOG_Obj * log)
複位日誌緩衝區
五、儲存空間管理MEM
(1)void * addr = MEM_alloc(int segid,Uns size,Uns align)
指定儲存段分配連續塊,返回起始地址
segid = 儲存段的標識符或者ID號
size 塊大小 等於多少個字
align 邊界條件 只為0或2的冪 若align為0、1 則無約束
(2)void * addr = MEM_calloc(segid, size, align)
分配記憶體並初始化為0
(3)int segid = MEM_define(Ptr base, Uns length, MEM_Attrs* attrs)
定義一個新的儲存段。傳回值為儲存段的ID標號
attr參數為NULL,會按照預設參數進行配置,段的參數由結構體type MEM_Attrs規定
此函數僅在main函數中使用
base: 新段的基地址
length:段長度
attrs:段屬性
(4)bool status = MEM_free(segid,addr,size)
釋放申請的動態記憶體 不能在SWI和HWI中調用
調用之前,用LCK中API查看記憶體塊的鎖定情況
(5)void MEM_redefine(segid,base,length)
重新定義一個儲存段,只能在main中調用
(6)bool status = MEM_stat(int segid, MEM_Stat * statbuf)
segid 儲存段標識符
statbuf 狀態緩衝區指標
struct mem_stat{
Uns size;//儲存段大小
Uns used;//已經使用的數量
Uns length;//最大連續儲存塊長度
}
同理:若segid有效,則MEM_stat返回TRUE
不能在SWI和HWI中使用,應判斷鎖定情況
(7)void * addr = MEM_valloc(int segid, Uns size, Uns align, char value)
先申請記憶體,初始化為指定的值value
六、C6000專用模組C64x
(1)Uns oldmask = C64_diableIER(Uns mask)
關閉相應的中斷 傳回值實際屏蔽的中斷
(2)void C64_enableIER(Uns oldmask)
開放相應的中斷
Uns oldmask;
oldmask = C64_disableIER(0x1); // disable INT0
C64_enableIER(oldmask); // enable INT0
(3)void C64_plug(int vecid, Fxn fxn, int dmachan)
插入一個中斷向量
int vecid: 中斷序號
Fxn fxn: 中斷服務程式的函數指標
int dmachan: 插入操作使用的DMA通道
將ISFP寫到中斷服務表IST中。若IST在外部RAM,則CPU複製代替DMA,此時DMA為-1
IST在片內RAM時,使用DMA方式,是0,1,2,3 使用者保證在函數調用時該DMA通道有效
七、統計模組STS
(1)void STS_add(STS_Obj * sts, LgInt value)
使用我們提供的資料更新STS統計對象的Total,Count,Max等參數
傳入一個32位參數,Count加1,Total累加傳遞的32位參數,MAX記錄傳遞參數的最大值
(2)void STS_delta(STA_Obj * sts, LgInt value)
每個對象都包含有初始值,該初始值由設定檔指定或者由STS_set函數設定
STS_delta先計算當前傳遞參數與先前初始值只差,然後調用STS_add更新統計累加值
一般和STS_set一起用
eg:
STS_set(&sts,CLK_gethtime());
STS_delta(&sts,CLK_gethtime());
(3)void STS_reset(STS_Obj * sts)
複位統計對象中的累加值。Count和Total設定為0.MAX成為最大的負值。
(4)void STS_set(STS_Obj * sts, LgInt value)
監視或統計程式的執行時間
八、統計類別模組TRC
(1)TRC_LOGCLK 日誌記錄定時器中斷
(2)TRC_LOGPRD 日誌記錄周期時隙和周期函數的開始
(3)TRC_LOGSWI 日誌記錄軟體中斷的啟動和完成
(4)TRC_LOGTSK 日誌記錄任務處於準備好、開始、停止、繼續執行、終止等事件
(5)TRC_STSHWI 收集關於HWI統計資料
(6)TRC_STSPIP 寫管道和讀管道幀進行計數
(7)TRC_STSPRD 執行期間CLK時隙個數的統計資料
(8)TRC_STSSWI SWI執行時間的統計資料
(9)TRC_STSTSK TSK執行時間的統計資料 從TSK準備好到調用TSK deltatime都要收集
(10)TRC_USER0 AND TRC_USER1 和TRC_query一起用 執行和忽略結果的裝置調用
(11)TRC_GBLHOST 執行所有的隱藏儀器功能,此位元位能夠開始或停止收集所有開啟的跟蹤類型
(12)TRC_GBLTARG 執行所有的隱藏儀器功能,此位元位只能被目標程式設定
九、任務管理 TSK任務管理模組
(1)void TSK_checkstacks(TSK_Handle oldtask,TSK_Handle newtask)
無論是新任務還是老任務,如果堆棧的最後位置上都沒有RG_STACKSTAMP標識,那麼TSK_checkstacks就會
報錯SYS_abort,出現這種情況可能是由於上一個任務堆疊溢位或無效的儲存佔用了新任務的堆棧
一般地,用TSK_checkstacks(TSK_self(),TSK_self())來檢查堆棧
定義Switch函數,這樣在任務切換時自動呼叫堆疊檢查函數:
void myswitchfxn(TSK_Handle oldtask, TSK_Handle newtask)
{
...
TSK_checkstacks(oldtask,newtask);
...
}
(2)TSK_Handle task = TSK_create(Fxn fxn, TSK_Attrs * attr, Arg [arg,]...)
建立一個調用函數fxn的任務對象,返回新對象的控制代碼,失敗返回NULL。
調用此函數是動態建立,而在組態工具中建立是靜態建立,二者效果一樣。
靜態建立的任務對象,建立函數將在BIOS_start函數中自動調用。BIOS_start函數在main函數之後,
在後台IDL迴圈之前運行。而動態建立的任務處於Ready狀態。函數參數最多不超過8個。
任務對象函數fxn返回時,自動調用TSK_exit函數。
解析:TSK_Attrs * attrs 任務參數指標
struct TSK_Attrs{
int priority;
Ptr stack;
Uns stacksize;
#ifdef _64_ // imitate C55 series. to check
Uns sysstacksize;
#endif
Uns stackseg;
Ptr environ;
String name;
bool exitflag;
}
(3)void TSK_delete(TSK_Handle task)
從所有內部隊列裡面刪除這個任務,並且調用MEM_free釋放任務對象和堆棧。
只能刪除處於結束狀態的任務,也可調用刪除的鉤子函數。
void myDeleteFxn(TSK_Handle task);
(4)void TSK_deltatime(TSK_Handle task)
累計從任務準備好到執行此函數時候的時間差
如果未調用此函數,那麼就算開啟任務統計累加器選項,統計對象也不會更新
一般地,統計時先用TSK_settime函數記錄起始點,此函數記錄終點。
(5)void TSK_settime(TSK_Handle task)
設定統計初始值
void task()
{
--do some startup work--
TSK_settime(TSK_self);
for(;;){
SIO_get(...);
--process data--
TSK_deltatime(TSK_self);
}
}
假如流式IO沒有準備好,那麼該API函數會阻塞(Blocked),任務切換,一段時間後,流式IO資料
準備好了,此時發出READY訊號,將本任務置為ready狀態,此時TSK_settime會重新記錄時間。
(6)void TSK_disable(void)
全域關閉核心調度機制,Busy-Shutting-Down狀態。只有當前任務可行,其餘所有任務禁止。
此函數不會禁止中斷,所以在中斷開始前需要調用此函數保證中斷髮生時不會發生任務切換。
可以嵌套,但是調用幾次TSK_disable,就得相應調用幾次TSK_enable
(7)void TSK_enable(void)
全域開啟核心調度機制
(8)void TSK_exit(void)
終止當前任務運行。如果所有任務都被終止,則DSP/BIOS會調用SYS_exit終止程式。
無論什麼時候,任務從頂層函數返回時,都是自動調用此函數。
可以註冊一個退出輔助函數 void myExitFxn(void)
這樣,在任務被設定為TSK_TERMINATED模式之前,會調用這個輔助函數。
(9)Ptr environ = TSK_getenv(TSK_Handle task)
返回任務環境指標,這個指標指向一個該任務可以訪問的全域屬性的結構。
若程式定義多個鉤子物件,那麼HOOK_getenv函數可以擷取設定的環境指標。
(10)void TSK_setenv(TSK_Handle task, Ptr environ)
設定指定任務的環境指標。
若程式定義多個鉤子物件,那麼HOOK_setenv函數可以為每個鉤子和任務對象的組合體設定獨立的環境指標。
(11)int errno = TSK_geterr(TSK_Handle task)
每個任務對象都有一個包含任務錯誤號碼的儲存單元。初始值為SYS_OK
(12)void TSK_seterr(TSK_Handle task, int errno)
改變錯誤號碼
(13)String name = TSK_getname(TSK_Handle task)
返回任務的名字。
對於靜態對象來說,必須開啟Allocate Task Name on Target
對於動態對象來說,TSK_getname返回attrs.name欄位
(14)int priority = TSK_getpri(TSK_Handle task)
返回優先順序
(15)int oldpri = TSK_setpri(TSK_Handle task, int newpri)
設定優先權
設定優先權對於TSK_BLOCKED狀態任務只是優先順序改變,而不會改變狀態;
對於TSK_READY狀態的任務而言,可能會改變運行狀態。
(16)STS_Handle sts = TSK_getsts(TSK_Handle task)
獲得統計物件控點,以便查看資料
(17)void TSK_sleep(Uns nticks)
暫停任務的時鐘個數,此時鐘數可能比真實的暫停時鐘少一個時鐘(警示時鐘)
(18)void TSK_itick(void)
對警示時鐘加1,以便讓TSK_sleep或者SEM_pend函數暫停執行的任務恢複到ready。
一些暫停任務可能會隨著警示時鐘的增加而逾時,從而就緒。
(19)void TSK_tick(void)
對警示時鐘加1,以便讓TSK_sleep或者SEM_pend函數暫停執行的任務恢複到ready。
一些暫停任務可能會隨著警示時鐘的增加而逾時,從而就緒。
可以在中斷服務程式和當前任務中調用,後者在控制逾時非常有用。
(20)Uns currtime = TSK_time(void)
返回系統警示時鐘的當前值。(由於延遲,只能得到一個大概的系統時鐘)
(21)TSK_Handle currtask = TSK_self(void)
返回當前任務對象的控制代碼
(22)void TSK_stat(TSK_Handle task,TSK_Stat * statbuf)
返回任務的屬性參數和狀態資訊
struct TSK_Stat{
TSK_Attrs attrs;//任務參數
TSK_Mode mode; //任務執行模式
Ptr sp; //任務當前堆棧指標
Uns used; //任務堆棧曾經使用的最大值
}
注意:任務比HWI和SWI中斷優先順序要低,所以當任務被中斷時,還是返回TSK_RUNNING,
因為中斷完成後任務繼續運行。
(23)void TSK_yield(void)
強制任務切換,請注意,任務可以被中斷,但是,任務之間必須依靠切換來進行,就是說,
即便當前有高優先順序任務就緒,它不能被執行,除非切換。
此函數用於任務之間的同步。
十、任務管理 HOOK鉤子函數管理模組
HOOK模組管理者一組涉及鉤子函數的對象。DSP/BIOS初始化期間,每一個HOOK對象都分配了一個數位識別碼符。
每個HOOK模組都有一個初始化函數,該函數會在鉤子函數調用前運行。在調用初始化函數是,DSP/BIOS核心
會將HOOK對象的標識符以參數的形式傳給初始化函數。
HOOK對象的資料是存放在.bss部分中的。
關於HOOK屬性的設定,對應關係如下:
Initialization function: TSK_create
delete function: TSK_delete
Exit function: TSK_exit
另外還有Call switch function, switch function, Call ready function, ready function
十一、DSP/BIOS後台管理 IDL模組
IDL 模組管理著應用中最低等級的線程。除了使用者自己編寫的函數外,IDL模組執行DSP/BIOS的API函數,
DSP/BIOS核心正是利用這些函數來處理主機通訊和CPU負載計算的。
當DSP/BIOS分析工具的RTA控制台啟用時,應用程式會包含一個IDL_cpuLoad的IDL對象,其會調用一個提供
CPU利用率的函數,繪出負載圖。另外,還有LINL_dataPump函數在幕後處理與主機的資料交換,RTDX,HST等。
程式模組執行狀態圖,就是RTA_dispatch函數處理的結果。
(1)void IDL_run(void)
依次調用IDL模組中定義的所有IDL函數,其在所有IDL函數執行一次後返回,由於IDL函數中有完成主機和目標
系統交換資料的函數,所有IDL函數必須定期調用。