下载

3下载券

加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 第11章

第11章.doc

第11章

linwhwylb
2018-09-05 0人阅读 举报 0 0 暂无简介

简介:本文档为《第11章doc》,可适用于IT/计算机领域

μCOSII:实时操作系统内核参考手册第章参考手册本章提供了μCOSⅡ的用户指南。每一个用户可以调用的内核函数都按字母顺序加以说明包括:·函数的功能描述·函数原型·函数名称及源代码·函数使用到的常量·函数参数·函数返回值·特殊说明和注意点OSInit()VoidOSInit(void)所属文件调用者开关量OSCOREC启动代码无OSinit()初始化μCOSⅡ对这个函数的调用必须在调用OSStart()函数之前而OSStart()函数真正开始运行多任务。参数无返回值无注意警告必须先于OSStart()函数的调用范例:voidmain(void){OSInit()*初始化uCOSII*OSStart()*启动多任务内核*}OSIntEnter()VoidOSIntEnter(void)所属文件调用者开关量OSCOREC中断无OSIntEnter()通知μCOSⅡ一个中断处理函数正在执行这有助于μCOSⅡ掌握中断嵌套的情况。OSIntEnter()函数通常和OSIntExit()函数联合使用。参数无返回值无注意警告在任务级不能调用该函数。如果系统使用的处理器能够执行自动的独立执行读取修改写入的操作那么就可以直接递增中断嵌套层数(OSIntNesting)这样可以避免调用函数所带来的额外的开销。范例一:(Intelx的实模式,在大模式下编译realmodelargemodel)ISRxPROCFARPUSHA保存中断现场PUSHESPUSHDSMOVAX,DGROUP读入数据段MOVDS,AXCALLFARPTROSIntEnter通知内核进入中断POPDS恢复中断现场POPESPOPAIRET中断返回ISRxENDP范例二:(Intelx的实模式,在大模式下编译,realmode,largemodel)ISRxPROCFARPUSHA保存中断现场PUSHESPUSHDSMOVAX,DGROUP读入数据段MOVDS,AXINCBYTEPTROSIntNesting通知内核进入中断POPDS恢复中断现场POPESPOPAIRET中断返回ISRxENDPOSIntExit()VoidOSIntExit(void)所属文件调用者开关量OSCOREC中断无OSIntExit()通知μCOSⅡ一个中断服务已执行完毕这有助于μCOSⅡ掌握中断嵌套的情况。通常OSIntExit()和pdatafor(){err=OSQPost(CommQ,(void*)CommRxBuf)if(err==OSNOERR){*将消息放入消息队列*}else{*消息队列已满*}}}OSQPostFront()INTUOSQPostFront(OSEVENT*pevent,void*msg)所属文件调用者开关量OSQC任务或中断OSQENOSQPostFront()函数通过消息队列向任务发送消息。OSQPostFront()函数和OSQPost()函数非常相似不同之处在于OSQPostFront()函数将发送的消息插到消息队列的最前端。也就是说OSQPostFront()函数使得消息队列按照后入先出(LIFO)的方式工作而不是先入先出(FIFO)。消息是一个指针长度的变量在不同的程序中消息的使用也可能不同。如果队列中已经存满消息返回错误码。OSQPost()函数立即返回调用者消息也没能发到队列。如果有任何任务在等待队列中的消息最高优先级的任务将得到这个消息。如果等待消息的任务优先级比发送消息的任务优先级高那么高优先级的任务将得到消息而恢复执行也就是说发生了一次任务切换参数pevent是指向即将接受消息的消息队列的指针。该指针的值在建立该队列时可以得到。(参考OSQCreate()函数)。Msg是即将实际发送给任务的消息。消息是一个指针长度的变量在不同的程序中消息的使用也可能不同。不允许传递一个空指针。返回值OSQPost()函数的返回值为下述之一:·OSNOERR:消息成功的放到消息队列中。·OSMBOXFULL:消息队列已满。·OSERREVENTTYPE:pevent不是指向消息队列的指针。注意警告必须先建立消息队列然后使用。不允许传递一个空指针。范例:OSEVENT*CommQINTUCommRxBufvoidCommTaskRx(void*pdata){INTUerrpdata=pdatafor(){err=OSQPostFront(CommQ,(void*)CommRxBuf)if(err==OSNOERR){*将消息放入消息队列*}else{*消息队列已满*}}}OSQQuery()INTUOSQQuery(OSEVENT*pevent,OSQDATA*pdata)所属文件调用者开关量OSQC任务或中断OSQENOSQQuery()函数用来取得消息队列的信息。用户程序必须建立一个OSQDATA的数据结构该结构用来保存从消息队列的事件控制块得到的数据。通过调用OSQQuery()函数可以知道任务是否在等待消息、有多少个任务在等待消息、队列中有多少消息以及消息队列可以容纳的消息数。OSQQuery()函数还可以得到即将被传递给任务的消息的信息。参数pevent是指向即将接受消息的消息邮箱的指针。该指针的值在建立该消息邮箱时可以得到。(参考OSQCreate()函数)。Pdata是指向OSQDATA数据结构的指针该数据结构包含下述成员:Void*OSMsg*下一个可用的消息*INTUOSNMsgs*队列中的消息数目*INTUOSQSize*消息队列的大小*INTUOSEventTblOSEVENTTBLSIZE*消息队列的等待队列*INTUOSEventGrp返回值OSQQuery()函数的返回值为下述之一:·OSNOERR:调用成功·OSERREVENTTYPE:pevent不是指向消息队列的指针。注意警告必须先建立消息队列然后使用。范例:OSEVENT*CommQvoidTask(void*pdata){OSQDATAqdataINTUerrpdata=pdatafor(){err=OSQQuery(CommQ,qdata)if(err==OSNOERR){*取得消息队列的信息*}}}OSSchedLock()VoidOSSchedLock(void)所属文件调用者开关量OSCOREC任务或中断NAOSSchedLock()函数停止任务调度只有使用配对的函数OSSchedUnlock()才能重新开始内核的任务调度。调用OSSchedLock()函数的任务独占CPU不管有没有其他高优先级的就绪任务。在这种情况下中断仍然可以被接受和执行(中断必须允许)。OSSchedLock()函数和OSSchedUnlock()函数必须配对使用。μCOSⅡ可以支持多达层的OSSchedLock()函数嵌套必须调用同样次数的OSSchedUnlock()函数才能恢复任务调度。参数无返回值无注意警告任务调用了OSSchedLock()函数后决不能再调用可能导致当前任务挂起的系统函数:OSTimeDly()OSTimeDlyHMSM()OSSemPend()OSMboxPend()OSQPend()。因为任务调度已经被禁止其他任务不能运行这会导致系统死锁。范例:voidTaskX(void*pdata){pdata=pdatafor(){OSSchedLock()*停止任务调度**不允许被打断的执行代码*OSSchedUnlock()*恢复任务调度*}}OSSchedUnlock()VoidOSSchedUnlock(void)所属文件调用者开关量OSCOREC任务或中断NA在调用了OSSchedLock()函数后OSSchedUnlock()函数恢复任务调度。参数无返回值无注意警告任务调用了OSSchedLock()函数后决不能再调用可能导致当前任务挂起的系统函数:OSTimeDly()OSTimeDlyHMSM()OSSemPend()OSMboxPend()OSQPend()。因为任务调度已经被禁止其他任务不能运行这会导致系统死锁。范例:voidTaskX(void*pdata){pdata=pdatafor(){OSSchedLock()*停止任务调度**不允许被打断的执行代码*OSSchedUnlock()*恢复任务调度*}}OSSemAccept()INTU*OSSemAccept(OSEVENT*pevent)所属文件调用者开关量OSSEMC任务或中断OSSEMENOSSemAccept()函数查看设备是否就绪或事件是否发生。不同于OSSemPend()函数如果设备没有就绪OSSemAccept()函数并不挂起任务。中断调用该函数来查询信号量。参数pevent是指向需要查询的设备的信号量。当建立信号量时该指针返回到用户程序。(参考OSSemCreate()函数)。返回值当调用OSSemAccept()函数时设备信号量的值大于零说明设备就绪这个值被返回调用者设备信号量的值减一。如果调用OSSemAccept()函数时设备信号量的值等于零说明设备没有就绪返回零。注意警告必须先建立信号量然后使用。范例:OSEVENT*DispSemvoidTask(void*pdata){INTUvaluepdata=pdatafor(){value=OSSemAccept(DispSem)*查看设备是否就绪或事件是否发生*if(value>){*就绪执行处理代码*}}}OSSemCreate()OSEVENT*OSSemCreate(WORDvalue)所属文件调用者开关量OSSEMC任务或启动代码OSSEMENOSSemCreate()函数建立并初始化一个信号量。信号量的作用如下:·允许一个任务和其他任务或者中断同步。·取得设备的使用权·标志事件的发生参数value参数是建立的信号量的初始值可以取到之间的任何值。返回值OSSemCreate()函数返回指向分配给所建立的消息邮箱的事件控制块的指针。如果没有可用的事件控制块OSSemCreate()函数返回空指针。注意警告必须先建立信号量然后使用。范例:OSEVENT*DispSemvoidmain(void){OSInit()*初始化μCOSⅡ*DispSem=OSSemCreate()*建立显示设备的信号量*OSStart()*启动多任务内核*}OSSemPend()VoidOSSemPend(OSEVNNT*pevent,INTUtimeout,intu*err)所属文件调用者开关量OSSEMC任务OSSEMENOSSemPend()函数用于任务试图取得设备的使用权任务需要和其他任务或中断同步任务需要等待特定事件的发生的场合。如果任务调用OSSemPend()函数时信号量的值大于零OSSemPend()函数递减该值并返回该值。如果调用时信号量等于零OSSemPend()函数函数将任务加入该信号量的等待队列。OSSemPend()函数挂起当前任务直到其他的任务或中断置起信号量或超出等待的预期时间。如果在预期的时钟节拍内信号量被置起μCOSⅡ默认最高优先级的任务取得信号量恢复执行。一个被OSTaskSuspend()函数挂起的任务也可以接受信号量但这个任务将一直保持挂起状态直到通过调用OSTaskResume()函数恢复任务的运行。参数pevent是指向信号量的指针。该指针的值在建立该信号量时可以得到。(参考OSSemCreate()函数)。Timeout允许一个任务在经过了指定数目的时钟节拍后还没有得到需要的信号量时恢复运行状态。如果该值为零表示任务将持续的等待信号量。最大的等待时间为个时钟节拍。这个时间长度并不是非常严格的可能存在一个时钟节拍的误差因为只有在一个时钟节拍结束后才会减少定义的等待超时时钟节拍。Err是指向包含错误码的变量的指针。OSSemPend()函数返回的错误码可能为下述几种:·OSNOERR:信号量不为零。·OSTIMEOUT:信号量没有在指定的周期数内置起。·OSERRPENDISR:从中断调用该函数。虽然规定了不允许从中断调用该函数但μCOSⅡ仍然包含了检测这种情况的功能。·OSERREVENTTYPE:pevent不是指向信号量的指针。返回值注意警告必须先建立信号量然后使用。不允许从中断调用该函数。范例:OSEVENT*DispSemvoidDispTask(void*pdata){INTUerrpdata=pdatafor(){OSSemPend(DispSem,,err)*只有信号量置起该任务才能执行*}}OSSemPost()INTUOSSemPost(OSEVENT*pevent)所属文件调用者开关量OSSEMC任务或中断OSSEMENOSSemPost()函数置起指定的信号量。如果指定的信号量是零或大于零OSSemPost()函数递增该信号量并返回。如果有任何任务在等待信号量最高优先级的任务将得到信号量并进入就绪状态。任务调度函数将进行任务调度决定当前运行的任务是否仍然为最高优先级的就绪状态的任务。参数pevent是指向信号量的指针。该指针的值在建立该信号量时可以得到。(参考OSSemCreate()函数)。返回值OSSemPost()函数的返回值为下述之一:·OSNOERR:信号量成功的置起·OSSEMOVF:信号量的值溢出·OSERREVENTTYPE:pevent不是指向信号量的指针。注意警告必须先建立信号量然后使用。范例:OSEVENT*DispSemvoidTaskX(void*pdata){INTUerrpdata=pdatafor(){err=OSSemPost(DispSem)if(err==OSNOERR){*信号量置起*}else{*信号量溢出*}}}OSSemQuery()INTUOSSemQuery(OSEVENT*pevent,OSSEMDATA*pdata)所属文件调用者开关量OSSEMC任务或中断OSSEMENOSSemQuery()函数用于获取某个信号量的信息。使用OSSemQuery()之前应用程序需要先创立类型为OSSEMDATA的数据结构用来保存从信号量的事件控制块中取得的数据。使用OSSemQuery()可以得知是否有以及有多少任务位于信号量的任务等待队列中(通过查询OSEventTbl域)还可以获取信号量的标识号码。OSEventTbl域的大小由语句:#defineconstantOSENENTTBLSIZE定义(参阅文件uCOSIIH)。参数pevent是一个指向信号量的指针。该指针在信号量建立后返回调用程序参见OSSemCreat()函数。Pdata是一个指向数据结构OSSEMDATA的指针该数据结构包含下述域:INTUOSCnt*当前信号量标识号码*INTUOSEventTblOSEVENTTBLSIZE*信号量等待队列*INTUOSEventGrp返回值OSSemQuery()函数有下述两个返回值:·OSNOERR表示调用成功。·OSERREVENTTYPE表示未向信号量传递指针。注意警告被操作的信号量必须是已经建立了的。范例:在本例中应用程序检查信号量查找等待队列中优先级最高的任务。OSEVENT*DispSemvoidTask(void*pdata){OSSEMDATAsemdataINTUerrINTUhighest*在信号量中等待的优先级最高的任务*INTUxINTUypdata=pdatafor(){err=OSSemQuery(DispSem,semdata)if(err==OSNOERR){if(semdataOSEventGrp!=x){y=OSUnMapTblsemdataOSEventGrpx=OSUnMapTblsemdataOSEventTblyhighest=(y<<)x}}}}OSStart()voidOSStart(void)所属文件调用者开关量OSCOREC只能是初始化代码无OSStart()启动μCOSII的多任务环境。参数无返回值无注意警告在调用OSStart()之前必须先调用OSInit()。在用户程序中OSStart()只能被调用一次。第二次调用OSStart()将不进行任何操作。范例:voidmain(void){*用户代码*OSInit()*初始化オCOSII**用户代码*OSStart()*启动多任务环境*}OSStatInit()voidOSStatInit(void)所属文件调用者开关量OSCOREC只能是初始化代码OSTASKSTATENOSTASKCREATEEXTENOSStatInit()获取当系统中没有其他任务运行时位计数器所能达到的最大值。OSStatInit()的调用时机是当多任务环境已经启动且系统中只有一个任务在运行。也就是说该函数只能在第一个被建立并运行的任务中调用。参数无返回值无注意警告无范例:voidFirstAndOnlyTask(void*pdata){OSStatInit()*计算CPU使用率*OSTaskCreate(ノ)*建立其他任务*OSTaskCreate(ノ)for(){}}OSTaskChangPrio()INTUOSTaskChangePrio(INTUoldprio,INTUnewprio)所属文件调用者开关量OSTASKC任务OSTASKCHANGEPRIOENOSTaskChangePrio()改变一个任务的优先级。参数oldprio是任务原先的优先级。newprio是任务的新优先级。返回值OSTaskChangePrio()的返回值为下述之一:·OSNOERR:任务优先级成功改变。·OSPROINVALID:参数中的任务原先优先级或新优先级大于或等于OSLOWESTPRIO。·OSPRIOEXIST:参数中的新优先级已经存在。·OSPRIOERR:参数中的任务原先优先级不存在。注意警告参数中的新优先级必须是没有使用过的否则会返回错误码。在OSTaskChangePrio()中还会先判断要改变优先级的任务是否存在。范例:voidTaskX(void*data){INTUerrfor(){err=OSTaskChangePrio(,)}}OSTaskCreate()INTUOSTaskCreate(void(*task)(void*pd),void*pdata,OSSTK*ptos,INTUprio)所属文件调用者开关量OSTASKC任务或初始化代码无OSTaskCreate()建立一个新任务。任务的建立可以在多任务环境启动之前也可以在正在运行的任务中建立。中断处理程序中不能建立任务。一个任务必须为无限循环结构(如下所示)且不能有返回点。OSTaskCreate()是为与先前的μCOS版本保持兼容新增的特性在OSTaskCreateExt()函数中。无论用户程序中是否产生中断在初始化任务堆栈时堆栈的结构必须与CPU中断后寄存器入栈的顺序结构相同。详细说明请参考所用处理器的手册。参数task是指向任务代码的指针。Pdata指向一个数据结构该结构用来在建立任务时向任务传递参数。下例中说明μCOS中的任务结构以及如何传递参数pdata:voidTask(void*pdata){*Dosomethingwith'pdata'*for(){*任务函数体**在任务体中必须调用如下函数之一:**OSMboxPend()**OSQPend()**OSSemPend()**OSTimeDly()**OSTimeDlyHMSM()**OSTaskSuspend()(挂起任务本身)**OSTaskDel()(删除任务本身)*}ptos为指向任务堆栈栈顶的指针。任务堆栈用来保存局部变量函数参数返回地址以及任务被中断时的CPU寄存器内容。任务堆栈的大小决定于任务的需要及预计的中断嵌套层数。计算堆栈的大小需要知道任务的局部变量所占的空间可能产生嵌套调用的函数及中断嵌套所需空间。如果初始化常量OSSTKGROWTH设为堆栈被设为从内存高地址向低地址增长此时ptos应该指向任务堆栈空间的最高地址。反之如果OSSTKGROWTH设为堆栈将从内存的低地址向高地址增长。prio为任务的优先级。每个任务必须有一个唯一的优先级作为标识。数字越小优先级越高。返回值OSTaskCreate()的返回值为下述之一:·OSNOERR:函数调用成功。·OSPRIOEXIST:具有该优先级的任务已经存在。·OSPRIOINVALID:参数指定的优先级大于OSLOWESTPRIO。·OSNOMORETCB:系统中没有OSTCB可以分配给任务了。注意警告任务堆栈必须声明为OSSTK类型。在任务中必须调用μCOS提供的下述过程之一:延时等待、任务挂起、等待事件发生(等待信号量消息邮箱、消息队列)以使其他任务得到CPU。用户程序中不能使用优先级以及OSLOWESTPRIO,OSLOWESTPRIO,OSLOWESTPRIO,OSLOWESTPRIO。这些优先级μCOS系统保留其余的个优先级提供给应用程序。范例:本例中传递给任务Task()的参数pdata不使用所以指针pdata被设为。注意到程序中设定堆栈向低地址增长传递的栈顶指针为高地址TaskStk。如果在您的程序中设定堆栈向高地址增长则传递的栈顶指针应该为TaskStk。OSSTKTaskStkvoidmain(void){INTUerrOSInit()*初始化オCOSII*OSTaskCreate(Task,(void*),TaskStk,)OSStart()*启动多任务环境*}voidTask(void*pdata){pdata=pdatafor(){*任务代码*}}范例:您可以创立一个通用的函数多个任务可以共享一个通用的函数体例如一个处理串行通讯口的函数。传递不同的初始化数据(端口地址、波特率)和指定不同的通讯口就可以作为不同的任务运行。OSSTK*CommStkCOMMDATACommData*包含COMM口初始化数据的数据结构**通道的数据*OSSTK*CommStkCOMMDATACommData*包含COMM口初始化数据的数据结构**通道的数据*voidmain(void){INTUerrOSInit()*初始化オCOSII*OSTaskCreate(CommTask,(void*)CommData,CommStk,)OSTaskCreate(CommTask,(void*)CommData,CommStk,)OSStart()*启动多任务环境*}voidCommTask(void*pdata)*通讯任务*{for(){*任务代码*}}OSTaskCreateExt()INTUOSTaskCreateExt(void(*task)(void*pd),void*pdata,OSSTK*ptos,INTUprio,INTUid,OSSTK*pbos,INTUstksize,void*pext,INTUopt)所属文件调用者开关量OSTASKC任务或初始化代码无OSTaskCreateExt()建立一个新任务。与OSTaskCreate()不同的是OSTaskCreateExt()允许用户设置更多的细节内容。任务的建立可以在多任务环境启动之前也可以在正在运行的任务中建立但中断处理程序中不能建立新任务。一个任务必须为无限循环结构(如下所示)且不能有返回点。参数task是指向任务代码的指针。Pdata指针指向一个数据结构该结构用来在建立任务时向任务传递参数。下例中说明μCOS中的任务代码结构以及如何传递参数pdata:(如果在程序中不使用参数pdata为了避免在编译中出现“参数未使用”的警告信息可以写一句pdata=pdata译者注)voidTask(void*pdata){*对参数pdata进行操作例如pdata=pdata*for(){*任务函数体总是为无限循环结构**任务中必须调用如下的函数:**OSMboxPend()**OSQPend()**OSSemPend()**OSTimeDly()**OSTimeDlyHMSM()**OSTaskSuspend()(挂起任务自身)**OSTaskDel()(删除任务自身)*}}ptos为指向任务堆栈栈顶的指针。任务堆栈用来保存局部变量函数参数返回地址以及中断时的CPU寄存器内容。任务堆栈的大小决定于任务的需要及预计的中断嵌套层数。计算堆栈的大小需要知道任务的局部变量所占的空间可能产生嵌套调用的函数及中断嵌套所需空间。如果初始化常量OSSTKGROWTH设为堆栈被设为向低端增长(从内存高地址向低地址增长)。此时ptos应该指向任务堆栈空间的最高地址。反之如果OSSTKGROWTH设为堆栈将从低地址向高地址增长。prio为任务的优先级。每个任务必须有一个唯一的优先级作为标识。数字越小优先级越高。id是任务的标识目前这个参数没有实际的用途但保留在OSTaskCreateExt()中供今后扩展应用程序中可设置id与优先级相同。pbos为指向堆栈底端的指针。如果初始化常量OSSTKGROWTH设为堆栈被设为从内存高地址向低地址增长。此时pbos应该指向任务堆栈空间的最低地址。反之如果OSSTKGROWTH设为堆栈将从低地址向高地址增长。pbos应该指向堆栈空间的最高地址。参数pbos用于堆栈检测函数OSTaskStkChk()。stksize指定任务堆栈的大小。其单位由OSSTK定义:当OSSTK的类型定义为INTU、INTU、INTU的时候stksize的单位为分别为字节(位)、字(位)和双字(位)。pext是一个用户定义数据结构的指针可作为TCB的扩展。例如当任务切换时用户定义的数据结构中可存放浮点寄存器的数值任务运行时间任务切入次数等等信息。opt存放与任务相关的操作信息。opt的低位由μCOS保留用户不能使用。用户可以使用opt的高位。每一种操作由opt中的一位或几位指定当相应的位被置位时表示选择某种操作。当前的μCOS版本支持下列操作:·OSTASKOPTSTKCHK:决定是否进行任务堆栈检查。·OSTASKOPTSTKCLR:决定是否清空堆栈。·OSTASKOPTSAVEFP:决定是否保存浮点寄存器的数值。此项操作仅当处理器有浮点硬件时有效。保存操作由硬件相关的代码完成。其他操作请参考文件uCOSIIH。返回值OSTaskCreateExt()的返回值为下述之一:·OSNOERR:函数调用成功。·OSPRIOEXIST:具有该优先级的任务已经存在。·OSPRIOINVALID:参数指定的优先级大于OSLOWESTPRIO。·OSNOMORETCB:系统中没有OSTCB可以分配给任务了。注意警告任务堆栈必须声明为OSSTK类型。在任务中必须进行μCOS提供的下述过程之一:延时等待、任务挂起、等待事件发生(等待信号量消息邮箱、消息队列)以使其他任务得到CPU。用户程序中不能使用优先级以及OSLOWESTPRIO,OSLOWESTPRIO,OSLOWESTPRIO,OSLOWESTPRIO。这些优先级μCOS系统保留其余个优先级提供给应用程序。范例:本例中使用了一个用户自定义的数据结构TASKUSERDATA标识()在其中保存了任务名称和其他一些数据。任务名称可以用标准库函数strcpy()初始化标识()。在本例中允许堆栈检查操作标识()程序可以调用OSTaskStkChk()函数。本例中设定堆栈向低地址方向增长标识()。本例中OSSTKGROWTH设为。程序注释中的TOS意为堆栈顶端(Top–Of–Stack)BOS意为堆栈底顶端(Bottom–Of–Stack)。typedefstruct{*用户定义的数据结构()*charTaskNameINTUTaskCtrINTUTaskExecTimeINTUTaskTotExecTime}TASKUSERDATAOSSTKTaskStkTASKUSERDATATaskUserDatavoidmain(void){INTUerrOSInit()*初始化オCOSII*strcpy(TaskUserDataTaskName,"MyTaskName")*任务名()*err=OSTaskCreateExt(Task,(void*),TaskStk,*堆栈向低地址增长(TOS)()*,TaskStk,*堆栈向低地址增长(BOS)()*,(void*)TaskUserData,*TCB的扩展*OSTASKOPTSTKCHK)*允许堆栈检查()*OSStart()*启动多任务环境*}voidTask(void*pdata){pdata=pdata*此句可避免编译中的警告信息*for(){*任务代码*}}范例:本例中创立的任务将运行在堆栈向高地址增长的处理器上标识()例如Intel的MCS。此时OSSTKGROWTH设为。在本例中允许堆栈检查操作标识()程序可以调用OSTaskStkChk()函数。程序注释中的TOS意为堆栈顶端(Top–Of–Stack)BOS意为堆栈底顶端(Bottom–Of–Stack)。OSSTK*TaskStkvoidmain(void){INTUerrOSInit()*初始化オCOSII*err=OSTaskCreateExt(Task,(void*),TaskStk,*堆栈向高地址增长(TOS)()*,,TaskStk,*堆栈向高地址增长(BOS)()*,(void*),OSTASKOPTSTKCHK)*允许堆栈检查()*OSStart()*启动多任务环境*}voidTask(void*pdata){pdata=pdata*此句可避免编译中出现警告信息*for(){*任务代码*}}OSTaskDel()INTUOSTaskDel(INTUprio)所属文件调用者开关量OSTASKC只能是任务OSTASKDELENOSTaskDel()函数删除一个指定优先级的任务。任务可以传递自己的优先级给OSTaskDel()从而删除自身。如果任务不知道自己的优先级还可以传递参数OSPRIOSELF。被删除的任务将回到休眠状态。任务被删除后可以用函数OSTaskCreate()或OSTaskCreateExt()重新建立。参数prio为指定要删除任务的优先级也可以用参数OSPRIOSELF代替此时下一个优先级最高的就绪任务将开始运行。返回值OSTaskDel()的返回值为下述之一:·OSNOERR:函数调用成功。·OSTASKDELIDLE:错误操作试图删除空闲任务(Idletask)。·OSTASKDELERR:错误操作指定要删除的任务不存在。·OSPRIOINVALID:参数指定的优先级大于OSLOWESTPRIO。·OSTASKDELISR:错误操作试图在中断处理程序中删除任务。注意警告OSTaskDel()将判断用户是否试图删除μCOS中的空闲任务(Idletask)。在删除占用系统资源的任务时要小心此时为安全起见可以用另一个函数OSTaskDelReq()。范例:voidTaskX(void*pdata){INTUerrfor(){err=OSTaskDel()*删除优先级为的任务*if(err==OSNOERR){*任务被删除*}}}OSTaskDelReq()INTUOSTaskDel(INTUprio)所属文件调用者开关量OSTASKC只能是任务OSTASKDELENOSTaskDelReq()函数请求一个任务删除自身。通常OSTaskDelReq()用于删除一个占有系统资源的任务(例如任务建立了信号量)。对于此类任务在删除任务之前应当先释放任务占用的系统资源。具体的做法是:在需要被删除的任务中调用OSTaskDelReq()检测是否有其他任务的删除请求如果有则释放自身占用的资源然后调用OSTaskDel()删除自身。例如假设任务要删除任务而任务占有系统资源此时任务不能直接调用OSTaskDel()删除任务而应该调用OSTaskDelReq()向任务发送删除请求。在任务中调用OSTaskDelReq(OSPRIOSELF)并检测返回值。如果返回OSTASKDELREQ则表明有来自其他任务的删除请求此时任务应该先释放资源然后调用OSTaskDel(OSPRIOSELF)删除自己。任务可以循环调用OSTaskDelReq()并检测返回值如果返回OSTASKNOTEXIST表明任务已经成功删除。参数prio为要求删除任务的优先级。如果参数为OSPRIOSELF则表示调用函数的任务正在查询是否有来自其他任务的删除请求。返回值OSTaskDelReq()的返回值为下述之一:·OSNOERR:删除请求已经被任务记录。·OSTASKNOTEXIST:指定的任务不存。发送删除请求的任务可以等待此返回值看删除是否成功。·OSTASKDELIDLE:错误操作试图删除空闲任务(Idletask)。·OSPRIOINVALID:参数指定的优先级大于OSLOWESTPRIO或没有设定OSPRIOSELF的值。·OSTASKDELREQ:当前任务收到来自其他任务的删除请求。注意警告OSTaskDelReq()将判断用户是否试图删除μCOS中的空闲任务(Idletask)。范例:voidTaskThatDeletes(void*pdata)*任务优先级*{INTUerrfor(){err=OSTaskDelReq()*请求任务#删除自身*if(err==OSNOERR){err=OSTaskDelReq()while(err!=OSTASKNOTEXIST){OSTimeDly()*等待任务删除*}*任务#已被删除*}}}voidTaskToBeDeleted(void*pdata)*任务优先级*{pdata=pdatafor(){OSTimeDly()if(OSTaskDelReq(OSPRIOSELF)==OSTASKDELREQ){*释放任务占用的系统资源**释放动态分配的内存*OSTaskDel(OSPRIOSELF)}}}OSTaskQuery()INTUOSTaskQuery(INTUprio,OSTCB*pdata)所属文件调用者开关量OSTASKC任务或中断无OSTaskQuery()用于获取任务信息函数返回任务TCB的一个完整的拷贝。应用程序必须建立一个OSTCB类型的数据结构容纳返回的数据。需要提醒用户的是在对任务OSTCB对象中的数据操作时要小心尤其是数据项OSTCBNext和OSTCBPrev。它们分别指向TCB链表中的后一项和前一项。参数prio为指定要获取TCB内容的任务优先级也可以指定参数OSPRIOSELF获取调用任务的信息。pdata指向一个OSTCB类型的数据结构容纳返回的任务TCB的一个拷贝。返回值OSTaskQuery()的返回值为下述之一:·OSNOERR:函数调用成功。·OSPRIOERR:参数指定的任务非法。·OSPRIOINVALID:参数指定的优先级大于OSLOWESTPRIO。注意警告任务控制块(TCB)中所包含的数据成员取决于下述开关量在初始化时的设定(参见OSCFGH)·OSTASKCREATEEN·OSQEN·OSMBOXEN·OSSEMEN·OSTASKDELEN范例:voidTask(void*pdata){OSTCBtaskdataINTUerrvoid*pextINTUstatuspdata=pdatafor(){err=OSTaskQuery(OSPRIOSELF,taskdata)if(err==OSNOERR){pext=taskdataOSTCBExtPtr*获取TCB扩展数据结构的指针*status=taskdataOSTCBStat*获取任务状态*}}}OSTaskResume()INTUOSTaskResume(INTUprio)所属文件调用者开关量OSTASKC只能是任务OSTASKSUSPENDENOSTaskResume()唤醒一个用OSTaskSuspend()函数挂起的任务。OSTaskResume()也是唯一能“解挂”挂起任务的函数。参数prio指定要唤醒任务的优先级。返回值OSTaskResume()的返回值为下述之一:·OSNOERR:函数调用成功。·OSTASKRESUMEPRIO:要唤醒的任务不存在。·OSTASKNOTSUSPENDED:要唤醒的任务不在挂起状态。·OSPRIOINVALID:参数指定的优先级大于或等于OSLOWESTPRIO。注意警告无范例:voidTaskX(void*pdata){INTUerrfor(){err=OSTaskResume()*唤醒优先级为的任务*if(err==OSNOERR){*任务被唤醒*}}}OSTaskStkChk()INTUOSTaskStkChk(INTUprio,OSSTKDATA*pdata)所属文件调用者开关量OSTASKC只能是任务OSTASKCREATEEXTOSTaskStkChk()检查任务堆栈状态计算指定任务堆栈中的未用空间和已用空间。使用OSTaskStkChk()函数要求所检查的任务是被OSTaskCreateExt()函数建立的且opt参数中OSTASKOPTSTKCHK操作项打开。计算堆栈未用空间的方法是从堆栈底端向顶端逐个字节比较检查堆栈中的个数直到一个非的数值出现。这种方法的前提是堆栈建立时已经全部清零。要实现清零操作需要在任务建立初始化堆栈时设置OSTASKOPTSTKCLR为。如果应用程序在初始化时已经将全部RAM清零且不进行任务删除操作也可以设置OSTASKOPTSTKCLR为这将加快OSTaskCreateExt()函数的执行速度。参数prio为指定要获取堆栈信息的任务优先级也可以指定参数OSPRIOSELF获取调用任务本身的信息。pdata指向一个类型为OSSTKDATA的数据结构其中包含如下信息:INTUOSFree*堆栈中未使用的字节数*INTUOSUsed*堆栈中已使用的字节数*返回值OSTaskStkChk()的返回值为下述之一:·OSNOERR:函数调用成功。·OSPRIOINVALID:参数指定的优先级大于OSLOWESTPRIO或未指定OSPRIOSELF。·OSTASKNOTEXIST:指定的任务不存在。·OSTASKOPTERR:任务用OSTaskCreateExt()函数建立的时候没有指定OSTASKOPTSTKCHK操作或者任务是用OSTaskCreate()函数建立的。注意警告函数的执行时间是由任务堆栈的大小决定的事先不可预料。在应用程序中可以把OSSTKDATA结构中的数据项OSFree和OSUsed相加可得到堆栈的大小。虽然原则上该函数可以在中断程序中调用但由于该函数可能执行很长时间所以实际中不提倡这种做法。范例:voidTask(void*pdata){OSSTKDATAstkdataINTUstksizefor(){err=OSTaskStkChk(,stkdata)if(err==OSNOERR){stksize=stkdataOSFreestkdataOSUsed}}}OSTaskSuspend()INTUOSTaskSuspend(INTUprio)所属文件调用者开关量OSTASKC只能是任务OSTASKSUSPENDENOSTaskSuspend()无条件挂起一个任务。调用此函数的任务也可以传递参数OSPRIOSELF挂起调用任务本身。当前任务挂起后只有其他任务才能唤醒。任务挂起后系统会重新进行任务调度运行下一个优先级最高的就绪任务。唤醒挂起任务需要调用函数OSTaskResume()。任务的挂起是可以叠加到其他操作上的。例如任务被挂起时正在进行延时操作那么任务的唤醒就需要两个条件:延时的结束以及其他任务的唤醒操作。又如任务被挂起时正在等待信号量当任务从信号量的等待对列中清除后也不能立即运行而必须等到唤醒操作后。参数prio为指定要获取挂起的任务优先级也可以指定参数OSPRIOSELF挂起任务本身。此时下一个优先级最高的就绪任务将运行。返回值OSTaskSuspend()的返回值为下述之一:·OSNOERR:函数调用成功。·OSTASKSUSPENDIDLE:试图挂起μCOSII中的空闲任务(Idletask)。此为非法操作。·OSPRIOINVALID:参数指定的优先级大于OSLOWESTPRIO或没有设定OSPRIOSELF的值。·OSTASKSUSPENDPRIO:要挂起的任务不存在。注意警告在程序中OSTaskSuspend()和OSTaskResume()应该成对使用。用OSTaskSuspend()挂起的任务只能用OSTaskResume()唤醒。范例:voidTaskX(void*pdata){INTUerrfor(){err=OSTaskSuspend(OSPRIOSELF)*挂起当前任务**当其他任务唤醒被挂起任务时任务可继续运行*}}OSTimeDly()voidOSTimeDly(INTUticks)所属文件调用者开关量OSTIMCC只能是任务无OSTimeDly()将一个任务延时若干个时钟节拍。如果延时时间大于系统将立即进行任务调度。延时时间的长度可从到个时钟节拍。延时时间表示不进行延时函数将立即返回调用者。延时的具体时间依赖于系统每秒钟有多少时钟节拍(由文件SOCFGH中的常量OSTICKSPERSEC设定)。参数ticks为要延时的时钟节拍数。返回值无注意警告注意到延时时间表示不进行延时操作而立即返回调用者。为了确保设定的延时时间建议用户设定的时钟节拍数加。例如希望延时个时钟节拍可设定参数为。范例:voidTaskX(void*pdata){for(){OSTimeDly()*任务延时个时钟节拍*}}OSTimeDlyHMSM()voidOSTimeDlyHMSM(INTUhoursINTUminutesINTUsecondsINTUmilli)所属文件调用者开关量OSTIMCC只能是任务无OSTimeDlyHMSM()将一个任务延时若干时间。延时的单位是小时、分、秒、毫秒。所以使用OSTimeDlyHMSM()比OSTimeDly()更方便。调用OSTimeDlyHMSM()后如果延时时间不为系统将立即进行任务调度。参数hours为延时小时数范围从。minutes为延时分钟数范围从。seconds为延时秒数范围从milli为延时毫秒数范围从。需要说明的是延时操作函数都是以时钟节拍为为单位的。实际的延时时间是时钟节拍的整数倍。例如系统每次时钟节拍间隔是ms如果设定延时为ms将不产生任何延时操作而设定延时ms实际的延时是两个时钟节拍也就是ms。返回值·OSTimeDlyHMSM()的返回值为下述之一:·OSNOERR:函数调用成功。·OSTIMEINVALIDMINUTES:参数错误分钟数大于。·OSTIMEINVALIDSECONDS:参数错误秒数大于。·OSTIMEINVALIDMILLI:参数错误毫秒数大于。·OSTIMEZERODLY:四个参数全为。注意警告OSTimeDlyHMSM()表示不进行延时操作而立即返回调用者。另外如果延时总时间超过个时钟节拍将不能用OSTimeDlyResume()函数终止延时并唤醒任务。范例:voidTaskX(void*pdata){for(){OSTimeDlyHMSM(,,,)*任务延时秒*}}OSTimeDlyResume()voidOSTimeDlyResume(INTUprio)所属文件调用者开关量OSTIMCC只能是任务无OSTimeDlyResume()唤醒一个用OSTimeDly()或OSTimeDlyHMSM()函数延时的任务。参数prio为指定要唤醒任务的优先级。返回值OSTimeDlyResume()的返回值为下述之一:·OSNOERR:函数调用成功。·OSPRIOINVALID:参数指定的优先级大于OSLOWESTPRIO。·OSTIMENOTDLY:要唤醒的任务不在延时状态。·OSTASKNOTEXIST:指定的任务不存在。注意警告用户不应该用OSTimeDlyResume()去唤醒一个设置了等待超时操作并且正在等待事件发生的任务。操作的结果是使该任务结束等待除非的确希望这么做。OSTimeDlyResume()函数不能唤醒一个用OSTimeDlyHMSM()延时且延时时间总计超过个时钟节拍的任务。例如如果系统时钟为HzOSTimeDlyResume()不能唤醒延时OSTimeDlyHMSM()或更长时间的任务。(OSTimeDlyHMSM()共延时minutes*()seconds*=,次时钟节拍译者注)范例:voidTaskX(void*pdata){INTUerrpdata=pdatafor(){err=OSTimeDlyResume()*唤醒优先级为的任务*if(err==OSNOERR){*任务被唤醒*}}}OSTimeGet()INTUOSTimeGet(void)所属文件调用者开关量OSTIMCC任务或中断无OSTimeGet()获取当前系统时钟数值。系统时钟是一个位的计数器记录系统上电后或时钟重新设置后的时钟计数。参数无。返回值当前时钟计数(时钟节拍数)。注意警告无范例:voidTaskX(void*pdata){INTUclkfor(){clk=OSTimeGet()*获取当前系统时钟的值*}}OSTimeSet()voidOSTimeSet(INTUticks)所属文件调用者开关量OSTIMCC任务或中断无OSTimeSet()设置当前系统时钟数值。系统时钟是一个位的计数器记录系统上电后或时钟重新设置后的时钟计数。参数ticks要设置的时钟数单位是时钟节拍数。返回值无。注意警告无范例:voidTaskX(void*pdata){for(){OSTimeSet(L)*复位系统时钟*}}OSTimeTick()voidOSTimeTick(void)所属文件调用者开关量OSTIMCC任务或中断无每次时钟节拍μCOSII都将执行OSTimeTick()函数。OSTimeTick()检查处于延时状态的任务是否达到延时时间(用OSTimeDly()或OSTimeDlyHMSM()函数延时)或正在等待事件的任务是否超时。参数`无。返回值无。注意警告OSTimeTick()的运行时间和系统中的任务数直接相关在任务或中断中都可以调用。如果在任务中调用任务的优先级应该很高(优先级数字很小)这是因为OSTimeTick()负责所有任务的延时操作。范例:(Intel 80x86实模式)TickISRPROCFARPUSHA保存CPU寄存器内容PUSHESPUSHDSINCBYTEPTROSIntNesting标识COSII进入中断处理程序CALLFARPTROSTimeTick调用时钟节拍处理函数用户代码清除中断标志CALLFARPTROSIntExit标识COSII退出中断处理程序POPDS恢复CPU寄存器内容POPESPOPAIRET中断返回TickISRENDPOSVersion()INTUOSVersion(void)所属文件调用者开关量OSCOREC任务或中断无OSVersion()获取当前μCOSII的版本。参数`无。返回值当前版本格式为xyy返回值为乘以后的数值。例如当前版本则返回。注意警告无范例:voidTaskX(void*pdata){INTUosversionfor(){osversion=OSVersion()*获取uCOSII's的版本*}}OSENTERCRITICAL()OSEXITCRITICAL()所属文件调用者开关量OSCPUC任务或中断无OSENTERCRITICAL()和OSEXITCRITICAL()为定义的宏用来关闭、打开CPU的中断。参数`无。返回值无。注意警告OSENTERCRITICAL()和OSEXITCRITICAL()必须成对使用。范例:voidTaskX(void*pdata){for(){OSENTERCRITICAL()*关闭中断**进入核心代码*OSEXITCRITICAL()*打开中断*}

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

文档小程序码

使用微信“扫一扫”扫码寻找文档

1

打开微信

2

扫描小程序码

3

发布寻找信息

4

等待寻找结果

我知道了
评分:

/87

第11章

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利