test.c

来自「uCOS2嵌入式操作系统源码」· C语言 代码 · 共 416 行

C
416
字号
#include   "includes.h"

#define   TASK_STK_SIZE   512

#define   TASK_START_ID   0
#define   TASK_CLK_ID     1
#define   TASK_1_ID       2
#define   TASK_2_ID       3
#define   TASK_3_ID       4
#define   TASK_4_ID       5
#define   TASK_5_ID       6

#define   TASK_START_PRIO   10
#define   TASK_CLK_PRIO     11
#define   TASK_1_PRIO       12
#define   TASK_2_PRIO       13
#define   TASK_3_PRIO       14
#define   TASK_4_PRIO       15
#define   TASK_5_PRIO       16

#define   MSG_QUEUE_SIZE    20

typedef struct     //该结构用于描述任务额外的信息
{
  char TaskName[30];
  INT16U TaskCtr;
  INT16U TaskExecTime;
  INT32U TaskTotExecTime;
}TASK_USER_DATA;

OS_STK   TaskStartStk[TASK_STK_SIZE];
OS_STK   TaskClkStk[TASK_STK_SIZE];
OS_STK   Task1Stk[TASK_STK_SIZE];
OS_STK   Task2Stk[TASK_STK_SIZE];
OS_STK   Task3Stk[TASK_STK_SIZE];
OS_STK   Task4Stk[TASK_STK_SIZE];
OS_STK   Task5Stk[TASK_STK_SIZE];

TASK_USER_DATA    TaskUserData[7];    //用于7个用户任务的数据结构的数组

OS_EVENT    *MsgQueue;       //消息队列
void        *MsgQueueTb1[20];

void OSInitHookBegin(void);      // uC/OS-II接口函数定义
void OSInitHookEnd(void);
void OSTaskCreateHook(OS_TCB *ptcb);
void OSTaskDelHook(OS_TCB *ptcb);
void OSTaskIdleHook(void);
void OSTaskStatHook(void);
void OSTaskSwHook(void);
void OSTCBInitHook(OS_TCB *ptcb);
void OSTimeTickHook(void);

       void TaskStart(void *pdata);
static void TaskStartDispInit(void);
       void TaskStartCreateTasks(void);
static void TaskStartDisp(void);
       void DispTaskStat(INT8U id);
       void TaskClk(void *pdata);
       void Task5(void *pdata);


void main(void)
{
  PC_DispClrScr(DISP_BGND_BLACK);
  OSInit();
  PC_DOSSaveReturn();
  PC_VectSet(uCOS,OSCtxSw);
  PC_ElapsedInit();
  strcpy(TaskUserData[TASK_START_ID].TaskName,"StartTask");  //一个任务建立前,使用ANSI C规定的字符串处理函数strcpy()为任务命名。
  OSTaskCreateExt(TaskStart,     //创建TaskStart()任务。
                  (void *)0,
                  &TaskStartStk[TASK_STK_SIZE - 1],
                  TASK_START_PRIO,
                  TASK_START_ID,
                  &TaskStartStk[0],
                  TASK_STK_SIZE,
                  &TaskUserData[TASK_START_ID],//uC/OS-II中,每个任务的TCB控制块都可以保存一个用户定义的数据结构指针。
                  0);
  OSStart();
}

void TaskStart(void *pdata)
{
  #if OS_CRITICAL_METHOD == 3
      OS_CPU_SR  cpu_sr;
  #endif
  INT16S   key;
  pdata = pdata;
  TaskStartDispInit();

  OS_ENTER_CRITICAL();
  PC_VectSet(0x08,OSTickISR);
  PC_SetTickRate(OS_TICKS_PER_SEC);
  OS_EXIT_CRITICAL();

  OSStatInit();

  MsgQueue = OSQCreate(&MsgQueueTb1[0],MSG_QUEUE_SIZE);  //建立了Task1(),Task2(),Task3(),Task4()使用的消息队列。

  TaskStartCreateTasks();   //创建另外6个任务

  for(;;)
  {
    TaskStartDisp();
    if(PC_GetKey(&key))
    {
      if(key == 0x1B)
      {
        PC_DOSReturn();
      }
    }
    OSCtxSwCtr = 0;
    OSTimeDly(OS_TICKS_PER_SEC);
  }
}

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_GREEN);  //在屏幕上显示接收到的一列消息。
    OSTimeDlyHMSM(0,0,0,100);  //任务延时100ms,以便能看到消息已收到。
  }
}

void Task2(void *pdata)
{
  char msg[20];
  pdata = pdata;
  strcpy(&msg[0],"Task 2");
  for(;;)
  {
    OSQPost(MsgQueue,(void *)&msg[0]);  //发送一个指向字符串“Task 2”的指针到消息队列。
    OSTimeDlyHMSM(0,0,0,500);  //延时0.5s,再次发送消息。
  }
}

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

void OSInitHookBegin(void)
{
}

void OSInitHookEnd(void)
{
}

void OSTaskCreateHook(OS_TCB *ptcb)
{
  ptcb = ptcb;
}

void OSTaskDelHook(OS_TCB *ptcb)
{
  ptcb = ptcb;
}

void OSTaskIdleHook(void)
{
}

void OSTCBInitHook(OS_TCB *ptcb)
{
  ptcb = ptcb;
}

