範例二:
void main (void)
{
OS_STK *ptos;
OS_STK *pbos;
INT32U size;
{
OS_STK *ptos;
OS_STK *pbos;
INT32U size;
PC_DispClrScr(DISP_FGND_WHITE); /* Clear the screen */
OSInit(); /* Initialize uC/OS-II */
PC_DOSSaveReturn(); /* Save environment to return to DOS */
PC_VectSet(uCOS, OSCtxSw); /* Install uC/OS-II's context switch vector */
PC_VectSet(uCOS, OSCtxSw); /* Install uC/OS-II's context switch vector */
PC_ElapsedInit(); /* Initialized elapsed time measurement 初始化時間測量功能,用來精確地記錄PC_ElapsedStart()和PC_ElapsedStop()的函數調用時刻,通過這兩個時刻的差值可以很容易得到這兩個時刻之間的執行代碼的運行時間 */
ptos = &TaskStartStk[TASK_STK_SIZE - 1]; /* TaskStart() will use Floating-Point */
pbos = &TaskStartStk[0];
size = TASK_STK_SIZE;
OSTaskStkInit_FPE_x86(&ptos, &pbos, &size);
OSTaskCreateExt(TaskStart,
(void *)0,
ptos,
TASK_START_PRIO,
TASK_START_ID, /*任務標誌符,範例二中沒有使用它*/
pbos,
size,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* 使用了OSTaskCreate的擴展函數,支持對堆棧的修改和運行時對堆棧容量的檢查。最後一個參數的設置表明允許堆棧檢查並且需要在任務建立時將堆棧清零*/
pbos = &TaskStartStk[0];
size = TASK_STK_SIZE;
OSTaskStkInit_FPE_x86(&ptos, &pbos, &size);
OSTaskCreateExt(TaskStart,
(void *)0,
ptos,
TASK_START_PRIO,
TASK_START_ID, /*任務標誌符,範例二中沒有使用它*/
pbos,
size,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* 使用了OSTaskCreate的擴展函數,支持對堆棧的修改和運行時對堆棧容量的檢查。最後一個參數的設置表明允許堆棧檢查並且需要在任務建立時將堆棧清零*/
OSStart(); /* Start multitasking 讓最高優先級的任務運行即TaskStart*/
}
}
TaskStart的代碼如下:
void TaskStart (void *pdata)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT16S key;
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT16S key;
pdata = pdata; /* Prevent compiler warning */
TaskStartDispInit(); /* Setup the display 初始化屏幕,在該函數內部設定屏幕初始化的圖像*/
OS_ENTER_CRITICAL(); /* 關中斷 */
PC_VectSet(0x08, OSTickISR);
PC_SetTickRate(OS_TICKS_PER_SEC); /* Reprogram tick rate 設定時鐘節拍大小 */
OS_EXIT_CRITICAL();
PC_VectSet(0x08, OSTickISR);
PC_SetTickRate(OS_TICKS_PER_SEC); /* Reprogram tick rate 設定時鐘節拍大小 */
OS_EXIT_CRITICAL();
OSStatInit(); /* Initialize uC/OS-II's statistics 測試所使用的處理器的速度,得知處理器在運行所有應用任務時實際的CPU使用率 */
AckMbox = OSMboxCreate((void *)0); /* Create 2 message mailboxes在範例二中涉及到了消息的概念,任務4將向任務5發送消息,並且任務5會回覆一個應答消息,因此這裏建立了兩個通信工具即郵箱,它允許任務或中斷向另一個任務發送指針變量*/
TxMbox = OSMboxCreate((void *)0);
TxMbox = OSMboxCreate((void *)0);
TaskStartCreateTasks(); /* Create all other tasks 創建所有其他的任務 */
for (;;) {
TaskStartDisp(); /* Update the display 更新各項統計數據並顯示*/
TaskStartDisp(); /* Update the display 更新各項統計數據並顯示*/
if (PC_GetKey(&key)) { /* See if key has been pressed */
if (key == 0x1B) { /* Yes, see if it's the ESCAPE key */
PC_DOSReturn(); /* Yes, return to DOS */
}
}
if (key == 0x1B) { /* Yes, see if it's the ESCAPE key */
PC_DOSReturn(); /* Yes, return to DOS */
}
}
OSCtxSwCtr = 0; /* Clear context switch counter */
OSTimeDly(OS_TICKS_PER_SEC); /* Wait one second 掛起1s */
}
}
OSTimeDly(OS_TICKS_PER_SEC); /* Wait one second 掛起1s */
}
}
創建其他六個任務,暫不執行,只是創建,等待CPU被放出
static void TaskStartCreateTasks (void)
{
OSTaskCreateExt(TaskClk,
(void *)0,
&TaskClkStk[TASK_STK_SIZE - 1],
TASK_CLK_PRIO,
TASK_CLK_ID,
&TaskClkStk[0],
TASK_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
{
OSTaskCreateExt(TaskClk,
(void *)0,
&TaskClkStk[TASK_STK_SIZE - 1],
TASK_CLK_PRIO,
TASK_CLK_ID,
&TaskClkStk[0],
TASK_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
OSTaskCreateExt(Task1,
(void *)0,
&Task1Stk[TASK_STK_SIZE - 1],
TASK_1_PRIO,
TASK_1_ID,
&Task1Stk[0],
TASK_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
(void *)0,
&Task1Stk[TASK_STK_SIZE - 1],
TASK_1_PRIO,
TASK_1_ID,
&Task1Stk[0],
TASK_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
OSTaskCreateExt(Task2,
(void *)0,
&Task2Stk[TASK_STK_SIZE - 1],
TASK_2_PRIO,
TASK_2_ID,
&Task2Stk[0],
TASK_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
(void *)0,
&Task2Stk[TASK_STK_SIZE - 1],
TASK_2_PRIO,
TASK_2_ID,
&Task2Stk[0],
TASK_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
OSTaskCreateExt(Task3,
(void *)0,
&Task3Stk[TASK_STK_SIZE - 1],
TASK_3_PRIO,
TASK_3_ID,
&Task3Stk[0],
TASK_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
(void *)0,
&Task3Stk[TASK_STK_SIZE - 1],
TASK_3_PRIO,
TASK_3_ID,
&Task3Stk[0],
TASK_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
OSTaskCreateExt(Task4,
(void *)0,
&Task4Stk[TASK_STK_SIZE-1],
TASK_4_PRIO,
TASK_4_ID,
&Task4Stk[0],
TASK_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
(void *)0,
&Task4Stk[TASK_STK_SIZE-1],
TASK_4_PRIO,
TASK_4_ID,
&Task4Stk[0],
TASK_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
OSTaskCreateExt(Task5,
(void *)0,
&Task5Stk[TASK_STK_SIZE-1],
TASK_5_PRIO,
TASK_5_ID,
&Task5Stk[0],
TASK_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
}
(void *)0,
&Task5Stk[TASK_STK_SIZE-1],
TASK_5_PRIO,
TASK_5_ID,
&Task5Stk[0],
TASK_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
}
分別看其他幾個任務的代碼如下:
void Task1 (void *pdata)
{
INT8U err;
OS_STK_DATA data; /* Storage for task stack data */
INT16U time; /* Execution time (in uS) */
INT8U i;
char s[80];
{
INT8U err;
OS_STK_DATA data; /* Storage for task stack data */
INT16U time; /* Execution time (in uS) */
INT8U i;
char s[80];
pdata = pdata;
for (;;) {
for (i = 0; i < 7; i++) {
PC_ElapsedStart();
err = OSTaskStkChk(TASK_START_PRIO + i, &data); /*該函數是用來檢查任務堆棧使用情況*/
time = PC_ElapsedStop(); /*測量上面的OSTaskStkChk函數的運行時間,方法是將這個函數放在PC_ElapsedStart()和PC_ElapsedStop()之間即可,它會返回以ms計量的時間間隔*/
if (err == OS_NO_ERR) {
sprintf(s, "%4ld %4ld %4ld %6d",
data.OSFree + data.OSUsed,
data.OSFree,
data.OSUsed,
time);/*data是上面檢查任務堆棧使用情況的函數的第二個參數,也是它的返回值之一*/
PC_DispStr(19, 12 + i, s, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);/*把統計結果打印出來*/
}
}
OSTimeDlyHMSM(0, 0, 0, 100); /* Delay for 100 mS 100ms掛起一次 */
}
}
void Task2 (void *data)
{
data = data;
for (;;) {
PC_DispChar(70, 15, '|', DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDly(10);
PC_DispChar(70, 15, '/', DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDly(10);
PC_DispChar(70, 15, '-', DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDly(10);
PC_DispChar(70, 15, '//', DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDly(10);/*由四個字符輪流顯示的任務*/
}
}
{
data = data;
for (;;) {
PC_DispChar(70, 15, '|', DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDly(10);
PC_DispChar(70, 15, '/', DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDly(10);
PC_DispChar(70, 15, '-', DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDly(10);
PC_DispChar(70, 15, '//', DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDly(10);/*由四個字符輪流顯示的任務*/
}
}
void Task3 (void *data)
{
char dummy[500];
INT16U i;
{
char dummy[500];
INT16U i;
data = data;
for (i = 0; i < 499; i++) { /* Use up the stack with 'junk' */
dummy[i] = '?';
}
for (;;) {
PC_DispChar(70, 16, '|', DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDly(20);
PC_DispChar(70, 16, '//', DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDly(20);
PC_DispChar(70, 16, '-', DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDly(20);
PC_DispChar(70, 16, '/', DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDly(20);
}
}
void Task4 (void *data)
{
char txmsg;
INT8U err;
{
char txmsg;
INT8U err;
data = data;
txmsg = 'A';
for (;;) {
OSMboxPost(TxMbox, (void *)&txmsg); /* Send message to Task #5向郵箱TxMbox發送一個字符 */
OSMboxPend(AckMbox, 0, &err); /* Wait for acknowledgement from Task #5等待應答,第二個參數指定了等待超時的時限,單位爲時鐘節拍 */
txmsg++; /* Next message to send更新消息 */
if (txmsg == 'Z') {
txmsg = 'A'; /* Start new series of messages */
}
}
}
void Task5 (void *data)
{
char *rxmsg;
INT8U err;
{
char *rxmsg;
INT8U err;
data = data;
for (;;) {
rxmsg = (char *)OSMboxPend(TxMbox, 0, &err); /* Wait for message from Task #4無限期等待郵箱消息 */
PC_DispChar(70, 18, *rxmsg, DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDlyHMSM(0, 0, 1, 0); /* Wait 1 second 掛起1s */
OSMboxPost(AckMbox, (void *)1); /* Acknowledge reception of msg 給郵箱AckMbox發送消息 */
最後一個任務
void TaskClk (void *data)
{
char s[40];
{
char s[40];
data = data;
for (;;) {
PC_GetDateTime(s); /*得到PC當前的日期和時間*/
PC_DispStr(60, 23, s, DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDly(OS_TICKS_PER_SEC);
}
}
}
}