setjmp構(gòu)建簡(jiǎn)單協(xié)作式多任務(wù)系統(tǒng)
摘要:討論一個(gè)利用標(biāo)準(zhǔn)C語(yǔ)言setjmp庫(kù)函烽實(shí)現(xiàn)查詢式協(xié)作多任務(wù)系統(tǒng),給出完整的內(nèi)核和樣例程序并對(duì)源代碼進(jìn)行說(shuō)明。該系統(tǒng)具有簡(jiǎn)單易用的特點(diǎn),只需要編寫(xiě)存取堆棧指針的宏就可方便地移植到新的平臺(tái)上。文章詳述了系統(tǒng)的優(yōu)缺點(diǎn),討論一些性能擴(kuò)展的方法。該內(nèi)核適用于中小規(guī)模的嵌入式軟件。關(guān)鍵詞:協(xié)作式多任務(wù) C語(yǔ)言 setjmp
引言
本文介紹的是利用標(biāo)準(zhǔn)C語(yǔ)言setjmp庫(kù)函數(shù)實(shí)現(xiàn)的具備此特點(diǎn)的協(xié)作式多任務(wù)系統(tǒng)。從本質(zhì)上講,實(shí)時(shí)多任務(wù)操作系統(tǒng)應(yīng)該具備按照優(yōu)先級(jí)搶占調(diào)度的內(nèi)核。然而,在實(shí)際應(yīng)用中,搶中式的多任務(wù)某種程序上帶來(lái)了用戶程序設(shè)計(jì)時(shí)數(shù)據(jù)保護(hù)的困難,并且,具備搶占功能的多任務(wù)內(nèi)核設(shè)計(jì)時(shí)困難也比較多,這會(huì)增加操作系統(tǒng)自身的代碼,也使它在小資源單片機(jī)系統(tǒng)中應(yīng)用較少;而協(xié)作多任務(wù)系統(tǒng)的調(diào)度只在用戶指定的時(shí)機(jī)發(fā)生,這會(huì)大大簡(jiǎn)化內(nèi)核和用戶系統(tǒng)的設(shè)計(jì),尤其本文實(shí)現(xiàn)的系統(tǒng)通過(guò)條件查詢來(lái)放棄CPU,既符合傳統(tǒng)單片機(jī)程序設(shè)計(jì)的思維,又帶來(lái)了多任務(wù)、模塊化、可重入的編程便利。
Setjmp是標(biāo)準(zhǔn)C語(yǔ)言庫(kù)函數(shù)的組成部分,它可以實(shí)現(xiàn)程序執(zhí)行中的遠(yuǎn)程轉(zhuǎn)操作。具體來(lái)說(shuō),它可以在一個(gè)函數(shù)中使用setjmp來(lái)初始化一個(gè)全局標(biāo)號(hào),然后只要該函數(shù)未曾返回,那么在其它任何地方都可以通過(guò)longjmp調(diào)用來(lái)跳轉(zhuǎn)到setjmp的下一條語(yǔ)句執(zhí)行。實(shí)際上,setjmp函數(shù)將發(fā)生調(diào)用處的局部環(huán)境保存在一個(gè)jmp_buf的結(jié)構(gòu)當(dāng)中,只要主調(diào)函數(shù)中對(duì)應(yīng)的內(nèi)存未曾釋放(函數(shù)返回時(shí)局部?jī)?nèi)存就失效了),那么在調(diào)用longjmp的時(shí)候就可以根據(jù)已保存的jmp_buf參數(shù)恢復(fù)到setjmp的地方執(zhí)行。我們的系統(tǒng)中就是分析了setjmp標(biāo)準(zhǔn)庫(kù)函數(shù)的特點(diǎn),以簡(jiǎn)單的方式實(shí)現(xiàn)了協(xié)作式多任務(wù)。
1 演示程序
為了便于理解,首先給出多任務(wù)演示程序的源代碼。這個(gè)程序演示了協(xié)作式多任務(wù)切換、任務(wù)的動(dòng)態(tài)生成、多任務(wù)共用代碼等功能,一共使用了init_coos初始化根任務(wù)(也就是C語(yǔ)言main函數(shù))、creat_task創(chuàng)建新任務(wù)和WAITFOR查詢條件這3個(gè)基本的系統(tǒng)調(diào)用。由于面向嵌入式系統(tǒng),因而程序不會(huì)中止并且運(yùn)行中也沒(méi)有進(jìn)行任何輸出,需要借助適合的調(diào)試工具來(lái)理解多任務(wù)系統(tǒng)的運(yùn)行。
example.c文件清單:
#include<stdlib.h>
#include“co-os.h”
void tskfunc1(int argc,void *argv);
void tskfunc2(int argc,void *argv);
void subfunc(void);
volatile int cnt,test;
int main(void){
int i;
[1] [2] [3] [4] [5] [6]