UCOS-II移植ARM的读书笔记(12.16)续

来源:互联网 发布:淘宝红包图片素材 编辑:程序博客网 时间:2024/04/30 14:22
范例三:
在该范例中首先定义了一个用户任务数据结构,在这个结构中有该范例所需要的数据参数,和每个任务相关的,因此定了一个该数据结构类型的变量数组,分配给7个自建的任务
另外使用了消息队列的通讯方式,可以容纳多则消息。建立消息队列需要两个元素即OS_EVENT的数据结构和一串指针。
void  main (void)
{
    PC_DispClrScr(DISP_BGND_BLACK);                        /* 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     */
    strcpy(TaskUserData[TASK_START_ID].TaskName, "StartTask");
    OSTaskCreateExt(TaskStart,
                    (void *)0,
                    &TaskStartStk[TASK_STK_SIZE - 1],
                    TASK_START_PRIO,
                    TASK_START_ID,
                    &TaskStartStk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_START_ID],/*在UCOS中,每个任务的TCB控制块都可以保存一个用户定义的数据结构的指针*/
                    0);
    OSStart();                                             /* Start multitasking                       */
}
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();                                   /* Install uC/OS-II's clock tick ISR        */
    PC_VectSet(0x08, OSTickISR);
    PC_SetTickRate(OS_TICKS_PER_SEC);                      /* Reprogram tick rate                      */
    OS_EXIT_CRITICAL();
    OSStatInit();                                          /* Initialize uC/OS-II's statistics         */
    MsgQueue = OSQCreate(&MsgQueueTbl[0], MSG_QUEUE_SIZE); /* Create a message queue  建立了一个消息队列*/
    TaskStartCreateTasks();
    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 the context switch counter         */
        OSTimeDly(OS_TICKS_PER_SEC);                       /* Wait one second                          */
    }
}
void  TaskStartCreateTasks (void)
{
    strcpy(TaskUserData[TASK_CLK_ID].TaskName, "Clock Task");
    OSTaskCreateExt(TaskClk,
                    (void *)0,
                    &TaskClkStk[TASK_STK_SIZE - 1],
                    TASK_CLK_PRIO,
                    TASK_CLK_ID,
                    &TaskClkStk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_CLK_ID],
                    0);
    strcpy(TaskUserData[TASK_1_ID].TaskName, "MsgQ Rx Task");
    OSTaskCreateExt(Task1,
                    (void *)0,
                    &Task1Stk[TASK_STK_SIZE - 1],
                    TASK_1_PRIO,
                    TASK_1_ID,
                    &Task1Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_1_ID],
                    0);
    strcpy(TaskUserData[TASK_2_ID].TaskName, "MsgQ Tx Task #2");
    OSTaskCreateExt(Task2,
                    (void *)0,
                    &Task2Stk[TASK_STK_SIZE - 1],
                    TASK_2_PRIO,
                    TASK_2_ID,
                    &Task2Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_2_ID],
                    0);
    strcpy(TaskUserData[TASK_3_ID].TaskName, "MsgQ Tx Task #3");
    OSTaskCreateExt(Task3,
                    (void *)0,
                    &Task3Stk[TASK_STK_SIZE - 1],
                    TASK_3_PRIO,
                    TASK_3_ID,
                    &Task3Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_3_ID],
                    0);
    strcpy(TaskUserData[TASK_4_ID].TaskName, "MsgQ Tx Task #4");
    OSTaskCreateExt(Task4,
                    (void *)0,
                    &Task4Stk[TASK_STK_SIZE - 1],
                    TASK_4_PRIO,
                    TASK_4_ID,
                    &Task4Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_4_ID],
                    0);
    strcpy(TaskUserData[TASK_5_ID].TaskName, "TimeDlyTask");
    OSTaskCreateExt(Task5,
                    (void *)0,
                    &Task5Stk[TASK_STK_SIZE - 1],
                    TASK_5_PRIO,
                    TASK_5_ID,
                    &Task5Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_5_ID],
                    0);
}
void  Task1 (void *pdata)
{
    char  *msg;
    INT8U  err;

    pdata = pdata;
    for (;;) {
        msg = (char *)OSQPend(MsgQueue, 0, &err);  /*无限期等待消息队列的消息*/
        PC_DispStr(70, 13, msg, DISP_FGND_YELLOW + DISP_BGND_BLUE);
        OSTimeDlyHMSM(0, 0, 0, 100);
    }
}
void  Task2 (void *pdata)
{
    char  msg[20];

    pdata = pdata;
    strcpy(&msg[0], "Task 2");
    for (;;) {
        OSQPost(MsgQueue, (void *)&msg[0]);  /*向消息队列发送一个字符串的指针*/
        OSTimeDlyHMSM(0, 0, 0, 500);
    }
}
void  Task3 (void *pdata)
{
    char  msg[20];

    pdata = pdata;
    strcpy(&msg[0], "Task 3");
    for (;;) {
        OSQPost(MsgQueue, (void *)&msg[0]);  
        OSTimeDlyHMSM(0, 0, 0, 500);
    }
}
void  Task4 (void *pdata)
{
    char  msg[20];

    pdata = pdata;
    strcpy(&msg[0], "Task 4");
    for (;;) {
        OSQPost(MsgQueue, (void *)&msg[0]);
        OSTimeDlyHMSM(0, 0, 0, 500);
    }
}
Task3和4都是发送字符串,间隔半秒
void  Task5 (void *pdata)
{
    pdata = pdata;
    for (;;) {
        OSTimeDlyHMSM(0, 0, 0, 100);
    }
}
void  TaskClk (void *pdata)
{
    char  s[40];

    pdata = pdata;
    for (;;) {
        PC_GetDateTime(s);
        PC_DispStr(60, 23, s, DISP_FGND_YELLOW + DISP_BGND_BLUE);
        OSTimeDlyHMSM(0, 0, 0, 500);
    }
}
关于定义的接口函数的修改
OSTaskSwHook函数是在一个低优先级的任务切换到一个高优先级的任务时被调用
void  OSTaskSwHook (void)
{
    INT16U           time;
    TASK_USER_DATA  *puser;

    time  = PC_ElapsedStop();                    /* This task is done可以得到当前被切换的任务的运行时间 */
    PC_ElapsedStart();                           /* Start for next task开始记录当前任务的运行时间 */
    puser = OSTCBCur->OSTCBExtPtr;               /* Point to used data这个函数被调用的时候高优先级的任务还没有执行,因此OSTCBCur指向当前任务的任务控制块,而OSTCBHighRdy指向即将被调用运行的任务的任务控制块,OSTCBCur->OSTCBExtPtr是当前任务在建立时指定的数据结构的指针!!!*/
    if (puser != (TASK_USER_DATA *)0) {
        puser->TaskCtr++;                        /* Increment task counter 记录切换次数*/
        puser->TaskExecTime     = time;          /* Update the task's execution time记录本次执行时间                   */
        puser->TaskTotExecTime += time;          /* Update the task's total execution time 执行时间总和            */
    }
}
当允许使用统计任务时即OS_TASK_STAT_EN配置常数设为1,统计任务将首先调用定义的OSTaskStatHook接口函数
void  OSTaskStatHook (void)
{
    char    s[80];
    INT8U   i;
    INT32U  total;
    INT8U   pct;

    total = 0L;                                          /* Totalize TOT. EXEC. TIME for each task */
    for (i = 0; i < 7; i++) {
        total += TaskUserData[i].TaskTotExecTime;
        DispTaskStat(i);                                 /* Display task data  计算所有任务的执行时间                    */
    }
    if (total > 0) {
        for (i = 0; i < 7; i++) {                        /* Derive percentage of each task         */
            pct = 100 * TaskUserData[i].TaskTotExecTime / total;
            sprintf(s, "%3d %%", pct);
            PC_DispStr(62, i + 11, s, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
        }
    }
    if (total > 1000000000L) {                           /* Reset total time counters at 1 billion */
        for (i = 0; i < 7; i++) {
            TaskUserData[i].TaskTotExecTime = 0L;
        }
    }
}