實(shí)時(shí)多任務(wù)系統(tǒng)內(nèi)核分析_第1頁(yè)
實(shí)時(shí)多任務(wù)系統(tǒng)內(nèi)核分析_第2頁(yè)
實(shí)時(shí)多任務(wù)系統(tǒng)內(nèi)核分析_第3頁(yè)
實(shí)時(shí)多任務(wù)系統(tǒng)內(nèi)核分析_第4頁(yè)
實(shí)時(shí)多任務(wù)系統(tǒng)內(nèi)核分析_第5頁(yè)
已閱讀5頁(yè),還剩27頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、實(shí)時(shí)多任務(wù)系統(tǒng)內(nèi)核分析初次接觸實(shí)時(shí)多任務(wù)操作系統(tǒng)的人,往往對(duì)實(shí)時(shí)程序的運(yùn)行機(jī)制感到很困惑:任務(wù)在什么時(shí)候投入運(yùn)行?操作系統(tǒng)以什么機(jī)制決定目前應(yīng)該運(yùn)行哪一個(gè)任務(wù)?本任務(wù)什么時(shí)候放 棄了對(duì)CPU的控制?為了解答以上問(wèn)題,我們從分析一個(gè)很簡(jiǎn)單的實(shí)時(shí)調(diào)度程序入手, 來(lái)說(shuō)明一下多任務(wù)程序的運(yùn)行過(guò)程。從結(jié)構(gòu)上來(lái)說(shuō),實(shí)時(shí)多任務(wù)操作系統(tǒng)包括兩部分,一部分為操作系統(tǒng)內(nèi)核(kernel),即實(shí)時(shí)執(zhí)行程序(Real Time Executive:RTX),另一部分是輸入輸出部分 (1/0)(注意開(kāi)發(fā)系統(tǒng)不屬于操作系統(tǒng)的范疇);嵌入式系統(tǒng)對(duì)I/O的需求通常比較小(無(wú)文件系統(tǒng)需求),因此很 多實(shí)時(shí)多任務(wù)操作系統(tǒng)本質(zhì)上就

2、是一個(gè)實(shí)時(shí)執(zhí)行程序,如AMX(Kadak),VRTX(Microtec),iRMX(Intel)等(這里的X即:egcutive),如果純粹從kernel的角度來(lái)考察目前流行的各種 實(shí)時(shí)多任務(wù)操作系統(tǒng)的性能,它們的效率差別都不大。在市面上可以得到一些RTX的源代碼(有用C實(shí)現(xiàn)的,有用匯編實(shí)現(xiàn)的,還有用 PL/M語(yǔ)言實(shí)現(xiàn)的),從in ternet 上也可以蕩一些下來(lái)(我介紹一個(gè)站點(diǎn),堪稱(chēng)世界電 子工程師資源寶庫(kù)),下面我要介紹的一個(gè)RTX版本(我命名為SRTX:short RTX),可以說(shuō)是RTX中的元老級(jí)產(chǎn)品了,來(lái)自某研究所,九十年代初他們到美國(guó)考察,從美國(guó)某公司購(gòu)得。五

3、年以前,SRTX在國(guó)內(nèi)有售,許多搞工控的研究所利用SRTX開(kāi)發(fā)了一些大型或小型的產(chǎn)品,這里介紹的SRTX我作了一些簡(jiǎn)化和改動(dòng).在功能上,SRTX的確無(wú)法和目前市售的實(shí)時(shí)多任務(wù)操作系統(tǒng)相比,不支持任務(wù)的調(diào)試,不支持優(yōu)先級(jí)反轉(zhuǎn),甚至不支持相同優(yōu)先級(jí)任務(wù)的分時(shí)間片運(yùn)行;SRTX的功能單一,程序代碼非常短,效率高(畢竟是80年代末的產(chǎn)品)。從內(nèi)核的角度看,SRTX實(shí)現(xiàn)了一個(gè)較基本 的任務(wù)調(diào)度版本;因此通過(guò)對(duì)SRTX的介紹,可以了解其他實(shí)時(shí)多任務(wù)產(chǎn)品內(nèi)核的結(jié)構(gòu)及實(shí)現(xiàn)方法。一任務(wù)的管理及程序?qū)崿F(xiàn)1. 任務(wù)及程序結(jié)構(gòu):從程序?qū)崿F(xiàn)上說(shuō),任務(wù)就是一段能完成既定功能的程序代碼。與一般的程序代碼(或子程序)不一樣的

4、地方就在于任務(wù)是死循環(huán)的程序結(jié)構(gòu)。任務(wù)的通用程序結(jié)構(gòu)如下:#define void TASKTASK Common_Task( void )Task_ Init(); / initialize data structure for this taskwhile( 1 ) / loop foreverSuspend_Task_for_Msg(); /wait for messageProcess_This_Msg(); /process this message Post_Msg_to_Task(); /send message to other task舉例說(shuō)明:應(yīng)用戶的要求,需要在屏幕的右上

