1. 程式人生 > >【DSP開發】TI SYS/BIOS的 建立工程例項

【DSP開發】TI SYS/BIOS的 建立工程例項

SYS/BIOS是一個可擴充套件的實時核心(或者說是作業系統),其提供了許多模組化的APIs(應用程式介面),支援搶佔式多執行緒,硬體抽象,實時分析和配置工具,其設計目的是為了最大限度地減少對記憶體和CPU的要求。其擁有很多實時嵌入式作業系統的功能,如任務的排程,任務間的同步和通訊,記憶體管理,實時時鐘管理,中斷服務管理等。有了它,使用者可以編寫複雜的多執行緒程式,並且會佔用更少的CPU和記憶體資源。        SYS/BIOS的早期版本是DSP/BIOS,更名的原因,是因為SYS/BIOS不僅可以用於DSP,而且也可以嵌入到ARM等其他SoC中去。SYS/BIOS是一個可用於實時排程、同步,主機和目標機通訊,以及實時分析系統上的一個可裁減實時核心,它提供了搶佔式的多工排程,對硬體的及時反應,實時分析和配置工具等。同時也提供標準的API介面,易於使用。它是TI的eXpressDSP實時軟體技術的的一個關鍵部分。
       CCS中整合安裝了SYS/BIOS,能夠大大方便使用者編寫多工應用程式。另一方面,SYS/BIOS可以在XDCtools中使用配置技術,極大地方便了SYS/BIOS的開發流程。        本節主要是通過一些簡單的SYS/BIOS的例子來介紹相關APIs元件的作用,這裡主要包括了時鐘Clock模組、任務Tsk模組、軟體中斷Swi模組、訊號量Sem模組及日誌Log模組五類簡單模組的使用。
一、新建SYS/BIOS專案 (1)在專案模板中選擇SYS/BIOS專案中的Hello Example模板,點選Next

(2)在RTSC(XDCtools的別稱)配置頁中選中需要的SYS/BIOS,XDCtools及其他元件的版本,Target保持預設,不需修改,如果Platform沒有自動填充,選擇與裝置適用的平臺。Build-profile決定程式連結的庫,推薦使用release,即使仍然處於建立和除錯階段,點選完成建立專案。
Tips:當我們開始使用SYS/BIOS時,是不能指定自己新增的連結命令檔案.cmd。因為.cmd會在構建工程的時候由SYS/BIOS自動建立並使用。 (3)點選編譯 (4)匯入target檔案後,點選除錯,執行得到結果

二、SYS/BIOS的模組與配置 (1)SYS/BIOS可以用文字編輯器或者是影象配置編輯器XGCONF來編輯,雙擊開啟.cfg檔案如下
       單擊System Overview,可以顯示程式當前使用的主模組(帶綠色小箭頭的) (2)各種APIs模組的新增這裡有兩種方法,一種是直接雙擊主模板進入,然後勾選Add
       另一種方法是在Available Products中右擊選中的模組,選擇Use
(3)各個API模組的作用        CLK:片內定時器模組,主要控制片內定時器並提供高精度的32位實時邏輯時鐘,它能控制中斷的速度,使之最快達到單指令週期時間。        HST:主機輸入/輸出模組,管理主機通過物件,它允許應用程式在目標系統和主機之間交流資料,主機通道通過靜態配置為輸入或輸出。        HWI:硬體中斷模組,提供對硬體中斷服務例程的支援,可在配置檔案中指定當硬體中斷髮生時需要啟動的函式        IDL:休眠功能模組,管理休眠函式在目標系統程式沒有更高優先權的函式執行時啟動        LOG:日誌模組,管理LOG物件,LOG物件在目標系統程式執行時實時捕捉事件,開發者可以使用系統日誌或定義自己的日誌,並在CCS中利用它實時瀏覽資訊。        MEM:儲存器模組允許指定存放目標程式的程式碼和資料所需的儲存器段        PIP:資料通道模組管理資料通道,它用來快取輸入和輸出資料流,這此資料通道提供一致性的軟體資料結構,可以使用它們驅動DSP和其他實時外圍裝置之間的I/O通道        PRD:周期函式模組,管理週期物件,它觸發應用程式的週期性執行。        RTDX:實時資料交換允許資料在主機和目標系統之間實時交換,在主機上使用自動OLE的客戶都可對資料進行實時顯示和分析。        STS:統計模組,管理統計累積器,在程式執行時,它儲存關鍵統計資料並能通過CCS瀏覽這此統計資料        SWI:軟體中斷模組管理軟體中斷。        TRC:跟蹤模組,管理一套跟蹤控制位元,它們通過事件日誌和統計累積器控制程式資訊的實時捕捉。
三、在專案中匯入LOG模組        LOG模組實際上是一個實現列印資訊的API        (1)新增LOG模組
       (2)LOG模組的使用        LOG模組定義了許多比如Log_error、Log_info、Log_warning、Log_print等之類函式,這些函式的用法同printf函式的用法很相似,這些函式都可以在 <xdc/runtime/Log.h>找到,其實際上是將printf的有用法分成許多不同的類(如錯誤資訊、提示資訊、警告資訊等),LOG模組列印的內容可以在Tools/RTA/PrintfLogs中看到。        Tips:LOG中定義了許多如下的函式,i比如Log_info1函式後面的數字代表函式接的變數數目        如Log_info1("%d",s1)、Log_info2("%d, %d", s1, s2)

