建立一個(gè)屬于自己的AVR的RTOS_第1頁
建立一個(gè)屬于自己的AVR的RTOS_第2頁
建立一個(gè)屬于自己的AVR的RTOS_第3頁
建立一個(gè)屬于自己的AVR的RTOS_第4頁
建立一個(gè)屬于自己的AVR的RTOS_第5頁
已閱讀5頁,還剩42頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、序 自從03年以來,對單片機(jī)的RTOS的學(xué)習(xí)和應(yīng)用的熱潮可謂一浪高過一浪.03年,在離開校園前的,非典的那幾個(gè)月,在華師的后門那里買了本邵貝貝的UCOSII,通讀了幾次,沒有實(shí)驗(yàn)器材,也不了了之。 在21IC上,大家都可以看到楊屹寫的關(guān)于UCOSII在51上的移植,于是掀起了51上的RTOS的熱潮。 再后來,陳明計(jì)先生推出的smallrots,展示了一個(gè)用在51上的微內(nèi)核,足以在52上進(jìn)行任務(wù)調(diào)度。 前段時(shí)間,在ouravr上面開有專門關(guān)于AVR的Rtos的專欄,并且不少的兄弟把自己的作品拿出來,著實(shí)開了不少眼界。這時(shí),我重新回顧了使用單片機(jī)的經(jīng)歷,覺得很有必要,從根本上對單片機(jī)的RTOS的知

2、識進(jìn)行整理,于是,我開始了編寫一個(gè)用在AVR單片機(jī)的RTOS。 當(dāng)時(shí),我所有的知識和資源有: Proteus6.7可以用來模擬仿真avr系列的單片機(jī) WinAVRv8基于GCCAVR的編譯環(huán)境,好處在于可以在C語言中插入asm的語句 mega81K的ram有8K的rom,是開發(fā)8位的RTOS的一個(gè)理想的器件,并且我對它也比較熟悉。 寫UCOS的JeanJ.Labrosse在他的書上有這樣一句話,“漸漸地,我自然會想到,寫個(gè)實(shí)時(shí)內(nèi)核直有那么難嗎?不就是不斷地保存,恢復(fù)CPU的那些寄存器嘛。” 好了,當(dāng)這一切準(zhǔn)備好后,我們就可以開始我們的Rtosformega8的實(shí)驗(yàn)之旅了。 本文列

3、出的例子,全部完整可用。只需要一個(gè)文件就可以編譯了。我相信,只要適當(dāng)可用,最簡單的就是最好的,這樣可以排除一些不必要的干擾,讓大家專注到每一個(gè)過程的學(xué)習(xí)。 第一篇:函數(shù)的運(yùn)行 在一般的單片機(jī)系統(tǒng)中,是以前后臺的方式(大循環(huán)+中斷)來處理數(shù)據(jù)和作出反應(yīng)的。 例子如下: makefile的設(shè)定:運(yùn)行WinAvr中的Mfile,設(shè)定如下 MCUType:mega8 Optimizationlevel:s Debugformat:AVR-COFF C/C+sourcefile:選譯要編譯的C文件 #include voidfun1(void) unsignedchari=0; while(1) POR

4、TB=i+; PORTC=0x01(i%8); intmain(void) fun1(); 首先,提出一個(gè)問題:如果要調(diào)用一個(gè)函數(shù),真是只能以上面的方式進(jìn)行嗎? 相信學(xué)習(xí)過C語言的各位會回答,No!我們還有一種方式,就是“用函數(shù)指針變量調(diào)用函數(shù)”,如果大家都和我一樣,當(dāng)初的教科書是譚浩強(qiáng)先生的C程序設(shè)計(jì)的話,請找回書的第9.5節(jié)。 例子:用函數(shù)指針變量調(diào)用函數(shù) #include voidfun1(void) unsignedchari=0; while(1) PORTB=i+; PORTC=0x01(i%8); void(*pfun)();/指向函數(shù)的指針 intmain(void) pfun