5、角顯示當(dāng)前時(shí)鐘,我們可以把此功能當(dāng)作一個(gè) 專(zhuān)用的任務(wù)來(lái)設(shè)計(jì),該任務(wù)的功能是每隔一秒取出系統(tǒng)當(dāng)前的時(shí)鐘,轉(zhuǎn)換成規(guī)定格式的 字符串, 將其指針傳送給顯示任務(wù), 接著繼續(xù)等下一秒的到來(lái)。 任務(wù)的程序?qū)崿F(xiàn)結(jié)構(gòu)為:TASK Alert_Clock( void )Set_String_NULL(); / initialize stringwhile( 1 )Get_Current_Clock( );/get clockFormat_Clock_Str( );/format digit to stringSend_Msg_To_Task( DISPLAY,str ); /post message point

6、er to /DISPLAY taskSuspend_Task( 100 ); /suspend 1 second2 數(shù)據(jù)區(qū)及堆棧區(qū)的組織方法以下講一下SRTX勺系統(tǒng)數(shù)據(jù)區(qū)及堆棧區(qū)的組織方法。任務(wù)在運(yùn)行的時(shí)候可能被更高優(yōu)先級(jí)的任務(wù)中斷,這時(shí)候任務(wù)需要將現(xiàn)場(chǎng)信息放 到其堆棧中,以便今后能從該堆棧中取出被中斷的現(xiàn)場(chǎng)信息(包括斷點(diǎn)位置,任務(wù)狀態(tài) 等)恢復(fù)任務(wù)的斷點(diǎn)運(yùn)行,任務(wù)需要有自己獨(dú)立的堆棧區(qū)以及描述任務(wù)運(yùn)行狀態(tài)措施, 在實(shí)時(shí)多任務(wù)系統(tǒng)中,采用一種任務(wù)控制塊( Task Control Block:TCB )的數(shù)據(jù)結(jié)構(gòu)描 述任務(wù)的運(yùn)行狀態(tài),每個(gè)任務(wù)有一個(gè)TCB。在SRTX中,采用如下方法定義任務(wù)的

7、堆棧:max_task_no equ 32;support maxinum tasks;defined by myself;stacks for all tasks stack segme nt para stack stackdbmax_task_ no *1024 dupstack ends每個(gè)任務(wù)的堆棧大小為1K,用戶可以根據(jù)需要修改(同時(shí)需要改動(dòng)程序)。在SRTX中,TCB的結(jié)構(gòu)為:(共16個(gè)字節(jié):10h)表1任務(wù)的TCB的結(jié)構(gòu)偏移(字節(jié))說(shuō)明0任務(wù)號(hào):Task_ID1任務(wù)狀態(tài):Task_Status2-3初始代碼偏移:lnit_Offset4-5初始CS段值:Init_CS6-7初始

8、堆棧指針SP:I ni t_SP8-9初始堆棧段SS:Init_SS10- 11上下文堆棧指針 SP:Last_SP12- 13上下文堆棧段SS:Last_SS14- 15系統(tǒng)時(shí)鐘援用:Slice以下是系統(tǒng)數(shù)據(jù)區(qū)的組織方法:;buffer for task and queue man age dseg segme ntdb 10h dup(?) ;00h- RUNning task message; public for all tasksdb taskdescripitors ;10h- TCB starti ng flagdbmax_task_ no *10h dup(?) ;20h- t

9、ask TCBs messagedb queue tables ;220h-QUEUE starti ng flagdbmax_task_ no *108h dup(?) ;230h-all queues messagedb SRTX version 1.0; SRTX version flagdseg ends其中:taskdescripitors為16字節(jié)的標(biāo)志串,以標(biāo)明 TCB的開(kāi)始;queue tables 為16字節(jié)的標(biāo)志串,標(biāo)明任務(wù)隊(duì)列的開(kāi)始;SRTX version 1.0為16字節(jié)的版本標(biāo)志,關(guān)于TCB各字段的含義以及SRTX的隊(duì)列組織方法見(jiàn)相應(yīng)章節(jié)。3. 任務(wù)狀態(tài)及其表示在T

10、CB的Task_Status字段用于描述本任務(wù)當(dāng)前的狀態(tài),TCB狀態(tài)及其它信息也在本字段中描述。表2任務(wù)狀態(tài)及其描述位狀態(tài)描述10000000INHIBIT任務(wù)被強(qiáng)制禁止執(zhí)行00100000AVAILABLE本TCB為空,可以使用00010000INTERRUPT任務(wù)運(yùn)行被中斷00001000ASLEEP任務(wù)處于睡眠狀態(tài)(調(diào)用SYSSLP)00000010AWAKENED任務(wù)睡眠超時(shí),被喚醒00000001RUNNING任務(wù)處于可運(yùn)行狀態(tài) (ready to run)以上描述了系統(tǒng)數(shù)據(jù)區(qū)的組織方法,尤其描述了其中的任務(wù)狀態(tài)字節(jié),以下程序代碼用于系統(tǒng)運(yùn)行初期對(duì)系統(tǒng)數(shù)據(jù)區(qū)的初始化,它是最先需要運(yùn)行

11、的代碼movax,dsegmovds,axcldpushdspopesxordi,di;in itialize public areamovcx,10hxorax,axrepzstosb;set 0 for all 10h bytesmovbx,20h;bx-first tcbmovcx,max_task_notask_dec:movbyte ptrbx+01,20h; in itialize tcbaddbx,10h;set TCBs are all AVAILABLElooptask_decmov bx,0230hmov cx,max_task_ notask_queue:mov byte

