ImageVerifierCode 换一换
格式:DOCX , 页数:12 ,大小:22.17KB ,
资源ID:4746450      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4746450.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(UCOSII概念及内核.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

UCOSII概念及内核.docx

1、UCOSII概念及内核UCOS-II概念及内核实时系统概念 1. 有两种类型的实时系统:软实时系统和硬实时系统。在软实时系统中系统的宗旨是使各个任务运行得越快越好,并不要求限定某一任务必须在多长时间内完成。在硬实时系统中,各任务不仅要执行无误而且要做到准时。 2. 前后台系统: 应用程序是一个无限的循环,循环中调用相应的函数完成相应的操作,这部分可以看成后台行为(background)。中断服务程序处理异步事件,这部分可以看成前台行为(foreground)。后台也可以叫做任务级。前台也叫中断级。 3. 可重入型函数: 可重入型函数可以被一个以上的任务调用,而不必担心数据的破坏。可重入型函数任

2、何时候都可以被中断,一段时间以后又可以运行,而相应数据不会丢失。可重入型函数或者只使用局部变量,即变量保存在CPU寄存器中或堆栈中。如果使用全局变量,则要对全局变量予以保护。以下技术之一即可使不可重入函数具有可重入性: , 把变量定义为局部变量 , 调用函数之前关中断,调动后再开中断 , 用信号量禁止该函数在使用过程中被再次调用 4. 优先级反转: 应用程序执行过程中,任务的优先级是可变的,则称之为动态优先级。实时内核应当避免出现优先级反转问题。为防止发生优先级反转,内核能自动变换任务的优先级,这叫做优先级继承(Priority inheritance) 5. 互斥条件:实现任务间通讯最简便到

3、办法是使用共享数据结构。特别是当所有到任务都在一个单一地址空间下,能使用全程变量、指针、缓冲区、链表、循环缓冲区等,使用共享数据结构通讯就更为容易。虽然共享数据区法简化了任务间的信息交换,但是必须保证每个任务在处理共享数据时的排它性,以避免竞争和数据的破坏。与共享资源打交道时,使之满足互斥条件最一般的方法有: , 关中断(C/OS-?在处理内部变量和数据结构时就是使用的这种手段) , 使用测试并置位指令 , 禁止做任务切换 , 利用信号量 6. 信号量:信号量用于: , 控制共享资源的使用权(满足互斥条件) , 标志某事件的发生 , 使两个任务的行为同步 对信号量只能实施三种操作: , 初始化

4、(INITIALIZE),也可称作建立(CREATE); , 等信号(WAIT)也可称作挂起(PEND); , 给信号(SIGNAL)或发信号(POST)。 这是我自己写的验证信号量的部分代码: void task_one(void* pdata); void task_two(void* pdata); OS_EVENT *tasktwo; #include includes.h GUI_Init(); VCInit(); /初始化一些变量 OSInit(); timeSetEvent(OS_TICKS_PER_SEC, 0, OSTickISR, 0, TIME_PERIODIC); /产

5、生节拍 tasktwo = OSSemCreate(0); OSTaskCreate(task_two, 0, &TaskStk7TASK_STK_SIZE-1, 1); OSTaskCreate(task_one, 0, &TaskStk8TASK_STK_SIZE-1, 2); OSStart(); 7. 使用实时内核的优缺点: 实时内核也称为实时操作系统或RTOS。它的使用使得实时应用程序的设计和扩展变得容易,不需要大的改动就可以增加新的功能。通过将应用程序分割成若干独立的任务,RTOS使得应用程序的设计过程大为减化。使用可剥夺性内核时,所有时间要求苛刻的事件都得到了尽可能快捷、有效的处

6、理。通过有效的服务,如信号量、邮箱、队列、延时、超时等,RTOS使得资源得到更好的利用。如果应用项目对额外的需求可以承受,应该考虑使用实时内核。这些额外的需求是:内核的价格,额外的ROM/RAM开销,2到4百分点的CPU额外负荷。 内核结构 1. 任务: 一个任务通常是一个无限的循环。看起来像其它C的函数一样,有函数返回类型,有形式参数变量,但是任务是绝不会返回的。故返回参数必须定义成void。当任务完成以后任务代码并非真的删除了,C/OS-?只是简单地不再理会这个任务了。 列出一任务: void YourTask (void *pdata) (1) for (;) (2) /* 用户代码 *

7、/ 调用uC/OS-II的某种系统服务: OSMboxPend(); OSQPend(); OSSemPend(); OSTaskDel(OS_PRIO_SELF); OSTaskSuspend(OS_PRIO_SELF); OSTimeDly(); OSTimeDlyHMSM(); /* 用户代码 */ 形式参数变量(1)是由用户代码在第一次执行的时候带入的。该变量的类型是一个指向void的指针。这是为了允许用户应用程序传递任何类型的数据给任务。C/OS-?可以管理多达64个任务,但目前版本的C/OS-?有两个任务已经被系统占用了。作者保留了优先级为0、1、2、3、OS_LOWEST_PRI

8、O-3、OS_LOWEST_PRI0-2,OS_LOWEST_PRI0-1以及OS_LOWEST_PRI0这8个任务以被将来使用。为了使C/OS-?能管理用户任务,用户必须在建立一个任务的时候,将任务的起始地址与其它参数一起传给下面两个函数中的一个:OSTastCreat或OSTaskCreatExt()。 2. 任务控制块:一旦任务建立了,任务控制块OS_TCBs将被赋值。任务控制块是一个数据结构,当任务的CPU使用权被剥夺时,C/OS-?用它来保存该任务的状态。当任务重新得到CPU使用权时,任务控制块能确保任务从当时被中断的那一点丝毫不差地继续执行。OS_TCBs全部驻留在RAM中。 C/

9、OS-II任务控制块清单: typedef struct os_tcb OS_STK *OSTCBStkPtr; /指向当前任务栈顶的指针。每个任务的栈的容量可以是/任意的。 #if OS_TASK_CREATE_EXT_EN void *OSTCBExtPtr; /指向用户定义的任务控制块扩展 OS_STK *OSTCBStkBottom; /是指向任务栈底的指针 INT32U OSTCBStkSize; /存有栈中可容纳的指针元数目 INT16U OSTCBOpt; /把“选择项”传给OSTaskCreateExt() INT16U OSTCBId; /存储任务的识别码,留给将来扩展用 #

10、endif /用于任务控制块OS_TCBs的双重链接,该链表在时钟节 struct os_tcb *OSTCBNext; /拍函数OSTimeTick()中使用,用于刷新各个任务的任 struct os_tcb *OSTCBPrev; /务延迟变量. #if (OS_Q_EN & (OS_MAX_QS = 2) | OS_MBOX_EN | OS_SEM_EN OS_EVENT *OSTCBEventPtr; /指向事件控制块的指针 #endif #if (OS_Q_EN & (OS_MAX_QS = 2) | OS_MBOX_EN void *OSTCBMsg; /是指向传给任务的消息的指针

11、 #endif INT16U OSTCBDly; INT8U OSTCBStat; INT8U OSTCBPrio; INT8U OSTCBX; INT8U OSTCBY; INT8U OSTCBBitX; INT8U OSTCBBitY; #if OS_TASK_DEL_EN BOOLEAN OSTCBDelReq; #endif OS_TCB; 目前,一个用于空闲任务,另一个用于任务统计(如果OS_TASK_STAT_EN是设为1的)。在C/OS-?初始化的时候,所有任务控制块OS_TCBs被链接成单向空任务链表。当任务一旦建立,空任务控制块指针OSTCBFreeList指向的任务控制块便

12、赋给了该任务,然后OSTCBFreeList的值调整为指向下链表中下一个空的任务控制块。一旦任务被删除,任务控制块就还给空任务链表。 3. 就绪表(Ready List):每个任务被赋予不同的优先级等级,从0级到最低优先级OS_LOWEST_PR1O。每个任务的就绪态标志都放入就绪表中的,就绪表中有两个变量OSRedyGrp和OSRdyTbl。在OSRdyGrp中,任务按优先级分组,8个任务为一组。OSRdyGrp中的每一位表示8组任务中每一组中是否有进入就绪态的任务。任务进入就绪态时,就绪表OSRdyTbl中的相应元素的相应位也置位。 以下程序清单中的代码用于将任务放入就绪表。Prio是任务

13、的优先级 OSRdyGrp |= OSMapTblprio 3; OSRdyTblprio 3 |= OSMapTblprio & 0x07; 如果一个任务被删除了,则用程序清单中的代码做求反处理 if (OSRdyTblprio 3 &= OSMapTblprio & 0x07) = 0) OSRdyGrp &= OSMapTblprio 3; 找出进入就绪态的优先级最高的任务 y = OSUnMapTblOSRdyGrp; x = OSUnMapTblOSRdyTbly; prio = (y OS_LOWEST_PRIO) /检测分配给任务的优先级是否有效 return (OS_PRIO_

14、INVALID); OS_ENTER_CRITICAL(); /关中断 if (OSTCBPrioTblprio = (OS_TCB *)0) /确保在规定的优先级上还没有建立任务 OSTCBPrioTblprio = (OS_TCB *)1; /放置一个非空指针保留该优先级 OS_EXIT_CRITICAL(); /开中断 psp = (void *)OSTaskStkInit(task, pdata, ptos, 0); /建立任务的堆栈 err = OSTCBInit(prio, psp, (void *)0, 0, 0, (void *)0, 0); /从空闲的OS_TCB池中获得并初