5、=fun1;/ (*pfun)();/運(yùn)行指針?biāo)赶虻暮瘮?shù) 第二種,是“把指向函數(shù)的指針變量作函數(shù)參數(shù)” #include voidfun1(void) unsignedchari=0; while(1) PORTB=i+; PORTC=0x01(i%8); voidRunFun(void(*pfun)()/獲得了要傳遞的函數(shù)的地址 (*pfun)();/在RunFun中,運(yùn)行指針?biāo)赶虻暮瘮?shù) intmain(void) RunFun(fun1);/將函數(shù)的指針作為變量傳遞 看到上面的兩種方式,很多人可能會說,“這的確不錯(cuò)”,但是這樣與我們想要的RTOS,有什么關(guān)系呢?各位請細(xì)心向下看。 以下

6、是GCC對上面的代碼的編譯的情況: 對main()中的RunFun(fun1);的編譯如下 ldir24,lo8(pm(fun1) ldir25,hi8(pm(fun1) rcallRunFun 對voidRunFun(void(*pfun)()的編譯如下 /*voidRunFun(void(*pfun)()*/ /*(*pfun)();*/ .LM6: movwr30,r24 icall ret 在調(diào)用voidRunFun(void(*pfun)()的時(shí)候,的確可以把fun1的地址通過r24和r25傳遞給RunFun()。但是,RTOS如何才能有效地利用函數(shù)的地址呢? 第二篇:人工堆棧 在單

7、片機(jī)的指令集中,一類指令是專門與堆棧和PC指針打道的,它們是 rcall相對調(diào)用子程序指令 icall間接調(diào)用子程序指令 ret子程序返回指令 reti中斷返回指令 對于ret和reti,它們都可以將堆棧棧頂?shù)膬蓚€(gè)字節(jié)被彈出來送入程序計(jì)數(shù)器PC中,一般用來從子程序或中斷中退出。其中reti還可以在退出中斷時(shí),重開全局中斷使能。 有了這個(gè)基礎(chǔ),就可以建立我們的人工堆棧了。 例: #include voidfun1(void) unsignedchari=0; while(1) PORTB=i+; PORTC=0x018;/將函數(shù)的地址高位壓入堆棧, *pStack-=(unsignedint)p

8、fun;/將函數(shù)的地址低位壓入堆棧, SP=pStack;/將堆棧指針指向人工堆棧的棧頂 _asm_volatile_(RET t);/返回并開中斷,開始運(yùn)行fun1() intmain(void) RunFunInNewStack(fun1,&Stack99); RunFunInNewStack(),將指向函數(shù)的指針的值保存到一個(gè)unsignedchar的數(shù)組Stack中,作為人工堆棧。并且將棧頂?shù)臄?shù)值傳遞組堆棧指針SP,因此當(dāng)用ret返回時(shí),從SP中恢復(fù)到PC中的值,就變?yōu)榱酥赶騠un1()的地址,開始運(yùn)行fun1(). 上面例子中在RunFunInNewStack()的最后一句嵌入了匯編

9、代碼ret,實(shí)際上是可以去除的。因?yàn)樵赗unFunInNewStack()返回時(shí),編譯器已經(jīng)會加上ret。我特意寫出來,是為了讓大家看到用ret作為返回后運(yùn)行fun1()的過程。 第三篇:GCC中對寄存器的分配與使用 在很多用于AVR的RTOS中,都會有任務(wù)調(diào)度時(shí),插入以下的語句: 入棧: _asm_volatile_(PUSHR0 t); _asm_volatile_(PUSHR1 t); . _asm_volatile_(PUSHR31 t); 出棧 _asm_volatile_(POPR31 t); . _asm_volatile_(POPR1 t); _asm_volatile_(PO

10、PR0 t); 通常大家都會認(rèn)為,在任務(wù)調(diào)度開始時(shí),當(dāng)然要將所有的通用寄存器都保存,并且還應(yīng)該保存程序狀態(tài)寄存器SREG。然后再根據(jù)相反的次序,將新任務(wù)的寄存器的內(nèi)容恢復(fù)。 但是,事實(shí)真的是這樣嗎?如果大家看過陳明計(jì)先生寫的smallrots51,就會發(fā)現(xiàn),它所保存的通用寄存器不過是4組通用寄存器中的1組。 在WinAVR中的幫助文件avr-libcManual中的RelatedPages中的FrequentlyAskedQuestions,其實(shí)有一個(gè)問題是WhatregistersareusedbytheCcompiler?回答了編譯器所需要占用的寄存器。一般情況下,編譯器會先用到以下寄存器