12、 ptrbx+0100h,80h ; in itialize queue is empty add bx,0108hloop task_queue4. 任務(wù)創(chuàng)建及啟動(dòng)為了詳細(xì)說(shuō)明TCB中一些字段的使用,我們介紹在SRTX中的創(chuàng)建任務(wù)例程。在SRTX中, syscre為任務(wù)創(chuàng)建例程,其使用方法是:輸入:寄存器DX: AX包含初始任務(wù)代碼段的CS offset輸出:若創(chuàng)建成功,CARRY清0;此時(shí),AX包含了任務(wù)的ID號(hào),它是唯一的任務(wù)標(biāo)識(shí)符。若CARRY!位,AX寄存器將包含下列錯(cuò)誤碼:03eah,任務(wù)創(chuàng)建錯(cuò)誤。以下是SYSCRE勺典型使用方法:Jmov dx, seg NEW_TASK ;pu

13、t seg to dxmov ax, offset NEW_TASK ;offset to axcall SYSCRE;creat NEW_TASKjc creat_error ;creat error processmov NEW_TASKID,ax ;put task id to NEW_TASKIDcall SYSSTR;startup this taskfill_task_msg:mov cl,0; initial task status以下是具體的實(shí)現(xiàn)代碼J;syscre: create a taskJsyscre_sub:push push push push mov movbxc

14、x sidsbx,dsegds,bx;reserve used regsmovsi,0;first task ID=0movbx,20h;bx-first TCBmovcx,max_task_no;max loop countfind_empty_tcb:testbyte ptrbx+01,20h; is this tcb empty?jnzfill_task_msg; yes,TCB is AVAILABLEJplease see table 2addbx,10h; next tcbincsi; task ID+loopfind_empty_tcbmovax,03eah; no tcb AV

15、AILABLEjmpsyscre_errormovbx+01,cl; save initial task statusmovbx+02,ax; offset of task codemovbx+04,dx; segment of task codemovax,si; si:task IDmovcx,0400h; stack lengthmulcxaddax,0400h; initial task stack pointer ; stack bottom =SPmovbx+06,ax; set initial spmovword ptr bx+08,stack ; set initial sta

16、ck segmentmovax,si; tasks IDmovbx+0,al; reserve task IDclcjmp syscre_exitsyscre_error:stcsyscre_exitpopds;restore used regspopsipopcxpopretbx由此可見(jiàn),在TCB中,Task_ID 表示任務(wù)創(chuàng)建的順序號(hào) (系統(tǒng)創(chuàng)建的第一個(gè)任務(wù), Task_ID=O,創(chuàng)建的第二個(gè)任務(wù),Task_ID=1 ,),任務(wù)創(chuàng)建后,Task_Status = 0;所 有的狀態(tài)清除。 Init_Offset= 任務(wù)代碼的 offset,Init_CS= 任務(wù)代碼的 CS, Init_SP

17、= 該任務(wù)創(chuàng)建時(shí)系統(tǒng)分配給該任務(wù)的 SP,Init_SS= 該任務(wù)創(chuàng)建時(shí)系統(tǒng)分配給該任務(wù)的 SS, 在任務(wù)創(chuàng)建階段 ,TCB 的其它域未涉及到。在SRTX中, sysstr為任務(wù)啟動(dòng)例程,其使用方法是:輸入:寄存器 AX包含待啟動(dòng)任務(wù)的ID號(hào);輸出:若啟動(dòng)成功,CARRY清0;否則,CARR逼位,AX寄存器將包含下列錯(cuò)誤碼: 03e9h , , 無(wú)效任務(wù) ID 號(hào)。關(guān)于SYSSTR勺使用示例見(jiàn)上.以下是SYSSTR實(shí)現(xiàn)代碼.;sysstr start(or restart task)Jsysstr_sub:pushaxpushbxpushcxpushds; reserve used regsm

18、ovbx,dsegmovds,bxcmp jnbax,max_task_nosysstr_error;task ID is too largemov bx,20hmov cl,04; size of TCB=16,by this tasks TCBtest byte ptrbx+01,20h ; task created ?jnz sysstr_error; task is not created stillor byte ptrbx+01,01 ; set runnable flagclcjmp sysstr_exitsysstr_error: mov ax,03e9h stcsysstr_

19、exit:popdspopcxpopbxpopaxret; restore used regs在SRTX中,啟動(dòng)一個(gè)任務(wù)實(shí)質(zhì)上就是設(shè)置該任務(wù)的狀態(tài)為可運(yùn)行狀態(tài),等待調(diào)度程序 reschedul 運(yùn)行時(shí)根據(jù)優(yōu)先級(jí)啟動(dòng)該任務(wù)的運(yùn)行 .5. 任務(wù)刪除及其實(shí)現(xiàn)方法SYSDEL用于刪除一個(gè)已經(jīng)創(chuàng)建的任務(wù),釋放該任務(wù)占用的 TCB.SYSDE啲使用方法:輸入 :AX 包含將要?jiǎng)h除任務(wù)的標(biāo)識(shí)符 .輸出:如果刪除成功,CARRY清零,否則,CARRY置位,AX寄存器包含如下的錯(cuò)誤 碼,03e9h, 無(wú)效任務(wù) ID 號(hào)。以下是SYSDE啲實(shí)現(xiàn)代碼。J; sysdel delete a tasksysdel_su