四、在專案中匯入TSK任務模組        TSK任務模組是作業系統中最基本的模組,其實際上反映了多執行緒搶佔,每個任務單獨是一個執行緒,各個執行緒(任務)具有各自的優先順序        (1)新建任務,首先選擇Use TSK,確定TSK模擬是否匯入
       然後建立新任務New Task
       這裡我們建立兩個任務task0、task1,分別對應其函式func_tsk0、func_tsk1。其優先順序都為1
       (2)編寫任務函式
       a). 這裡我們在主函式中BIOS_start()函式,說明任務開始執行了        b). 任務執行完後呼叫BIOS_exit(0)退出        c). Task_yield()是個優先順序排程函式,其作用就是如果有相同優先順序的任務,則排程到同優先順序的其它任務執行!        d). Log_info1()的作用是列印日誌資訊        e). while和count迴圈的目標是讓任務執行較長的時間,而不是隻執行一次就退出了。        f). 最後別忘了在增加相關標頭檔案和函式的宣告!
       (3)編譯除錯,執行檢視結果(這裡我們只需要選擇單核執行就可以了)        從下面的分析,我們可以看到兩個任務是相互依次執行的,每個任務執行一次後,其優先順序就會降低,此時就切換到下一個任務

五、在專案中匯入Swi軟體中斷模組        前面我們已經知道了不同任務有不同優先順序,而軟體中斷具有比任何任務都高的優先順序,而其中硬體中斷(HWI)又比軟體中斷(SWI)優先順序更高。        (1)新增軟體中斷Swi,這裡方法同前面新增TSK的方法不一樣,似乎不能用圖形介面方式去新增(我沒有成功=_=||)        這裡我選擇通過直接在原始碼中新增相關程式碼:        a). 首先需要新增一個全域性的Swi控制代碼: Swi_Handle swi0;        b). 初始化Swi引數:             Swi_Params swiParams;                     Swi_Params_init(&swiParams);             swiParams.priority = 2;        // 軟體中斷的優先順序             swiParams.trigger = 2;         // 軟體中斷的計數器        c). 建立軟體中斷:             swi0 = Swi_create(func_swi0, &swiParams, NULL);  // swi0是中斷名,func_swi0是中斷函式        d). 編寫中斷函式:                void func_swi0(void)                {                     static Int count = 0;                     Log_info1("Swi0 is doing %d\n",count);                     count++;                }        e). 更改軟體中斷計數器trigger,要觸發軟體中斷,首先需要讓trigger的計數為0,這裡我們可以在任務函式內增加一個trigger自減的函式,任務函式執行兩次後,將會觸發軟體中斷。        void func_tsk0(void)        {             Int count = 0;             while(count<10){                 Log_info1("Task0 is doing %d\n",count);                 Swi_dec(swi0);                 Task_yield();                 count++;             }             BIOS_exit(0);        }        (2)一些Swi APIs 函式        Swi_inc Swi.trigger自增函式,每次增加1        Swi_dec Swi.trigger自減函式,每次減少1
       Swi_or 將trigger的值與模板求或操作        Swi_and 將trigger的值與模板求和操作        (3)編譯除錯,執行檢視結果(這裡我們只需要選擇單核執行就可以了)        從下面的分析,我們可以看到兩個任務的每次都會使得軟體中斷計數 trigger 減1(通過 Swi_dec函式),直到trigger的值減少到0時,執行軟體中斷,中斷後,trigger恢復到原來的值,這裡的trigger初始值為2,所以執行兩次任務後就會觸發一次軟體中斷

