?? guide.txt
字號:
MicroStar1.0版,北京航天航空大學自動化學院,鄭玉全,2003.7
Email: yuquanzheng@163.net yuquanzheng@163.com
New! 最新版本MicroStar1.1不僅能支持按優(yōu)先級調(diào)度,還支持時間片輪轉調(diào)度和前二者相接合調(diào)度。
聲明 代碼未經(jīng)嚴格測試,現(xiàn)僅作學習和交流用途,不得利用其作任何商業(yè)目的的開發(fā)。擅自使用之進行商業(yè)開發(fā),所造成的后果由自已承擔,本人不負任何法律上的責任。
使用需知
1. MicroStar1.0最多只能創(chuàng)建16個任務。最多可提供16個定時器。最多能直接提供16個同步對象,若要更多的同步對象,須自行分配內(nèi)存。
2 為了使代碼能在DOS下運行,不少函數(shù)聲明和定義前都有_FAR宏,以使所有函數(shù)都可以通過在os_type.h中添刪FAR_MODE宏來編譯成遠調(diào)函數(shù)還是近調(diào)函數(shù)。隨演示程序提供的是在小模式下編譯的obj文件,不必關心_FAR。
3 部分函數(shù),結構體在DOS下必須使用 far 指針,移植時只需在os_type.h中添加一條-----#define far
4 此手冊并不專對PC機編寫,因而有些函數(shù)的原型與PC機源碼不符,請讀者注意。
5 調(diào)試版本中內(nèi)核調(diào)用用戶編寫的os_WARNINGE 和 os_ASSERT校驗函數(shù),可參考演示程序中的other.c文件。出錯類型和警告類型可在os_macro.h中查的。
有關宏的說明
1.如果要使用message函數(shù),須在#include "os_user.h"之前定義#define _MESSAGE,此時項目文件應包含os_msg.obj.
2.如果要使用定時器函數(shù),須在#include "os_user.h"之前定義#define _TIMER,此時項目文件應包含os_timer.obj.在PC機上還需要安裝系統(tǒng)的定時中斷程序,參加演示示例。
3.如果要使用信號函數(shù),須在#include "os_user.h"之前定義#define _SIGNAL,此時項目文件應包含os_sign.obj.
4.如果要使用同步對象函數(shù),須在#include "os_user.h"之前定義#define _OBJECT,此時項目文件應包含os_obj.obj.
/***************main的一般框架********************/
main( )
{
os_Initial( );
installTimer( ); /*PC機上如果使用定時器*/
os_CreateTask(....);
.....;
os_CreateTask(....);
os_StartUp(..);
uninstallTimer( );/*PC機上如果使用定時器*/
}
/*************************************************/
使用消息的典型任務函數(shù)示例如下:
void MyTask( void* param )
{
MSG msg;
InitTask( );/*線程初始化*/
while( (msg = os_GetMessage( )) != TASK_QUIT )
{
switch( msg )
{
case message1:......
break;
case message2:.....
break;
...................;
...................;
default :
..........;
}
}
}
/***************************************************/
使用信號的典型任務函數(shù)示例如下:
uint_16 g_signal;
void task( )
{
while(1)
{
os_WaitORSignal(&g_signal,0x00FF,0x000F);
if( g_signal&0x000F) /*緊急級信號處理代碼放在前面*/
{
if(g_signal&0x0001)
{ ..............;g_signal &= ~0x0001;}
if(g_signal&0x0002)
{ ..............;g_signal &= ~0x0002;}
if(g_signal&0x0004)
{ ..............;g_signal &= ~0x0004;}
if(g_signal&0x0008)
{ ..............;g_signal &= ~0x0008;}
continue; /*注意:此語句是必須的*/
}
else
{
if(g_signal&0x0010)
..............;
if(g_signal&0x0020);
..............;
if(g_signal&0x0040)
..............;
if(g_signal&0x0080)
..............;
}
}
}
/***************以下為函數(shù)說明*********************/
任務創(chuàng)建函數(shù)
void os_CreateTask(
TASKPROC task, //線程函數(shù)的指針
uchar taskId, //線程的ID號
uchar priority, //優(yōu)先級
int * pStack, //線程堆棧底地址
void * param //線程函數(shù)的入口參數(shù)
);
創(chuàng)建一個線程
Parameters
task
線程函數(shù)的指針,即線程函數(shù)的起始地址
taskId
線程的ID號,有效值為0到USER_TASK_NUM,系統(tǒng)默認線程的ID號USER_TASK_NUM+1,不同線程不得使有相同的ID號。PC版本將USER_TASK_NUM固定為15。
priority
線程的優(yōu)先級,由靜態(tài)優(yōu)先級與動態(tài)優(yōu)先級組成,按下式得出:
priority = 動態(tài)優(yōu)先級值*16 + 靜態(tài)優(yōu)先級值。
靜態(tài)優(yōu)先級有效值為0到14(15為系統(tǒng)保留給默認線程),值越小優(yōu)先級越高,不同線程不能使用相同的靜態(tài)優(yōu)先級。動態(tài)優(yōu)先級值為0和1,0級高于1級。
pStack
線程堆棧的棧底地址。
param
線程函數(shù)的入口參數(shù)
Return Value
無返回值,調(diào)試版本會進行參數(shù)合法性檢查,可在os_ASSERT函數(shù)中查看出錯類型。
注意
傳遞sp參數(shù),要弄清處理器棧的增長方向,避免棧底與棧頂搞混。
在DOS上運行系統(tǒng)時,sp和param參數(shù)有所不同,都為遠指針,因些可用param傳遞四個字節(jié)的參數(shù)。
銷毀一個線程
void os_KillTask(
uchar taskId //線程的ID號
);
注意
使用該函數(shù)時可能使線程不能正確釋放如定時器,同步對象等系統(tǒng)資源,須慎重使用。
結束當前線程
void os_Exit( );
注意
調(diào)用前應使放所取得的系統(tǒng)資源(定時器,同步對象)。
掛起當前線程
void os_Suspend( );
其它線程調(diào)用os_Resume可使其恢復執(zhí)行。
使調(diào)用os_Suspend而掛起線程恢復執(zhí)行
void os_Resume(
uchar taskId //要恢復執(zhí)行的線程的ID號
);
注意
如果taskId標識的線程并未掛起,調(diào)用該函數(shù)不起任何作用。不得用此函數(shù)去讓由于等待同步對象而掛起的線程恢復執(zhí)行。
提升動態(tài)優(yōu)先級至0級
void os_RaisePriority( );
降低動態(tài)優(yōu)先級至1級
void os_LowerPriority( );
注意
調(diào)用該函數(shù)時,如果有動態(tài)優(yōu)先級為0級的其它線程處于就緒態(tài),內(nèi)核會暫停當前線程執(zhí)行,讓高優(yōu)先級線程執(zhí)行。
重新設定靜態(tài)優(yōu)先級
BOOL os_SetStaticPriority(
uchar priority //新的靜態(tài)優(yōu)先級值
);
返回值
如果該靜態(tài)優(yōu)先級值未被使用,返回為os_true,原優(yōu)先級閑置
如果已被使用,返回os_false,線程的靜態(tài)優(yōu)先級不變
HTIMER os_SetTimer(
uchar timerId, //定時器ID號
uint_16 elapse,//定時時長(time-out)
TIMERPROC lpTimerFunc//定時調(diào)用函數(shù)
);
參數(shù)
timerId
有效值為0至31,在一個線程內(nèi),此ID號不能復用。定時時間到時,將此ID以消息的形式發(fā)送給擁有定時器的線程。如果該值設為NULL_TIMER_ID時,將不發(fā)送消息,怱略該參數(shù)。其它值保留。
elapse
定時時長,以時鐘節(jié)拍為單位。
lpTimerFunc
定時時間到時被調(diào)用的函數(shù)
返回值
若無空閑定時器可用,返回NULL_TIMER(0xFF)
若設定成功,返回非NULL_TIMER的整型值,將該值為參數(shù)來調(diào)用os_KillTimer來釋放定時器
注意
將timerId設為0至15時,定時時間到時,會提高擁用器的線程的動態(tài)優(yōu)先級,因些實時性較好。一般情況下,應設定為16-31。
定時調(diào)用函數(shù)應該簡短,如果過長,將NULL為參數(shù)傳給lpTimerFunc,在線程函數(shù)中來處理。最好不要同時使timerId和lpTimerFunc有效,否則調(diào)度延遲時間和調(diào)度負荷均會增大。
釋放定時器
void os_KillTimer(
HTIMER hTimer //由os_SetTime函數(shù)返回的句柄值
);
睡眠一段時間
void os_Sleep(
uint_16 elapse //睡眠時長,以時鐘節(jié)拍為單位
);
注意
調(diào)用該函數(shù)也會消耗定時器資源
發(fā)送消息
BOOL os_SendMessage(
uchar taskId,//接收該消息的線程ID
MSG msg //消息值
);
void os_PostMessage(
uchar taskId, //接收該消息的線程ID
MSG msg //消息值
);
返回值
使用os_SendMessage時,如果接收線程還有相同值的消息未處理,發(fā)送失敗,返回os_false。成功則返回os_true。
使用os_PostMessage時,如果接收線程是有相同值的消息未處理,將會覆蓋原消息,不返回任何信息。
注意 向不存在的線程發(fā)送消息時,會怱略。在調(diào)試版中會發(fā)出警告,可在os_WARNING中查看之。 msg值只能使用0-31,其中,0-15為緊急級消息,16-31為普通級消息。發(fā)送緊急級消息時會提高接收線程的動態(tài)優(yōu)先級,因而處理的實時性優(yōu)于普通級消息。對實時性沒太大要求時,不要使用緊急級消息。
接收消息
MSG os_GetMessage( );
返回消息緩沖區(qū)中優(yōu)先級最高的消息,范圍為0-31,值越小消息的優(yōu)先級越高。
MSG os_PeekMessage( );
返回消息緩沖區(qū)中優(yōu)先級最高的消息,范圍為0-31,值越小消息的優(yōu)先級越高。若無消息,則返回0xFF。
注意
如果消息緩沖區(qū)中沒有消息,os_PeekMessage會直接返回,os_GetMessage則會阻塞直到有消息發(fā)送過來。
如果消息緩沖區(qū)中只有普通級消息,os_GetMessage會降低線程的動態(tài)優(yōu)先級,os_PeekMessage則不會改變線程的動態(tài)優(yōu)先級。
等待多個或方式組合的信號
void os_WaitORSignal(
volatile uint_16 *pSignal,//二進制信號組指針
uint_16 acceptMask, //信號掩碼
uint_16 urgentMask //信號緊急級掩碼
);
參數(shù)
pSignal
二進制信號組指針。指針所指向的16位二進制數(shù)每一位為一個信號(signal),即標志位,為1表示激活,為0表示未激活。由用戶來設定各標志位。
acceptMask
有效信號掩碼。如果掩碼的某一位為1,則信號組中對應的信號有效;為0,則對應位怱略。
urgentMask
信號緊急級掩碼。如果掩碼的某一位為1,則信號組中對應的信號為緊急級,否則為普通級。
注意
調(diào)用該函數(shù)時,如果沒有有效信號為激活態(tài),線程會暫停執(zhí)行,直到該有效信號激活且用os_Notify函數(shù)通知了該線程。所謂信號的緊急級或普通級是相對線程而言的,即某個信號轉為激活態(tài),要求線程對此的響應的緊迫程度。緊急級時,內(nèi)核會提高線程的動態(tài)優(yōu)先級,因而響應的實時性好。
void os_WaitANDSignal(
volatile uint_16 *pSignal,//二進制信號組指針
uint_16 acceptMask ////信號掩碼
);
如果有效信號不都為激活態(tài),函數(shù)會被阻塞,直到有效信號全為激活態(tài)
通知線程信號狀態(tài)已改變
void os_Notify(
uchar taskId, //線程ID
BOOL isUrgent //信號是否為緊急級信號
);
信號狀態(tài)是由用戶代碼來完成的,內(nèi)核是不知道的,因此將信號轉為激活態(tài)后,需要調(diào)用該函數(shù)來顯式的通知等待該信號的線程。isUrgent為os_true時,內(nèi)核會提高taskId標識的線程的動態(tài)優(yōu)先級,因此實時性好一些。可以在改變同一個線程等待的多個信號狀態(tài)后,再來調(diào)用os_Notify函數(shù),只要有一個信號是緊急級信號,就應該將isUrgent設為os_true。
創(chuàng)建事件同步對象
HEVENT os_CReateEvent(
BOOL isNotified //事件同步對象的初始態(tài),os_true為激活態(tài),os_false為未激活態(tài)
);
返回值
若創(chuàng)建成功,返回非零值,否則返回NULL_HEVENT。
創(chuàng)建信標同步對象
HSEMAPHORE os_CreateSemaphore(
uchar nResource //初始資源數(shù)目
);
返回值
若創(chuàng)建成功,返回非零值,否則返回NULL_HSEMAPHORE。
刪除同步對象
void os_DeleteObject(
HOBJECT hObject //同步對象句柄
);
參數(shù)
hObject
由os_CreateEvent 或 os_CreateSemaphore 返回的有效同步對象句柄
將事件同步對象設為通知態(tài)
void os_SetEvent(
HEVENT hEvent, //事件同步對象句柄
uchar resetMode //復位方式
);
參數(shù)
hEvent
由os_CreateEvent返回的有效事件同步對象句柄
resetMode
復位方式。可選項位
AUTO_RESET 自動復位方式
HANDLE_RESET 手動復位方式
Remark
調(diào)用該函數(shù)時,等待該事件對象的線程轉為就緒態(tài)。選用手動復位方式時,事件同步對象保持通知態(tài)只到顯示調(diào)用os_ResetEvent來改變?yōu)槲赐ㄖ獞B(tài)。選用自動方式下,退出該函數(shù)時事件同步對象為未通知態(tài)。一般選用手動復位方式。
將事件同步對象復位為未通知態(tài)
void os_ResetEvent(
HEVENT hEvent//事件同步對象句柄
);
等待事件同步對象
void os_WaitEvent(
HEVENT hEvent //事件同步對象句柄
);
Remark
調(diào)用該函數(shù)時,若事件同步對象為通知態(tài),同直接返回,若為未通知態(tài),則線程會被暫停執(zhí)行直到事件同步對象變?yōu)橥ㄖ獞B(tài)。
查詢事件同步對象
BOOL os_RequireEvent(
HEVENT hEvent //事件同步對象句柄
);
Remark
若事件同步對象為通知態(tài),返回os_true;若為未通知態(tài)返回os_false
等待信標同步對象
void os_WaitSemaphore(
HSEMAPHORE hSemaphore //信標同步對象句柄
);
Remark
若信標同步對象的現(xiàn)有資源數(shù)不為0,則現(xiàn)有資源數(shù)減一后返回;若為0,則線程被暫停執(zhí)行直到其它線程來調(diào)用os_ReleaseSemahore來釋放資源。不再使用資源時,應調(diào)用os_ReleaseSemaphore及時釋放資源。
查詢信標同步對象
BOOL os_RequireSemaphore(
HSEMAPHORE hSemaphore //信標同步對象句柄
);
返回值
若信標同步對象的現(xiàn)有資源數(shù)不為0,則現(xiàn)有資源數(shù)減一后返回os_true;若為0,返回os_false
釋放信標同步對象資源
void os_ReleaseSemaphore(
HSEMAPHORE hSemaphore //信標同步對象句柄
);
Remark
調(diào)用此函數(shù)使信標同步對象的資源數(shù)加一。
在限定時間內(nèi)等待同步對象
uchar os_WaitObjectTimeOut(
HOBJECT hObject,//同步對象句柄
uint_16 elapse //限定時長
);
參數(shù)
hObject
由os_CreateEvent或os_CreateSemaphore返回的有效同步對象句柄
elapse
限定時長,以時鐘節(jié)為單位。
返回值
若在限定時間內(nèi)等到同步對象,則返回WAIT_SUCCESS;若在限定時間內(nèi)未能等到,則返回WAIT_TIME_OUT。
若系統(tǒng)定時器資源不足,返回NOT_ENOUGH_TIMER。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -