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

📄 test.c

📁 移植的ucos
💻 C
字号:
/*
 *************************************************************************************************************
 *                                               uC/OS-II
 *                                         The Real-Time Kernel
 *
 *
 *                                            AVR Sample code
 * File     : TEST.C
 * By       : Ole Saether
 *
 * $Modtime: 19.07.01 22:24 $
 * $Revision: 3 $
 *
 * Description :
 *
 *         This file contains a simple example program showing how to use the AVR port of uC/OS-II. It is
 *         based on Example #1 from Jean Labrosse's book "MicroC/OS-II, The Real Time Kernel." The main
 *         difference is that this example does not display the time of day.
 *         You must have the AVR UART connected to a VT102 compatible terminal with color support to get the
 *         most out of this example.
 *
 *         The support routines at the end of this file are included only to make this example run; they
 *         should not be used in production code without careful testing.
 *
 *************************************************************************************************************
*/

#include "includes.h"

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

#define  TASK_STK_SIZE  OS_TASK_DEF_STK_SIZE            /* Size of each task's stacks (# of bytes)          */
#define  N_TASKS        10                              /* Number of identical tasks                        */

/*
**************************************************************************************************************
*                                               VARIABLES
**************************************************************************************************************
*/

OS_STK          TaskStk[N_TASKS][TASK_STK_SIZE];        /* Tasks stacks                                     */
OS_STK          TaskStartStk[TASK_STK_SIZE];
char            TaskData[N_TASKS];                      /* Parameters to pass to each task                  */
OS_EVENT       *RandomSem;
OS_EVENT       *DispStrSem;
INT32U          RndNext;                                /* Used by random generator                         */
INT8U           UartTxBuf[256];                         /* 256 bytes UART transmit buffer                   */
volatile INT8U  UartTxRdPtr;                            /* UART transmit buffer read pointer                */
INT8U           UartTxWrPtr;                            /* UART transmit buffer write pointer               */
volatile INT8U  UartTxCount;                            /* Number of characters to send                     */
OS_EVENT       *UartTxSem;

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

C_task Task(void *data);                                 /* Function prototypes of tasks                    */
C_task TaskStart(void *data);                            /* Function prototypes of Startup task             */
void   PutChar(char c);                                  /* Write a character to the AVR UART               */
void   AvrInit(void);                                    /* Initialize AVR                                  */
void   PutString(const char *s);                         /* Write a null-terminated string to the AVR UART  */
void   SPrintDec(char *, INT32U, INT8U, char);           /* Output an INT16U to a string (right adjust)     */
void   PutDec (INT8U x);                                 /* Display an INT8U without leading zeros          */
void   VT102Attribute (INT8U fgcolor, INT8U bgcolor);    /* Set attributes on VT102 terminal                */
void   VT102DispClrScr(void);                            /* Clear VT102 terminal                            */
void   VT102DispChar(INT8U, INT8U, char, INT8U, INT8U);  /* Display a character on VT102 terminal           */
void   VT102DispStr(INT8U, INT8U, char *, INT8U, INT8U); /* Display a string on VT102 terminal              */
INT8U  random(INT8U n);                                  /* Simple random generator (found in K&R)          */

/*
**************************************************************************************************************
*                                                MAIN
**************************************************************************************************************
*/

C_task main (void)
{
    AvrInit();                                          /* Initialize the AVR UART and Timer                */
    OSInit();
    RandomSem  = OSSemCreate(1);                        /* Random number semaphore                          */
    DispStrSem = OSSemCreate(1);                        /* Display string semaphore                         */
    UartTxSem  = OSSemCreate(254);                      /* Initialize Uart transmit buffer semaphore to 2   */
                                                        /* bytes less than the buffer size                  */
    OSTaskCreate(TaskStart, (void *)0, (void *)&TaskStartStk[TASK_STK_SIZE - 1], 0);
    RndNext = 1;                                        /* set random generator seed to 1                   */
    OSStart();                                          /* Start multitasking                               */
}