20、b:pushbxpushdsmovbx,dsegmovds,bxcmpax,max_task_nojnbsysdel_sub_error;task id is too largemovbx,10hmulbxmovbx,20haddbx,ax;bx-tcb for this task IDmoval,bx+01oral,20h;tcb is now AVAILABLEmovbx+01,alclcjmpsysdel_sub_exitsysdel_sub_error:mov ax,03e9h stc sysdel_sub_exit: pop ds pop bx ret任務(wù)在創(chuàng)建之后,該任務(wù)的TCB勺

21、AVAILABLE字段被設(shè)置為0,表明該任務(wù)對(duì)應(yīng)的 TCB 不可用(或已經(jīng)被占用);SYSDEL實(shí)質(zhì)上就是簡(jiǎn)單地將該任務(wù)的TCB的AVAILABLE字段被設(shè)置為 1,重新置為可用 (未被占用 ) ,這樣,今后在創(chuàng)建一個(gè)新任務(wù)時(shí), 可以重新利用該 TCB。6. 禁止任務(wù)切換、允許任務(wù)切換的實(shí)現(xiàn) 在需要對(duì)臨界區(qū)數(shù)據(jù)進(jìn)行訪問(wèn)的時(shí)候 , 需要禁止任務(wù)的切換 , 以保護(hù)共享的資源 . 舉例如下 :任務(wù) A 需要任務(wù) B 的數(shù)據(jù)以便繼續(xù)操作 , 任務(wù) A 和任務(wù) B 通過(guò)設(shè)置公共變量READY信號(hào)量)來(lái)表示數(shù)據(jù)是否準(zhǔn)備好,任務(wù)B設(shè)置READY勺初值為false, 一旦B將數(shù) 據(jù)放入公共的緩沖區(qū)之后,設(shè)置R

22、EADY為true;任務(wù)A掛在信號(hào)量 READY上,若READY 為true,任務(wù)A從公共的緩沖區(qū)取出 B存放的數(shù)據(jù).對(duì)公共數(shù)據(jù)的訪問(wèn)就成了臨界區(qū)的 操作這主要是由于,在A測(cè)試READY為true之后,馬上取公共緩沖區(qū)的數(shù)據(jù),如果這時(shí)候發(fā)生任務(wù)的切換 ,任務(wù) B 開(kāi)始運(yùn)行 , 它可能將最新的數(shù)據(jù)放入公共緩沖區(qū)中 ,這樣任務(wù)A恢復(fù)運(yùn)行后,將繼續(xù)讀取公共緩沖區(qū)的數(shù)據(jù),使得任務(wù)A讀取的數(shù)據(jù)不完整,達(dá)不到預(yù)期的效果 .對(duì)臨界區(qū)資源的訪問(wèn)時(shí) ,一定要禁止任務(wù)的切換 ,以保護(hù)資源的完整性 .SRTX采用了最簡(jiǎn)單的關(guān)門(mén)算法實(shí)現(xiàn)對(duì)任務(wù)切換的管理,即:需要對(duì)臨界資源進(jìn)行訪問(wèn)時(shí),任務(wù)A首先將某全局變量M減1,然后

23、訪問(wèn)臨界資源;操作系統(tǒng)的調(diào)度程序 reschedul首先判斷M是否等于0,如果M不等于0,則不能進(jìn)行 任務(wù)的切換 ( 即不能讓高優(yōu)先級(jí)的任務(wù)打斷 ), 繼續(xù)運(yùn)行當(dāng)前的任務(wù) , 直到完成 ; 等于 0, 表明任務(wù)已經(jīng)不需要該資源,可以進(jìn)行任務(wù)的切換任務(wù)A對(duì)臨界資源訪問(wèn)完畢后,將M加 1, 實(shí)現(xiàn)配對(duì)操作 .以下是任務(wù)禁止切換和任務(wù)允許切換的實(shí)現(xiàn)代碼 :J;sysdti-disable task interrpt(task switching)Jsysdti_sub:pushfpush dspush axmov ax,dsegmov ds,axdec ds:byte ptr07; disable f