15、始化一个OS_TCB if (err = OS_NO_ERR) OS_ENTER_CRITICAL(); OSTaskCtr+; /于保存产生的任务数目 OSTaskCreateHook(OSTCBPrioTblprio); /户自己定义的函数,用来扩展OSTaskCreate()的功能 OS_EXIT_CRITICAL(); if (OSRunning) /如果OSTaskCreate()函数是在某个任务的执行过程中被调用 OSSched(); /调用调度函数 else OS_ENTER_CRITICAL(); OSTCBPrioTblprio = (OS_TCB *)0; /放弃该任务的优

16、先级 OS_EXIT_CRITICAL(); return (err); else OS_EXIT_CRITICAL(); return (OS_PRIO_EXIST); 用OSTaskCreateExt()函数来建立任务会更加灵活,但会增加一些额外的开销。其内部结构与OSTaskCreate()大体相同。 2. 任务堆栈:每个任务都有自己的堆栈空间。堆栈必须声明为OS_STK类型,并且由连续的内存空间组成。用户可以静态分配堆栈空间(在编译的时候分配)也可以动态地分配堆栈空间(在运行的时候分配)。C/OS-?支持的处理器的堆栈既可以从上(高地址)往下(低地址)长也可以从下往上长。用户在调用OS

17、TaskCreate()或OSTaskCreateExt()的时候必须知道堆栈是怎样长的,因为用户必须得把堆栈的栈顶传递给以上两个函数,当OS_CPU.H文件中的OS_STK_GROWTH置为0时,用户需要将堆栈的最低内存地址传递给任务创建函数,当OS_CPU.H文件中的OS_STK_GROWTH置为1时,用户需要将堆栈的最高内存地址传递给任务创建函数。任务所需的堆栈的容量是由应用程序指定的。用户在指定堆栈大小的时候必须考虑用户的任务所调用的所有函数的嵌套情况,任务所调用的所有函数会分配的局部变量的数目,以及所有可能的中断服务例程嵌套的堆栈需求。另外,用户的堆栈必须能储存所有的CPU寄存器。

18、3. 堆栈检验OSTaskStkChk(): 为了使用C/OS-?的堆栈检验功能,用户必须要做以下几件事情: , 在OS_CFG.H文件中设OS_TASK_CREATE_EXT为1。 , 用OSTaskCreateExt()建立任务,并给予任务比实际需要更多的内存空间。 , 在OSTaskCreateExt()中,将参数opt设置为OS_TASK_OPT_STK_CHK+ OS_TASK_OPT_STK_ CLR。注意如果用户的程序启动代码清除了所有的RAM,并且从未删除过已建立了的任务,那么用户就不必设置选项OS_TASK_OPT_STK_CLR了。这样就会减少OSTaskCreateExt

19、()的执行时间。 , 将用户想检验的任务的优先级作为OSTaskStkChk()的参数并调用之。 OSTaskStkChk()顺着堆栈的栈底开始计算空闲的堆栈空间大小。具体实现方法是统计储存值为0的连续堆栈入口的数目,直到发现储存值不为0的堆栈入口。用户应该使自己的应用程序运行足够长的时间,并且经历最坏的堆栈使用情况,这样才能得到正确的数。 4. 删除任务OSTaskDel():删除任务,是说任务将返回并处于休眠状态,并不是说任务的代码被删除了,只是任务的代码不再被C/OS-?调用。过调用OSTaskDel()就可以完成删除任务的功能。 删除任务程序清单 INT8U OSTaskDel (IN

20、T8U prio) OS_TCB *ptcb; OS_EVENT *pevent; if (prio = OS_IDLE_PRIO) /确保用户所要删除的任务并非是空闲任务 return (OS_TASK_DEL_IDLE); if (prio = OS_LOWEST_PRIO & prio != OS_PRIO_SELF) /用户可以删除statistic任务 return (OS_PRIO_INVALID); OS_ENTER_CRITICAL(); if (OSIntNesting 0) /确保用户不是在ISR例程中去试图删除一个任务 OS_EXIT_CRITICAL(); return

21、 (OS_TASK_DEL_ISR); if (prio = OS_PRIO_SELF) /任务可以通过指定OS_PRIO_SELF参数来删除自己 Prio = OSTCBCur-OSTCBPrio; if (ptcb = OSTCBPrioTblprio) != (OS_TCB *)0) /保证被删除的任务确实存在 if (OSRdyTblptcb-OSTCBY &= ptcb-OSTCBBitX) = 0) OSRdyGrp &= ptcb-OSTCBBitY; /任务处于就绪表中,它会直接被移除 if (pevent = ptcb-OSTCBEventPtr) != (OS_EVENT

22、*)0) if (pevent-OSEventTblptcb-OSTCBY &= ptcb-OSTCBBitX) = 0) /如果任务处于邮箱、消息队列或信号量的等待表中,它就从自己所处的表中被移除 pevent-OSEventGrp &= ptcb-OSTCBBitY; Ptcb-OSTCBDly = 0; /将任务的时钟延迟数清零,以确保自己重新允许中断的时候,ISR例程不会使该任务就绪 Ptcb-OSTCBStat = OS_STAT_RDY; /阻止其它任务或ISR例程让该任务重新开始执行 OSLockNesting+; /阻止任务调度程序在删除过程中切换到其它的任务中去 OS_EXI

23、T_CRITICAL(); /重新允许中断以减少中断的响应时间 OSDummy(); /确保在再次禁止中断之前至少执行了一个调用指令和一个返回指令 OS_ENTER_CRITICAL(); OSLockNesting-; /锁定嵌套计数器减一以重新允许任务调度 OSTaskDelHook(ptcb); /调用用户自定义的OSTaskDelHook()函数 OSTaskCtr-; OSTCBPrioTblprio = (OS_TCB *)0;/将指向被删除的任务的OS_TCB的指针指向NULL if (ptcb-OSTCBPrev = (OS_TCB *)0) /将任务从OS_TCB双向链表中移

24、除 ptcb-OSTCBNext-OSTCBPrev = (OS_TCB *)0; OSTCBList = ptcb-OSTCBNext; else ptcb-OSTCBPrev-OSTCBNext = ptcb-OSTCBNext; ptcb-OSTCBNext-OSTCBPrev = ptcb-OSTCBPrev; ptcb-OSTCBNext = OSTCBFreeList; /OS_TCB返回到空闲OS_TCB表中,并允许其它任务的建立 OSTCBFreeList = ptcb; OS_EXIT_CRITICAL(); OSSched(); /中断服务子程序是否曾使更高优先级的任务处于

25、就绪状态 return (OS_NO_ERR); else OS_EXIT_CRITICAL(); return (OS_TASK_DEL_ERR); 5. 请求删除任务,OSTaskDelReq():有时候,如果任务A拥有内存缓冲区或信号量之类的资源,而任务B想删除该任务,这些资源就可能由于没被释放而丢失。在这种情况下,用户可以想法子让拥有这些资源的任务在使用完资源后,先释放资源,再删除自己。用户可以通过OSTaskDelReq()函数来完成该功能。 6. 改变任务的优先级OSTaskChangePrio():为了改变调用本函数的任务的优先级,用户可以指定该任务当前的优先级或OS_PRIO_

26、SELF,OSTaskChangePrio()会决定该任务的优先级。用户还必须指定任务的新(即想要的)优先级。因为C/OS-?不允许多个任务具有相同的优先级,所以OSTaskChangePrio()需要检验新优先级是否是合法的 7. 挂起任务OSTaskSuspend():挂起任务可通过调用OSTaskSuspend()函数来完成。被挂起的任务只能通过调用OSTaskResume()函数来恢复。 , OSTaskSuspend()要确保用户的应用程序不是在挂起空闲任务 , 确认用户指定优先级是有效的,记住最大的有效的优先级数是OS_LOWEST_PRIO , 检验用户是否通过指定OS_PRIO

27、_SELF来挂起调用本函数的任务本身 , 用户也可以通过指定优先级来挂起调用本函数的任务 , 检验要挂起的任务是否存在 , 在任务的OS_TCB中设置OS_STAT_SUSPEND标志,以表明任务正在被挂起 , 若被挂起的任务是调用本函数的任务本身,调用任务调度程序 任务管理2 1. 时钟节拍:C/OS-?(其它内核也一样)要求用户提供定时中断来实现延时与超时控制等功能。五个与时钟节拍有关的系统服务: , OSTimeDly() , OSTimeDlyHMSM() , OSTimeDlyResume() , OSTimeGet() , OSTimeSet() 2. 任务延时函数OSTimeDly():调用该函数会使C/OS-?进行一次任务调度,并且执行下一个优先级最高的就绪态任务。 其实现过程如下: , 如果用户指定0值,则表明用户不想延时任务,函数会立即返回到调用者 ,

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1