UCOS-II移植ARM的讀書筆記(12.16)

 
範例二:
void main (void)
{
    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_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的擴展函數,支持對堆棧的修改和運行時對堆棧容量的檢查。最後一個參數的設置表明允許堆棧檢查並且需要在任務建立時將堆棧清零*/
    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;

    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();
    OSStatInit();                                          /* Initialize uC/OS-II's statistics  測試所使用的處理器的速度,得知處理器在運行所有應用任務時實際的CPU使用率        */
    AckMbox = OSMboxCreate((void *)0);                     /* Create 2 message mailboxes在範例二中涉及到了消息的概念,任務4將向任務5發送消息,並且任務5會回覆一個應答消息,因此這裏建立了兩個通信工具即郵箱,它允許任務或中斷向另一個任務發送指針變量*/
    TxMbox  = OSMboxCreate((void *)0);
    TaskStartCreateTasks();                                /* Create all other tasks  創建所有其他的任務 */
    for (;;) {
        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                       */
            }
        }
        OSCtxSwCtr = 0;                                    /* Clear context switch counter             */
        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(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);
    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);
    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);
    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);
    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  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];

    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);/*由四個字符輪流顯示的任務*/
    }
}
 
void  Task3 (void *data)
{
    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;

    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;

    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];

    data = data;
    for (;;) {
        PC_GetDateTime(s);          /*得到PC當前的日期和時間*/
        PC_DispStr(60, 23, s, DISP_FGND_YELLOW + DISP_BGND_BLUE);
        OSTimeDly(OS_TICKS_PER_SEC);
    }
}
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章