24、lagpop axpop dspopfret;syseti:enable task interrpt( task switching)syseti_sub:pushfpush dspush axmov ax,dsegmov ds,axinc ds:byte ptr07; enable flagpop axpop dspopfret這里可以看出系統(tǒng)數(shù)據(jù)區(qū)公共字段中的第 7字節(jié)的用途 ,當(dāng)?shù)?7字節(jié)不等于 0時(shí), 不允許發(fā)生任務(wù)的切換 ( 系統(tǒng)數(shù)據(jù)區(qū)公共字段一共有 16個(gè)字節(jié) ,保存目前系統(tǒng)運(yùn)行的 一些信息 )隊(duì)列的實(shí)現(xiàn)及其管理1 通路的概念及其實(shí)現(xiàn)限制對(duì)不可重入進(jìn)程的訪問(wèn) ,通路 (gatewa

25、y) 是一種常用的程序結(jié)構(gòu)。不可重入過(guò)程最明顯的例子是DOS的不可重入,最初在設(shè)計(jì)DOS勺磁盤(pán)文件系統(tǒng)時(shí),編程人員用了較多的全局變量 , 以標(biāo)識(shí)目前文件操作的位置和狀態(tài) ; 可是, 在多任務(wù)環(huán)境 下, 一個(gè)低優(yōu)先級(jí)任務(wù)調(diào)用 int 21h 用于寫(xiě)磁盤(pán)文件的操作的時(shí)候被中斷 , 另一個(gè)優(yōu)先級(jí) 高的任務(wù)被激活 , 它也需要調(diào)用 int 21h 用于磁盤(pán)文件的操作 , 這樣 , 新的狀態(tài)值便代替 了舊的狀態(tài)值 , 當(dāng)高優(yōu)先級(jí)任務(wù)運(yùn)行結(jié)束之后 , 低優(yōu)先級(jí)任務(wù)取得控制權(quán) , 這時(shí)由于相關(guān) 的變量已經(jīng)無(wú)法恢復(fù) , 造成低優(yōu)先級(jí)任務(wù)無(wú)法繼續(xù)正常運(yùn)轉(zhuǎn) .一個(gè)很容易想到的方法是讓一個(gè)任務(wù)徹底完成使用該不可重入

26、進(jìn)程的調(diào)用之后, 才允許另一個(gè)任務(wù)調(diào)用這個(gè)不可重入的進(jìn)程 .gateway 能實(shí)現(xiàn)對(duì)不可重入進(jìn)程的保護(hù)作用,在某一時(shí)刻它只允許一個(gè)任務(wù)使用這 個(gè)進(jìn)程。gateway 實(shí)現(xiàn)對(duì)不可重入進(jìn)程受控訪問(wèn)的簡(jiǎn)單模擬是:到大使館簽證,你必須清早 去排隊(duì)領(lǐng)取一個(gè)順序號(hào)碼 , 當(dāng)叫到你的號(hào)時(shí) , 你才能進(jìn)去,否則,你只能耐心地等待。一個(gè)有序的 gateway 對(duì)各調(diào)用任務(wù)提供了類(lèi)似的裁決方法。 gateway 為調(diào)用者分配 一個(gè)號(hào),若這個(gè)號(hào)與當(dāng)前正在服務(wù)的號(hào)相符合,則允許調(diào)用者進(jìn)入不可重入的過(guò)程。在 gateway 初始化時(shí),局部變量“當(dāng)前標(biāo)簽號(hào)”和當(dāng)前正在服務(wù)的號(hào)都應(yīng)置為0,這里列舉了有序 gateway 的

27、典型算法 :調(diào)用SYSDTI禁止任務(wù)中斷。(2) 將“我的標(biāo)簽號(hào)”置成等于“當(dāng)前標(biāo)簽號(hào)”。(即申請(qǐng)一個(gè)屬于自己的號(hào)碼 )(3) “當(dāng)前標(biāo)簽號(hào)”加 1 。 ( 以便下一次申請(qǐng)到下一個(gè)號(hào)碼 )調(diào)用SYSETI開(kāi)中斷。(5) 若“我的標(biāo)簽號(hào)”不等于“當(dāng)前正在服務(wù)的號(hào)”,則調(diào)用SYSSLP垂眠一會(huì),再進(jìn)入(5);(6) 調(diào)用這個(gè)不可重入的過(guò)程。(7) “當(dāng)前正在服務(wù)的號(hào)”加 1。(8) 返回到調(diào)用者。下例是用匯編語(yǔ)言編寫(xiě)的對(duì) gateway 算法的實(shí)現(xiàn)。gateway proc farpush axpush dsmov ax,dsegmov ds,axg_10:call SYSDTI ; preven

28、t task switch mov ax,current_ticket; apply my ticketinc current_ticket call SYSETI; restoreg_20 :cmp ax,current_service ; is my number up?jc g_30 ; if so jumppushaxmovax,1000callSYSSLPpopaxjmpg_20g_30 :pop ds; save my ticketJ; sleep 1 second ; restore my ticket; and try again; restore callers DSpopa

29、x; restore callercallnon_reentrant; invoke the procedurepushax; save resulting AXpushds; save resulting DSmovax,dseg; reclaim local DSmovds,axJinccurrent_service; whopopdspopaxrets next?s AX(釋放對(duì)CPU的控制這里用到SYSSLP調(diào)用,它的作用是讓本任務(wù)掛起給定時(shí)間長(zhǎng)度 權(quán)), 然后又繼續(xù)往下執(zhí)行 ; 因?yàn)樗婕暗蕉〞r(shí)管理和系統(tǒng)調(diào)度,將在后面講述。2. SRTX中隊(duì)列的表示及存取算法從SRTX系統(tǒng)數(shù)據(jù)區(qū)的2

