<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 一個(gè)搶先式“裸奔\"系統的設計

一個(gè)搶先式“裸奔\"系統的設計

作者: 時(shí)間:2018-09-07 來(lái)源:網(wǎng)絡(luò ) 收藏

5 程序運行流程
程序初始化流程圖如圖1所示。

本文引用地址:http://dyxdggzs.com/article/201809/388713.htm


首先,main()在完成硬件初始化Sys_init()后,調用I2c_svr()總線(xiàn)通信服務(wù)程序。
I2c_svr()服務(wù)程序里,首先完成類(lèi)似通用RTOS的任務(wù)現場(chǎng)保護的過(guò)程。再通過(guò)切換堆棧指針,完成了新任務(wù)堆棧的初始化過(guò)程。然后進(jìn)入I2C總線(xiàn)通信模塊主循環(huán)(類(lèi)似創(chuàng )建任務(wù)的操作),再通過(guò)調用idelay(),將CPU的控制權交還給main()。奧妙就在于idelay()首先保存通信程序的寄存器現場(chǎng)(ACC和PSW),然后轉換到main()的堆??臻g,并恢復剛才被I2c_svr()保存的寄存器現場(chǎng)(ACC和PSW)。所以;i2c_svr()里的idelay()函數返回后將不執行其下面的i2write(),而是執行main()里的while(1)。
i2write()又如何能得到執行呢?它是通過(guò)定時(shí)中斷服務(wù)程序timer1()再次獲得CPU控制權的。如果在main()的執行中發(fā)生timer1()中斷,因為timer1()里也進(jìn)行與idelay()類(lèi)似的任務(wù)切換操作,這時(shí)候將切換到I2c_svr()的堆棧和寄存器(現場(chǎng))。此時(shí)timer1()中斷返回時(shí),不會(huì )返回到main()里,而是執行i2write()。
另外,函數i2write()內部執行中也會(huì )調用idelay(),在I2c_svr()中的每次調用idelay()都會(huì )將CPU控制權交給main()的切換。main()和I2c_svr()的切換關(guān)系如圖2所示。


當然,timer1()并不總是引起任務(wù)的切換,通過(guò)判斷bi2csvr標志可以避免(在不需要數據傳輸時(shí))不必要的任務(wù)切換。另外,timer1()也可能進(jìn)行從I2c_svr()到main()的切換。所以即使I2c_svr()里很長(cháng)時(shí)間沒(méi)有調用idelay(),也不會(huì )阻塞main()的執行。
切換現場(chǎng)一般基于80C51的RTOS,通常要保存所有的CPU寄存器(包括8個(gè)工作寄存器、ACC、PSW、B、DPTR等),而這里與它們不同,因為在筆者的通信服務(wù)模塊I2c_svr()中使用了另外的寄存器組,且未使用B和DPTR,因此不需要保存8個(gè)工作寄存器及B和DPTR,僅保存和恢復PSW和ACC這兩個(gè)寄存器就可以了,大大提高了切換效率。
里僅有兩個(gè)“任務(wù)”,即main()和I2c_svr(),也沒(méi)有固定優(yōu)先級,處于“等待”狀態(tài)任務(wù)的優(yōu)先級總比當前運行中的任務(wù)高,所以相當于同優(yōu)先級時(shí)間片輪轉調度方式。但相對于RTOS,這里還缺少操作必須管理的與任務(wù)相關(guān)的狀態(tài)和數據結構,所以筆者還將其稱(chēng)做“裸奔”。

6 現場(chǎng)保護的補充說(shuō)明
任務(wù)切換中的寄存器現場(chǎng)保護代碼如下:


上面是Keil C51對定時(shí)中斷服務(wù)函數timer1()編譯生成的LST文件。編譯器在中斷服務(wù)里自動(dòng)生成壓棧和出棧寄存器的指令,所以在寫(xiě)idelay()函數的寄存器現場(chǎng)切換的時(shí)候,必須完全遵守這個(gè)寄存器壓棧和出棧順序規則才能正常工作。

結語(yǔ)
通過(guò)學(xué)習和借鑒RTOS的CPU時(shí)間搶先調度和分配方法,可以將本系統中總線(xiàn)時(shí)序里許多很短的延時(shí)都交給主程序使用,最大程度利用CPU時(shí)間,實(shí)現主程序和通信服務(wù)程序的并行執行,從而讓主程序和通信服務(wù)程序均達到系統要求的實(shí)時(shí)性能。
本文為時(shí)間緊張的系統設計提供了一個(gè)新的解決思路。應該有助于初學(xué)操作系統的讀者理解操作系統任務(wù)切換的工作機理。


上一頁(yè) 1 2 3 下一頁(yè)

關(guān)鍵詞: 系統

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>