void OSTimeTickHook(void)
{
}

void OSTaskSwHook(void)
{
  INT16U   time;
  TASK_USER_DATA  *puser;
  time = PC_ElapsedStop();   //计算当前被切换的任务的运行时间
  PC_ElapsedStart();  //下一个任务运行前,记录下时刻
  puser = OSTCBCur -> OSTCBExtPtr;
  if(puser != (TASK_USER_DATA *)0)  //检查该任务是否正确定义了一个TASK_USER_DATA数据结构
  {
    puser->TaskCtr++;   //任务运行次数加1
    puser->TaskExecTime = time;  //任务的本次运行时间记录在TASK_USER_DATA数据结构中
    puser->TaskTotExecTime += time;  //记录总的任务运行时间
  }
}

void OSTaskStatHook(void)
{
  char  s[80];
  INT8U  i;
  INT32U  total;
  INT8U   pct;
  total = 0L;
  for(i = 0;i < 7;i++)
  {
    total += TaskUserData[i].TaskTotExecTime;  //计算所有任务运行时间(除空闲任务、统计任务)
    DispTaskStat(i);   //在合适的位置显示每个任务的累计运行时间,同时也显示每个任务的名称。
  }
  if(total > 0)
  {
    for(i = 0;i < 7;i++)
    {
      pct = 100 * TaskUserData[i].TaskTotExecTime / total;
      sprintf(s,"%3d %",pct);   //显示每个任务的相对CPU占用率。
      PC_DispStr(62,
                 i + 11,
                 s,
                 DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    }
  }
  if(total > 100000000L)
  {
    for(i =0;i < 7;i++)
    {
      TaskUserData[i].TaskTotExecTime = 0L;
    }
  }
}

static  void  TaskStartDispInit (void)
{
    PC_DispStr( 0,  0, "                         uC/OS-II, The Real-Time Kernel                         ", DISP_FGND_WHITE + DISP_BGND_RED + DISP_BLINK);
    PC_DispStr( 0,  1, "                                Jean J. Labrosse                                ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0,  2, "                             by Xu Dong     2005.6.25                           ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0,  3, "                                    EXAMPLE #3                                  ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0,  4, "                                                                                ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0,  5, "                                                                                ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0,  6, "                                                                                ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0,  7, "                                                                                ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0,  8, "                                                                                ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0,  9, "Task Name         Counter  Exec.Time(uS)   Tot.Exec.Time(uS)  %Tot.             ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0, 10, "----------------- -------  -------------   -----------------  -----             ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0, 11, "                                                                                ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0, 12, "                                                                                ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0, 13, "                                                                                ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0, 14, "                                                                                ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0, 15, "                                                                                ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0, 16, "                                                                                ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0, 17, "                                                                                ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0, 18, "                                                                                ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0, 19, "                                                                                ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0, 20, "                                                                                ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0, 21, "                                                                                ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0, 22, "#Tasks          :        CPU Usage:     %                                       ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0, 23, "#Task switch/sec:                                                               ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
    PC_DispStr( 0, 24, "                            <-PRESS 'ESC' TO QUIT->                             ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY + DISP_BLINK);
}

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

static  void  TaskStartDisp(void)
{
    char   s[80];


    sprintf(s, "%5d", OSTaskCtr);                                  /* Display #tasks running               */
    PC_DispStr(18, 22, s, DISP_FGND_YELLOW + DISP_BGND_BLUE);

#if OS_TASK_STAT_EN > 0
    sprintf(s, "%3d", OSCPUUsage);                                 /* Display CPU usage in %               */
    PC_DispStr(36, 22, s, DISP_FGND_YELLOW + DISP_BGND_BLUE);
#endif

    sprintf(s, "%5d", OSCtxSwCtr);                                 /* Display #context switches per second */
    PC_DispStr(18, 23, s, DISP_FGND_YELLOW + DISP_BGND_BLUE);

    sprintf(s, "V%1d.%02d", OSVersion() / 100, OSVersion() % 100); /* Display uC/OS-II's version number    */
    PC_DispStr(75, 24, s, DISP_FGND_YELLOW + DISP_BGND_BLUE);

    switch (_8087)
    {                             /* Display whether FPU present          */
        case 0:
             PC_DispStr(71, 22, " NO  FPU ", DISP_FGND_YELLOW + DISP_BGND_BLUE);
             break;

        case 1:
             PC_DispStr(71, 22, " 8087 FPU", DISP_FGND_YELLOW + DISP_BGND_BLUE);
             break;

        case 2:
             PC_DispStr(71, 22, "80287 FPU", DISP_FGND_YELLOW + DISP_BGND_BLUE);
             break;

        case 3:
             PC_DispStr(71, 22, "80387 FPU", DISP_FGND_YELLOW + DISP_BGND_BLUE);
             break;
    }
}

void DispTaskStat(INT8U id)
{
    char  s[80];

    sprintf(s, "%-18s %05u      %5u          %10ld",
            TaskUserData[id].TaskName,
            TaskUserData[id].TaskCtr,
            TaskUserData[id].TaskExecTime,
            TaskUserData[id].TaskTotExecTime);
    PC_DispStr(0, id + 11, s, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
}

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

void Task5(void *pdata)
{
    pdata = pdata;
    for (;;)
    {
        OSTimeDlyHMSM(0, 0, 0, 100);
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?