30、30H開(kāi)始的部分是系統(tǒng)隊(duì)列區(qū),可以看出,系統(tǒng)可以有MAX_TASK_NO個(gè)隊(duì)列(可以自己定義 ),每個(gè)隊(duì)列有108H字節(jié),其中,后8個(gè)字節(jié)(100h-107h)是隊(duì)列的控制信息,前100h個(gè)字節(jié)存放消息指針 (offset+segment=4bytes,即雙字指針,偏移量在前2字節(jié),數(shù)據(jù)段值在后2字節(jié)),因此每個(gè)隊(duì)列最多可以同時(shí)存放100h/4=64條指針消息.后8字節(jié)的詳細(xì)安排如下表3:表3隊(duì)列控制字段的位置和作用偏移(字節(jié))作用100h本隊(duì)列的最大記錄數(shù)(由隊(duì)列創(chuàng)建時(shí)指疋)101h本隊(duì)列中現(xiàn)有記錄數(shù)(現(xiàn)存消息數(shù)目)102h訪問(wèn)隊(duì)列的當(dāng)前標(biāo)簽id(見(jiàn)通路的描述)103h提供服務(wù)的server

31、_id(見(jiàn)通路的描述)104h-105h隊(duì)列的輸入指針(輸入消息的存放位置:put)106h-107h隊(duì)列的輸出指針(輸出消息的存放位置:out)應(yīng)該注意的是,第100h是一個(gè)字節(jié),可以記錄最大255條記錄,因?yàn)楸鞠到y(tǒng)最大才 允許有64條記錄,因此100h的高兩位(bit 7-6)其實(shí)沒(méi)有用上,在 SRTX中,設(shè)置100h 的最高位為1,表明本隊(duì)列沒(méi)有被使用在初始化時(shí),設(shè)置100h的內(nèi)容為80H,就表明本隊(duì) 列尚未被使用(程序詳見(jiàn)”任務(wù)狀態(tài)及其表示”的系統(tǒng)數(shù)據(jù)區(qū)的初始化).SRTX采用循環(huán)隊(duì)列的算法實(shí)現(xiàn)對(duì)隊(duì)列的管理,循環(huán)隊(duì)列實(shí)現(xiàn)方法如下in putoutput64其中:DWORDuffq64;

32、 /64為隊(duì)列的深度,DWORI表示為2個(gè)字,第一字為offset, 第二字為segulo ng in put:為輸入指針,消息存放在輸入指針的位置ulong output:為輸出指針;消息從輸出指針位置取出隊(duì)列空的條件 : input = output 隊(duì)列滿的條件 : input = output+1 mod 64; 實(shí)現(xiàn)隊(duì)列管理的匯編代碼見(jiàn)如下的介紹3 隊(duì)列的創(chuàng)建及其實(shí)現(xiàn)在SRTX中,syqcre用于創(chuàng)建隊(duì)列,其使用方法是:輸入:寄存器 CX包含欲創(chuàng)建隊(duì)列的最大深度(注意必須小于最大隊(duì)列深度64).輸出:若創(chuàng)建成功,CARRY清0;此時(shí),AX包含了隊(duì)列的ID號(hào).若CARR澧位,AX 寄存

33、器將包含下列錯(cuò)誤碼:0451h, 無(wú)效隊(duì)列長(zhǎng)度。044eh, 隊(duì)列建立錯(cuò)誤以下 syqcre 是的典型使用方法:Jmov cx,40call syqcrejc creat_errormov queue_id,AX以下是 syqcre 的實(shí)現(xiàn)代碼:J;syqcre create a queueJsyqcre_sub:pushbxpushcxpushdxpushsipushds;reserve used regsmovbx,dsegmovds,bxorcx,cx; is queues size zero?jnzsyqcre_sub_check1 ; no jumpmovax,0451h; queu

34、e depth=0 errorjmpsyqcre_sub_error; larger than 64; no jump; errorsyqcre_sub_check1:cmp cx,40hjbe syqcre_sub1mov ax,0451hjmp syqcre_sub_errorsyqcre_sub1:movdl,cl ; depth in clxorax,ax ; first queue ID=0-AXmovbx,0230hmovcx,max_task_nosyqcre_sub2:testbyte ptrbx+0100h,80h ; is this queue AVAILABLE?jnzf

35、ill_queue_message ; yes, jmpaddbx,0108h; find next queueincax; queue id increasedloopsyqcre_sub2movax,044eh; no empty queue for usejmpsyqcre_sub_errorfill_queue_message:movsi,bx ; bx-queue buffer headmovsi+0100h,dl ; record size for this queuemovbyte ptrsi+0101h,0 ; initial message countmovbyte ptrs

36、i+0102h,0 ; initial current label numbermovbyte ptrsi+0103h,0 ; initial server numbermovds:si+0104h,bx; initial input pointer; point to first elementmovds:si+0106h,bx; initial output pointer; point to first element,tooclc jmpJsyqcre_sub_exitsyqcre_sub_error:stcsyqcre_sub_exit:popdspopsipopdxpopcxpop

