版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
在这一章里将提供三个范例来说明如何使用µC/OS-II。笔者之所以在本书一开始就写这一章是为了让读者尽快开始使用µC/OS-II。在开始讲述这些例子之前,笔者想先说明一这些例子曾经用BorlandC/C++编译器(V3.1)编译过,用选择项产生In/AMD80186处理器(大模式下编译)的代码。这些代码实际上是在InPentiumIIPC(300MHz)上运行和测试过,InPentiumIIPC可以看成是特别快的80186。笔者选择PC做为目标系PCEPROMEPROM真器中程序等等。用户只需要简单地编译、和执行。其次,使用BorlandC/C++产CPUPentium-IIDOSWindows955MbuC/OS-II。A:INSTALLdriveINSTALL.BATDOS的批处理文件,位于磁盘的根下。它会自动在读者指定的目标驱动器中建立\SOFTWARE并且将uCOS-II.EXE文件从A:驱动器到\SOFTWARE并µC/OS-II\SOFTWARE下添加所有的INSTALL.BATuCOS-II.EXE并且将改为\SOFTWARE\uCOS-II\EX1_x86L录下应该有一下子:这是 下 这 TO存放在 下。DOS下的可执行文件(HPLIST.EXE)存放在TO(D,HPLISTCTOTO.CDOS(TO.EXETOTO.TBL文件,它必须放在根下。用户可以在\SOFTWARE\TO\EXE 下与µC/OS-II相关的文件都放在这 这 这 这 这 *.C#include#includeINCLUDE.H可以使用户不必在工程项目中每个*.C文件中都考虑需要什么样的头文件。INCLUDES.H,3\SOFTWARE\uCOS-II\EX1_x86L\SOFTWARE\uCOS-II\EX2_x86L,以及TypedefTypedefunsignedcharBOOLEAN;TypedefunsignedcharINT8U;TypedefsignedcharINT8S;TypedefunsignedintINT16U;TypedefsignedTypedefunsignedTypedefsignedlongTypedefTypedef#define#define#define#define#define#defineINT16U16µC/OS-II065,535µCO/S-II32INT16UµC/OS-IIINT16U1.1BorlandC/C++编译器为例,为80x86µC/OSBYTE,WORD,LONGµC/OSµC/OS-IIWORD3216Cextern.C和.H文件中定义。这种重复#ifdef#ifdef#define#definexxx_EXT#definexxx_EXT.Hxxx_EXTxxx.C#define#define#includexxx_EXT已经定义。所以编译器给每个全局变量分配内存空间,而当编译器处理其他.C文件时,uC/OS_II.H,其中包括以下定义:#ifdef#ifdefOS_GLOBALS#defineOS_EXT#defineOS_EXTOS_EXTOS_EXTOS_EXT#define#define#includeOS_GLOBALOS_EXTextern。externexternexternextern到。9.03.02#define OS_CRITICAL_METHOD==#define OS_CRITICAL_METHOD==#defineOS_ENTER_CRITICAL()asm{PUSHF;#defineOS_EXIT_CRITICAL()asmPOPFOS_CRITICAL_METHOD==OS_ENTER_CRITICAL()OS_EXIT_CRITICAL()PC.C文件和PC.H文件(在\SOFTWARE\BLOCKS\PC\SOURCE下)是笔者在范例中使PCµC/OS-II(即µC/OS)不同,笔者希望集PC_为前缀。B800:0000以把#defineconstantDISP_BASE0xB8000xB000。(1)(0)中#defienconstantsPC.C Clearthescreen Clearasinglerow(orline) DisyasingleASCIIcharacteranywhereonthescreen DisyanASCIIstringanywhereonthescreenC的82C4定时器2PC_ElapedStar()和PC_ElapsdStop(P_ElapseInit()C_ElapsdStop(个函数不具备重入性所以,须,不要多个任同时调这两个函数。表1.4说明了何测量P_DisChar()执时间。注,时间以uS为位的。INT16UINT16U..PC_DispChar(40,24,‘A’,time=译其他单线程的程序一样编译和用户程序。所生成的.EXE程序可以在DOS下装载和运DOSµC/OS-IIDOS。调用都会使DOS环境被破坏,从而导致DOS或WINDOWS95下的DOS窗口。MM-DD-YYHH:MM:SS,19BorlandC/C++gettime()getdateDOSCPC_GetKey()精确地为20.000Hz。笔者决定将时钟节拍设得更快一些,用的是200Hz(实际是上是标频率,PC_SetTickRate()18.2Hz,82C54。PC_VectGet()PC_VectSet()很容易改写,以适用于其它编译器。的。可执行代码可以在每个范例的OBJ子下找到。实际上这些代码是在BorlandIDE(IntegratedDevelopmentEnvironment1.1表 CodeCode : :TreatenumsasAdvancedcodeAssumeSSEquals :DefaultforAdvancedcodeFloating :Instruction :GenerateunderbarsDebuginfoinOBJsFastfloatingpoint GlobalregisterallocationInvariantcodemotionInductionvariablesLoopoptimizationSuppressredundantloadsCopypropagationDeadcodeeliminationJumpoptimizationIn-lineintrinsicRegistervariables Commonsubexpressions OptimizegloballyOptimizefor BorlandC/C++C:\CPP下,如果用户的编译器是在不同的Options/DirectoriesIDEOS_???_EN。第一个范例可以在\SOFTWARE\uCOS_II\EX1_x86L下找到,它有13个任务(包括µC/OS-IIµC/OS-IICPU9main()DOS[L1.5(1)]。DOSµC/OS-IIOSInit[L1.5(2CPU程序L1.5voidvoidmain{PC_DispClrScr(DISP_FGND_WHITE+PC_VectSet(uCOS,RandomSem=(void(void*)&TaskStartStk[TASK_STK_SIZE-1],}DOSPC_DOSSaveReturn()[L1.5(3)]来保存的。这使得用户可以返回到没有运行µC/OS-II以前的DOS环境。跟随L1.6中的程序可以看到PC_DOSSaveReturn()做了很多事情。PC_DOSSaveReturn(首先设置PC_ExitFlag为FALSE[L1.6(1)]DOSOSTickDOSCtr1[L1.6(2)],因为OSTickISR(0OSTickISR1255。然后,PC_DOSSaveReturn()DOS的时钟节拍处理(tickhandler)存入一个自由向量表入口中[L1.6(3)-(4)]µC/OS-IIPC_DOSSaveReturn()调jmp()[L1.6(5)],它将处理器状态(即所有寄存器的值)PC_JumpBuf构之中。保存处理器的全部寄存器使得程序返回到PC_DOSSaveReturn()并且在调用setjmp()PC_ExitFlagFALSE[L1.6(1)]。PC_DOSSaveReturn()跳if状态语句[L1.6(6)–(9)]回到main()DOS,可以调用PC_DOSReturn()(程序L1.7),它设置PC_ExitFlag为TRUE,并且执行longjmp()语PC_ExitFlagTRUEifPC_DOSSaveReturn()将时钟节拍改为18.2Hz[L1.6(6PC时钟节拍中断服务[L1.6(7)],清屏幕[L1.6(8)],通exit(0)DOS[L1.6(9)]。voidvoidPC_DOSSaveReturn{PC_ExitFlag=OSTickDOSCtrPC_TickISRPC_TickISR=PC_VectSet(VECT_DOS_CHAIN,if(PC_ExitFlag==TRUE){PC_VectSet(VECT_TICK,PC_DispClrScr(DISP_FGND_WHITE+}}程序L1.7设置返回DOSvoidvoidPC_DOSReturn{PC_ExitFlag=longjmp(PC_JumpBuf,}现在回到main()这个函数,在程序L1.5中,main()调用PC_VectSet()来设0x80(128DOSBIOS1,意思是在某一时刻只有一个任务可以调用随机数产生函数。立其它任务,必须保证用户的任务代码全局变量OSStatRdy和延时程序[即调用已经到了数据。例1中的主要工作由TaskStart()来完成。TaskStart()函数的示意代码如程序18.2Hz200Hz[L1.8(3)]。在处理器改变中断向量时以及系统没有完全初始化前,当然不希望有中断打入!注意main()这个函数(见程序L1.5)在系统初始化的时候并µC/OS-IIvoidvoidTaskStart(void{Preventcompilerwarningbyassigning‘data’to ybanneridentifyingthisasEXAMPLEPC_VectSet(0x08,InitializethestatistictaskbycallingCreate10identicalfor(;;) ythenumberoftaskscreated; ythe%ofCPUused; ythenumberoftaskswitchesin1second; yuC/OS-II’sversionnumberIf(keywaspressed)if(keypressedwastheESCAPEkey){}}Delayfor1}}}没有别的任务可以执行,它只能执行空闲任务(µC/OS-II。空闲任务是一个无最大值。而当用户再增加其他应用代码时,空闲任务就不会占用那样多的CPU时间。(TRUE[L1.9(5)]µC/OS-IICPUvoidvoidOSStatInit{ =OSIdleCtrMax= =}DOS程序L1.10给出了任务的代码任务一开始调用OSSemPend()获取信号量RandomSemL1.10(1)(的库函数random()来获得一个随机数[程序L1.10(2)],此处设random()函数是不200102000voidvoidTask(void{UBYTEx;UBYTEUBYTEfor(;;)OSSemPend(RandomSem,0,x=y=PC_DispChar(x,y+5,*(char*)data, }}作(OSTaskCreateExt()建立任务—译者注。当用户不知道应扩展,一般多分配10%,25%或者。如果系统对稳定性要求高,则应该多一倍以上。的。同时要OSTaskCreateExt()进行堆栈操作是一项很费时的工作,而且取决于uCOS-图F µC/OS-IIstackL1.11一,main()函数调用PC_ElapsedInit()[程序清单L1.11(1)]来初始化定时器记录OSTaskStkChk()的执行时间。第二,所有的任务都使用OSTaskCreateExt()函数来建立任务OSTaskCreat(程序L1.11例2中的Main()函数voidvoidmain{PC_DispClrScr(DISP_FGND_WHITE+PC_VectSet(uCOS,PC_VectSet(uCOS,(void*)0,(voidOS_TASK_OPT_STK_CHK|}除了OSTaskCreate()函数的四个参数外,OSTaskCreateExt()还需要五个参数(一共9个ID,一个指向任务堆栈栈底的指针,堆栈的大小(以堆栈单元为单位,80X86为字TCBuCOS-II2TCB程序L1.12列出了TaskStart()的伪码。前五项操作和例1中相同。TaskStart()建立了两个邮箱,分别提供给任务4和任务5[程序L1.12(1)]。除此之外,还建立了一程序L1.12TaskStart()的伪码。voidvoidTaskStart(void{Preventcompilerwarningbyassigning‘data’to yabannerandnon-changingtext;InstalluC/OS-II’stickhandler;Changethetickrateto200Hz;Initializethestatisticstask;Create2mailboxeswhichareusedbyTask#4andCreateataskthatwilldis ythedateandtimeonthescreen;(2)Create5applicationtasks;for(;;) y#tasksrunning; yCPUusagein y#contextswitchesperseconds;Clearthecontextswitchcounter; yuC/OS-II’sIf(Keywaspressed)if(KeypressedwastheESCAPEkey){ReturntoDOS;}}Delayfor1}}序L1.13(1)–(2)],并与堆栈大小一起显示出来。注意所有堆栈的大小都是以字节为单位的。任务1每秒执行10次[程序L1.13(3)](间隔100msvoidTask1(void{OS_STK_DATAvoidTask1(void{OS_STK_DATApdata=for(;;)for(i=0;i<7;i++)err=time=if(err==OS_NO_ERR)sprintf(s,sprintf(s,+,PC_DispStr(19,12+i,s,}}OSTimeDlyHMSM(0,0,0,}}程序L1.14所示的任务2在屏幕上显示一个顺时针旋转的指针(用横线,斜线等字符表示—译者注200msvoidTask2(void{datavoidTask2(void{data=data;for(;;){PC_DispChar(70,15,'|',DISP_FGND_WHITE+}+'-++}任务3(程序L1.15)也显示了与任务2相同的一个旋转指针但是旋转的方向不同。程序L1.15任务voidvoidTask3(void{ INT16Ui;data=for(I=0;i<499;i++)dummy[i]=}for(;;)PC_DispChar(70,16,'|',DISP_FGND_WHITE+PC_DispChar(70,16,'\\',DISP_FGND_WHITE+PC_DispChar(70,16,'-',DISP_FGND_WHITE+PC_DispChar(70,16,'/',DISP_FGND_WHITE+}}任务4(程序L1.16)向任务5发送消息并等待确认[程序L1.16(1)]。发送的消ASCII码加1再发送[程序L1.16(3)],结果是不断的传送“ABCDEFG.程序L1.16任务voidvoidTask4(void{chartxmsg;INT8Uerr;data=data;txmsg='A';for(;;)whilewhile(txmsg<='Z')OSMboxPost(TxMbox,(void*)&txmsg);OSMboxPend(AckMbox,0,&err);}txmsg=}}当任务5[程序L1.17]接收消息后[程序L1.17(1)](发送的字符,就将消息显示到屏幕上[程序L1.17(2)],然后延时1秒[程序L1.17(3)],再向任务4发送程序L1.17任务voidvoidTask5(void{char*rxmsg;INT8Uerr;data=data;for(;;){rxmsg=(char*)OSMboxPend(TxMbox,0,PC_DispChar(70,18,*rxmsg,DISP_FGND_YELLOW+DISP_BGND_RED);OSTimeDlyHMSM(0,0,1,OSMboxPost(AckMbox,(void}}程序L1.18时钟显示任voidvoidTaskClk(void{Structtimenow;Structdatetoday;data=data;for(;;){PC_DispStr(0,24,s,DISP_FGND_BLUE+DISP_BGND_CYAN);}}(OSTaskwHook()main()函数[程序L1.19]和例2中的相不多,不同的是在用户定义的TCB扩展数据结构中可以保存每个任务的名称[程序L1.19(1)](扩展结构的在INCLUDES.H中定义,也可参看程序L1.20。笔者定义了30个字节来存放任务名(包括空格)[程序程序L1.19例3的main()函voidvoidmain{PC_DispClrScr(DISP_FGND_WHITE+PC_VectSet(uCOS,OSCtxSw);(void*)0,}typedefstruct}typedefstruct}程序L1.21TaskStart()的伪码voidvoidTaskStart(void{Preventcompilerwarningbyassigning‘data’to yabannerandnon-changingtext;InstalluC/OS-II’stickhandler;Changethetickrateto200Hz;Initializethestatisticstask;CreateamessageCreateataskthatwillythedateandtimeontheCreate5applicationtaskswithanamestoredintheTCBfor(;;) y#tasksrunning; yCPUusagein y#contextswitchesperseconds;Clearthecontextswitchcounter; yuC/OS-II’sIf(Keywaspressed)if(KeypressedwastheESCAPEkey){ReturntoDOS;}}Delayfor1}}程序L1.22任务1voidvoidTask1(void{charone=chartwo='2';charthree=data=data;for(;;){OSQPost(MsgQueue,(voidOSTimeDlyHMSM(0,0,1,OSQPost(MsgQueue,(void*)&two);OSTimeDlyHMSM(0,0,0,500);OSQPost(MsgQueue,(voidOSTimeDlyHMSM(0,0,1,}}程序L1.23任务2voidvoidTask2(void{INT8U*msg;INT8Udata=data;for(;;){msg=(INT8U*)OSQPend(MsgQueue,0,PC_DispChar(70,14,*msg, OSTimeDlyHMSM(0,0,0,}}任务3同样处于等待消息的挂起状态,但是它设定了等待结束时间250mSL1.24(1)]。如果有消息来到,任务3将显示消息号[程序L1.24(3)],如果超过了等待时间,任务3就显示“T(意为timeout)[程序L1.24(2)]。voidvoidTask3(void{INT8U*msg;INT8Udata=data;for(;;){msg=(INT8U*)OSQPend(MsgQueue,OS_TICKS_PER_SEC/4, If(err==OS_TIMEOUT)}else }}}任务4的操作只是从邮箱发送[程序L1.25(1)]和接收[程序L1.25(2)],这使得用户可以测量任务在自己PC上执行的时间任务4每10mS执行一次[程序L1.25(3)]程序L1.25任务4voidvoidTask4(void{OS_EVENTdata=mbox=OSMboxCreate((void*)0);for(;;){OSMboxPost(mbox,(voidOSMboxPend(mbox,0,OSTimeDlyHMSM(0,0,0,}}CPU。程序L1.26任务5voidvoidTas
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 住宅买卖合同模板
- 文化产业招投标合同范本
- 建筑节能改造服务工程合同模板
- 地质勘探水井租赁合同
- 零星照明工程安装协议
- 停车场交通组织施工协议
- 体育馆游泳池除湿管道安装协议
- 外企员工解除劳动合同证明
- 垃圾处理场建设顶管施工合同
- 计算机硬件灰土施工合同
- 统编版(2024版)七年级上册历史期末复习课件
- 高校教师职称答辩演讲稿
- 《“PDCA”循环管理法在医院传染病防控中应用研究》
- 基于单片机的智能家居环境监测与控制系统设计-毕业设计说明书
- 2024-2025学年人教版七年级地理上学期地理知识点
- 国开2024年秋《机械制图》形考作业1-4答案
- 劳动教育智慧树知到期末考试答案章节答案2024年温州医科大学
- MOOC 创业管理-江苏大学 中国大学慕课答案
- 2024年四川省自然资源投资集团有限责任公司招聘笔试参考题库附带答案详解
- 手机号码归属地数据库
- 年度养护计划和方案(绿化)
评论
0/150
提交评论