《ucos嵌入式实时操作系统应用解析.ppt》由会员分享,可在线阅读,更多相关《ucos嵌入式实时操作系统应用解析.ppt(55页珍藏版)》请在金锄头文库上搜索。
1、初识C/OS-II范例讲解 C/OSC/OS简介简介1、C/OSmicro O S,微控制器操作系统2、 C/OS简介美国人Jean Labrosse 1992年完成应用面覆盖了诸多领域,如照相机、医疗器械、音响设备、发动机控制、高速公路电话系统、自动提款机等 1998年C/OS-II,目前的版本C/OS -II V2.842000年,得到美国航空管理局(FAA)的认证,可以用于飞行器中网站,有大量的代码可供参考u公开源代码公开源代码u可移植性(可移植性(PortablePortable) 绝大部分绝大部分 C/OS-IIC/OS-II的源码是用移植性很强的的源码是用移植性很强的ANSI CA
2、NSI C写的。和微写的。和微处理器硬件相关的那部分是用汇编语言写的。汇编语言写的部分已经处理器硬件相关的那部分是用汇编语言写的。汇编语言写的部分已经压到最低限度,使得压到最低限度,使得 C/OS-IIC/OS-II便于移植到其他微处理器上。便于移植到其他微处理器上。 C/OS-C/OS-IIII可以在绝大多数可以在绝大多数8 8位、位、1616位、位、3232位以至位以至6464位微处理器、微控制器位微处理器、微控制器 、数字信号处理器(数字信号处理器(DSPDSP)上运行。上运行。u可固化(可固化(ROMableROMable) C/OS-IIC/OS-II是为嵌入式应用而设计的,这就意味
3、着,只要读者有是为嵌入式应用而设计的,这就意味着,只要读者有固化手段(固化手段(C C编译、连接、下载和固化),编译、连接、下载和固化), C/OS-IIC/OS-II可以嵌入到读者可以嵌入到读者的产品中成为产品的一部分。的产品中成为产品的一部分。u可裁剪(可裁剪(ScalableScalable) 可以只使用可以只使用 C/OS-IIC/OS-II中应用程序需要的那些系统服务。中应用程序需要的那些系统服务。也就是说某产品可以只使用很少几个也就是说某产品可以只使用很少几个 C/OS-IIC/OS-II调用,而另一个调用,而另一个产品则使用了几乎所有产品则使用了几乎所有 C/OS-IIC/OS-
4、II的功能,这样可以减少产品中的功能,这样可以减少产品中的的 C/OS-IIC/OS-II所需的存储器空间(所需的存储器空间(RAMRAM和和ROMROM)。)。这种可剪裁性是这种可剪裁性是靠条件编译实现的。靠条件编译实现的。 C/OSC/OS的性能特点(一)的性能特点(一)u占先式(占先式(PreemptivePreemptive)u多任务多任务 C/OS-IIC/OS-II可以管理可以管理6464个任务,然而,目前这一版本保留个任务,然而,目前这一版本保留8 8个给系统。个给系统。应用程序最多可以有应用程序最多可以有5656个任务个任务. . 在最新版本中,在最新版本中, C/OS-IIC
5、/OS-II可以管理可以管理255255个个任务任务。u可确定性可确定性 全部全部 C/OS-IIC/OS-II的函数调用与服务的执行时间具有可确定性。的函数调用与服务的执行时间具有可确定性。u任务栈任务栈 每个任务有自己单独的栈,每个任务有自己单独的栈, C/OS-IIC/OS-II允许每个任务有不同的允许每个任务有不同的栈空间,以便压低应用程序对栈空间,以便压低应用程序对RAMRAM的需求。的需求。u系统服务系统服务 C/OS-IIC/OS-II提供很多系统服务,例如邮箱、消息队列、信号量、提供很多系统服务,例如邮箱、消息队列、信号量、块大小固定的内存的申请与释放、时间相关函数等。块大小固
6、定的内存的申请与释放、时间相关函数等。u中断管理中断管理 中断可以使正在执行的任务暂时挂起,如果优先级更高的任务中断可以使正在执行的任务暂时挂起,如果优先级更高的任务被该中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,被该中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,中断嵌套层数可达中断嵌套层数可达255255层。层。u稳定性与可靠性稳定性与可靠性 C/OSC/OS的性能特点(二)的性能特点(二)C/OS-II图书描述了描述了C/OS-IIC/OS-II内部的工作原理内部的工作原理随书的随书的CDCD中包含了源代码中包含了源代码n工业界最清晰的源代码工业界最清晰的源代码除英文
7、版外,有中文和韩文版除英文版外,有中文和韩文版ChineseKoreanEnglishISBN 1-57820-103-9美国CMP BOOK ISBN 7-81077-290-2北京航空航天大学出版社ISBN 89-951540-5-5安装安装 C/OS-II这些例子用这些例子用BorlandC/C+编译器编译器(V4.51)编译过,用选择项产生)编译过,用选择项产生Intel/AMD80186处理器(大模式下编译)处理器(大模式下编译)的代码。的代码。安装步骤:安装步骤:1.双击双击ucos252.exe,然后点击,然后点击unzip范例1范例范例1演示了演示了C/OS-II的多任务处理能
8、力。的多任务处理能力。它包含了它包含了13个任务,个任务,11个任务在屏幕随机个任务在屏幕随机的位置上显示一个的位置上显示一个09的数字和的数字和2个系统内个系统内部任务空闲任务和部任务空闲任务和CPU利用率统计任务。利用率统计任务。运行安装目录下的运行安装目录下的test,即可看到运行结果。,即可看到运行结果。1.01 INCLUDES.H 用户将注意到本书中所有的用户将注意到本书中所有的*.C文件都包括了以下定义:文件都包括了以下定义:#includeincludes.hINCLUDE.H可以使用户不必在工程项目中每个可以使用户不必在工程项目中每个*.C文件中文件中都考虑需要什么样的头文件
9、。换句话说,都考虑需要什么样的头文件。换句话说,INCLUDE.H是是主头文件。这样做唯一的缺点是主头文件。这样做唯一的缺点是INCLUDES.H中许多头文中许多头文件在一些件在一些*.C文件的编译中是不需要的。这意味着逐个编文件的编译中是不需要的。这意味着逐个编译这些文件要花费额外的时间。这虽有些不便,但代码的译这些文件要花费额外的时间。这虽有些不便,但代码的可移植性却增加了。本书中所有的例子使用一个共同的头可移植性却增加了。本书中所有的例子使用一个共同的头文件文件INCLUDES.H,3个副本分别存放在个副本分别存放在SOFTWAREuCOS-IIEX1_x86L,SOFTWAREuCOS
10、-IIEX2_x86L,以及,以及SOFTWAREuCOS-IIEX3_x86L中。当然可以重新编辑中。当然可以重新编辑INCLUDES.H以添加用户自己的头文件。以添加用户自己的头文件。Test.c代码分析#include includes.h #define TASK_STK_SIZE 512 #define N_TASKS 10 OS_STK TaskStkN_TASKSTASK_STK_SIZE; OS_STK TaskStartStkTASK_STK_SIZE;char TaskDataN_TASKS; OS_EVENT *RandomSem;void main (void) PC_
11、DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); OSInit(); /* Initialize uC/OS-II */ PC_DOSSaveReturn(); /*Save environment for DOS*/ PC_VectSet(uCOS, OSCtxSw); RandomSem = OSSemCreate(1); OSTaskCreate(TaskStart, (void *)0, &TaskStartStkTASK_STK_SIZE - 1, 0); OSStart(); /*Start multitasking */指向任务运行代码
12、的指针指向任务运行代码的指针指向任务初始化数据的指针指向任务初始化数据的指针任务堆栈的栈顶任务堆栈的栈顶TOS任务优先级任务优先级1.07.02TaskStart()void TaskStart (void *pdata)#if OS_CRITICAL_METHOD = 3/*Allocate storage for CPU status register*/ OS_CPU_SR cpu_sr;#endif char s100; INT16S key; pdata = pdata; /* Prevent compiler warning */ TaskStartDispInit(); /* I
13、nitialize the display */ OS_ENTER_CRITICAL(); PC_VectSet(0x08, OSTickISR);/*Install uC/OS-IIs clock tick ISR*/ PC_SetTickRate(OS_TICKS_PER_SEC); /* Reprogram tick rate */ OS_EXIT_CRITICAL(); OSStatInit(); /* Initialize uC/OS-IIs statistics */续TaskStartCreateTasks(); /*/*调用创建的任务函数调用创建的任务函数* */ / for
14、(;) TaskStartDisp(); /* Update the display */ if (PC_GetKey(&key) = TRUE) /* See if key has been pressed */ if (key = 0x1B) /* Yes, see if its the ESCAPE key*/ PC_DOSReturn(); /* Return to DOS */ OSCtxSwCtr = 0; /* Clear context switch counter */ OSTimeDlyHMSM(0, 0, 1, 0); /* Wait one second */ Task
15、StartCreateTasksTaskStartCreateTasks()()static void TaskStartCreateTasks (void) INT8U i; for (i = 0; i N_TASKS; i+) /* Create N_TASKS identical tasks */ TaskDatai = 0 + i; /* Each task will display its own letter*/ OSTaskCreate(Task, (void*)&TaskDatai, &TaskStkiTASK_STK_SIZE - 1, i + 1); 10TaskTaskv
16、oid Task (void *pdata) INT8U x,y,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 semap
17、hore */ /* 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 */ 作业:作业:哲学家就餐问题的哲学家就餐问题的C/OS-II实现实现掌握在基于嵌入式实时操作系统掌握在基于嵌入式实时操作系统C/OS-II的应用中任务的应用中任务使用信号量的一般原理,了解如何利用信号量来对共使用信号量的一般原理,了解如何利用信号量来对共享资源进
18、行互斥访问。享资源进行互斥访问。五个哲学家任务(五个哲学家任务(ph1、ph2、ph3、ph4、ph5)主要)主要有两种过程:思考(即睡眠一段时间)和就餐。每个有两种过程:思考(即睡眠一段时间)和就餐。每个哲学家任务在就餐前必须申请并获得一左一右两支筷哲学家任务在就餐前必须申请并获得一左一右两支筷子,就餐完毕后释放这两支筷子。五个哲学家围成一子,就餐完毕后释放这两支筷子。五个哲学家围成一圈,每两人之间有一支筷子。一共有五支筷子,在该圈,每两人之间有一支筷子。一共有五支筷子,在该作业中用了五个互斥信号量来代表。如下图所示作业中用了五个互斥信号量来代表。如下图所示作业要求作业要求1、使用假想函数、
19、使用假想函数eat()表示就餐表示就餐;例如:例如:#defineeat()printf(“eating”)2、假设可以使用、假设可以使用printf()函数打印出哲学函数打印出哲学家的动作信息(如:家的动作信息(如:sleep,eatetc.)。)。也可以使用示例代码中的也可以使用示例代码中的PC_DispStr()函函数来打印信息。数来打印信息。3、此作业作为平时成绩,根据作业的完成、此作业作为平时成绩,根据作业的完成情况分别给情况分别给010分。分。3、五一节后上课之前交给可代表,迟交者、五一节后上课之前交给可代表,迟交者根据迟交时间的长短扣相应的平时分根据迟交时间的长短扣相应的平时分范
20、例范例2范例范例2演示了演示了C/OS-II的堆栈检查功能,每的堆栈检查功能,每个任务的已用空间和剩余的堆栈空间都可个任务的已用空间和剩余的堆栈空间都可以显示出来。同时范例以显示出来。同时范例2还显示堆栈检查函还显示堆栈检查函数数OSTaskStkChk()的运行时间。该范例表的运行时间。该范例表明,如果一个堆栈使用量很大,堆栈检查明,如果一个堆栈使用量很大,堆栈检查的时间就比较短。的时间就比较短。#include includes.h #define TASK_STK_SIZE 512 /* Size of each tasks stacks(# of WORDs) */#define TA
21、SK_START_ID 0 /* tasks IDs */#define TASK_CLK_ID 1#define TASK_1_ID 2#define TASK_2_ID 3#define TASK_3_ID 4#define TASK_4_ID 5#define TASK_5_ID 6#define TASK_START_PRIO 10 /* tasks priorities */#define TASK_CLK_PRIO 11#define TASK_1_PRIO 12#define TASK_2_PRIO 13#define TASK_3_PRIO 14#define TASK_4_P
22、RIO 15#define TASK_5_PRIO 16OS_STK TaskStartStkTASK_STK_SIZE; /* Startup task stack*/OS_STK TaskClkStkTASK_STK_SIZE; /* Clock task stack*/OS_STK Task1StkTASK_STK_SIZE; /* Task #1 task stack*/OS_STK Task2StkTASK_STK_SIZE; /* Task #2 task stack*/OS_STK Task3StkTASK_STK_SIZE; /* Task #3 task stack*/OS_
23、STK Task4StkTASK_STK_SIZE; /* Task #4 task stack*/OS_STK Task5StkTASK_STK_SIZE; /* Task #5 task stack */OS_EVENT *AckMbox; /*Message mailboxes for Tasks #4 and #5*/OS_EVENT *TxMbox; MAINvoid main (void) OS_STK *ptos; OS_STK *pbos; INT32U size; PC_DispClrScr(DISP_FGND_WHITE);/*Clear the screen*/ OSIn
24、it(); /* Initialize uC/OS-II */ PC_DOSSaveReturn(); /* Save environment to return to DOS */ PC_VectSet(uCOS, OSCtxSw); /* Install uC/OS-IIs context switch vector */ PC_ElapsedInit(); /*Initialized elapsed time easurement*/ ptos = &TaskStartStkTASK_STK_SIZE - 1; pbos = &TaskStartStk0; size = TASK_STK
25、_SIZE; OSTaskStkInit_FPE_x86(&ptos, &pbos, &size);OSTaskCreateExt(TaskStart, (void *)0, ptos, TASK_START_PRIO, TASK_START_ID, pbos, size, (void *)0, OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); OSStart(); /* Start multitasking */允许堆栈检查允许堆栈检查在建立任务时将堆栈清零在建立任务时将堆栈清零指向指向TCB的指针的指针(TaskControlBlock)任务的任务的I
26、D号,当前版本中没号,当前版本中没用到,用于以后的扩展用到,用于以后的扩展TaskStart()void TaskStart (void *pdata)#if OS_CRITICAL_METHOD = 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr;#endif INT16S key; pdata = pdata; /* Prevent compiler warning */ TaskStartDispInit(); /* Setup the display */ OS_ENTER_CRITICAL(); /*
27、 Install uC/OS-IIs clock tick ISR */ PC_VectSet(0x08, OSTickISR); PC_SetTickRate(OS_TICKS_PER_SEC); /* Reprogram tick rate*/ OS_EXIT_CRITICAL(); OSStatInit(); /* Initialize uC/OS-IIs statistics */ AckMbox = OSMboxCreate(void *)0); /*Create 2 message mailboxes*/ TxMbox = OSMboxCreate(void *)0);续 Task
28、StartCreateTasks(); /* Create all other tasks*/ for (;) TaskStartDisp(); /* Update the display */ if (PC_GetKey(&key) /* See if key has been pressed */ if (key = 0x1B) /* Yes, see if its the ESCAPE key*/ PC_DOSReturn(); /* Yes, return to DOS*/ OSCtxSwCtr = 0; /* Clear context switch counter*/ OSTime
29、Dly(OS_TICKS_PER_SEC);/* Wait one second*/ TaskStartCreateTasks()static void TaskStartCreateTasks (void) OSTaskCreateExt(TaskClk, (void *)0, &TaskClkStkTASK_STK_SIZE - 1, TASK_CLK_PRIO, TASK_CLK_ID, &TaskClkStk0, TASK_STK_SIZE, (void *)0, OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); OSTaskCreateExt(T
30、ask1, (void *)0, &Task1StkTASK_STK_SIZE - 1, TASK_1_PRIO, TASK_1_ID, &Task1Stk0, TASK_STK_SIZE, (void *)0, OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); OSTaskCreateExt(Task2, (void *)0, &Task2StkTASK_STK_SIZE - 1, TASK_2_PRIO, TASK_2_ID, &Task2Stk0, TASK_STK_SIZE, (void *)0, OS_TASK_OPT_STK_CHK | OS_
31、TASK_OPT_STK_CLR);OSTaskCreateExt(Task3, (void *)0, &Task3StkTASK_STK_SIZE - 1, TASK_3_PRIO, TASK_3_ID, &Task3Stk0, TASK_STK_SIZE, (void *)0, OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);OSTaskCreateExt(Task4, (void *)0, &Task4StkTASK_STK_SIZE-1, TASK_4_PRIO, TASK_4_ID, &Task4Stk0, TASK_STK_SIZE, (voi
32、d *)0, OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);OSTaskCreateExt(Task5, (void *)0, &Task5StkTASK_STK_SIZE-1, TASK_5_PRIO, TASK_5_ID, &Task5Stk0, TASK_STK_SIZE, (void *)0, OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);Task1()void Task1 (void *pdata) INT8U err; OS_STK_DATA data; /* Storage for task stac
33、k data */ INT16U time; /* Execution time (in uS) */ INT8U i; char s80; pdata = pdata; for (;) for (i = 0; i 7; i+) PC_ElapsedStart(); err = OSTaskStkChk(TASK_START_PRIO + i, &data); time = PC_ElapsedStop(); if (err = OS_NO_ERR) sprintf(s, %4ld %4ld %4ld %6d, data.OSFree + data.OSUsed, data.OSFree, d
34、ata.OSUsed, time); PC_DispStr(19, 12 + i, s, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY); OSTimeDlyHMSM(0, 0, 0, 100); /* Delay for 100 mS*/ TASK #2Description: This task displays a clockwise rotating wheel on the screen.void Task2 (void *data) data = data; for (;) PC_DispChar(70, 15, |, DISP_FGND_YELLO
35、W + DISP_BGND_BLUE); OSTimeDly(10); PC_DispChar(70, 15, /, DISP_FGND_YELLOW + DISP_BGND_BLUE); OSTimeDly(10); PC_DispChar(70, 15, -, DISP_FGND_YELLOW + DISP_BGND_BLUE); OSTimeDly(10); PC_DispChar(70, 15, , DISP_FGND_YELLOW + DISP_BGND_BLUE); OSTimeDly(10); TASK #3Description: This task displays a co
36、unter-clockwise rotating wheel on the screen.void Task3 (void *data) char dummy500; INT16U i; data = data; for (i = 0; i 499; i+) /* Use up the stack with junk */ dummyi = ?; for (;) PC_DispChar(70, 16, |, DISP_FGND_YELLOW + DISP_BGND_BLUE); OSTimeDly(20); PC_DispChar(70, 16, , DISP_FGND_YELLOW + DI
37、SP_BGND_BLUE); OSTimeDly(20); PC_DispChar(70, 16, -, DISP_FGND_YELLOW + DISP_BGND_BLUE); OSTimeDly(20); PC_DispChar(70, 16, /, DISP_FGND_YELLOW + DISP_BGND_BLUE); OSTimeDly(20); TASK #4 Description: This task sends a message to Task #5. The message consist of a character that needs to be displayed b
38、y Task #5. This task then waits for an acknowledgement from Task #5 indicating that the message has been displayed.void Task4 (void *data) char txmsg; INT8U err; data = data; txmsg = A; for (;) OSMboxPost(TxMbox, (void *)&txmsg); /* Send message to Task #5*/ OSMboxPend(AckMbox, 0, &err); /* Wait for
39、 acknowledgement fromTask #5 */ txmsg+; /* Next message to send */ if (txmsg = Z) txmsg = A; /* Start new series of messages */ TASK #5Description: This task displays messages sent by Task #4. When the message is displayed, Task #5 acknowledges Task #4.void Task5 (void *data) char *rxmsg; INT8U err;
40、 data = data; for (;) rxmsg = (char *)OSMboxPend(TxMbox, 0, &err); /* Wait for message from Task #4 */ PC_DispChar(70, 18, *rxmsg, DISP_FGND_YELLOW + DISP_BGND_BLUE); OSTimeDlyHMSM(0, 0, 1, 0); /* Wait 1 second */ OSMboxPost(AckMbox, (void *)1); /* Acknowledge reception of msg */ CLOCK TASKvoid Task
41、Clk (void *data) char s40; data = data; for (;) PC_GetDateTime(s); PC_DispStr(60, 23, s, DISP_FGND_YELLOW + DISP_BGND_BLUE); OSTimeDly(OS_TICKS_PER_SEC); 范例3 Test3.c范例范例3使用了许多使用了许多C/OS-II提供的附加功能。使用提供的附加功能。使用了了OSTaskCreateExt()中中TCB的扩展数据结构,的扩展数据结构,用户定义的对外接口函数用户定义的对外接口函数OSTaskCreateSwHook()、统计任务的对外接口函
42、数、统计任务的对外接口函数OSTaskStatHook()以及消息队列以及消息队列这个范例里可以看到如何确定每个任务的运行次这个范例里可以看到如何确定每个任务的运行次数及每个任务的运行时间。任务的执行时间可以数及每个任务的运行时间。任务的执行时间可以用来确定每个任务的用来确定每个任务的CPU使用率。使用率。CONSTANTS#include includes.h#define TASK_STK_SIZE 512#define TASK_START_ID 0 #define TASK_CLK_ID 1#define TASK_1_ID 2#define TASK_2_ID 3#define TA
43、SK_3_ID 4#define TASK_4_ID 5#define TASK_5_ID 6#define TASK_START_PRIO 10#define TASK_CLK_PRIO 11#define TASK_1_PRIO 12#define TASK_2_PRIO 13#define TASK_3_PRIO 14#define TASK_4_PRIO 15#define TASK_5_PRIO 16#define MSG_QUEUE_SIZE 20 DATA TYPEStypedef struct char TaskName30; INT16U TaskCtr; INT16U Ta
44、skExecTime; INT32U TaskTotExecTime; TASK_USER_DATA;VARIABLESOS_STK TaskStartStkTASK_STK_SIZE; /* Startup task stack */OS_STK TaskClkStkTASK_STK_SIZE; /* Clock task stack */OS_STK Task1StkTASK_STK_SIZE; /* Task #1 task stack */OS_STK Task2StkTASK_STK_SIZE; /* Task #2 task stack */OS_STK Task3StkTASK_
45、STK_SIZE; /* Task #3 task stack */OS_STK Task4StkTASK_STK_SIZE; /* Task #4 task stack */OS_STK Task5StkTASK_STK_SIZE; /* Task #5 task stack */TASK_USER_DATA TaskUserData7;OS_EVENT *MsgQueue; /* Message queue pointer*/void *MsgQueueTbl20; /* Storage for messages */Main()void main (void) PC_DispClrScr
46、(DISP_BGND_BLACK); /* Clear the screen */ OSInit(); /* Initialize uC/OS-II */ PC_DOSSaveReturn(); /* Save environment to return to DOS */ PC_VectSet(uCOS, OSCtxSw); /* Install uC/OS-IIs context switch vector */ PC_ElapsedInit(); /* Initialized elapsed time measurement */ strcpy(TaskUserDataTASK_STAR
47、T_ID.TaskName, StartTask); OSTaskCreateExt(TaskStart, (void *)0, &TaskStartStkTASK_STK_SIZE - 1, TASK_START_PRIO, TASK_START_ID, &TaskStartStk0, TASK_STK_SIZE, &TaskUserDataTASK_START_ID, 0); OSStart(); /* Start multitasking*/TaskStart void TaskStart (void *pdata)#if OS_CRITICAL_METHOD = 3 /* Alloca
48、te storage for CPU status register */ OS_CPU_SR cpu_sr;#endif INT16S key; pdata = pdata; /* Prevent compiler warning */ TaskStartDispInit(); /* Setup the display*/ OS_ENTER_CRITICAL(); /* Install uC/OS-IIs clock tick ISR */ PC_VectSet(0x08, OSTickISR); PC_SetTickRate(OS_TICKS_PER_SEC); /* Reprogram
49、tick rate */ OS_EXIT_CRITICAL(); OSStatInit(); /* Initialize uC/OS-IIs statistics */ MsgQueue = OSQCreate(&MsgQueueTbl0, MSG_QUEUE_SIZE); /* Create a message queue*/ TaskStartCreateTasks(); for (;) TaskStartDisp(); /* Update the display */ if (PC_GetKey(&key) /* See if key has been pressed */ if (ke
50、y = 0x1B) /* Yes, see if its the ESCAPE key */ PC_DOSReturn(); /* Yes, return to DOS */ OSCtxSwCtr = 0; /* Clear the context switch counter */ OSTimeDly(OS_TICKS_PER_SEC); /* Wait one second */ TaskStartCreateTasks (void)void TaskStartCreateTasks (void) strcpy(TaskUserDataTASK_CLK_ID.TaskName, Clock
51、 Task); OSTaskCreateExt(TaskClk, (void *)0, &TaskClkStkTASK_STK_SIZE - 1, TASK_CLK_PRIO, TASK_CLK_ID, &TaskClkStk0, TASK_STK_SIZE, &TaskUserDataTASK_CLK_ID, 0); strcpy(TaskUserDataTASK_1_ID.TaskName, MsgQ Rx Task); OSTaskCreateExt(Task1, (void *)0, &Task1StkTASK_STK_SIZE - 1, TASK_1_PRIO, TASK_1_ID,
52、 &Task1Stk0, TASK_STK_SIZE, &TaskUserDataTASK_1_ID, 0); strcpy(TaskUserDataTASK_2_ID.TaskName, MsgQ Tx Task #2); OSTaskCreateExt(Task2, (void *)0, &Task2StkTASK_STK_SIZE - 1, TASK_2_PRIO, TASK_2_ID, &Task2Stk0, TASK_STK_SIZE, &TaskUserDataTASK_2_ID, 0); strcpy(TaskUserDataTASK_3_ID.TaskName, MsgQ Tx
53、 Task #3); OSTaskCreateExt(Task3, (void *)0, &Task3StkTASK_STK_SIZE - 1, TASK_3_PRIO, TASK_3_ID, &Task3Stk0, TASK_STK_SIZE, &TaskUserDataTASK_3_ID, 0); strcpy(TaskUserDataTASK_4_ID.TaskName, MsgQ Tx Task #4); OSTaskCreateExt(Task4, (void *)0, &Task4StkTASK_STK_SIZE - 1, TASK_4_PRIO, TASK_4_ID, &Task
54、4Stk0, TASK_STK_SIZE, &TaskUserDataTASK_4_ID, 0); strcpy(TaskUserDataTASK_5_ID.TaskName, TimeDlyTask); OSTaskCreateExt(Task5, (void *)0, &Task5StkTASK_STK_SIZE - 1, TASK_5_PRIO, TASK_5_ID, &Task5Stk0, TASK_STK_SIZE, &TaskUserDataTASK_5_ID, 0);Task1 void Task1 (void *pdata) char *msg; INT8U err; pdat
55、a = pdata; for (;) msg = (char *)OSQPend(MsgQueue, 0, &err); PC_DispStr(70, 13, msg, DISP_FGND_YELLOW + DISP_BGND_BLUE); OSTimeDlyHMSM(0, 0, 0, 100); Task2void Task2 (void *pdata) char msg20; pdata = pdata; strcpy(&msg0, Task 2); for (;) OSQPost(MsgQueue, (void *)&msg0); OSTimeDlyHMSM(0, 0, 0, 500);
56、 void Task3 (void *pdata) char msg20; pdata = pdata; strcpy(&msg0, Task 3); for (;) OSQPost(MsgQueue, (void *)&msg0); OSTimeDlyHMSM(0, 0, 0, 500); void Task4 (void *pdata) char msg20; pdata = pdata; strcpy(&msg0, Task 4); for (;) OSQPost(MsgQueue, (void *)&msg0); OSTimeDlyHMSM(0, 0, 0, 500); void Ta
57、sk5 (void *pdata) pdata = pdata; for (;) OSTimeDlyHMSM(0, 0, 0, 100); TaskClk任务用来显示时间void TaskClk (void *pdata) char s40; pdata = pdata; for (;) PC_GetDateTime(s); PC_DispStr(60, 23, s, DISP_FGND_YELLOW + DISP_BGND_BLUE); OSTimeDlyHMSM(0, 0, 0, 500); /*修改演示*/钩子钩子函数函数介绍介绍voidOSInitHookBegin(void)void
58、OSInitHookEnd(void)voidOSTaskCreateHook(OS_TCB*ptcb)voidOSTaskDelHook(OS_TCB*ptcb)voidOSTaskIdleHook(void)voidOSTaskStatHook(void)voidOSTaskSwHook(void)voidOSTCBInitHook(OS_TCB*ptcb)voidOSTimeTickHook(void) STATISTIC TASK HOOKvoid OSTaskStatHook (void) char s80; INT8U i; INT32U total; INT8U pct; tot
59、al = 0L; /* Totalize TOT. EXEC. TIME for each task */ for (i = 0; i 0) for (i = 0; i 1000000000L) /* Reset total time counters at 1 billion*/ for (i = 0; i OSTCBExtPtr; /* Point to used data*/ if (puser != (TASK_USER_DATA *)0) puser-TaskCtr+; /* Increment task counter */ puser-TaskExecTime = time; /
60、* Update the tasks execution time */ puser-TaskTotExecTime += time; /* Update the tasks total execution time */ 范例4本例中建立了10个基本的任务,每个任务运行200次/秒。每个任务计算一个角度的正弦和余弦值,每个任务计算的角度相差36度,每次执行任务时,这个角度都增加0.01度。本范例没有涉及很多新概念,有很少内容需要解释。着重演示了C/OS-II在浮点处理器上的运行情况。TaskStartCreateTasks ()static void TaskStartCreateTasks (void) INT8U i; INT8U prio; for (i = 0; i = (FP32)360.0) angle = (FP32)0.0; else angle += (FP32)0.01; OSTimeDly(1);