37、bxret由上可見(jiàn), queue_ID 與 Task_ID 的定義方法差不多,表示隊(duì)列創(chuàng)建的順序號(hào) ( 創(chuàng)建的第一個(gè)隊(duì)列,queue_ID=0, 創(chuàng)建的第二個(gè)隊(duì)列 , queue_ID=1 ,) ,隊(duì)列創(chuàng)建后,初始隊(duì)列消息數(shù)為 0( 隊(duì)列中沒(méi)有消息 ),input 和 output 指針都指向隊(duì)列緩沖區(qū)的頭部初始當(dāng)前標(biāo)簽號(hào)和服務(wù)號(hào)均為 0.4 插入一條消息到指定隊(duì)列在SRTX中,syqpst用于發(fā)送消息到隊(duì)列,其使用方法是:輸入:寄存器BX包含隊(duì)列的標(biāo)識(shí)符,DX:AX包含記錄在隊(duì)列里的雙字信息輸出:若成功,CARRY清0;若CARR澧位,AX寄存器將包含下列錯(cuò)誤碼: 044dh, 隊(duì)列標(biāo)識(shí)符錯(cuò)

38、誤。044fh , 隊(duì)列滿錯(cuò)誤以下 syqpst 是的典型使用方法:mov ax,offset block mov dx,seg block mov bx,queue_ID call SYQPST jc error以下是 syqcre 的實(shí)現(xiàn)代碼 , 注意其中對(duì)臨界區(qū)和隊(duì)列的操作方法:;syqpst: post a message to a queuesyqpst_sub:push bx push dx push si push di push dspush axpush dx mov ax,bx cmp ax,max_task_nojb syqpst_sub1mov ax,044dh;que

39、ue_id is too largejmp syqpst_sub_errorsyqpst_sub1:mov bx,dseg mov ds,bx mov bx,0108h mul bxmov bx,axadd bx,0230h; bx-this queue addrsyqpst_sub2:test byte ptrbx+0100h,80h ; is queue empty? jz syqpst_sub3 ; no jmpmov ax,044dh; queue is still not createdjmp syqpst_sub_errorsyqpst_sub3:callsysdti_sub; d

40、isable task switchmoval,bx+0101h; get current message countcmpal,bx+0100h; greater than max length?jbsyqpst_sub4; no,jmpcallsyseti_sub; enable task switchmovax,044fh; queue is fulljmpsyqpst_sub_error; exitsyqpst_sub4:movsi,bx+0104h; take input pointerpopdx; dx=segpopax; ax=offsetmovsi,ax; insert a d

41、ouble wordmovsi+02,dx; message in current locationmovdi,bxadddi,0100h; di-queue bottomaddsi,04; next input pointercmpsi,di; input pointer arrive at bottom?jbsyqpst_sub5; No, jumpmovsi,bx; input pointer - queue head;1996.1.29 by yqhsyqpst_sub5:mov bx+0104h,si; reserve input pointerinc ds:byte ptr bx+

42、0101h ; message count+ call syseti_sub; enable task switch againclcjmp syqpst_sub_exitsyqpst_sub_error: pop bx pop bx stcsyqpst_sub_exit:pop dspop dipop sipop dxpop bxret注意其中對(duì)隊(duì)列輸入指針的處理 , 每加入一條消息 ,輸入指針 input 加 4, 若輸入 指針加 4 后已經(jīng)到達(dá)隊(duì)列的底部 , 這時(shí)需要將輸入指針調(diào)整到隊(duì)列的頭部 , 實(shí)現(xiàn)循環(huán) 隊(duì)列的操作 .5 從隊(duì)列中取出一條消息 (1)在SRTX中,syqacc用于從隊(duì)

43、列中取出一條消息,其使用方法是:輸入:寄存器BX包含隊(duì)列的標(biāo)識(shí)符.輸出:若成功,CARRY清0; DX:AX中包含雙字信息,若CARR逼位,AX寄存器將包 含下列錯(cuò)誤碼:044dh , , 隊(duì)列標(biāo)識(shí)符ID 錯(cuò)誤。0450h, 隊(duì)列空錯(cuò)誤 .以下 syqacc 是的典型使用方法:mov bx, queue_IDcall SYQACCjc error mov ds, dx mov si, ax以下是 syqacc 的實(shí)現(xiàn)代碼 , 注意其中對(duì)臨界區(qū)和隊(duì)列的操作方法:;syqacc accept a message from a queuesyqacc_sub:push bxpush cxpush s

44、ipush dipush dsmov ax,bx cmp ax,max_task_nojb syqacc_sub1mov ax,044dh;queue_ID is to largejmp syqacc_sub_errorsyqacc_sub1:movbx,dsegmovds,bxmovbx,0108hmulbxmovbx,axaddbx,0230h; bx- this queue buffertestbyte ptr bx+0100h,80h ; is this queue createdjzsyqacc_sub2; yes, jumpmovax,044dh; queue is still n

45、ot createdjmp syqacc_sub_errorsyqacc_sub2:callsysdti_submoval,bx+0101h; get msg countoral,al; is there message in queuejnzsyqacc_sub3; yes jumpcallsyseti_sub; no msg in queuemovax,0450hJjmp syqacc_sub_exitsyqacc_sub3:movsi,bx+0106h; remove a message from queuemovax,si; get offset firstmovdx,si+02; g

