新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 一個搶先式“裸奔“系統的設計

        一個搶先式“裸奔“系統的設計

        作者: 時間:2012-12-16 來源:網絡 收藏


        2 程序主執行函數main()函數
        c.JPG
        d.JPG
        main()函數也非常簡單。首先,調用Sys_init()完成單片機硬件系統的初始化;然后調用I2c_svr(),完成I2C總線通信系統的初始化,并執行數據傳輸,本函數稍后將作詳細的介紹;接下來是一個while(1)主循環,其中的mainfunc()是執行主要任務的函數,完成系統的主要功能,并返回一個bool變量,這個變量用于I2C總線數據傳輸的請求;
        這里定義了一個bool型變量bi2csvr。作用:由mainfunc()執行結果來置位,系統根據此標志,啟動數據通信,并在數據傳輸完成后清零這個標志。

        3 I2C總線通信服務程序
        通信服務程序I2c_svr()函數代碼如下:
        e.JPG
        這個函數看起來也不復雜,但是需要讀者用RTOS任務的概念來理解這個函數。
        首先,關于寄存器組,這里的I2C服務程序I2c_svr()使用了單獨的寄存器組(寄存器組1),由于#pragmarb(1)編譯指令并不會讓編譯器自動生成切換寄存器組的指令,所以I2c_svr()中又通過修改PSW特殊寄存器來切換到工作寄存器組1。當然,要切換寄存器組,還需要確認在切換前,本函數沒有使用工作寄存器。
        同時,I2c_svr()的初始化部分還執行了特殊功能寄存器壓棧保存和切換堆棧指針SP,這些本是實時內核調度器里要完成的任務,在這里的出現相當于建立了新的任務。
        接下來的while(1)表明,這里相當于實時系統里的一個任務了。
        這個任務很簡單,i2write()的功能就是通過I2C總線,發送數據緩沖區里所有的數據,在這里就不做詳細介紹了。在發送完成后,清零數據發送請求標志位bi2csvr,然后執行延時等待。

        4 定時中斷和延時函數
        搶先系統的關鍵部分是定時中斷timer1()和延時函數idelay(),代碼如下:
        f.JPG
        首先看tsksw()宏,它的作用是保存堆棧指針并切換堆棧。這等同于RTOS里任務的上下文切換,但這里僅切換一下堆棧指針即可。
        接下來看這個定時中斷服務函數timer1(),其中systern_tmr()是個修改定時器TH0的函數,這里不作介紹了。隨后,約束判斷(后面再作詳細介紹)再通過tsksw()函數進行任務間的切換。
        接下來看延時函數idelay(),它提供I2C總線時序里要求的延時函數。注意:我們通常都是使用若干nop或者類似“for(x=LOOP;x>0;x——);”的延時來完成的,但這里一改這類傳統的方式,而是通過“任務切換”將CPU控制權交給另外一個任務main來實現的。需要特別指出,idelay()里的關中斷很重要,學習過RTOS的讀者應該都記得RTOS里面的“臨界段代碼”的概念。
        最后,介紹上面未詳細說明的定時中斷服務函數timer1()中任務切換的約束判斷。bi2csvr是I2C總線請求標志,如果這個標志為零,則表示不需要I2C總線的通信服務,定時中斷里也就不需要做任務切換;此外,bi2cdly也是個控制切換的小技巧,該標志在idelay()中置位,在定時中斷服務中判斷并清零。也就是在執行idelay()后發生的第一次定時中斷里只清除這個標志,而在第二次定時中斷中才可能發生任務切換,以此保證idelay()的延時時間一定不少于一個定時器的溢出周期。


        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 顺义区| 珲春市| 施甸县| 寿光市| 松江区| 德令哈市| 宜阳县| 石嘴山市| 蒙城县| 宜城市| 三亚市| 华宁县| 志丹县| 藁城市| 河北省| 诸暨市| 郎溪县| 通城县| 九龙坡区| 斗六市| 原平市| 大洼县| 灵丘县| 盐亭县| 余江县| 多伦县| 门源| 钟山县| 鄂伦春自治旗| 德清县| 华坪县| 集安市| 四会市| 礼泉县| 南丰县| 博白县| 姚安县| 虎林市| 连平县| 神农架林区| 石阡县|