精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

使用C語言setjmp庫函烽實現查詢式協作多任務系統的設計

牽手一起夢 ? 來源:單片機與嵌入式系統應用 ? 作者:胡道徐 ? 2020-10-04 17:46 ? 次閱讀

討論一個利用標準C語言setjmp庫函烽實現查詢式協作多任務系統,給出完整的內核和樣例程序并對源代碼進行說明。該系統具有簡單易用的特點,只需要編寫存取堆棧指針的宏就可方便地移植到新的平臺上。文章詳述了系統的優缺點,討論一些性能擴展的方法。該內核適用于中小規模的嵌入式軟件

本文介紹的是利用標準C語言setjmp庫函數實現的具備此特點的協作式多任務系統。從本質上講,實時多任務操作系統應該具備按照優先級搶占調度的內核。然而,在實際應用中,搶中式的多任務某種程序上帶來了用戶程序設計時數據保護的困難,并且,具備搶占功能的多任務內核設計時困難也比較多,這會增加操作系統自身的代碼,也使它在小資源單片機系統中應用較少;而協作多任務系統的調度只在用戶指定的時機發生,這會大大簡化內核和用戶系統的設計,尤其本文實現的系統通過條件查詢來放棄CPU,既符合傳統單片機程序設計的思維,又帶來了多任務、模塊化、可重入的編程便利。

Setjmp是標準C語言庫函數的組成部分,它可以實現程序執行中的遠程轉操作。具體來說,它可以在一個函數中使用setjmp來初始化一個全局標號,然后只要該函數未曾返回,那么在其它任何地方都可以通過longjmp調用來跳轉到setjmp的下一條語句執行。實際上,setjmp函數將發生調用處的局部環境保存在一個jmp_buf的結構當中,只要主調函數中對應的內存未曾釋放(函數返回時局部內存就失效了),那么在調用longjmp的時候就可以根據已保存的jmp_buf參數恢復到setjmp的地方執行。我們的系統中就是分析了setjmp標準庫函數的特點,以簡單的方式實現了協作式多任務。

1 演示程序

為了便于理解,首先給出多任務演示程序的源代碼。這個程序演示了協作式多任務切換、任務的動態生成、多任務共用代碼等功能,一共使用了init_coos初始化根任務(也就是C語言main函數)、creat_task創建新任務和WAITFOR查詢條件這3個基本的系統調用。由于面向嵌入式系統,因而程序不會中止并且運行中也沒有進行任何輸出,需要借助適合的調試工具來理解多任務系統的運行。

使用C語言setjmp庫函烽實現查詢式協作多任務系統的設計

while(1){

WAITFOR(cnt= =8);

while(i++argc);

test=0x55;

/*使用函數調用在子程序中測試WAITFOR*/

subfunc();

while(i++15);

cnt=0;

}

}

