uCOS Port - Code

main.cpp

Allocate Stack

// prototype for startup task
void StartupTask(void* pdata);

// allocate a stack for the startup task
static OS_STK  StartupStk[APP_TASK_START_STK_SIZE];

// allocate the print buffer
PRINT_DEFINEBUFFER();

main()

int main(void)
{
    INT8U err;

    scb2300_t SCBParams = {
        /* Initial SCB Parameters */
        .PLL_M_Mul = 12,           /* PLL Multiplier. Valid values 6 through 512*/
        .PLL_N_Div = 1,            /* PLL Divider. Valid values 1 through 32 */
        .PLL_Fcco = 288000000,     /* Frequency (Hz) of PLL output */
        .CCLK_Div = 6,            /* CPU Clock divider, cclk */
        .MAMMode = MAMCR_PARTIAL,  /* MAM mode Partial is the preferred setting for Rev -,A parts */
        .MAMTim = MAMTIM_AUTOCFG,  /* Let initMAM calculate the optimal MAM timing */
    };


    /* pre-initialize so we can use the serial port, etc.*/
    initHardware(&SCBParams);


    RETAILMSG(1, (
              "main: Built %s %s.\n\r\n\r",
              __DATE__,
              __TIME__));


    // initialize the OS
    DEBUGMSG(1, ("main: Running OSInit()...\n\r"));
    OSInit();

      // create the startup task
    DEBUGMSG(1, ("main: Creating start up task\n\r"));
    err = OSTaskCreate(StartupTask, (void*)0,
                 (void*)&StartupStk[APP_TASK_START_STK_SIZE-1], APP_TASK_START_PRIO);
    if (err != OS_NO_ERR) {
        DEBUGMSG(1, ("main: failed creating start up task: %d\n\r", err));
        while(TRUE);  //park on error
    }

    DEBUGMSG(1, ("Starting SBC5206 Hardware setup...\n\r"));


    // start the OS
    OSStart();

    // We never get here.
    RETAILMSG(1, (
              "main: Programming Assignment #6: Exiting.\n\r\n\r"));

    return 0;
}

Tasks.c

#include "includes.h"  // OS includes
#include "print.h"
#include "uarts.h"
#include "init.h"


// allocate the stacks for each task
static OS_STK   Task1Stk[APP_TASK_DEFAULT_STK_SIZE];
static OS_STK   Task2Stk[APP_TASK_DEFAULT_STK_SIZE];
static OS_STK   Task3Stk[APP_TASK_DEFAULT_STK_SIZE];

#define MP3BUFFERSIZE   256  //??????
INT8U buffer[MP3BUFFERSIZE];

// allocate queue and events
OS_EVENT *    MySem;
OS_EVENT *    MyQueue;
void     *Q1[Q1_SIZE];

// task prototypes
void Task1(void* pdata);
void Task2(void* pdata);
void Task3(void* pdata);
static void SetLED(BOOLEAN On);

//get external refrence to the print buffer
PRINT_BUFFER();

//
// this task is the initial task running, started by main(). It begins the system tick timer
// and creates all the other task. Then it deletes itself.
//
void StartupTask(void* pdata)
{
    // Initialize BSP functions
    BSP_Init();

    // re-init the UART so we can use the serial port
    initUART0(38400, UART_8N1, UART_FIFO_OFF, getFcclk());

    // setup queues and semaphore needed for test threads

    MyQueue = OSQCreate(&Q1[0],Q1_SIZE);

    if (MyQueue == NULL) {
        DEBUGMSG(1,("StartupTask: failed to create queue.\n\r"));
        OSTaskDel(OS_PRIO_SELF);
    }

    MySem = OSSemCreate(1);

    if (MySem == NULL) {
        DEBUGMSG(1,("StartupTask: failed to create semaphore.\n\r"));
        OSTaskDel(OS_PRIO_SELF);
    }

    // create the the test tasks
    // we have OS_STK_GROWTH set to 1, so the stack grows from high to low

    OSTaskCreate(Task1, (void*)0, (void*)&Task1Stk[APP_TASK_DEFAULT_STK_SIZE-1], APP_TASK_TEST1_PRIO);
    OSTaskCreate(Task2, (void*)0, (void*)&Task2Stk[APP_TASK_DEFAULT_STK_SIZE-1], APP_TASK_TEST2_PRIO);
    OSTaskCreate(Task3, (void*)1000, (void*)&Task3Stk[APP_TASK_DEFAULT_STK_SIZE-1], APP_TASK_TEST3_PRIO);

    // delete ourselves, letting the work be done in the new tasks.
    OSTaskDel(OS_PRIO_SELF);
}


// Task 1,2 & 3 have dependencies on each otherthrough semaphores and queues.
// They demonstrate tasking, delays and IPCs operating within the OS port
//
// Task1 prints an alternating message (Led On/Led Off) each time it wakes
// up from the semaphore MySem.
//
void Task1(void* pdata)
{
    INT8U err;
    BOOLEAN LedOn;

    LedOn = FALSE;

    DEBUGMSG(1,("Task1: begin\n\r"));

    for(;;)
    {
        OSSemPend(MySem, 0, &err);

        if (err != OS_NO_ERR) {
            DEBUGMSG(1,("Task1: failed to get semaphore, err: %d\n\r", err));
            // now what should we do????????
        }

        // toggle the LED and print a message
        if (LedOn==TRUE)
        {
            DEBUGMSG(1,("Task1: Led On\n\r"));
            LedOn = FALSE;
        }
        else
        {
            DEBUGMSG(1,("Task1: Led Off\n\r"));
            LedOn = TRUE;
        }

        SetLED(LedOn);
    }
}

