⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test_cl.c

📁 uCOS的源码例子
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*********************************************************************************************************
*                                                 uC/OS
*                                          The Real-Time Kernel
*
*                                               TEST FILE
*
*                                       Philips Semiconductors, Inc.
*                                             XA (Large Model)
*
*
* File : TEST_CL.C
*
* Notes: The tick rate is set at 100 Hz.  The CPU usage will be high because the tick rate is generally
*        between 10 and 100 Hz.  If you need a slower tick rate, you will need to modify the code because
*        the timer initialization function currently only allows you to have a faster tick rate, not a
*        slower one!  You can change the tick rate (see OS_TICKS_PER_SEC below) without affecting the
*        code (except that the XA Usage % and the number of context switches per second will be different).
*
* This code assumes it is running on the Future Design, Inc. XTEND board.
*
* Once started, uC/OS will be running a total of 14 tasks:
*
*     8 identical tasks.  Each task will toggle a bit on the XTEND board's OUTPUT port
*
*     1 task that will blink the XTEND's LED 10 times per second.
*
*     1 task that sends a message to another task though a message queue.
*
*     1 task that waits for messages from the other task (see above).
*
*     1 task that updates a clock every second (MM:SS) that counts up to 99 minutes and 59 seconds.
*       The clock then rolls over to 00:00 after 100 minutes.
*
*     1 task that displays information to a 'dumb' terminal.  You should thus see the following message
*       appear on serial port #0 of the XA:
*
*                      Philips Semiconductors, Inc.
*                            XA (Large Model)
*                      uC/OS,  The Real-Time Kernel
*
*          XA Usage: PP%  #CtxSw: CCCC  MM:SS  Q: $   BBBB BBBB
*
*       PP        is the percentage of CPU time used.  You should see about 6 to 7% of CPU usage.
*       CCCC      is the number of context switches that uC/OS performs every second.  You should see
*                 between 494 and 498 context switches per second.
*       MM:SS     is the clock where 'MM' are the minutes and 'SS' are the seconds.
*       $         is the message sent/received.  The sender of the message actually cycles through all
*                 26 letters of the alphabet ('A' through 'Z').
*       BBBB BBBB is the binary state of the XTEND's 8-bit input port.  The first bit to the left is the
*                 most significant bit (i.e. Bit #7).  When all headers (in JP4) are in place, the value
*                 will be '0000 0000'.
*
*     1 task (the last task) is actually executed when no other task is ready to run.  In this case,
*       uC/OS will keep track of how much of the CPU is being used.
*********************************************************************************************************
*/

/*$PAGE*/

#include "INCLUDES.H"

/*
*********************************************************************************************************
*                                             CONSTANTS
*********************************************************************************************************
*/

#define            XA_CRYSTAL_FREQ   (ULONG)(24000000L)

#define            OS_TICKS_PER_SEC  100

#define            TIME_10mS         (OS_TICKS_PER_SEC / 100)
#define            TIME_50mS         (OS_TICKS_PER_SEC /  20)
#define            TIME_100mS        (OS_TICKS_PER_SEC /  10)
#define            TIME_200mS        (OS_TICKS_PER_SEC /   5)
#define            TIME_500mS        (OS_TICKS_PER_SEC /   2)
#define            TIME_1S           (OS_TICKS_PER_SEC)
#define            TIME_2S           (OS_TICKS_PER_SEC * 2)
#define            TIME_3S           (OS_TICKS_PER_SEC * 3)
#define            TIME_4S           (OS_TICKS_PER_SEC * 4)
#define            TIME_5S           (OS_TICKS_PER_SEC * 5)

#define            TASK_STK_SIZE     128              /* Size of each task's stacks (# of UWORDs)      */
#define            N_TASKS            20              /* Maximum number of tasks                       */
#define            N_IDENTICAL         8

/*$PAGE*/
/*
*********************************************************************************************************
*                                             VARIABLES
*
* Notes : The size of all task stacks are the same for convenience.  uC/OS, however, allow you have
*         different stack sizes.
*********************************************************************************************************
*/

far   OS_STK_TYPE  StartTaskStk[TASK_STK_SIZE];

far   OS_STK_TYPE  TaskStk[N_IDENTICAL][TASK_STK_SIZE];    /* Stacks for identical tasks               */
far   UBYTE        TaskData[N_TASKS];                      /* Argument to pass to each task            */

far   OS_STK_TYPE  LEDTaskStk[TASK_STK_SIZE];
far   OS_STK_TYPE  QTxTaskStk[TASK_STK_SIZE];
far   OS_STK_TYPE  QRxTaskStk[TASK_STK_SIZE];
far   OS_STK_TYPE  ClkTaskStk[TASK_STK_SIZE];
far   OS_STK_TYPE  DispTaskStk[TASK_STK_SIZE];

far   ULONG        OSIdleCtrMax;                      /* Maximum value taken by OSIdleCtr in 1 second  */
far   UWORD        OSCtxSwCtrMax;                     /* Number of context switches in the past second */

far   UBYTE        OutPortImage;                      /* RAM image of output port defined below        */
far   UBYTE       *OutPort;                           /* 8-bit Output port                             */
far   UBYTE       *InPort;                            /* 8-bit Input  port                             */

far   UBYTE        CPUUsage;                          /* CPU usage in %                                */

far   char         StatStr[80];

far   UBYTE        Min;                               /* Clock (MM:SS), up to 99 minutes and 59 seconds*/
far   UBYTE        Sec;

far   OS_EVENT    *QPtr;                              /* Pointer to a queue                            */
far   void        *QTbl[10];                          /* Message queue storage area                    */
far   UBYTE        QMsg;

/*$PAGE*/
/*
*********************************************************************************************************
*                                           MESSAGE STRINGS
*********************************************************************************************************
*/

code  char         PhilipsMsg[]   = {"\n\n            Philips Semiconductors, Inc.\n\r"};
code  char         XAMsg[]        = {"                  XA (Large Model)\n\r"};
code  char         uCOSMsg[]      = {"            uC/OS,  The Real-Time Kernel\n\n\r"};
code  char         StatMsg[]      = {"XA Usage: xx%  #CtxSw: xxxx  xx:xx  Q: x   xxxx xxxx\r"};

/*
*********************************************************************************************************
*                                         FUNCTION PROTOTYPES
*********************************************************************************************************
*/

       void StartTask(far void *data);                /* Startup Task                                  */
       void Task(far void *data);                     /* 8 Identical Tasks                             */
       void LEDTask(far void *data);                  /* LED blinking task                             */
       void MsgPostTaskQ(far void *data);             /* Message queue posting task                    */
       void MsgPendTaskQ(far void *data);             /* Message queue pending task                    */
       void ClkTask(far void *data);                  /* Clock Task                                    */
       void DispTask(far void *data);                 /* Display Task                                  */

static void XATmrInit(UBYTE tmr, UWORD freq, UBYTE prio);
static void XAComm0Init(UWORD baud);
static void XAComm0TxStr(far char *s);
static void XAStrCpy(far char *s1, code char *s2);

/*$PAGE*/
/*
*********************************************************************************************************
*                                                  MAIN
*
* Description : C main entry point.  This function initializes the XA, uC/OS, the 8-bit output port on
*               the XTEND board, creates a single task and starts multitasking.  Note that the 'ticker'
*               is neither initialized nor running at this point.  The ticker needs to be initialized by
*               the first running task.
*********************************************************************************************************
*/

void main(void)
{
                                            /* -------------------- XA CONFIGURATION ------------------*/
    WDCON  = 0xF0;                          /* Disable watchdog ...                                    */
    WFEED1 = 0xA5;                          /* ... Feed watchdog so new config. takes effect           */
    WFEED2 = 0x5A;
                                            /* Initialize the XA's buses ...                           */
    P0CFGA = 0xFF;                          /* ... Port 0 configured for PUSH-PULL                     */
    P0CFGB = 0xFF;
    P1CFGA = 0xFF;                          /* ... Port 1 configured for Quasi-bidirectional except    */
    P1CFGB = 0x0F;                          /*            A3..A0 are PUSH-PULL                         */
    P2CFGA = 0xFF;                          /* ... Port 2 configured for PUSH-PULL                     */
    P2CFGB = 0xFF;
    P3CFGA = 0xFF;                          /* ... Port 3 configured for Quasi-bidirectional except    */
    P3CFGB = 0xC0;                          /*            Rd and Wr are PUSH-PULL                      */

    BCR    = 0x16;                          /* WAIT disabled, 16-bit data bus, 20 address lines        */

    OSInit();                               /* Initialize uC/OS, The Real-Time Kernel                  */
    OutPortImage = 0x00;                    /* Initialize the RAM based port image                     */
    OSTaskCreate(StartTask, (far void *)0, (far void *)&StartTaskStk[TASK_STK_SIZE], 62);
    OSStart();                              /* Start multitasking                                      */
}

/*$PAGE*/
/*
*********************************************************************************************************
*                                              STARTUP TASK
*
* Description : This function is the first task that executes under uC/OS.  The task starts off by
*               initializing the 'ticker' which happens to be TIMER #0 of the XA.  The task then
*               synchronizes itself to the ticker in order to determine how high 'OSIdleCtr' will
*               count up to during a one second period.  'OSIdleCtr' is a 32-bit variable that is
*               incremented whenever uC/OS is not running any task.  The maximum count is saved in
*               'OSIdleCtrMax'.
*
*               Next, the startup task will create 9 identical tasks (see description of the
*               next function (i.e. 'Task()').  The startup task will then enter an infinite loop that
*               basically calculate the CPU usage (in %) once per second and some other stats.
*
* Notes       : It is assumed that TIMER #0 is used as the system ticker.  Because of this, TIMER #0's
*               interrupt should vector to 'OSTickISR()'.
*********************************************************************************************************
*/

void StartTask(far void *data)
{
    UBYTE  i;
    ULONG  idle;


    data = data;                                 /* Prevent compiler warning                           */
    XATmrInit(0, OS_TICKS_PER_SEC, 3);           /* Configure TIMER#0 for tick rate                    */
    XAComm0Init(4800);                           /* Configure SERIAL#0 for 4800 baud                   */
    OSTimeDly(1);                                /* Synchronize to ticker                              */
    OSIdleCtr    = 0L;                           /* Clear the idle counter                             */
    OSTimeDly(TIME_1S);                          /* Wait one second (no other task will run for 1 sec.)*/
    OSIdleCtrMax = OSIdleCtr;                    /* Save maximum idle counter count                    */

    QPtr = OSQCreate((far void **)&QTbl[0], 10); /* Create a message queue with 10 entries             */

                                                 /* ------------------- TASK CREATIONS ----------------*/
    for (i = 0; i < N_IDENTICAL; i++) {          /* Create identical tasks                             */
        TaskData[i] = i;
        OSTaskCreate(Task, (far void *)&TaskData[i], (far void *)&TaskStk[i][TASK_STK_SIZE], i);
    }
    OSTaskCreate(DispTask,     (far void *)0, (far void *)&DispTaskStk[TASK_STK_SIZE], 20);
    OSTaskCreate(LEDTask,      (far void *)0, (far void *)&LEDTaskStk[TASK_STK_SIZE],  21);
    OSTaskCreate(ClkTask,      (far void *)0, (far void *)&ClkTaskStk[TASK_STK_SIZE],  22);
    OSTaskCreate(MsgPostTaskQ, (far void *)0, (far void *)&QTxTaskStk[TASK_STK_SIZE],  23);
    OSTaskCreate(MsgPendTaskQ, (far void *)0, (far void *)&QRxTaskStk[TASK_STK_SIZE],  24);

    OSCtxSwCtr = 0;                              /* Clear the context switch counter                   */
    OSIdleCtr  = 0L;
    while (1) {
        OS_ENTER_CRITICAL();
        OSCtxSwCtrMax   = OSCtxSwCtr;            /* Get number of context switches in past second      */
        OSCtxSwCtr      = 0;                     /* Reset statistics counters                          */
        idle            = OSIdleCtr;
        OSIdleCtr       = 0L;
        OS_EXIT_CRITICAL();
        CPUUsage        = 100 - (UBYTE)((idle * 100L) / OSIdleCtrMax); /* Compute % CPU usage          */
        OSTimeDly(TIME_1S);                      /* Wait one second until next update of CPU usage     */
    }
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                                  TASKS
*
* Description : Generic task of which there are N_TASKS instances.  When the task is first executed, it
*               is passed an argument.  The argument actually represents the task#.
*
*               These tasks will each toggle a bit on the XTEND output port located at 0xB0000.
*               The bit being toggled is based on the task#.  Task#0 will toggle bit 0 of the output port
*               every tick, Task#1 will toggle bit 1 of the output port every 2 ticks, Task #3 will toggle
*               bit 2 of the output port every 3 ticks, etc.  A RAM image of the port is maintained
*               because the port is WRITE only and can thus not be modified through a read-modify-write
*               operation.  Instead, the port image in RAM is modified and written to the output port.
*               The toggle rate is also dependant on the task#.  The lower the number, the higher the
*               rate.
*********************************************************************************************************
*/

void Task(far void *data)
{
    UBYTE   taskid;
    UBYTE   msk;


    data    = data;
    taskid  = *(far UBYTE *)data;
    msk     = 1 << taskid;                       /* Setup mask to toggle bit based on task#            */
    OutPort = (far UBYTE *)0xB0000;              /* Point to output port (XTEND board)                 */
    while (1) {
        OSTimeDly(taskid + 1);                   /* Delay based on task I.D.                           */
        OS_ENTER_CRITICAL();
        OutPortImage ^= msk;                     /* Change memory port image                           */
        *OutPort      = OutPortImage;            /* Output changed bit to output port                  */
        OS_EXIT_CRITICAL();
    }
}

/*
*********************************************************************************************************
*                                             LED BLINKING TASK
*********************************************************************************************************
*/

void LEDTask(far void *data)
{
    data = data;
    while (1) {
        OSTimeDly(TIME_50mS);                    /* Delay 50 mS                                        */

⌨️ 快捷键说明

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