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();
// 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();
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;
}
#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);
}
}
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() */
}
/***********************************************
>> 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
//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)
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) */
#define OS_TICKS_PER_SEC 1000 /* Set the number of ticks in one second */