void subfunc(void){

int i;

WAITFOR(cnt

/*選擇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(?。╟ondition)){

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

#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 代碼說明

任務代碼通過執行setjmp設置本任務下次查詢時的返回點,然后在等待條件放棄掉CPU跳轉到下一任務的返回點處執行。如此周而復始,讓各任務都獲得輪轉運行的機會,也要求各任務都需要主動通過等待條件的方式放棄掉CPU。系統中除了中斷服務程序之外,所有任務都是平等的,都應該遵循同樣的規則和其它任務一起協作運行。基本系統中沒有設計殺死任務的調用,這要求各任務都應當設計成某種形式的無限循環。

任務中等待的條件可以是任務復雜的表達式或都函數調用,也可以是中斷服務程序設置的全局變量(注意加volatile定義)。一般在任務執行時會讓下次等待的條件不再滿足,避免某個任務一直霸占CPU將系統餓死。在嵌入式軟件中還經常會遇到任務定時啟動和超時等待在I/O操作上,在我們的系統中可以維護一個時間計數器,只需在適當的地方記錄時刻,然后在任務查詢條件中判斷當前計數器和記錄時刻之間的差值就可以了。

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

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

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

4 性能分析

所有的協作式多任務系統中任務切換時間都和用戶代碼(是否長期占用CPU)、就緒時刻有關,比標準系統略差的是,我們的簡單系統中不支持任務優先級,并且完成一輪查詢調度的時間還和任務數目有關。這也是為了達到簡單和可移植性目標而不得已作出的犧牲。在各任務間切換查詢條件通過C語言標準庫函數longjmp實現,一般來講longjmp函數要從內存中恢復大部分CPU寄存器,執行它也需要若干條指令的時間。

為了面向嵌入式系統應用,任務控制塊(TCB)采用靜態數組來實現,這樣要求預先確定系統的最大任務數(co-os.h中的MAX_TSK)。如果需要,也可以通過環波鏈表來動態管理任務控制塊(TCB),這時可以簡單實現任務的動態創建和刪除,并且通過指針來訪問TCB也要比通過下標(tskid)略快一點。

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

5 結論

setjmp是標準C語言中用于遠程跳轉的庫函數,利用它可方便實現一個簡單易移植的協作式多任務系統。該系統功能完備、編程簡單、易于學習,適合一些中小規模的嵌入式軟件使用;并且,以此為基礎,還可以用一些與平臺相關的編程技巧提高其實時性和靈活性。

責任編輯:gt

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 單片機
    +關注

    關注

    6032

    文章

    44525

    瀏覽量

    633261
  • 操作系統
    +關注

    關注

    37

    文章

    6747

    瀏覽量

    123204
  • 代碼
    +關注

    關注

    30

    文章

    4753

    瀏覽量

    68368
收藏 人收藏

    評論

    相關推薦

    setjmp構建簡單協作多任務系統

    setjmp構建簡單協作多任務系統摘要:討論一個利用標準C
    發表于 10-06 16:12

    setjmp構建簡單協作多任務系統

    longjmp的時候就可以根據已保存的jmp_buf參數恢復到setjmp的地方執行。我們的系統中就是分析了setjmp標準庫函數的特點,以簡單的方式實現
    發表于 12-07 15:55

    setjmp、longjmp原理探究及實現

    setjmp、longjmp原理探究及實現一、原理1、實驗2、猜想二、實現三、調用四、總結一、原理C語言中包含頭文件即可
    發表于 01-25 07:08

    MCU是怎樣用c語言實現查詢紅外解碼的

    紅外的編碼格式是怎樣的?MCU是怎樣用c語言實現查詢紅外解碼的?
    發表于 02-25 07:44

    如何去實現一種基于ARM9的多任務搶占調度器設計

    調度器的功能。雖然不能稱為操作系統,但已體現了小型嵌入操作系統的精髓。OS代碼不到1.5K,核心函數只有幾個,思路簡單明了。比起 UCOS,更適合用作多任務
    發表于 04-14 09:14

    多任務系統中的堆棧使用

    多任務系統運行過程中,此堆棧將專門用于中斷和異常處理程序。多任務啟動后,C堆棧會丟失,導致嵌入應用中可用的RAM量減少,在資源有限的應用中
    發表于 01-05 13:52

    使用<cont.h>進行協作多任務處理?

    認為我可以使用來滾動自己的。文檔有點稀疏...我想知道當由 cont_run() 生成的函數正常完成時(即不以 yield 退出)是否會發生這種情況,以及是否有檢測函數是否正常退出或通過 yield 退出的方法?還有其他人玩過嗎?關于協作
    發表于 02-23 06:57

    求助,有沒有人能夠實現協作多任務處理?

    有沒有人能夠實現協作多任務處理?除了破解 cont_run 和 cont_init 之外,我嘗試過的任何事情似乎都奏效了。我想要像https://github.com/mikaelp
    發表于 02-24 06:35

    setjmp 構建簡單協作多任務系統

    討論一個利用標準C 語言setjmp 庫函數實現查詢協作
    發表于 05-15 13:32 ?10次下載

    采用Protothread實現實時多任務系統

    采用Protothread實現實時多任務系統 在許多系統資源非常緊張的單片機應用中,使用實時操作系統進行
    發表于 03-29 15:10 ?1440次閱讀
    采用Protothread<b class='flag-5'>實現</b>實時<b class='flag-5'>多任務</b><b class='flag-5'>系統</b>

    分布式數據庫分片關系變換查詢優化

    基于分布查詢的概念和優化要求,結合實際的信息管理系統分片查詢的實踐,描述分布式數據庫分片查詢
    發表于 05-03 17:04 ?0次下載
    分布<b class='flag-5'>式數據庫</b>分片關系變換<b class='flag-5'>查詢</b>優化

    使用單片機實現查表顯示LED燈的C語言實例免費下載

    本文檔的主要內容詳細介紹的是使用單片機實現查表顯示LED燈的C語言實例免費下載。
    發表于 11-09 17:24 ?9次下載

    C語言標準實現搶占多任務資料

    C語言標準實現搶占多任務,使用C
    發表于 12-31 18:00 ?4次下載

    c語言實現查詢紅外解碼

    #MCU 用c語言循環 紅外解碼紅外解碼的實現一般有定時器中斷、外部中斷+定時器、查詢三種解碼方法
    發表于 01-13 13:37 ?3次下載
    用<b class='flag-5'>c</b><b class='flag-5'>語言實現查詢</b>紅外解碼

    STM32 圖像處理介紹

    STM32 圖像處理STM32IPL是由 C 語言所編寫的開放原始碼軟件
    的頭像 發表于 07-11 11:39 ?1247次閱讀
    STM32 圖像處理<b class='flag-5'>函</b><b class='flag-5'>式</b><b class='flag-5'>庫</b>介紹