日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 嵌入式 > 嵌入式硬件
[導讀]在許多系統(tǒng)資源非常緊張的單片機應用中,使用實時操作系統(tǒng)進行任務調度來實現(xiàn)實時多任務系統(tǒng)時,由操作系統(tǒng)帶來的系統(tǒng)開銷往往是不可接受的。通過升級硬件來改善系統(tǒng)資源緊張,意味著成本的增加,降低產品的競爭力。本文介紹采用Protothread在非常小的系統(tǒng)開銷下實現(xiàn)實時多任務系統(tǒng)的方法。

作者: 長沙威勝儀表集團 羅光平 湖南大學 郭衛(wèi)鋒
摘要 在許多系統(tǒng)資源非常緊張的單片機應用中,使用實時操作系統(tǒng)進行任務調度來實現(xiàn)實時多任務系統(tǒng)時,由操作系統(tǒng)帶來的系統(tǒng)開銷往往是不可接受的。通過升級硬件來改善系統(tǒng)資源緊張,意味著成本的增加,降低產品的競爭力。本文介紹采用Protothread在非常小的系統(tǒng)開銷下實現(xiàn)實時多任務系統(tǒng)的方法。
關鍵詞 Protothread 實時 多任務 線程模型
嵌入式程序框架一般類似于程序1所示結構:系統(tǒng)中有3個任務——TaskA、TaskB、TaskC,均放置于主循環(huán)內,在每一個循環(huán)周期內都被執(zhí)行一次。在這種結構中,能滿足系統(tǒng)實時性要求的條件是: (當且僅當)TaskA 、TaskB、TaskC三個任務的運行時間之和要小于系統(tǒng)實時響應的時間要求。在系統(tǒng)較為簡單、任務運行時間能滿足實時要求的情況下,可以采用這種最簡單、最直接的順序執(zhí)行方式。但是更多的情形是,系統(tǒng)不僅要對一些事件做出實時響應,并且還要承擔很多其他的非實時任務,并且這些非實時任務的運行時間要遠遠超出了實時響應時間的要求。傳統(tǒng)的這種程序結構顯然不能滿足系統(tǒng)的實時性要求。通常的解決方案是,引入實時操作系統(tǒng),由操作系統(tǒng)進行任務的調度,優(yōu)先執(zhí)行實時任務,達到滿足系統(tǒng)實時性的要求。
程序1嵌入式程序框架
void main(void) {
Init();
while(1) {
TaskA();
TaskB();
TaskC();
}
}
void Interrupt_1(void) interrupt 1 {

}
void Interrupt_2(void) interrupt 2 {

}
一般來說,在嵌入式系統(tǒng)開發(fā)中引入實時操作系統(tǒng)有諸多優(yōu)點:
◆ 更好地支持多任務,實時性要求能夠得以保障;
◆ 程序開發(fā)更加容易,也更便于維護;
◆ 有利于提高系統(tǒng)的穩(wěn)定性和可靠性。但是,操作系統(tǒng)的引入也將帶來較多的系統(tǒng)開銷:
◆ 實時操作系統(tǒng)往往使用定時器中斷來切換任務,需要消耗不少的CPU處理時間;
◆ 實時操作系統(tǒng)在切換任務時需要保護當前任務的執(zhí)行現(xiàn)場,這就需要為每個任務準備足夠多的RAM空間來實現(xiàn)任務切換;
◆ 實時操作系統(tǒng)的本身也需要占用相當數(shù)量的Flash空間和RAM空間。
如果這些系統(tǒng)開銷都在可承受的范圍內,那么采用實時操作系統(tǒng)將是最佳的選擇。但是在很多應用的場合,特別是系統(tǒng)的資源非常緊張的單片機應用,實時操作系統(tǒng)帶來的系統(tǒng)開銷往往是不可接受的。而更換速度更快、RAM更大、Flash更多的CPU意味著成本的增加,且會降低產品的競爭力。當系統(tǒng)中的任務不須進行非常復雜的優(yōu)先級調度,而且其任務也相對簡單時,引入實時操作系統(tǒng)似有殺雞用牛刀之嫌。
1 Protothread的特點
Protothread是專為資源有限的系統(tǒng)設計的一種耗費資源特別少并且不使用堆棧的線程模型,其特點是:
◆ 以純C語言實現(xiàn),無硬件依賴性;
◆ 極少的資源需求,每個Protothread僅需要2個額外的字節(jié);
◆ 可以用于有操作系統(tǒng)或無操作系統(tǒng)的場合;
◆ 支持阻塞操作且沒有棧的切換。
使用Protothread實現(xiàn)多任務的最主要的好處在于它的輕量級。每個Protothread不需要擁有自已的堆棧,所有的Protothread共享同一個堆棧空間,這一點對于RAM資源有限的系統(tǒng)尤為有利。相對于操作系統(tǒng)下的多任務而言,每個任務都有自已的堆??臻g,這將消耗大量的RAM資源,而每個Protothread僅使用一個整型值保存當前狀態(tài)。
2 Protothread的阻塞運行機制
以下是一個典型的Protothread程序示例:
程序2Protothread程序示例
PT_THREAD(radio_wake_thread(struct pt *pt)) {
PT_BEGIN(pt);
while(1) {
radio_on();
timer_set(&timer, T_AWAKE);
PT_WAIT_UNTIL(pt, timer_expired(&timer));
timer_set(&timer, T_SLEEP);
if(!communication_complete()) {
PT_WAIT_UNTIL(pt, communication_complete()‖timer_expired(&timer));
}
if(!timer_expired(&timer)) {
radio_off();
PT_WAIT_UNTIL(pt, timer_expired(&timer));
}
}
PT_END(pt);
}
這是一個非常簡單的無線通信的狀態(tài)切換程序①,展開Protothread的宏定義,便可以得到程序3所示的展開代碼:
程序3Protothread宏展開代碼
void radio_wake_thread(struct pt *pt) {
switch(pt﹥lc) {
case 0:
while(1) {
radio_on();
timer_set(&timer, T_AWAKE);
pt﹥lc = 8;
case 8:
if(!timer_expired(&timer)) {
return;
}
timer_set(&timer, T_SLEEP);
if(!communication_complete()) {
pt﹥lc = 13;
case 13:
if(!(communication_complete() ||timer_expired(&timer))) {
return;
}
}
if(!timer_expired(&timer)) {
radio_off();
pt﹥lc = 18;
case 18:
if(!timer_expired(&timer)) {
return;
}
}
}
}
}
當Protothread程序運行到PT_WAIT_UNTIL時,判斷其運行條件是否滿足,若不滿足,則阻塞。通過比對程序2和程序3的程序代碼可以得知,Protothread的阻塞其實質就是函數(shù)返回,只不過在返回前保存了當前的阻塞位置,待下一次Protothread被調用時,直接跳到阻塞位置執(zhí)行,再次判斷運行條件是否滿足,并執(zhí)行后續(xù)程序或繼續(xù)阻塞。
3 利用Protothread構造實時多任務系統(tǒng)
與操作系統(tǒng)下的多任務不同,操作系統(tǒng)下的每個任務可在任意時刻被打斷并阻塞,Protothread僅能在程序員指定位置阻塞。用Protothread實現(xiàn)實時多任務,正是利用了Protothread在指定位置阻塞的特點,讓出執(zhí)行權限給更高優(yōu)先級的任務先運行。
下面舉例說明如何利用Protothread構造實時多任務系統(tǒng)。
系統(tǒng)要求:
TaskA實時任務,30 ms內響應,運行時間<20 ms;
TaskB實時任務,200 ms內響應,運行時間<40 ms;
TaskC非實時任務,響應時間無要求,運行時間>30 ms。
設計思路:
將TaskB和TaskC分成若干步,每步運行時間不超過10 ms(這個時間可視系統(tǒng)需求而定,例如TaskA若為40 ms內響應,則每步可擴至20 ms)。任務以3個Protothread的方式運行。首先執(zhí)行TaskA,在TaskA執(zhí)行完成1次后,釋放執(zhí)行權限,讓TaskB和TaskC執(zhí)行。TaskB或TaskC在每執(zhí)行1步之前檢查運行時間,一旦發(fā)現(xiàn)30 ms內不夠執(zhí)行1步時,阻塞運行,讓出執(zhí)行權限給TaskA。同樣,TaskB和TaskC的調度關系也類似,先運行TaskB,完成時釋放執(zhí)行權限,讓TaskC執(zhí)行;TaskC在每執(zhí)行1步之前檢查運行時間,若發(fā)現(xiàn)200 ms內不夠執(zhí)行1步時,阻塞運行,讓出執(zhí)行權限重新交給TaskB。
源程序(Task0TimeCounter、Task1TimeCounter為計數(shù)器,每毫秒加1):
#include "ptsem.h"
#define TASKA_MAX_RUN_TIME20
#define TASKA_CYCLE_TIME30
#define TASKB_CYCLE_TIME200
#define TASK_STEP_TIME10
#define TASK0_VALID_TIME TASKA_CYCLE_TIME?TASK_STEP_TIME
#define TASK1_VALID_TIME TASKB_CYCLE_TIME?TASK_STEP_TIME?TASKA_MAX_RUN_TIME *2
/*按照PT_WAIT_UNTIL 的宏定義擴展一個新宏:當程序進入阻塞時發(fā)送一信號,告知高優(yōu)先級任務獲得執(zhí)行權限*/
#define LC_STEP_SET(s,n) s = __LINE__ + n; case __LINE__ + n:
#define PT_SEM_WAIT_UNTIL(pt, s, condition, n)
do {
LC_STEP_SET((pt)﹥lc,n);
if(!(condition)) {if((s)﹥count==0)
PT_SEM_SIGNAL(pt,s);
return PT_WAITING;
}
} while(0)
struct pt TaskAPt;
struct pt TaskBPt;
struct pt TaskCPt;
struct pt_sem SemRunTaskA;
struct pt_sem SemRunTaskB;
/*若30 ms內已經不夠時間執(zhí)行1步,則讓出TaskA的執(zhí)行權限*/
#define TASKB_STEP(pt)
PR_SEM_WAIT_UNTIL(pt, & SemRunTaskA,TaskOTimeCounter<=TASKO_VALID_TIME,0)
/*若200 ms內已經不夠時間執(zhí)行1步,則讓出TaskB的執(zhí)行權限*/
/*若30 ms內已經不夠時間執(zhí)行1步,則讓出TaskA的執(zhí)行權限*/
#define TASKC_STEP(pt)
PT_SEM_WAIT_UNTIL(pt, &SemRunTaskB,Task1TimeCounter<=TASK1_VALID_TIME,0);
PT_SEM_WAIT_UNTIL(pt, &SemRunTaskA,Task0TimeCounter<=TASK0_VALID_TIME,1)
int ProtothreadTaskA(struct pt *pt) {
PT_BEGIN(pt);
PT_SEM_WAIT(pt, &SemRunTaskA);/*等待其他任務讓出執(zhí)行權限*/
ResetTask0TimeCounter;/*對時間計數(shù)器置0*/
TaskA();/*TaskA任務*/
PT_END(pt);
}
int ProtothreadTaskB(struct pt *pt) {
PT_BEGIN(pt);
PT_SEM_WAIT(pt, &SemRunTaskB);/*等待TaskC讓出執(zhí)行權限*/
ResetTask1TimeCounter;/*對時間計數(shù)器置0*/
TASKB_STEP(pt);/*如果不夠1步執(zhí)行,則阻塞,讓出執(zhí)行權限*/
TaskB_1();/*TaskB任務的第1步*/
TASKB_STEP(pt);
TaskB_2();/*TaskB任務的第2步*/
TASKB_STEP(pt);
TaskB_3();/*…*/
PT_END(pt);
}
int ProtothreadTaskC(struct pt *pt) {
PT_BEGIN(pt);
TASKC_STEP(pt);/*如果不夠1步執(zhí)行,則阻塞,讓出執(zhí)行權限*/
TaskC_1();/*TaskB任務的第1步*/
TASKC_STEP(pt);
TaskC_2();/*TaskB任務的第2步*/
TASKC_STEP(pt);
TaskC_3();/*…*/
TASKC_STEP(pt);
TaskC_4();
PT_END(pt);
}
void main(void) {/*系統(tǒng)初始化*/?
PT_INIT(&TaskAPt);
PT_INIT(&TaskBPt);
PT_INIT(&TaskCPt);
PT_SEM_INIT(&SemRunTaskA,1);
PT_SEM_INIT(&SemRunTaskB,1);/*運行任務*/
while(1) {
ProtothreadTaskA(&TaskAPt);
ProtothreadTaskB(&TaskBPt);
ProtothreadTaskC(&TaskCPt);
}
}
模擬運行結果如表1所列。運行結果顯示,3個任務的運行情況完全滿足系統(tǒng)的設計要求。從資源需求來看,完成此例的系統(tǒng)設計,共需要12個字節(jié)的RAM空間。筆者進一步對Protothread定義文件做了少許修改和優(yōu)化,最終僅耗費6個字節(jié)。
結語
本文旨在解決資源緊張型應用的、多任務環(huán)境下的實時性問題。 通過借助Protothread的阻塞運行機制, 成功實現(xiàn)了低開銷的實時多任務系統(tǒng)。
表1 模擬運行結果運行

