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);
    }
}
    }
}

你可能感兴趣的:(UCOS-II移植ARM的读书笔记(12.16))