11、 1Call-usedregisters(r18-r27,r30-r31):調(diào)用函數(shù)時(shí)作為參數(shù)傳遞,也就是用得最多的寄存器。 2Call-savedregisters(r2-r17,r28-r29):調(diào)用函數(shù)時(shí)作為結(jié)果傳遞,當(dāng)中的r28和r29可能會被作為指向堆棧上的變量的指針。 3Fixedregisters(r0,r1):固定作用。r0用于存放臨時(shí)數(shù)據(jù),r1用于存放0。 還有另一個(gè)問題是Howtopermanentlybindavariabletoaregister?,是將變量綁定到通用寄存器的方法。而且我發(fā)現(xiàn),如果將某個(gè)寄存器定義為變量,編譯器就會不將該寄存器分配作其它用途。這對RTOS

12、是很重要的。 在InlineAsm中的CNamesUsedinAssemblerCode明確表示,如果將太多的通用寄存器定義為變量,剛在編譯的過程中,被定義的變量依然可能被編譯器占用。 大家可以比較以下兩個(gè)例子,看看編譯器產(chǎn)生的代碼:(在*.lst文件中) 第一個(gè)例子:沒有定義通用寄存器為變量 #include unsignedcharadd(unsignedcharb,unsignedcharc,unsignedchard) returnb+c*d; intmain(void) unsignedchara=0; while(1) a+; PORTB=add(a,a,a); 在本例中,add(

13、a,a,a);被編譯如下: movr20,r28 movr22,r28 movr24,r28 rcalladd 第二個(gè)例子:定義通用寄存器為變量 #include unsignedcharadd(unsignedcharb,unsignedcharc,unsignedchard) returnb+c*d; registerunsignedcharaasm(r20);/將r20定義為變量a intmain(void) while(1) a+; PORTB=add(a,a,a); 在本例中,add(a,a,a);被編譯如下: movr22,r20 movr24,r20 rcalladd 當(dāng)然,在上

14、面兩個(gè)例子中,有部份代碼被編譯器優(yōu)化了。 通過反復(fù)測試,發(fā)現(xiàn)編譯器一般使用如下寄存器: 第1類寄存器,第2類寄存器的r28,r29,第3類寄存器 如在中斷函數(shù)中有調(diào)用基它函數(shù),剛會在進(jìn)入中斷后,固定地將第1類寄存器和第3類寄存器入棧,在退出中斷又將它們出棧。第四篇:只有延時(shí)服務(wù)的協(xié)作式的內(nèi)核 CooperativeMultitasking 前后臺系統(tǒng),協(xié)作式內(nèi)核系統(tǒng),與占先式內(nèi)核系統(tǒng),有什么不同呢? 記得在21IC上看過這樣的比喻,“你(小工)在用廁所,經(jīng)理在外面排第一,老板在外面排第二。如果是前后臺,不管是誰,都必須按排隊(duì)的次序使用廁所;如果是協(xié)作式,那么可以等你用完廁所,老板就要比經(jīng)理先進(jìn)

15、入;如果是占先式,只要有更高級的人在外面等,那么廁所里無論是誰,都要第一時(shí)間讓出來,讓最高級別的人先用。” #include #include #include unsignedcharStack200; registerunsignedcharOSRdyTblasm(r2);/任務(wù)運(yùn)行就緒表 registerunsignedcharOSTaskRunningPrioasm(r3);/正在運(yùn)行的任務(wù) #defineOS_TASKS3/設(shè)定運(yùn)行任務(wù)的數(shù)量 structTaskCtrBlock/任務(wù)控制塊 unsignedintOSTaskStackTop;/保存任務(wù)的堆棧頂 unsignedin

16、tOSWaitTick;/任務(wù)延時(shí)時(shí)鐘 TCBOS_TASKS+1; /防止被編譯器占用 registerunsignedchartempR4asm(r4); registerunsignedchartempR5asm(r5); registerunsignedchartempR6asm(r6); registerunsignedchartempR7asm(r7); registerunsignedchartempR8asm(r8); registerunsignedchartempR9asm(r9); registerunsignedchartempR10asm(r10); register