參考文獻
[1] Adam Dunkels, Oliver Schmidt, Thiemo Voigt. Using Protothreads for Sensor Node Programming[C]. REALWSN‘05 Workshop on RealWorld Wireless Sensor Networks, Stockholm, Sweden, June 2005
[2] Adam Dunkels, Oliver Schmidt, Thiemo Voigt, et al. Protothreads: Simplifying EventDriven Programming of MemoryConstrained Embedded Systems[C]. In Proceedings of the Fourth ACM Conference on Embedded Networked Sensor Systems (SenSys 2006), Boulder, Colorado, USA, November 2006.
[3] Labrosse Jean J. MicroC/OSII The Real Time Kernel Second Edition[M]. CMP Books, CMP Media.
[4] 冉全. 單片機中基于多線程機制的實時多任務研究[J] .微型機與應用,2003(8): 39-40.

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: 驅動電源

在工業(yè)自動化蓬勃發(fā)展的當下,工業(yè)電機作為核心動力設備,其驅動電源的性能直接關系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護是驅動電源設計中至關重要的兩個環(huán)節(jié),集成化方案的設計成為提升電機驅動性能的關鍵。

關鍵字: 工業(yè)電機 驅動電源

LED 驅動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設備的使用壽命。然而,在實際應用中,LED 驅動電源易損壞的問題卻十分常見,不僅增加了維護成本,還影響了用戶體驗。要解決這一問題,需從設計、生...

關鍵字: 驅動電源 照明系統(tǒng) 散熱

根據(jù)LED驅動電源的公式,電感內電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關鍵字: LED 設計 驅動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產業(yè)的重要發(fā)展方向。電動汽車的核心技術之一是電機驅動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機驅動系統(tǒng)中的關鍵元件,其性能直接影響到電動汽車的動力性能和...

關鍵字: 電動汽車 新能源 驅動電源

在現(xiàn)代城市建設中,街道及停車場照明作為基礎設施的重要組成部分,其質量和效率直接關系到城市的公共安全、居民生活質量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關鍵字: 發(fā)光二極管 驅動電源 LED

LED通用照明設計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關鍵字: LED 驅動電源 功率因數(shù)校正

在LED照明技術日益普及的今天,LED驅動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關鍵字: LED照明技術 電磁干擾 驅動電源

開關電源具有效率高的特性,而且開關電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現(xiàn)在的LED驅動電源

關鍵字: LED 驅動電源 開關電源

LED驅動電源是把電源供應轉換為特定的電壓電流以驅動LED發(fā)光的電壓轉換器,通常情況下:LED驅動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: LED 隧道燈 驅動電源
關閉