46、et segaddsi,04; next output pointermovdi,bxadddi,0100h; queue bottomcmpsi,di; if next point to bottom?jbsyqacc_sub4; no, jumpmovsi,bx; next point to queue headsyqacc_sub4:mov bx+0106h,si; set next output pointerdec byte ptr bx+0101h ; dec message count call syseti_subclcjmp syqacc_sub_exitsyqacc_sub

47、_error:stcsyqacc_sub_exit:pop dspop dipop sipop cxpop bxret注意其中對(duì)隊(duì)列輸出指針的處理 , 每取出一條消息 ,輸出指針 output 加4, 若輸出 指針加 4 后已經(jīng)到達(dá)隊(duì)列的底部 , 這時(shí)需要將輸出指針調(diào)整到隊(duì)列的頭部 , 實(shí)現(xiàn)循環(huán) 隊(duì)列的操作 .注意,SYQACC實(shí)現(xiàn)的是從隊(duì)列中直接取出一條記錄 ,若隊(duì)列中沒(méi)有消息,則返回 錯(cuò)誤代碼0450H,以下要介紹的SYQPN也是從隊(duì)列中取出一條記錄 ,但若隊(duì)列中沒(méi)有 消息時(shí),本任務(wù)需要掛在此隊(duì)列上等待,直到超時(shí)為止.(由于SYQPN抄及到任務(wù)調(diào) 度和定時(shí)管理的內(nèi)容 , 因此留到后面的章節(jié)

48、來(lái)介紹 ).6 隊(duì)列狀態(tài)查詢?cè)赟RTX中,syqinq用于查詢指定隊(duì)列的狀態(tài),其使用方法是:輸入:寄存器BX包含隊(duì)列的標(biāo)識(shí)符.輸出:若CARRY為0; CX包含本隊(duì)列中的元素?cái)?shù)目(可能為0), DX:AX中包含雙字信 息(當(dāng)CX=0時(shí),DX:AX無(wú)效);若CARRYS位,查詢失敗,CX=0,AX寄存器將包含下列錯(cuò) 誤碼:044dh, 隊(duì)列標(biāo)識(shí)符 ID 錯(cuò)誤。以下是 syqinq 的典型使用方法:mov bx, queue_IDcall SYQINQjcerrororcx, cxjzno_mailmovds, dxmovsi, ax以下是 syqinq 的實(shí)現(xiàn)代碼 , 注意其中對(duì)臨界區(qū)的操作:;

49、syqinq perform a queue inquirysyqinq_sub:push bxpushpushpushsi di dsxorcx,cxmovax,bxcmpax,max_task_nojb syqinq_sub1mov ax,044dh;queue_ID is too largejmp syqinq_sub_errorsyqinq_sub1:movbx,dsegmovds,bxmovbx,0108hmulbxmovbx,axaddbx,0230h; bx- queue headtestbyte ptrbx+0100h,80h ; is queue created ?jzsyq

50、inq_sub2; yes, jumpmovax,044dh; queue is not still createdjmp syqinq_sub_errorsyqinq_sub2:callsysdti_submovsi,bx+0106h; find out addr of messagemovax,si; dx:ax contain a copy ofmovdx,si+02; first_out queue datamovcl,bx+0101h; take message countcallsyseti_subclcjmpsyqinq_sub_exitsyqinq_sub_error:stcs

51、yqinq_sub_exit:pop dspop dipop sipop bxret注意SYQINC完成的操作只是將雙字指針的拷貝取出,并不象SYQACCE樣將輸出指針移位,在SYQINQ之后,再用SYQACC得到的DX:AX與SYQINQ完全一樣.三. 定時(shí)管理及其實(shí)現(xiàn)多任務(wù)程序的超時(shí)機(jī)制和狀態(tài)的切換都與定時(shí)管理有關(guān),本節(jié)介紹以下SRTX勺定時(shí)管理。1定時(shí)器及定時(shí)中斷 多任務(wù)程序的運(yùn)行一定需要有定時(shí)機(jī)制的硬件支持,通過(guò)對(duì)硬件的編程,可以使系統(tǒng)實(shí)現(xiàn)既定時(shí)間長(zhǎng)度產(chǎn)生中斷,在中斷服務(wù)程序中,完成對(duì)相應(yīng)需要定時(shí)的進(jìn)程進(jìn)行控 制。SRTX是針對(duì)PC機(jī)而設(shè)計(jì)的,DOS系統(tǒng)每隔55ms產(chǎn)生一次INT8的中斷,在INT8的 中斷服務(wù)程序中,調(diào)用了 INT 1C(INT 1C 的函數(shù)體是空 ), 因此可以編一個(gè)自己的函數(shù)替 換INT1C,就可以讓系統(tǒng)定時(shí)調(diào)用我們自己的函數(shù),在此函數(shù)中,可以讓它實(shí)現(xiàn)定時(shí)管理功能,在SRTX中 ,SYSRTI就是這樣一個(gè)函數(shù)2定時(shí)器的實(shí)現(xiàn)在SRTX中 ,系統(tǒng)定時(shí)調(diào)用sysrti,實(shí)現(xiàn)定時(shí)管理功能以下是SYSRTI的實(shí)現(xiàn)代碼:J;colck interrupt handlersysrti proc farpushdspushaxmovax,dsegmovds,axaddds:wo

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論