/*
**************************************************************************************************************
*                                              STARTUP TASK
**************************************************************************************************************
*/
C_task TaskStart (void *data)
{
    INT8U   i;
    INT8U   err;
    char    s[10];


    data = data;                                        /* Prevent compiler warning                         */

    VT102DispClrScr();                                  /* Clear the screen                                 */
    VT102DispStr(26,  1, "uC/OS-II, The Real-Time Kernel", COLOR_WHITE, COLOR_RED);
    VT102DispStr(33,  2, "Jean J. Labrosse", COLOR_WHITE, COLOR_BLACK);
    VT102DispStr(29,  3, "AVR port by Ole Saether", COLOR_WHITE, COLOR_BLACK);
    VT102DispStr(1, 23, "Determining  CPU's capacity ...", COLOR_WHITE, COLOR_BLACK);

    OSStatInit();                                       /* Initialize uC/OS-II's statistics                 */

    for (i = 0; i < N_TASKS; i++) {                     /* Create N_TASKS identical tasks                   */
        TaskData[i] = '0' + i;                          /* Each task will display its own letter            */
        OSTaskCreate(Task, (void *)&TaskData[i], (void *)&TaskStk[i][TASK_STK_SIZE - 1], i + 1);
    }
    VT102DispStr(1, 23, "#Tasks          : xxxxx  CPU Usage: xxx %", COLOR_WHITE, COLOR_BLACK);
    VT102DispStr(1, 24, "#Task switch/sec: xxxxx", COLOR_WHITE, COLOR_BLACK);

    s[0] = 'V';
    SPrintDec(&s[1], OSVersion() / 100, 1, '0');
    s[2] = '.';
    SPrintDec(&s[3], OSVersion() % 100, 2, '0');
    VT102DispStr(76, 24, s, COLOR_WHITE, COLOR_BLUE);
    for (;;) {
        SPrintDec(s, (INT32U)OSTaskCtr, 5, ' ');        /* Display #tasks running                           */
        VT102DispStr(19, 23, s, COLOR_BLUE, COLOR_CYAN);
        SPrintDec(s, (INT32U)OSCPUUsage, 3, ' ');       /* Display CPU usage in %                           */
        VT102DispStr(37, 23, s, COLOR_BLUE, COLOR_CYAN);
        SPrintDec(s, (INT32U)OSCtxSwCtr, 5, ' ');       /* Display #context switches per second             */
        VT102DispStr(19, 24, s, COLOR_BLUE, COLOR_CYAN);
        OSCtxSwCtr = 0;
        OSTimeDlyHMSM(0, 0, 1, 0);                      /* Wait one second                                  */
    }
}

/*
**************************************************************************************************************
*                                                  TASKS
**************************************************************************************************************
*/
C_task Task (void *data)
{
    INT8U x;
    INT8U y;
    INT8U err;

    for (;;) {
        OSSemPend(RandomSem, 0, &err);                  /* Acquire semaphore to perform random numbers      */
        x = random(80);                                 /* Find X position where task number will appear    */
        y = random(16);                                 /* Find Y position where task number will appear    */
        OSSemPost(RandomSem);                           /* Release semaphore                                */
                                                        /* Display the task number on the screen            */
        VT102DispChar(x + 1, y + 5, *(char *)data, COLOR_WHITE, COLOR_BLACK);
        OSTimeDly(10);                                  /* Delay 3 clock ticks                              */
    }
}

/*
**************************************************************************************************************
*                                                  SUPPORT ROUTINES
**************************************************************************************************************
*/

void UartTxHandler (void)
{
    UartTxCount--;                                      /* Decrement number of characters left to send      */
    if (UartTxCount) {
		OS_ENTER_CRITICAL();
        UDR = UartTxBuf[UartTxRdPtr];                   /* Place next character into UART transmit register */
        UartTxRdPtr++;                                  /* Advance to next character                        */
		OS_EXIT_CRITICAL();        
    } else {
        UCR &= ~0x40;                                   /* Disable UART transmit complete interrupt         */
    }
	OSSemPost(UartTxSem);                               /* Signal that we have room for one more character  */
}

