在真正开始分析源代码前,先来看使用uC/OS-II的三个例子
1)使用信号量
#define
TASK_STK_SIZE 512 /* 每个任务堆栈的大小(以字计算)*/
#define N_TASKS 10 /* 任务数*/
OS_STK TaskStk[N_TASKS][TASK_STK_SIZE]; /* 任务堆栈 */
OS_STK TaskStartStk[TASK_STK_SIZE]; // 开始任务的堆栈
char TaskData[N_TASKS]; /* 传给每个任务的数据 */
OS_EVENT * RandomSem; // 互斥型信号量
void main ( void )
{
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); /* 清空屏幕 */
OSInit(); /* 初始化uC/OS-II */
PC_DOSSaveReturn(); /* 保存环境以便稍后可以返回DOS环境 */
PC_VectSet(uCOS, OSCtxSw); /* 设置uC/OS-II的切换处理函数 */
RandomSem = OSSemCreate( 1 ); /* 建立一个信号量 */
OSTaskCreate(TaskStart, ( void * ) 0 , & TaskStartStk[TASK_STK_SIZE - 1 ], 0 ); // 创建第一个任务,优先级设置为最大值
OSStart(); /* 开始多任务 */
}
void TaskStart ( void * pdata)
{
#if OS_CRITICAL_METHOD == 3 /* 为CPU的状态寄存器分配内存*/
OS_CPU_SR cpu_sr;
#endif
char s[ 100 ];
INT16S key;
pdata = pdata; /* 这步是为了防止编译错误 */
TaskStartDispInit(); /* 初始化显示屏 */
OS_ENTER_CRITICAL();
PC_VectSet( 0x08 , OSTickISR); /* 替换机器的时钟中断函数为uC/OS-II所需要的中断函数 */
PC_SetTickRate(OS_TICKS_PER_SEC); /* 调整时钟频率 */
OS_EXIT_CRITICAL();
OSStatInit(); /* 初始化统计任务 */
TaskStartCreateTasks(); /* 创建其他任务 */
for (;;) {
TaskStartDisp();
if (PC_GetKey( & key) == TRUE) { /* 是否按键 */
if (key == 0x1B ) { /* ESCAPE按下了 */
PC_DOSReturn(); /* 返回DOS */
}
}
OSCtxSwCtr = 0 ; /* 切换次数计数器清零 */
OSTimeDlyHMSM( 0 , 0 , 1 , 0 ); /* 挂起秒,让给其他任务运行 */
}
}
static void TaskStartCreateTasks ( void )
{
INT8U i;
for (i = 0 ; i < N_TASKS; i ++ ) { /* 创建N_TASKS个任务 */
TaskData[i] = ' 0 ' + i; /* 每个任务显示其数据 */
OSTaskCreate(Task, ( void * ) & TaskData[i], & TaskStk[i][TASK_STK_SIZE - 1 ], i + 1 );
}
}
void Task ( void * pdata)
{
INT8U x;
INT8U y;
INT8U err;
for (;;) {
OSSemPend(RandomSem, 0 , & err); /* 获取信号量 */
x = random( 80 ); /* 计算X坐标 */
y = random( 16 ); /* 计算Y坐标 */
OSSemPost(RandomSem); /* 释放信号量 */
/* Display the task number on the screen */
PC_DispChar(x, y + 5 , * ( char * )pdata, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
OSTimeDly( 1 ); /* 挂起秒,让给其他任务运行 */
}
}
#define N_TASKS 10 /* 任务数*/
OS_STK TaskStk[N_TASKS][TASK_STK_SIZE]; /* 任务堆栈 */
OS_STK TaskStartStk[TASK_STK_SIZE]; // 开始任务的堆栈
char TaskData[N_TASKS]; /* 传给每个任务的数据 */
OS_EVENT * RandomSem; // 互斥型信号量
void main ( void )
{
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); /* 清空屏幕 */
OSInit(); /* 初始化uC/OS-II */
PC_DOSSaveReturn(); /* 保存环境以便稍后可以返回DOS环境 */
PC_VectSet(uCOS, OSCtxSw); /* 设置uC/OS-II的切换处理函数 */
RandomSem = OSSemCreate( 1 ); /* 建立一个信号量 */
OSTaskCreate(TaskStart, ( void * ) 0 , & TaskStartStk[TASK_STK_SIZE - 1 ], 0 ); // 创建第一个任务,优先级设置为最大值
OSStart(); /* 开始多任务 */
}
void TaskStart ( void * pdata)
{
#if OS_CRITICAL_METHOD == 3 /* 为CPU的状态寄存器分配内存*/
OS_CPU_SR cpu_sr;
#endif
char s[ 100 ];
INT16S key;
pdata = pdata; /* 这步是为了防止编译错误 */
TaskStartDispInit(); /* 初始化显示屏 */
OS_ENTER_CRITICAL();
PC_VectSet( 0x08 , OSTickISR); /* 替换机器的时钟中断函数为uC/OS-II所需要的中断函数 */
PC_SetTickRate(OS_TICKS_PER_SEC); /* 调整时钟频率 */
OS_EXIT_CRITICAL();
OSStatInit(); /* 初始化统计任务 */
TaskStartCreateTasks(); /* 创建其他任务 */
for (;;) {
TaskStartDisp();
if (PC_GetKey( & key) == TRUE) { /* 是否按键 */
if (key == 0x1B ) { /* ESCAPE按下了 */
PC_DOSReturn(); /* 返回DOS */
}
}
OSCtxSwCtr = 0 ; /* 切换次数计数器清零 */
OSTimeDlyHMSM( 0 , 0 , 1 , 0 ); /* 挂起秒,让给其他任务运行 */
}
}
static void TaskStartCreateTasks ( void )
{
INT8U i;
for (i = 0 ; i < N_TASKS; i ++ ) { /* 创建N_TASKS个任务 */
TaskData[i] = ' 0 ' + i; /* 每个任务显示其数据 */
OSTaskCreate(Task, ( void * ) & TaskData[i], & TaskStk[i][TASK_STK_SIZE - 1 ], i + 1 );
}
}
void Task ( void * pdata)
{
INT8U x;
INT8U y;
INT8U err;
for (;;) {
OSSemPend(RandomSem, 0 , & err); /* 获取信号量 */
x = random( 80 ); /* 计算X坐标 */
y = random( 16 ); /* 计算Y坐标 */
OSSemPost(RandomSem); /* 释放信号量 */
/* Display the task number on the screen */
PC_DispChar(x, y + 5 , * ( char * )pdata, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
OSTimeDly( 1 ); /* 挂起秒,让给其他任务运行 */
}
}