17、unsignedchartempR11asm(r11); registerunsignedchartempR12asm(r12); registerunsignedchartempR13asm(r13); registerunsignedchartempR14asm(r14); registerunsignedchartempR15asm(r15); registerunsignedchartempR16asm(r16); registerunsignedchartempR16asm(r17); /建立任務(wù) voidOSTaskCreate(void(*Task)(void),unsigned

18、char*Stack,unsignedcharTaskID) unsignedchari; *Stack-=(unsignedint)Task8;/將任務(wù)的地址高位壓入堆棧, *Stack-=(unsignedint)Task;/將任務(wù)的地址低位壓入堆棧, *Stack-=0x00;/R1_zero_reg_ *Stack-=0x00;/R0_tmp_reg_ *Stack-=0x80;/SREG在任務(wù)中,開啟全局中斷 for(i=0;i14;i+)/在avr-libc中的FAQ中的WhatregistersareusedbytheCcompiler? *Stack-=i;/描述了寄存器的作用

19、 TCBTaskID.OSTaskStackTop=(unsignedint)Stack;/將人工堆棧的棧頂,保存到堆棧的數(shù)組中 OSRdyTbl|=0x01TaskID;/任務(wù)就緒表已經(jīng)準(zhǔn)備好 /開始任務(wù)調(diào)度,從最低優(yōu)先級的任務(wù)的開始 voidOSStartTask() OSTaskRunningPrio=OS_TASKS; SP=TCBOS_TASKS.OSTaskStackTop+17; _asm_volatile_(reti t); /進(jìn)行任務(wù)調(diào)度 voidOSSched(void) /根據(jù)中斷時(shí)保存寄存器的次序入棧,模擬一次中斷后,入棧的情況 _asm_volatile_(PUSH_

20、zero_reg_ t);/R1 _asm_volatile_(PUSH_tmp_reg_ t);/R0 _asm_volatile_(IN_tmp_reg_,_SREG_ t);/保存狀態(tài)寄存器SREG _asm_volatile_(PUSH_tmp_reg_ t); _asm_volatile_(CLR_zero_reg_ t);/R0重新清零 _asm_volatile_(PUSHR18 t); _asm_volatile_(PUSHR19 t); _asm_volatile_(PUSHR20 t); _asm_volatile_(PUSHR21 t); _asm_volatile_(P

21、USHR22 t); _asm_volatile_(PUSHR23 t); _asm_volatile_(PUSHR24 t); _asm_volatile_(PUSHR25 t); _asm_volatile_(PUSHR26 t); _asm_volatile_(PUSHR27 t); _asm_volatile_(PUSHR30 t); _asm_volatile_(PUSHR31 t); _asm_volatile_(PUSHR28 t);/R28與R29用于建立在堆棧上的指針 _asm_volatile_(PUSHR29 t);/入棧完成 TCBOSTaskRunningPrio.O