void AvrInit (void)
{
    TCCR0       = 0x05;                                 /* Set TIMER0 prescaler to CLK/1024                 */
    TIMSK       = 0x02;                                 /* Enable TIMER0 overflow interrupt                 */
    UBRR        = 23;                                   /* 19200 BAUD at 7.3728MHz                          */
    MCUCR      |= 0x80;                                 /* Enable external RAM                              */
    UCR         = 0x08;                                 /* Enable UART transmitter                          */
    UartTxCount = 0;                                    /* Clear number of characters to send               */
    UartTxRdPtr = 0;                                    /* Initialize transmit buffer read pointer          */
    UartTxWrPtr = 0;                                    /* Initialize transmit buffer write pointer         */
}


void PutChar (char c)
{
    INT8U err;

    OSSemPend(UartTxSem, 0, &err);                      /* Wait for space in transmit buffer                */
    OS_ENTER_CRITICAL();
    if (UartTxCount) {
        UartTxBuf[UartTxWrPtr] = c;                     /* Put character to send in transmit buffer         */
        UartTxWrPtr++;                                  /* Prepare for next character                       */
        UartTxCount++;                                  /* Increment number of characters to send           */
    } else {
        UDR         = c;                                /* Write first char directly to the UART            */
        UartTxCount = 1;
        UCR        |= 0x40;                             /* Enable UART transmit complete interrupt          */
    }
    OS_EXIT_CRITICAL();
}


void PutString (const char *s)
{
    while (*s != '\0') {
        PutChar(*s++);
    }
}


void SPrintDec(char *s, INT32U x, INT8U n, char c)
{
    INT8U i;


    s[n] = '\0';
    for (i = 0; i < n; i++) {
        s[n - i - 1] = '0' + (x % 10);
        x /= 10;
    }
    for (i = 0; i < (n - 1); i++) {
        if (s[i] == '0') {
            s[i] = c;
        } else {
            break;
        }
    }
}


INT8U random (INT8U n)
{
    RndNext = RndNext * 1103515245 + 12345;
    return ((INT8U)(RndNext / 256) % (n + 1));
}


void PutDec (INT8U x2)
{
    INT8U x0;
    INT8U x1;


    x0  = (x2 % 10);
    x2 /= 10;
    x1  = (x2 % 10);
    x2 /= 10;
    if (x2) {
        PutChar(x2 + '0');
    }
    if (x1 || x2) {
        PutChar(x1 + '0');
    }
    PutChar(x0 + '0');
}


void VT102Attribute (INT8U fgcolor, INT8U bgcolor)
{
    PutChar(0x1b);
    PutChar('[');
    PutDec(30 + fgcolor);
    PutChar(';');
    PutDec(40 + bgcolor);
    PutChar('m');
}


void VT102DispClrScr (void)
{
    VT102Attribute(COLOR_WHITE, COLOR_BLACK);
    PutString("\x1B[2J");
}


void VT102DispChar (INT8U x, INT8U y, char c, INT8U fgcolor, INT8U bgcolor)
{
    INT8U err;

    OSSemPend(DispStrSem, 0, &err);                     /* Acquire semaphore to display string              */
    VT102Attribute(fgcolor, bgcolor);
    PutChar(0x1B);
    PutChar('[');
    PutDec(y);
    PutChar(';');
    PutDec(x);
    PutChar('H');
    PutChar(c);
    OSSemPost(DispStrSem);                              /* Release semaphore                                */
}


void VT102DispStr (INT8U x, INT8U y, char *s, INT8U fgcolor, INT8U bgcolor)
{
    INT8U err;

    OSSemPend(DispStrSem, 0, &err);                     /* Acquire semaphore to display string              */
    VT102Attribute(fgcolor, bgcolor);
    PutChar(0x1B);
    PutChar('[');
    PutDec(y);
    PutChar(';');
    PutDec(x);
    PutChar('H');
    PutString(s);
    OSSemPost(DispStrSem);                              /* Release semaphore                                */
}

⌨️ 快捷键说明

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