移植的工作难以分析下去,先来几个UCOS的使用范例看看吧
第一个范例:
void main (void)
{
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); /* PC的清屏函数,PC_DispClrScr(INT8U color),这里调用时是前景色为白色,背景色为黑色*/
OSInit(); /* Initialize uC/OS-II ,初始化UCOS-II,在使用任何功能之前必须调用OSInit函数,建立两个任务:空闲任务-所有其他任务均未就绪时运行,统计任务-计算CPU的利用率*/
PC_DOSSaveReturn(); /* Save environment to return to DOS 允许程序在正式开始多任务前,保存重要的寄存器的值,以保证UCOS能够正常地返回DOS */
PC_VectSet(uCOS, OSCtxSw); /* Install uC/OS-II's context switch vector ,用于设定中断向量表的内容。*/
RandomSem = OSSemCreate(1); /* Random number semaphore,建立一个信号量,并制定信号量的初值为1,OSSemCreate(1)返回一个指向信号量的指针,那么之后对该信号量的操作全部通过这个指针来实现 */
OSTaskCreate(TaskStart, (void *)0, &TaskStartStk[TASK_STK_SIZE - 1], 0); /*至少建立一个任务,TaskStart为指向该任务运行代码的指针,第二个参数是一个指向任务初始化数据的指针,第三个是任务的堆栈栈顶,当堆栈是从上到下,必须把堆栈高地址传给该函数,最后一个参数指定建立的任务的优先级,数值越小优先级越高,每个任务的优先级都是介于0-62之间独一无二的。*/
OSStart(); /* Start multitasking,调用该函数将控制权交给内核,开始运行多任务 */
}
OSStart函数会让优先级最高的就绪任务开始运行,即TaskStart
void TaskStart (void *pdata)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
char s[100];
INT16S key;
pdata = pdata; /* Prevent compiler warning,这是这个参数是当任务建立时传递过来的一个指针 */
TaskStartDispInit(); /* Initialize the display 初始化屏幕显示 */
OS_ENTER_CRITICAL(); /*关中断*/
PC_VectSet(0x08, OSTickISR); /* Install uC/OS-II's clock tick ISR */
PC_SetTickRate(OS_TICKS_PER_SEC); /* Reprogram tick rate */
OS_EXIT_CRITICAL(); /*开中断*/
OSStatInit(); /* Initialize uC/OS-II's statistics测试所使用的处理器的速度,得知处理器在运行所有应用任务时实际的CPU使用率 */
TaskStartCreateTasks(); /* Create all the application tasks建立更多任务,10个显示不同字符的任务,在每次建立一个新任务的时候,UCOS都会判断新建立的任务是否比建立它们的任务优先级更高,如果更高,这个新建立的任务将立刻开始运行。 */
for (;;) {
TaskStartDisp(); /* Update the display */
if (PC_GetKey(&key) == TRUE) { /* See if key has been pressed */
if (key == 0x1B) { /* Yes, see if it's the ESCAPE key */
PC_DOSReturn(); /* Return to DOS */
}
}
OSCtxSwCtr = 0; /* Clear context switch counter 每秒都将记录任务切换次数的清零 */
OSTimeDlyHMSM(0, 0, 1, 0); /* Wait one second 将自身挂起1s,1s是通过四个参数传送的,小时,分钟,秒,毫秒 */
}
}
static void TaskStartCreateTasks (void)
{
INT8U i;
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], &TaskStk[i][TASK_STK_SIZE - 1], i + 1);
}
}
上面的函数循环建立了十个Task任务,下面是Task任务的代码
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); /* Delay 1 clock tick 通知ucos该任务本次运行已经结束,可以让其他低优先级的任务运行了,参数1代表该任务延时1个时钟节拍,在200Hz的情况下就是5ms */
}
}