ucOS-II范例分析_01汇总课件

上传人:hknru****knru 文档编号:241299332 上传时间:2024-06-16 格式:PPT 页数:98 大小:660.08KB
返回 下载 相关 举报
ucOS-II范例分析_01汇总课件_第1页
第1页 / 共98页
ucOS-II范例分析_01汇总课件_第2页
第2页 / 共98页
ucOS-II范例分析_01汇总课件_第3页
第3页 / 共98页
点击查看更多>>
资源描述
嵌入式操作系统ucOS-II分析嵌入式操作系统ucOS-II分析1ucOS-II应用程序基本结构voidtask(void*pdata)INT8Uerr;InitTimer();/可选For(;)/你的应用程序代码.OSTimeDly(1);/可选ucOS-II应用程序基本结构voidtask(voi2一些重要的ucOS-IIAPI)任务类)消息类)同步类)时间类)临界区与事件类任务类和时间类是必须要首先掌握的两种类型的API一些重要的ucOS-IIAPI)任务类任务类和时间类是必3)OSTaskCreate函数函数n这个函数应该至少在main函数内调用一次,在OSInit函数调用之后调用,以创建一个任务。n系统首先从TCB空闲列表内申请一个空的TCB指针,然后根据用户给出的参数初始化任务堆栈,并在内部的任务就绪表内标记该任务为就绪状态。最后返回,这样一个任务就创建成功了。)OSTaskCreate函数这个函数应该至少在main4)OSTaskSuspend函数函数n将指定的任务挂起。如果挂起的是当前任务,会引发系统执行任务切换先导函数OSShed来进行一次任务切换。n这个函数只有一个优先级参数,在系统内部,优先级除了表示一个任务执行的先后次序外,还起着区分每一个任务的作用,即优先级也是任务的ID。所以uCOS-II不允许出现相同优先级的任务。)OSTaskSuspend函数将指定的任务挂起。如果挂5)OSTaskResume函数函数n将指定的已经挂起的任务恢复成就绪状态。如果恢复任务的优先级高于当前任务,那么还会引发一次任务切换。n参数类似OSTaskSuspend函数,为指定任务的优先级。需要特别说明是,本函数并不要求和OSTaskSuspend函数成对使用。)OSTaskResume函数将指定的已经挂起的任务恢复6)OS_ENTER_CRITICAL宏宏n分析一下OS_CPU.H文件,它涉及特定CPU的实现。一般都被替换为一条或者几条嵌入式汇编代码。其实,它就是关中断。n只要任务不主动放弃CPU使用权,别的任务就没有占用CPU的机会,这个任务就是独占了。进入临界区后,这个应宏尽量少用,它会破坏系统的一些服务,尤其是时间服务。并使系统对外界响应性能降低。)OS_ENTER_CRITICAL宏分析一下OS_CP7)OS_EXIT_CRITICAL宏宏n与OS_ENTER_CRITICAL配套使用的一个宏,在系统手册说明里它是退出临界区,其实就是重新开中断。n它必须和OS_ENTER_CRITICAL成对出现,否则会带来意想不到的后果,如系统会崩溃。我们应尽量少用这两个宏调用,因为他们的确会破坏系统的多任务性能。)OS_EXIT_CRITICAL宏与OS_ENTER_8)OSTimeDly函数函数n这是调用最多的一个函数,它的功能是先挂起当前任务,然后进行任务切换,在指定的时间到来之后,将当前任务恢复为就绪状态,但是并不一定运行,如果恢复后是优先级最高的就绪任务话,那么就运行之。n可以将任务延时一定时间后再执行它,依靠时钟机制进行任务切换,暂时放弃CPU的使用权,但多任务性能会降低。)OSTimeDly函数这是调用最多的一个函数,它的功能9ucOS-II范例的源码分析ucOS-II范例的源码分析10INCLUDES.HnucOS-II中所有的*.C文件都包括了以下定义:#includeincludes.h“n唯一的缺点是INCLUDES.H中许多头文件在一些*.C文件的编译中是不需要的。虽然逐个编译这些文件要花费额外的时间,但代码的可移植性却增加了。INCLUDES.HucOS-II中所有的*.C文件都11不依赖于编译的数据类型可移植型数据类型的程序可移植型数据类型的程序TypedefunsignedcharBOOLEAN;TypedefunsignedcharINT8U;TypedefsignedcharINT8S;TypedefunsignedintINT16U;TypedefsignedintINT16S;TypedefunsignedlongINT32U;TypedefsignedlongINT32S;TypedeffloatFP32;TypedefdoubleFP64;#defineBYTEINT8S-|#defineUBYTEINT8U-|#defineWORDINT16S-|ucos-ucosII#defineUWORDINT16U-|#defineLONGINT32S-|#defineULONGINT32U-|不依赖于编译的数据类型可移植型数据类型的程序12全局变量n定义全局宏的程序定义全局宏的程序#ifdefxxx_GLOBALS#definexxx_EXT#else#definexxx_EXTextern#endif.H文件中每个全局变量都加上了xxx_EXT的前缀。xxx代表模块的名字。该模块的.C文件中有以下定义:#definexxx_GLOBALS#includeincludes.h全局变量定义全局宏的程序13uCOS_II.H中有以下定义:n#ifdefOS_GLOBALSn#defineOS_EXTn#elsen#defineOS_EXTexternn#endifnOS_EXTINT32UOSIdleCtr;nOS_EXTINT32UOSIdleCtrRun;nOS_EXTINT32UOSIdleCtrMax;uCOS_II.H中有以下定义:#ifdefOS_G14uCOS_II.C中有以下定义:n#defineOS_GLOBALSn#include“includes.h”当编译器处理uCOS_II.C时,它使uCOS_II.H变成如下所示,因为OS_EXT被设置为空。编译器就会将这些全局变量分配到内存中。nINT32UOSIdleCtr;nINT32UOSIdleCtrRun;nINT32UOSIdleCtrMax;uCOS_II.C中有以下定义:#defineOS_G15当编译器处理其他.C文件时,头文件变成了如下的样子,因为OS_GLOBAL没有定义,所以OS_EXT被定义为extern。nexternINT32UOSIdleCtr;nexternINT32UOSIdleCtrRun;nexternINT32UOSIdleCtrMax;在这种情况下,不产生内存分配,而任何.C文件都可以使用这些变量。这样的就只需在.H文件中定义一次就可以了。当编译器处理其他.C文件时,头文件变成了如下的样子,因为OS16OS_ENTER_CRITICAL()和和 OS_EXIT_CRITICAL()nOS_ENTER_CRITICAL()关中断;OS_EXIT_CRITICAL()开中断。n是为了保护临界段代码,这些代码与处理器有关。宏的定义在OS_CPU.H中。n关中断会影响中断延迟,所以要特别小心。用户还可以用信号量来保护临界段代码。OS_ENTER_CRITICAL()和OS_EXIT17基于PC的服务nPC.C文件和PC.H文件是范例中使用到的一些基于PC的服务程序。nPC.C包括字符显示,时间度量和其他各种服务。所有的函数都以PC_为前缀。基于PC的服务PC.C文件和PC.H文件是范例中使用18字符显示nPC_DispClrScr()ClearthescreennPC_DispClrLine()Clearasinglerow(orline)nPC_DispChar()DisplayasingleASCIIcharacteranywhereonthescreennPC_DispStr()DisplayanASCIIstringanywhereonthescreen字符显示PC_DispClrScr()Clearth19时间度量n用PC的82C54定时器2测试一个函数的运行花了多少时间。被测的程序代码放在函数PC_ElapsedStart()和PC_ElapsedStop()之间来测量。在用这两个函数之前,应该调用PC_ElapsedInit()来初始化,它主要是计算运行这两个函数本身所附加的的时间。这样,PC_ElapsedStop()函数中返回的数值就是准确的测量结果了。这两个函数都不具备可重入性,不要有多个任务同时调用这两个函数。时间度量用PC的82C54定时器2测试一个函数的运行花了多20测量PC_DisplayChar()的执行时间(us)n测量代码执行时间的程序测量代码执行时间的程序INT16Utime;PC_ElapsedInit();.PC_ElapsedStart();PC_DispChar(40,24,A,DISP_FGND_WHITE);time=PC_ElapsedStop();测量PC_DisplayChar()的执行时间(us)测量代21应用应用 C/OS-II 的范例的范例n用BCIDE(IntegratedDevelopmentEnvironment)编译通过,在WindowsXP的DOS窗口下编译运行。可执行代码在每个范例的OBJ子目录中。应用C/OS-II的范例用BCIDE(Integ22IDE中编译选项中编译选项nCode generationModel:LargeOptions:TreatenumsasintsAssumeSSEqualsDS:DefaultformemorymodelnAdvanced code generationFloatingpoint:EmulationInstructionset:80186Options:GenerateunderbarsDebuginfoinOBJsFastfloatingpointIDE中编译选项Codegeneration23IDE中编译选项中编译选项nOptimizationsGlobalregisterallocationInvariantcodemotionInductionvariablesLoopoptimizationSuppressredundantloadsCopypropagationDeadcodeeliminationJumpoptimizationIn-lineintrinsicfunctionsIDE中编译选项Optimizations24IDE中编译选项中编译选项nRegister variables AutomaticnCommon subexpressions OptimizegloballynOptimize for SpeedIDE中编译选项Registervariables25例例1n有13个任务(包括C/OS-II的空闲任务和一个计算CPU利用率的任务)。TaskStart()在函数main()中建立,功能是建立其它任务并且在屏幕上显示如下统计信息:n每秒钟任务切换次数;CPU利用百分率;寄存器切换次数;目前日期和时间;C/OS-II的版本号;nTaskStart()还检查是否按下ESC键,以决定是否返回到DOS。n其余10个任务基于相同的代码Task();每个任务在屏幕上随机的位置显示一个0到9的数字。例1有13个任务(包括C/OS-II的空闲任务和一个计26main()nmain()程序从清整个屏幕开始,为的是保证屏幕上不留有以前的DOS下的显示。n用户在使用任何服务之前先调用OSInit()。建立两个任务:空闲任务和统计任务,前者在没有其它任务处于就绪态时运行;后者计算CPU的利用率。main()main()程序从清整个屏幕开始,为的是保证屏27main()程序程序nvoidmain(void)PC_DispClrScr(DISP_FGND_WHITE+DISP_BGND_BLACK);(1)OSInit();(2)PC_DOSSaveReturn();/保存当前DOS环境(3)PC_VectSet(uCOS,OSCtxSw);/设置CPU寄存器切换(4)RandomSem=OSSemCreate(1);/信号量置为1,在某一时刻只有一个任务可以调用随机数产生函数(5)OSTaskCreate(TaskStart,(void*)0,/启动多任务OSStart()之前,用户至少要先建立一个任务如TaskStart()(void*)&TaskStartStkTASK_STK_SIZE-1,0);(6)OSStart();/启动多任务(7)main()程序voidmain(void)28OSInit()初始化【在OS_CORE.C中定义】voidOSInit(void)#ifOS_VERSION=204OSInitHookBegin();/系统初始化开始接口函数#endifOS_InitMisc();/初始化变量OS_InitRdyList();/初始化任务就绪列表OS_InitTCBList();/初始化任务控制块列表OS_InitEventList();/初始化事件控制块列表OSInit()初始化【在OS_CORE.C中定义】voi29OSInit()初始化(续)#if(OS_VERSION=251)&(OS_FLAG_EN0)&(OS_MAX_FLAGS0)OS_FlagInit();/事件标志结构初始化#endif#if(OS_MEM_EN0)&(OS_MAX_MEM_PART0)OS_MemInit();/内存管理初始化#endif#if(OS_Q_EN0)&(OS_MAX_QS0)OS_QInit();/消息队列初始化#endifOS_InitTaskIdle();/创建空闲任务(无条件)#ifOS_TASK_STAT_EN0OS_InitTaskStat();/创建统计任务#endif#ifOS_VERSION=204OSInitHookEnd();/系统初始化结束接口函数#endif#ifOS_VERSION=270&OS_DEBUG_EN0OSDebugInit();#endifOSInit()初始化(续)#if(OS_VERSION30OS_InitMisc()初始化变量nOSIntNesting=0;/清除中断嵌套计数器nOSLockNesting=0;/清除调度锁定计数器nOSTaskCtr=0;/任务数清零nOSRunning=FALSE;/系统多任务没有执行nOSIdleCtr=0L;/清除空闲任务计数器nOSCtxSwCtr=0;/清除程序切换计数器OS_InitMisc()初始化变量OSIntNestin31OS_InitRdyList()初始化任务就绪列表nstaticvoidOS_InitRdyList(void)INT8Ui;INT8U*prdytbl;OSRdyGrp=0 x00;/清除任务就绪表prdytbl=&OSRdyTbl0;/将OSRdyTbl数组全部初始化0for(i=0;iOS_RDY_TBL_SIZE;i+)*prdytbl+=0 x00;/把任务就绪表里面所有的项目全部清零OSPrioCur=0;/当前运行任务的优先级寄存器清零OSPrioHighRdy=0;/将处于就绪状态的最高优先级的任务寄存器清零OSTCBHighRdy=(OS_TCB*)0;/将处于就绪态的最高优先级的任务控制块指针寄存器清零OSTCBCur=(OS_TCB*)0;/将当前运行任务的任务控制块指针寄存器清零OSTCBList=(OS_TCB*)0;/任务控制块列表清零for(i=0;i(OS_LOWEST_PRIO+1);i+)OSTCBPrioTbli=(OS_TCB*)0;/清除优先级列表,这个列表存储各个优先级对应的任务控制块的地址,系统用它来寻找下一个要运行的任务地址OS_InitRdyList()初始化任务就绪列表stat32OS_InitTCBList()初始化任务控制块列表nstaticvoidOS_InitTCBList(void)INT8Ui;OS_TCB*ptcb1;OS_TCB*ptcb2;OS_MemClr(INT8U*)&OSTCBTbl0,sizeof(OSTCBTbl);/清除TCBOS_MemClr(INT8U*)&OSTCBPrioTbl0,sizeof(OSTCBPrioTbl);/清除优先级表ptcb1=&OSTCBTbl0;/任务控制块列表的第一个任务块地址给变量PTCB1ptcb2=&OSTCBTbl1;/任务控制块列表的第二个任务块地址给变量PTCB2for(i=0;iOSTCBNext=ptcb2;#ifOS_TASK_NAME_SIZE1ptcb1-OSTCBTaskName0=?;/*Unknownname*/ptcb1-OSTCBTaskName1=OS_ASCII_NUL;/把前一个任务控制块的下一个任务指针指向下一个任务控制块#endifptcb1+;ptcb2+;ptcb1-OSTCBNext=(OS_TCB*)0;/把最后一个人物控制块的下个指针清零#ifOS_TASK_NAME_SIZE1ptcb1-OSTCBTaskName0=?;/*Unknownname*/ptcb1-OSTCBTaskName1=OS_ASCII_NUL;#endifOSTCBList=(OS_TCB*)0;/TCB列表初始化OSTCBFreeList=&OSTCBTbl0;/把第一个任务控制块的地址送给空闲任务控制块列表OS_InitTCBList()初始化任务控制块列表stat33建立其它任务的任务建立其它任务的任务TaskStart()nvoidTaskStart(void*data)Preventcompilerwarningbyassigningdatatoitself;DisplaybanneridentifyingthisasEXAMPLE#1;(1)/在屏幕顶端显示一个标识,说明这是例1。OS_ENTER_CRITICAL();PC_VectSet(0 x08,OSTickISR);(2)PC_SetTickRate(200);(3)/关中断,以改变中断向量,让其指向C/OS-II的时钟节拍处理,然后,改变时钟节拍为200HzOS_EXIT_CRITICAL();建立其它任务的任务TaskStart()voidTas34建立其它任务的任务建立其它任务的任务TaskStart()(续)(续)InitializethestatistictaskbycallingOSStatInit();(4)Create10identicaltasks;/建立10个同样的任务(5)for(;)Displaythenumberoftaskscreated;Displaythe%ofCPUused;Displaythenumberoftaskswitchesin1second;DisplayuC/OS-IIsversionnumberIf(keywaspressed)if(keypressedwastheESCAPEkey)PC_DOSReturn();Delayfor1Second;建立其它任务的任务TaskStart()(续)Initia35测试CPU速度voidOSStatInit(void)OSTimeDly(2);/延时两个时钟节拍(1)OS_ENTER_CRITICAL();OSIdleCtr=0L;/32位的计数器OSIdleCtr被清0,并产生另一个延时,这个延时使OSStatInit()挂起。(2)OS_EXIT_CRITICAL();/uCOS-II执行一个无限循环的空闲任务,不断的递增OSIdleCtrOSTimeDly(OS_TICKS_PER_SEC);(3)OS_ENTER_CRITICAL();OSIdleCtrMax=OSIdleCtr;(4)OSStatRdy=TRUE;/COS-II将统计CPU的利用率(5)OS_EXIT_CRITICAL();测试CPU速度voidOSStatInit(void)36在屏幕随机位置显示任务号(09)voidTask(void*data)UBYTEx;UBYTEy;UBYTEerr;for(;)OSSemPend(RandomSem,0,&err);/获取信号量RandomSem,同时禁止其他任务运行这段代码(1)x=random(80);/获得一个随机数(2)y=random(16);/获得一个随机数OSSemPost(RandomSem);/计算出x和y坐标并释放信号量(3)PC_DispChar(x,y+5,*(char*)data,DISP_FGND_LIGHT_GRAY);/在计算的坐标处显示其任务号(0-9)(4)OSTimeDly(1);/延时一个时钟节拍,等待进入下一次循环(5)在屏幕随机位置显示任务号(09)voidTask(v37例1的运行结果例1的运行结果38例例2n磁盘文件为SOFTWAREuCOS-IIEX2_x86L,它包含9个任务。加上uCOS-II本身的两个任务:空闲任务(idletask)和统计任务,共11个任务。n由main()中的TaskStart()函数建立任务,功能是建立其他任务并在屏幕上显示如下的统计数据:每秒种任务切换的次数;CPU利用率的百分比;当前日期和时间;uCOS_II的版本号;n使用带扩展功能的任务建立函数OSTaskCreateExt()和uCOS-II的堆栈检查操作(要使用堆栈检查操作必须用OSTaskCreateExt()建立任务)。例2磁盘文件为SOFTWAREuCOS-IIEX2_x39C/OS-IIstackcheckinguCOS-II的堆栈检查功能要求任务建立时堆栈清零。OSTaskCreateExt()可以执行此项操作(设置选项OS_TASK_OPT_STK_CHK和OS_TASK_OPT_STK_CLR打开此项操作)。OSTaskCreateExt()进行堆栈清零操作是一项很费时的工作,取决于堆栈的大小。执行堆栈检查操作的时候,uCOS-II从栈底向栈顶搜索非0元素(参看上图),同时用一个计数器记录0元素的个数。C/OS-IIstackcheckinguCOS-I40main()n例2的main()函数和例1的看起来差不多;n有两点区别:第一,main()函数调用PC_ElapsedInit()来初始化定时器记录OSTaskStkChk()的执行时间。第二,所有的任务都使用OSTaskCreateExt()函数来建立(替代了OSTaskCreate()函数),这使得每一个任务都可进行堆栈检查。main()例2的main()函数和例1的看起来差不多;41例例2中的中的Main()函数()函数nvoidmain(void)PC_DispClrScr(DISP_FGND_WHITE+DISP_BGND_BLACK);OSInit();PC_DOSSaveReturn();PC_VectSet(uCOS,OSCtxSw);PC_ElapsedInit();(1)/对消逝时间的测量进行初始化OSTaskCreateExt(TaskStart,(void*)0,&TaskStartStkTASK_STK_SIZE-1,TASK_START_PRIO,TASK_START_ID,&TaskStartStk0,TASK_STK_SIZE,(void*)0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);(2)OSStart();除了OSTaskCreate()函数的四个参数外,OSTaskCreateExt()还需要五个参数:任务的ID,一个指向任务堆栈栈底的指针,堆栈的大小(以堆栈单元为单位,80X86中为字),一个指向用户定义的TCB扩展数据结构的指针,和一个用于指定对任务操作的变量。例2中的Main()函数voidmain(void)除42TaskStart()nTaskStart()建立两个邮箱,分别提供给任务4和任务5。n接着建立一个专门显示时间和日期的任务,随后又建立5个不同的任务。TaskStart()TaskStart()建立两个邮箱,分43TaskStart()的伪码nvoidTaskStart(void*data)Preventcompilerwarningbyassigningdatatoitself;Displayabannerandnon-changingtext;InstalluC/OS-IIstickhandler;/关中断,PC_VectSet()Changethetickrateto200Hz;/PC_SetTickRate(),开中断Initializethestatisticstask;/OSStatInit()以上几项操作和例1中的相同。TaskStart()的伪码voidTaskStart44TaskStart()的伪码(续)nCreate2mailboxeswhichareusedbyTask#4and#5;(1)n/调用TaskStartCreateTasks(void)nCreateataskthatwilldisplaythedateandtimeonthescreen;(2)nCreate5applicationtasks;nfor(;)Display#tasksrunning;DisplayCPUusagein%;Display#contextswitchesperseconds;Clearthecontextswitchcounter;DisplayuC/OS-IIsversion;If(Keywaspressed)if(KeypressedwastheESCAPEkey)ReturntoDOS;Delayfor1second;TaskStart()的伪码(续)Create2mail45创建2个邮箱n通过调用2个OSMboxCreate(void*)0)函数,创建2个邮箱。n这2个邮箱在任务4与任务5中使用。创建2个邮箱通过调用2个OSMboxCreate(void46TaskStartCreateTasks(void)nstaticvoidTaskStartCreateTasks(void)nnOSTaskCreateExt(TaskClk,(void*)0,n&TaskClkStkTASK_STK_SIZE-1,nTASK_CLK_PRIO,TASK_CLK_ID,&TaskClkStk0,nTASK_STK_SIZE,(void*)0,nOS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);nOSTaskCreateExt(Task1,(void*)0,n&Task1StkTASK_STK_SIZE-1,nTASK_1_PRIO,TASK_1_ID,&Task1Stk0,nTASK_STK_SIZE,(void*)0,nOS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);nnOSTaskCreateExt(Task5,.);nTaskStartCreateTasks(void)stat47时钟显示任务nTaskClk()函数用于显示当前日期和时间,每秒更新一次。时钟显示任务TaskClk()函数用于显示当前日期和时间,每48时钟显示任务程序nvoidTaskClk(void*data)Structtimenow;Structdatetoday;chars40;data=data;for(;)PC_GetDateTime(s);PC_DispStr(0,24,s,DISP_FGND_BLUE+DISP_BGND_CYAN);OSTimeDly(OS_TICKS_PER_SEC);时钟显示任务程序voidTaskClk(void*49任务1n任务1将检查其他七个任务堆栈的大小,同时记录OSTackStkChk()函数的执行时间,并与堆栈大小(所有堆栈的大小都是以字节为单位)一起显示出来。任务1每秒执行10次(间隔100ms)。任务1任务1将检查其他七个任务堆栈的大小,同时记录OSTac50任务1程序nvoidTask1(void*pdata)INT8Uerr;OS_STK_DATAdata;/任务堆栈数据INT16Utime;/执行时间(us)INT8Ui;chars80;pdata=pdata;任务1程序voidTask1(void*pdata51任务1程序(续)for(;)for(i=0;i7;i+)PC_ElapsedStart();(1)err=OSTaskStkChk(TASK_START_PRIO+i,&data);time=PC_ElapsedStop();(2)if(err=OS_NO_ERR)sprintf(s,%3ld%3ld%3ld%5d,data.OSFree+data.OSUsed,data.OSFree,data.OSUsed,time);PC_DispStr(19,12+i,s,DISP_FGND_YELLOW);OSTimeDlyHMSM(0,0,0,100);(3)/延时100ms任务1程序(续)for(;)52任务2n任务2在屏幕上显示一个顺时针旋转的指针(用横线,斜线等字符表示),每200ms旋转一格。任务2任务2在屏幕上显示一个顺时针旋转的指针(用横线,斜线53任务2程序nvoidTask2(void*data)data=data;for(;)PC_DispChar(70,15,|,DISP_FGND_WHITE+DISP_BGND_RED);OSTimeDly(10);PC_DispChar(70,15,/,DISP_FGND_WHITE+DISP_BGND_RED);任务2程序voidTask2(void*data)54任务2程序(续)OSTimeDly(10);PC_DispChar(70,15,-,DISP_FGND_WHITE+DISP_BGND_RED);OSTimeDly(10);PC_DispChar(70,15,DISP_FGND_WHITE+DISP_BGND_RED);OSTimeDly(10);任务2程序(续)OSTimeDly(10);55任务3n任务3也显示了一个旋转指针,但是与任务2旋转的方向不同。任务3在堆栈中分配了一个很大的数组,将堆栈填充掉,使得OSTaskStkChk()只需花费很少的时间来确定堆栈的利用率,尤其是当堆栈已经快满的时候。任务3任务3也显示了一个旋转指针,但是与任务2旋转的方向不56任务3程序nvoidTask3(void*data)chardummy500;INT16Ui;data=data;for(I=0;i499;i+)dummyi=?;任务3程序voidTask3(void*data)57任务3程序(续)for(;)PC_DispChar(70,16,|,DISP_FGND_WHITE+DISP_BGND_BLUE);OSTimeDly(20);PC_DispChar(70,16,DISP_FGND_WHITE+DISP_BGND_BLUE);OSTimeDly(20);PC_DispChar(70,16,-,DISP_FGND_WHITE+DISP_BGND_BLUE);OSTimeDly(20);PC_DispChar(70,16,/,DISP_FGND_WHITE+DISP_BGND_BLUE);OSTimeDly(20);任务3程序(续)for(;)PC_DispC58任务4n任务4向任务5发送消息并等待确认。发送的消息是一个指向字符的指针。每当任务4从任务5收到确认,就将传递的ASCII码加1再发送,结果是不断的传送“ABCDEFG.”。任务4任务4向任务5发送消息并等待确认。发送的消息是一个指59任务4程序nvoidTask4(void*data)chartxmsg;INT8Uerr;data=data;txmsg=A;任务4程序voidTask4(void*data)60任务4程序(续)for(;)while(txmsgOSTCBExtPtr;(3)if(puser!=(void*)0)(4)/如果任务分配了TCB扩展数据结构puser-TaskCtr+;(5)/计数器TaskCtr进行累加以统计任务被切换的频繁程度,或检查某个任务是否在运行。puser-TaskExecTime=time;(6)/记录函数从切入到切出的运行时间puser-TaskTotExecTime+=time;(7)/记录任务总的运行时间用户定义的OSTaskSwHook()voidOSTas87OSTaskStatHook()函数n本例的统计任务(statistictask)通过OS_TaskStat()调用对外接口函数OSTaskStatHook()(设置OS_CFG.H文件中的OS_TASK_STAT_EN为1,允许对外接口函数),统计任务每秒运行一次。n对OSTaskSwHook()中每个任务的TaskExecTime与TaskTotExecTime两个变量进行统计,可以计算出一段时间内各个任务所占用CPU的百分比。nOSTaskStatHook()函数会显示这些统计信息。OSTaskStatHook()函数本例的统计任务(sta88用户定义的OSTaskStatHook()nvoidOSTaskStatHook(void)chars80;INT8Ui;INT32Utotal;INT8Upct;total=0L;for(I=0;i0)for(i=0;i1000000000L)for(i=0;i7;i+)TaskUserDatai.TaskTotExecTime=0L;用户定义的OSTaskStatHook()(续)if(to90例3的运行结果例3的运行结果91例例4n与例4相关的磁盘文件位于SOFTWAREuCOS-IIIx86L-FP和SOFTWAREuCOS-IIEX4_x86L.FP中。除了空闲任务(idletask)和统计任务(statistictask),还有10个相同的任务,总共13个任务。TaskStart()在函数main()中建立,功能是建立其它任务并且在屏幕上显示如下统计信息:任务总数;每秒钟任务切换次数;CPU利用率;C/OS-II的版本号;n其余10个任务基于同一代码Task();每个任务按任务序号110(优先级顺序)显示相应的角度、角度的余弦和角度的正弦。例4与例4相关的磁盘文件位于SOFTWAREuCOS-I92main()nmain()函数和前3例中的相差不多;n不同的是创建了10个相同的任务,并且对于每个任务,均设定为OS_TASK_OPT_SAVE_FP(支持统计任务的浮点运算)。main()main()函数和前3例中的相差不多;93main()函数函数nvoidmain(void)PC_DispClrScr(DISP_FGND_WHITE+DISP_BGND_BLACK);OSInit();PC_DOSSaveReturn();PC_VectSet(uCOS,OSCtxSw);OSTaskCreateExt(TaskStart,(void*)0,TaskStartStkTASK_STK_SIZE-1,0,/任务优先级为0(最高)0,&TaskStartStk0,TASK_STK_SIZE,(void*)0,OS_TASK_OPT_SAVE_FP);/支持浮点运算OSStart();main()函数voidmain(void)94TaskStart()函数n与前例1差不多,主要功能是显示相关的统计信息,并且调用TaskStartCreateTasks()创建10个相同的任务。TaskStart()函数与前例1差不多,主要功能是显示相95TaskStartCreateTasks()函数nstaticvoidTaskStartCreateTasks(void)INT8Ui;INT8Uprio;for(i=0;i=(FP32)360.0)angle=(FP32)0.0;elseangle+=(FP32)0.01;OSTimeDly(1);Task()函数voidTask(void*pda97例4的运行结果例4的运行结果98
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 办公文档 > 教学培训


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!