// task 2 places a message into MyQueue every 500 msecs.
void Task2(void* pdata)
{
    long  qmsg;
    INT32U count;
    INT8U err;

    count = 0;
    DEBUGMSG(1,("Task2: begin\n\r"));

    for(;;)
    {
        OSTimeDly(500);
        qmsg = count++;

        if (qmsg == (long)NULL) { // illegal to queue a NULL message
            qmsg = 1;
        }

        err = OSQPost(MyQueue,(void*)qmsg);

        if (err != OS_NO_ERR) {
            DEBUGMSG(1,("Task2: failed to post to queue, err: %d\n\r", err));
            // now what should we do????????
        }
    }
}

// task 3 waits on a message from MyQueue. When it reveives the message
// it sets the semaphore MySem.
//
void Task3(void* pdata)
{
    long qdata;
    volatile long passed_data;
    INT8U err;

    DEBUGMSG(1,("Task3: begin\n\r"));

    passed_data = (long)pdata;

    for(;;)
    {
        qdata = (long)OSQPend(MyQueue, 0, &err);

        if (err != OS_NO_ERR) {
            DEBUGMSG(1,("Task3: failed to pend from queue, err: %d\n\r", err));
            // now what should we do????????
        }

        if(qdata >= 100)  /* use data somehow */
        {
            if(passed_data++ == 2000)
                passed_data = passed_data;
        }
        err = OSSemPost(MySem);

        if (err != OS_NO_ERR) {
            DEBUGMSG(1,("Task3: failed to post to semaphore, err: %d\n\r", err));
            // now what should we do????????
        }
    }
}


// toggle the LED next to the display (labeled SD)
static void SetLED(BOOLEAN On)
{
    if (On) {
        WRITEREG32(FIO0CLR, SD_LED_BIT);
    } else {
        WRITEREG32(FIO0SET, SD_LED_BIT);
    }
}

bsp.c

static  void  Tmr_TickInit (void)
{
    CPU_INT32U  pclk_freq;
    CPU_INT32U  rld_cnts;

    // VIC timer #0 Initialization
    WRITEREG32(VICINTSELECT, READREG32(VICINTSELECT) & ~(1 << VIC_TIMER0));     /* Configure the timer interrupt as an IRQ source           */
    WRITEREG32(VICVECTADDR4, (CPU_INT32U)Tmr_TickISR_Handler);                  /* Set the vector address                                   */
    WRITEREG32(VICINTENABLE,  (1 << VIC_TIMER0));                               /* Enable the timer interrupt source                        */

    pclk_freq     =   BSP_CPU_PclkFreq(PCLKINDX_TIMER0);        /* Get the peripheral clock frequency                       */

    rld_cnts      =   pclk_freq / OS_TICKS_PER_SEC;             /* Calculate the # of counts necessary for the OS ticker    */

    WRITEREG32(T0TCR, (1 << 1));                                  /* Disable and reset counter 0 and the prescale counter 0   */
    WRITEREG32(T0TCR, 0);                                        /* Clear the reset bit                                      */
    WRITEREG32(T0PC,  0);                                        /* Prescaler is set to no division                          */

    WRITEREG32(T0MR0, rld_cnts);
    WRITEREG32(T0MCR, 3);                                        /* Interrupt on MR0 (reset TC), stop TC                     */

    WRITEREG32(T0CCR, 0);                                        /* Capture is disabled.                                     */
    WRITEREG32(T0EMR, 0);                                        /* No external match output.                                */
    WRITEREG32(T0TCR, 1);                                        /* Enable timer 0                                           */
}


/*
*********************************************************************************************************
*                                       Tmr_TickISR_Handler()
*
* Description : Handle the timer interrupt that is used to generate TICKs for uC/OS-II.
*
* Argument(s) : none.
*
* Return(s)   : none.
*********************************************************************************************************
*/

void  Tmr_TickISR_Handler (void)
{
    WRITEREG32(T0IR, 0xFF);                                     /* Clear timer #0 interrupt                                 */

    OSTimeTick();                                               /* Call uC/OS-II's OSTimeTick()                             */
}

cpu_a.s

/***********************************************
>> Implement save of CPSR register
************************************************/

/* this is a two step process to avoid possibly having FIQ's masted during IRQs */
CPU_SR_Save:
            MRS     r0, cpsr
            ORR     r1, r0, #CPU_ARM_CTRL_INT_IRQDIS               /* disable IRQs */
            MSR     cpsr_c, r1
            ORR     r1, r1, #CPU_ARM_CTRL_INT_FIQDIS               /* disable FIQs */
            MSR     cpsr_c, r1
            BX      LR                                             /* DISABLED, return the original CPSR contents in R0*/

/***********************************************
>> Implement restore of CPSR register
************************************************/

CPU_SR_Restore:                                                  /* See Note #2*/
        MSR     CPSR_c, R0
        BX      LR

app_cfg.h

//default stack size for tasks in OS_STK units
#define APP_TASK_DEFAULT_STK_SIZE         512
#define APP_TASK_START_STK_SIZE           512

//task priorities
#define APP_TASK_START_PRIO                 4
#define APP_TASK_TEST1_PRIO                 5
#define APP_TASK_TEST2_PRIO                 6
#define APP_TASK_TEST3_PRIO                 7

#define  OS_TASK_TMR_PRIO             (OS_LOWEST_PRIO - 2)

cpu.h

typedef unsigned int   OS_STK;                   /* Each stack entry is 32-bit wide                    */
typedef unsigned int   OS_CPU_SR;                /* Define size of CPU status register (PSR = 32 bits) */

os_cfg.h

#define OS_TICKS_PER_SEC       1000    /* Set the number of ticks in one second                        */