22、STaskStackTop=SP;/將正在運(yùn)行的任務(wù)的堆棧底保存 unsignedcharOSNextTaskID;/在現(xiàn)有堆棧上開設(shè)新的空間 for(OSNextTaskID=0;/進(jìn)行任務(wù)調(diào)度 OSNextTaskIDOS_TASKS&!(OSRdyTbl&(0x01OSNextTaskID); OSNextTaskID+); OSTaskRunningPrio=OSNextTaskID; cli();/保護(hù)堆棧轉(zhuǎn)換 SP=TCBOSTaskRunningPrio.OSTaskStackTop; sei(); /根據(jù)中斷時(shí)的出棧次序 _asm_volatile_(POPR29 t); _a

23、sm_volatile_(POPR28 t); _asm_volatile_(POPR31 t); _asm_volatile_(POPR30 t); _asm_volatile_(POPR27 t); _asm_volatile_(POPR26 t); _asm_volatile_(POPR25 t); _asm_volatile_(POPR24 t); _asm_volatile_(POPR23 t); _asm_volatile_(POPR22 t); _asm_volatile_(POPR21 t); _asm_volatile_(POPR20 t); _asm_volatile_(P

24、OPR19 t); _asm_volatile_(POPR18 t); _asm_volatile_(POP_tmp_reg_ t);/SERG出棧并恢復(fù) _asm_volatile_(OUT_SREG_,_tmp_reg_ t);/ _asm_volatile_(POP_tmp_reg_ t);/R0出棧 _asm_volatile_(POP_zero_reg_ t);/R1出棧 /中斷時(shí)出棧完成 voidOSTimeDly(unsignedintticks) if(ticks)/當(dāng)延時(shí)有效 OSRdyTbl&=(0x01OSTaskRunningPrio); TCBOSTaskRunnin

25、gPrio.OSWaitTick=ticks; OSSched();/從新調(diào)度 voidTCN0Init(void)/計(jì)時(shí)器0 TCCR0=0; TCCR0|=(1CS02);/256預(yù)分頻 TIMSK|=(1TOIE0);/T0溢出中斷允許 TCNT0=100;/置計(jì)數(shù)起始值 SIGNAL(SIG_OVERFLOW0) unsignedchari; for(i=0;iOS_TASKS;i+)/任務(wù)時(shí)鐘 if(TCBi.OSWaitTick) TCBi.OSWaitTick-; if(TCBi.OSWaitTick=0)/當(dāng)任務(wù)時(shí)鐘到時(shí),必須是由定時(shí)器減時(shí)的才行 OSRdyTbl|=(0x01

26、i);/使任務(wù)在就緒表中置位 TCNT0=100; voidTask0() unsignedintj=0; while(1) PORTB=j+; OSTimeDly(2); voidTask1() unsignedintj=0; while(1) PORTC=j+; OSTimeDly(4); voidTask2() unsignedintj=0; while(1) PORTD=j+; OSTimeDly(8); voidTaskScheduler() while(1) OSSched();/反復(fù)進(jìn)行調(diào)度 intmain(void) TCN0Init(); OSRdyTbl=0; OSTask

27、RunningPrio=0; OSTaskCreate(Task0,&Stack49,0); OSTaskCreate(Task1,&Stack99,1); OSTaskCreate(Task2,&Stack149,2); OSTaskCreate(TaskScheduler,&Stack199,OS_TASKS); OSStartTask(); 在上面的例子中,一切變得很簡單,三個(gè)正在運(yùn)行的主任務(wù),都通過延時(shí)服務(wù),主動(dòng)放棄對CPU的控制權(quán)。 在時(shí)間中斷中,對各個(gè)任務(wù)的的延時(shí)進(jìn)行計(jì)時(shí),如果某個(gè)任務(wù)的延時(shí)結(jié)束,將任務(wù)重新在就緒表中置位。 最低級的系統(tǒng)任務(wù)TaskScheduler(),在三個(gè)主任

28、務(wù)在放棄對CPU的控制權(quán)后開始不斷地進(jìn)行調(diào)度。如果某個(gè)任務(wù)在就緒表中置位,通過調(diào)度,進(jìn)入最高級別的任務(wù)中繼續(xù)運(yùn)行。第五篇:完善的協(xié)作式的內(nèi)核 現(xiàn)在為上面的協(xié)作式內(nèi)核添加一些OS中所必須的服務(wù): 1掛起和重新運(yùn)行任務(wù) 2信號量(在必要時(shí)候,可以擴(kuò)展成郵箱和信息隊(duì)列) 3延時(shí) #include #include #include unsignedcharStack400; registerunsignedcharOSRdyTblasm(r2);/任務(wù)運(yùn)行就緒表 registerunsignedcharOSTaskRunningPrioasm(r3);/正在運(yùn)行的任務(wù) #defineOS_TASKS

29、3/設(shè)定運(yùn)行任務(wù)的數(shù)量 structTaskCtrBlock unsignedintOSTaskStackTop;/保存任務(wù)的堆棧頂 unsignedintOSWaitTick;/任務(wù)延時(shí)時(shí)鐘 TCBOS_TASKS+1; /防止被編譯器占用 registerunsignedchartempR4asm(r4); registerunsignedchartempR5asm(r5); registerunsignedchartempR6asm(r6); registerunsignedchartempR7asm(r7); registerunsignedchartempR8asm(r8); reg

30、isterunsignedchartempR9asm(r9); registerunsignedchartempR10asm(r10); registerunsignedchartempR11asm(r11); registerunsignedchartempR12asm(r12); registerunsignedchartempR13asm(r13); registerunsignedchartempR14asm(r14); registerunsignedchartempR15asm(r15); registerunsignedchartempR16asm(r16); registeru

31、nsignedchartempR16asm(r17); /建立任務(wù) voidOSTaskCreate(void(*Task)(void),unsignedchar*Stack,unsignedcharTaskID) unsignedchari; *Stack-=(unsignedint)Task8;/將任務(wù)的地址高位壓入堆棧, *Stack-=(unsignedint)Task;/將任務(wù)的地址低位壓入堆棧, *Stack-=0x00;/R1_zero_reg_ *Stack-=0x00;/R0_tmp_reg_ *Stack-=0x80; /SREG在任務(wù)中,開啟全局中斷 for(i=0;i1

32、4;i+)/在avr-libc中的FAQ中的WhatregistersareusedbytheCcompiler? *Stack-=i;/描述了寄存器的作用 TCBTaskID.OSTaskStackTop=(unsignedint)Stack;/將人工堆棧的棧頂,保存到堆棧的數(shù)組中 OSRdyTbl|=0x01TaskID;/任務(wù)就緒表已經(jīng)準(zhǔn)備好 /開始任務(wù)調(diào)度,從最低優(yōu)先級的任務(wù)的開始 voidOSStartTask() OSTaskRunningPrio=OS_TASKS; SP=TCBOS_TASKS.OSTaskStackTop+17; _asm_volatile_(reti t);

33、 /進(jìn)行任務(wù)調(diào)度 voidOSSched(void) /根據(jù)中斷時(shí)保存寄存器的次序入棧,模擬一次中斷后,入棧的情況 _asm_volatile_(PUSH_zero_reg_ t);/R1 _asm_volatile_(PUSH_tmp_reg_ t);/R0 _asm_volatile_(IN_tmp_reg_,_SREG_ t);/保存狀態(tài)寄存器SREG _asm_volatile_(PUSH_tmp_reg_ t); _asm_volatile_(CLR_zero_reg_ t);/R0重新清零 _asm_volatile_(PUSHR18 t); _asm_volatile_(PUSH

34、R19 t); _asm_volatile_(PUSHR20 t); _asm_volatile_(PUSHR21 t); _asm_volatile_(PUSHR22 t); _asm_volatile_(PUSHR23 t); _asm_volatile_(PUSHR24 t); _asm_volatile_(PUSHR25 t); _asm_volatile_(PUSHR26 t); _asm_volatile_(PUSHR27 t); _asm_volatile_(PUSHR30 t); _asm_volatile_(PUSHR31 t); _asm_volatile_(PUSHR28

35、 t);/R28與R29用于建立在堆棧上的指針 _asm_volatile_(PUSHR29 t);/入棧完成 TCBOSTaskRunningPrio.OSTaskStackTop=SP;/將正在運(yùn)行的任務(wù)的堆棧底保存 unsignedcharOSNextTaskID;/在現(xiàn)有堆棧上開設(shè)新的空間 for(OSNextTaskID=0;/進(jìn)行任務(wù)調(diào)度 OSNextTaskIDOS_TASKS&!(OSRdyTbl&(0x01OSNextTaskID); OSNextTaskID+); OSTaskRunningPrio=OSNextTaskID; cli();/保護(hù)堆棧轉(zhuǎn)換 SP=TCBOST

36、askRunningPrio.OSTaskStackTop; sei(); /根據(jù)中斷時(shí)的出棧次序 _asm_volatile_(POPR29 t); _asm_volatile_(POPR28 t); _asm_volatile_(POPR31 t); _asm_volatile_(POPR30 t); _asm_volatile_(POPR27 t); _asm_volatile_(POPR26 t); _asm_volatile_(POPR25 t); _asm_volatile_(POPR24 t); _asm_volatile_(POPR23 t); _asm_volatile_(P

37、OPR22 t); _asm_volatile_(POPR21 t); _asm_volatile_(POPR20 t); _asm_volatile_(POPR19 t); _asm_volatile_(POPR18 t); _asm_volatile_(POP_tmp_reg_ t);/SERG出棧并恢復(fù) _asm_volatile_(OUT_SREG_,_tmp_reg_ t);/ _asm_volatile_(POP_tmp_reg_ t);/R0出棧 _asm_volatile_(POP_zero_reg_ t);/R1出棧 /中斷時(shí)出棧完成 /任務(wù)處理 /掛起任務(wù) voidOSTaskSuspend(unsignedcharprio) TCBprio.OS

溫馨提示

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

最新文檔

評論

0/150

提交評論