六、在專案中匯入訊號量Semaphore模組        訊號量是在多執行緒環境下使用的一種設施,是可以用來保證兩個或多個關鍵程式碼段不被併發呼叫,對於多個任務來說,使用訊號量可以防止多個任務同時執行。        訊號量可分互斥訊號量和計數訊號量,互斥訊號量只有兩種狀態:1和0,為1時說明可用,否則不可用。而計數訊號量通過設定一個計數值,如果計數值大於0,則任務請求該訊號量時是可用。        這裡例子是我們給task0任務中增加一個互斥訊號量,當訊號量狀態為1時,task0才能繼續執行。通過軟體中斷來達到訊號量歸1。        (1)新增訊號量               a). 首先需要新增一個全域性的訊號量控制代碼: Semaphore_Handle sem0;               b). 建立訊號量: sem0 = Semaphore_create(0, NULL, NULL);               c). 在增加互斥訊號量的任務函式中增加一個等待訊號量為1的函式                        Semaphore_pend(sem0, BIOS_WAIT_FOREVER);  // BIOS_WAIT_FOREVER表示一直等待,直到訊號量為1                d). 在軟體中斷函式中增加一個解鎖訊號量的函式                        Semaphore_post(sem0);                e). 最後別忘了新增Semaphore模組的標頭檔案                        #include <ti/sysbios/knl/Semaphore.h>                f). 如果.cfg檔案中沒有新增訊號量模組,記得一定要新增,否則雖然不會報錯,但訊號量不會工作        (2)編譯除錯,執行檢視結果(這裡我們只需要選擇單核執行就可以了)        從下面的分析,我們可以看到只有當軟體中斷執行後,此時訊號量才解鎖,task0才能執行,而任務執行兩次,才能觸發一次軟體中斷。

七、在專案中匯入時鐘Clock模組        Clocks模組主要提供週期性執行函式,我們這裡新建一個週期性執行函式,其每四個週期執行一次。        (1)新增訊號量                a). 首先初始化時鐘引數:                     Clock_Params clkParams;                     Clock_Params_init(&clkParams);                      clkParams.period = 5; // 函式執行週期                     clkParams.startFlag = TRUE; // True說明時鐘立即開始計時               b). 建立時鐘: Clock_create(func_clk, 5, &clkParams, NULL); //建立時鐘,func_clk是週期執行的函式,這裡5是開始執行的延時。               c).  編寫週期執行的時鐘函式                       void func_clk(UArg arg0)                       {                           UInt32 time;                           time = Clock_getTicks(); // 這裡是定時器的節拍器                           System_printf("System time in clk0Fxn = %lu\n", (ULong)time);                           if(time>20)                                BIOS_exit(0);                       }                 d). 因為任務的執行時間非常快,所以需要先把任務內的退出BIOS命令先刪除下,否則當任務完成後,時鐘函式還沒執行                       void func_tsk1(void)                       {                           Int count = 0;                           while(1){                            //while(count<10){                                Log_info1("Task1 is doing %d\n",count);                                Swi_dec(swi0);                                Task_yield();                               count++;                            }                            //BIOS_exit(0);                       }               e). 最後別忘了新增時鐘模組的標頭檔案               #include <ti/sysbios/knl/Clock.h>               f). 如果.cfg檔案中沒有新增時鐘Clock模組,記得一定要新增,否則雖然不會報錯,但時鐘模組不會工作        (2) 編譯除錯,執行檢視結果(這裡我們只需要選擇單核執行就可以了)        從下面的分析,我們可以看到只有當週期函式func_clk每隔5個週期開始執行,開始執行時間為5。

專案程式碼下載: https://github.com/tostq/EasyMulticoreDSP/tree/master/5.helloworldBios

附錄:關於SYS/BIOS的官方視訊學習資料 一、概覽  http://www.eeworld.com.cn/training/TI_study/2013/0503/257.html 二、 定時器和時鐘模組  http://www.eeworld.com.cn/training/TI_study/2013/0503/258.html 三、硬體中斷和空閒執行緒_1  http://www.eeworld.com.cn/training/TI_study/2013/0503/259.html 四、硬體中斷和空閒執行緒_2  http://www.eeworld.com.cn/training/TI_study/2013/0503/266.html 五、軟體中斷_1  http://www.eeworld.com.cn/training/TI_study/2013/0503/260.html 六、軟體中斷_2  http://www.eeworld.com.cn/training/TI_study/2013/0503/261.html 七、任務  http://www.eeworld.com.cn/training/TI_study/2013/0503/262.html 八、訊號量  http://www.eeworld.com.cn/training/TI_study/2013/0503/263.html 九、對MSP430的支援_1  http://www.eeworld.com.cn/training/TI_study/2013/0503/264.html 十、對MSP430的支援_2  http://www.eeworld.com.cn/training/TI_study/2013/0503/265.html