<del id="dhfrq"></del>

    1. <tr id="dhfrq"></tr>
      成人午夜激情在线观看,国产精品一线天粉嫩av,99精品国产综合久久久久五月天 ,一卡2卡三卡4卡免费网站,国产高清在线男人的天堂,五月天国产成人AV免费观看,67194熟妇在线观看线路,成人无码潮喷在线观看
      現(xiàn)在位置:范文先生網(wǎng)>理工論文>電子通信論文>setjmp構(gòu)建簡(jiǎn)單協(xié)作式多任務(wù)系統(tǒng)

      setjmp構(gòu)建簡(jiǎn)單協(xié)作式多任務(wù)系統(tǒng)

      時(shí)間:2023-02-20 22:48:58 電子通信論文 我要投稿
      • 相關(guān)推薦

      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)行說明。該系統(tǒng)具有簡(jiǎn)單易用的特點(diǎn),只需要編寫存取堆棧指針的宏就可方便地移植到新的平臺(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ù)某種程序上帶來了用戶程序設(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)通過條件查詢來放棄CPU,既符合傳統(tǒng)單片機(jī)程序設(shè)計(jì)的思維,又帶來了多任務(wù)、模塊化、可重入的編程便利。

      Setjmp是標(biāo)準(zhǔn)C語(yǔ)言庫(kù)函數(shù)的組成部分,它可以實(shí)現(xiàn)程序執(zhí)行中的遠(yuǎn)程轉(zhuǎn)操作。具體來說,它可以在一個(gè)函數(shù)中使用setjmp來初始化一個(gè)全局標(biāo)號(hào),然后只要該函數(shù)未曾返回,那么在其它任何地方都可以通過longjmp調(diào)用來跳轉(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)行中也沒有進(jìn)行任何輸出,需要借助適合的調(diào)試工具來理解多任務(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;

      init_coos(400);

      creat_tsk(tskfunc1,12,NULL,400);

      creat_tsk(tskfunc2,0,NULL,400);

      i=0;

      while(1){

      WAITFOR(cnt= =8);

      while(i++<cnt)test=i;

      cnt++;

      }

      }

      void tskfunc1(int argc,void *argv){

      int i;

      static int creat=0;

      if(!creat){

      creat_tsk(tskfunc1,9,NULL,400);

      creat=1;

      }

      i=0;

      while(1){

      WAITFOR(cnt>argc);

      test=0x55;

      /*使用函數(shù)調(diào)用在子程序中測(cè)試WAITFOR*/

      subfunc();

      >

      while(i++<cnt)test=i^0xAA;

      }

      }

      void tskfunc2(int argc,void *argv){

      while(1){

      WAITFOR(++cnt>15);

      cnt=0;

      }

      }

      void subfunc(void){

      int i;

      WAITFOR(cnt<5);

      for(i=0;i<++)test=0x10*i;

      }

      2 內(nèi)核構(gòu)成

      內(nèi)核包括一個(gè)供外部用戶程序包含的頭文件(co-os.h)和具體實(shí)現(xiàn)的源文件(co-os.c),它們提供了演示程序中用到的3個(gè)系統(tǒng)調(diào)用。

      內(nèi)核的實(shí)現(xiàn)代碼假定了CPU堆棧是向下增長(zhǎng)的,并且通過宏來直接操作堆棧指針。以下代碼在Microsoft VC6 for x86、Borland C++ Builder 5.5、SDS CrossCode7.0 for 68K和GCC3.2 for AVR四種平臺(tái)中測(cè)試過,只需在co-os.h頭文件中定義相應(yīng)的平臺(tái)類型即可順利編譯。

      (1)co-os.h文件清單

      #include<setjmp.h>

      /*選擇X86_VC6,X86_BC5,AVR_GCC或M68H_SDS.*/

      #define X86_VC6

      #define MAX_TSK 10

      typedef struct {

      void (*entry)(int argc,void *argv);

      jmp_buf env;

      int argc;

      void *argv;

      }TVB;

      extern TCB tcb[MAX_TSK];

      extern int task_num,tskid;

      void init_coos(int mainstk);

      int creat_tsk(void(*entry)(int argc,void *argv),int argc,void *argv,int stksize);

      #define WAITFOR(condition)do{

      setjmp(tcb[tskid].env);

      if(!(condition)){

      tskid++;

      if(tskid>=task_num)tskid=0;

      longijmp(tcb[tskid].env,1);

      }

      }while(0)

      (2)co-os.c文件清單

      #include "co-os.h"

      #if defined(X86_VC6)||defined(X86_BC5)

      #define SAVE_SP(p) _asm mov p,esp

      #define RESTORE_SP(p) _asm mov esp,p

      #elif defined(AVR_GCC)

      #include<io.h>

      #define SAVE_SP(p) p=(int*)SP

      #define RESTORE_SP(p) SP=(int)p

      #elif defined(M68K_SDS)

      #define SAVE_SP(p) asm("MOVE.L A7,{"#p"}")

      #define RESTORE_SP(p) asm("MOVE.L {"#p"},A7")

      #endif

      TCB tcb[MAX_TSK];

      Int task_num=1;

      Int tskid;

      Static int stktop,oldsp;

      Void init_coos(int mainstk){

      SAVE_SP(stktop);

      stktop=stktop+sizeof(void(*)(void))/sizeof(int)

      -(mainstk+sizeof(int)-1)/sizeof(int);

      }

      int creat_tsk(void(*entry)(int argc,void *argv),

      int argc,void *argv,int stksize){

      if(task_num>=MAX_TSK)terurn-1;

      SAVE_SP(oldsp);

      RESTORE_SP(stktop);

      If(!setjmp(tcb[task_num].env)){

      RESTORE_SP(oldsp);

      tcb[task_num].entry=entry;

      tcb[task_num].argc=argc;

      tcb[task_num].argv=argv;

      task_num++;

      stktop-=(stksize+sizeof(int)-1)/sizeof(int);

      }

      else tcb[tskid].entry(tcb[tskid].argc,tcb[tskid].argv);

      return 0;

      }

      3 代碼說明

      任務(wù)代碼通過執(zhí)行setjmp設(shè)置本任務(wù)下次查詢時(shí)的返回點(diǎn),然后在等待條件放棄掉CPU跳轉(zhuǎn)到下一任務(wù)的返回點(diǎn)處執(zhí)行。如此周而復(fù)始,讓各任務(wù)都獲得輪轉(zhuǎn)運(yùn)行的機(jī)會(huì),也要求各任務(wù)都需要主動(dòng)通過等待條件的方式放棄掉CPU。系統(tǒng)中除了中斷服務(wù)程序之外,所有任務(wù)都是平等的,都應(yīng)該遵循同樣的規(guī)則和其它任務(wù)一起協(xié)作運(yùn)行。基本系統(tǒng)中沒有設(shè)計(jì)殺死任務(wù)的調(diào)用,這要求各任務(wù)都應(yīng)當(dāng)設(shè)計(jì)成某種形式的無限循環(huán)。

      任務(wù)中等待的條件可以是任務(wù)復(fù)雜的表達(dá)式或都函數(shù)調(diào)用,也可以是中斷服務(wù)程序設(shè)置的全局變量(注意加volatile定義)。一般在任務(wù)執(zhí)行時(shí)會(huì)讓下次等待的條件不再滿足,避免某個(gè)任務(wù)一直霸占CPU將系統(tǒng)餓死。在嵌入式軟件中還經(jīng)常會(huì)遇到任務(wù)定時(shí)啟動(dòng)和超時(shí)等待在I/O操作上,在我們的系統(tǒng)中可以維護(hù)一個(gè)時(shí)間計(jì)數(shù)器,只需在適當(dāng)?shù)牡胤接涗洉r(shí)刻,然后在任務(wù)查詢條件中判斷當(dāng)前計(jì)數(shù)器和記錄時(shí)刻之間的差值就可以了。

      內(nèi)核實(shí)現(xiàn)的代碼則相當(dāng)簡(jiǎn)法。由于主要的保護(hù)和恢復(fù)任務(wù)現(xiàn)場(chǎng)的工作都由C語(yǔ)言標(biāo)準(zhǔn)庫(kù)setjmp實(shí)現(xiàn)了,我們就只需要操縱一下堆棧指針防止不同的任務(wù)使用了重疊的局部環(huán)境,這個(gè)工作在初始化和創(chuàng)建任務(wù)的時(shí)候通過預(yù)定義的兩個(gè)宏來實(shí)現(xiàn)。在init_coos函數(shù)中,記錄了主任務(wù)(main函數(shù))保留mainstk字節(jié)堆棧后的新棧頂位置(stktop),然后在每次creat_task時(shí)都根據(jù)要求為每個(gè)任務(wù)保留stksize字節(jié)的堆棧并重新計(jì)算下一個(gè)stktop。在creat_task函數(shù)中利用了setjmp函數(shù)的返回值(直接返回時(shí)為0,longjmp跳轉(zhuǎn)返回時(shí)非0),使得一方面creat_task能正常回到調(diào)用者,又讓下次輪轉(zhuǎn)到新任務(wù)時(shí)能夠找到創(chuàng)建時(shí)的入口。

      co-os.h中定義的WAITFOR使用了一個(gè)do{…while(0)實(shí)現(xiàn)多語(yǔ)句宏的C語(yǔ)言小技巧,這樣能保證在任何情況下WAITFOR都可以如單條語(yǔ)句一樣在源程序中使用,需要擔(dān)心多了或者少了大括弧破壞if/else匹配之類的問題,并且,所有的編譯器都會(huì)優(yōu)化掉這個(gè)假循環(huán)。

      為了盡量使程序簡(jiǎn)單并說明問題,以上代碼中沒有考慮中斷相關(guān)的數(shù)據(jù)保護(hù)問題。實(shí)際運(yùn)行的系統(tǒng)中,如果首先寫堆棧指針不能一步完成(如AVR這樣的8位機(jī)),那么,在寫操作正在進(jìn)行的時(shí)候絕對(duì)不能允許中斷;另外,在任務(wù)中查詢的條件如果和中斷有關(guān),那么也必須考慮數(shù)據(jù)的完整性。

      4 性能分

      所有的協(xié)作式多任務(wù)系統(tǒng)中任務(wù)切換時(shí)間都和用戶代碼(是否長(zhǎng)期占用CPU)、就緒時(shí)刻有關(guān),比標(biāo)準(zhǔn)系統(tǒng)略差的是,我們的簡(jiǎn)單系統(tǒng)中不支持任務(wù)優(yōu)先級(jí),并且完成一輪查詢調(diào)度的時(shí)間還和任務(wù)數(shù)目有關(guān)。這也是為了達(dá)到簡(jiǎn)單和可移植性目標(biāo)而不得已作出的犧牲。在各任務(wù)間切換查詢條件通過C語(yǔ)言標(biāo)準(zhǔn)庫(kù)函數(shù)longjmp實(shí)現(xiàn),一般來講longjmp函數(shù)要從內(nèi)存中恢復(fù)大部分CPU寄存器,執(zhí)行它也需要若干條指令的時(shí)間。

      為了面向嵌入式系統(tǒng)應(yīng)用,任務(wù)控制塊(TCB)采用靜態(tài)數(shù)組來實(shí)現(xiàn),這樣要求預(yù)先確定系統(tǒng)的最大任務(wù)數(shù)(co-os.h中的MAX_TSK)。如果需要,也可以通過環(huán)波鏈表來動(dòng)態(tài)管理任務(wù)控制塊(TCB),這時(shí)可以簡(jiǎn)單實(shí)現(xiàn)任務(wù)的動(dòng)態(tài)創(chuàng)建和刪除,并且通過指針來訪問TCB也要比通過下標(biāo)(tskid)略快一點(diǎn)。

      在某些情況下,如果在中斷返回后需要執(zhí)行某關(guān)鍵任務(wù),可以考慮通過設(shè)置“高級(jí)中斷”的方法來實(shí)現(xiàn)。具體地講,就是在中斷返回前改變返回地址到某函數(shù)入口(“高級(jí)中斷服務(wù)程序”),同時(shí)保留原返回地址到堆棧中,這樣在“高級(jí)中斷服務(wù)程序”完成后執(zhí)行return就又回到了正常的多任務(wù)查詢流程。使用“高級(jí)中斷”時(shí)要注意現(xiàn)場(chǎng)保護(hù)的銜接,并且這種技巧顯然和CPU和體系結(jié)構(gòu)有關(guān)。

      5 結(jié)論

      setjmp是標(biāo)準(zhǔn)C語(yǔ)言中用于遠(yuǎn)程跳轉(zhuǎn)的庫(kù)函數(shù),利用它可方便實(shí)現(xiàn)一個(gè)簡(jiǎn)單易移植的協(xié)作式多任務(wù)系統(tǒng)。該系統(tǒng)功能完備、編程簡(jiǎn)單、易于學(xué)習(xí),適合一些中小規(guī)模的嵌入式軟件使用;并且,以此為基礎(chǔ),還可以用一些與平臺(tái)相關(guān)的編程技巧提高其實(shí)時(shí)性和靈活性。


      【setjmp構(gòu)建簡(jiǎn)單協(xié)作式多任務(wù)系統(tǒng)】相關(guān)文章:

      嵌入式操作系統(tǒng)VxWorks中TFFS文件系統(tǒng)的構(gòu)建08-06

      微型搶占式多任務(wù)實(shí)時(shí)內(nèi)核設(shè)計(jì)08-06

      基于VxWorks的多DSP系統(tǒng)的多任務(wù)程序設(shè)計(jì)08-06

      利用實(shí)時(shí)內(nèi)核開發(fā)嵌入式多任務(wù)程序08-06

      單片機(jī)系統(tǒng)中的多任務(wù)多線程機(jī)制的實(shí)現(xiàn)08-06

      基于MSP430單片機(jī)的實(shí)時(shí)多任務(wù)操作系統(tǒng)08-06

      論軟件作品侵權(quán)防御系統(tǒng)的構(gòu)建08-18

      談美術(shù)開放式課堂的構(gòu)建08-17

      談怎樣構(gòu)建現(xiàn)代經(jīng)濟(jì)犯罪偵查協(xié)作機(jī)制08-15

      主站蜘蛛池模板: 久久国内精品自在自线91| 国产日韩久久免费影院| 中文字幕乱码十国产乱码| 国产精品高清视亚洲中文| 国产精品不卡一区二区在线| 四虎永久在线精品免费看| 亚洲欧美日韩在线码| 成人午夜大片免费看爽爽爽 | 亚洲人成人日韩中文字幕| 天堂V亚洲国产V第一次| 亚洲一区二区三区四区| 色综合久久精品亚洲国产| 青青青爽在线视频观看| 日韩深夜福利视频在线观看| 国产av一区二区久久蜜臀| 亚洲爆乳WWW无码专区| 亚洲中文一区二区av| 欧美日韩精品一区二区视频| 国产美女69视频免费观看 | 亚洲美女厕所偷拍美女尿尿| 一区二区三区精品偷拍| 国产绿帽在线视频看| 91精品亚洲一区二区三区| 好男人好资源WWW社区| 人人妻人人澡人人爽人人精品av| 国产美女直播亚洲一区色| 午夜视频免费试看| 国产激情一区二区三区在线 | 中文字幕在线精品人妻| 久久精品国产亚洲精品色婷婷 | 在线看国产精品三级在线| 久久精品国产99国产精品严洲| 国产精品高清国产三级囯产AV| 精品一二三四区在线观看| 1769国内精品视频在线播放| 在线精品亚洲区一区二区| 中国农村真卖bbwbbw| 久久精品无码免费不卡| 伊人成人在线视频免费| 日本深夜福利在线观看| 99热成人精品热久久66|