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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

UCOS2笔记.docx

1、UCOS2笔记目录内核结构 2临界段(Critical Sections) 2任务 2任务控制块(Task Control Blocks, OS_TCBs) 5就绪表(Ready List) 9任务调度(Task Scheduling) 11给调度器上锁和开锁(Locking and UnLocking the Scheduler) 12空闲任务(Idle Task) 14统计任务 14C/OS-中的中断处理 18时钟节拍 23C/OS-初始化 26C/OS-的启动 26获取当前C/OS-的版本号 30OSEvent?()函数 30任务管理 30建立任务,OSTaskCreate() 31建立

2、任务,OSTaskCreateExt() 35任务堆栈 38堆栈检验,OSTaskStkChk() 40删除任务,OSTaskDel() 43请求删除任务,OSTaskDelReq() 47改变任务的优先级,OSTaskChangePrio() 50挂起任务,OSTaskSuspend() 52恢复任务,OSTaskResume() 54获得有关任务的信息,OSTaskQuery() 55时间管理 57任务延时函数,OSTimeDly() 57按时分秒延时函数 OSTimeDlyHMSM() 59让处在延时期的任务结束延时,OSTimeDlyResume() 61系统时间,OSTimeGet(

3、)和OSTimeSet() 62内存管理 63内存控制块 65建立一个内存分区,OSMemCreate() 65释放一个内存块,OSMemPut() 69查询一个内存分区的状态,OSMemQuery() 70Using Memory Partitions 71等待一个内存块 73移植C/OS- 748.00 开发工具 768.01 目录和文件 768.02 INCLUDES.H 778.03 OS_CPU.H 778.04 OS_CPU_A.ASM 818.05 OS_CPU_C.C 85内核结构临界段(Critical Sections) 和其它内核一样,C/OS-为了处理临界段代码需要关中

4、断,处理完毕后再开中断。这使得C/OS-能够避免同时有其它任务或中断服务进入临界段代码。关中断的时间是实时内核开发商应提供的最重要的指标之一,因为这个指标影响用户系统对实时事件的响应性。C/OS-努力使关中断时间降至最短,但就使用C/OS-而言,关中断的时间很大程度上取决于微处理器的架构以及编译器所生成的代码质量。 微处理器一般都有关中断/开中断指令,用户使用的C语言编译器必须有某种机制能够在C中直接实现关中断/开中断地操作。某些C编译器允许在用户的C源代码中插入汇编语言的语句。这使得插入微处理器指令来关中断/开中断很容易实现。而有的编译器把从C语言中关中断/开中断放在语言的扩展部分。C/OS

5、-定义两个宏(macros)来关中断和开中断,以便避开不同C编译器厂商选择不同的方法来处理关中断和开中断。C/OS-中的这两个宏调用分别是:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。因为这两个宏的定义取决于所用的微处理器,故在文件OS_CPU.H中可以找到相应宏定义。每种微处理器都有自己的OS_CPU.H文件。一个例子就是 #define OS_ENTER_CRITICAL() EA=0 ;/移植到51,只使用中断方式1 #define OS_EXIT_CRITICAL() EA=1任务 一个任务通常是一个无限的循环L3.1(2),如程序清单3.1所示。一个

6、任务看起来像其它C的函数一样,有函数返回类型,有形式参数变量,但是任务是绝不会返回的。故返回参数必须定义成voidL3.1(1)。程序清单 L3.1 任务是一个无限循环 void YourTask (void *pdata) (1) for (;) (2) /* 用户代码 */ 调用uC/OS-II的某种系统服务: OSMboxPend(); OSQPend(); OSSemPend(); OSTaskDel(OS_PRIO_SELF); OSTaskSuspend(OS_PRIO_SELF); OSTimeDly(); OSTimeDlyHMSM(); /* 用户代码 */ 不同的是,当任务

7、完成以后,任务可以自我删除,如清单L3.2所示。注意任务代码并非真的删除了,C/OS-只是简单地不再理会这个任务了,这个任务的代码也不会再运行,如果任务调用了OSTaskDel(),这个任务绝不会返回什么。程序清单 L 3.2 . 任务完成后自我删除 void YourTask (void *pdata) /* 用户代码 */ OSTaskDel(OS_PRIO_SELF); 形式参数变量L3.1(1)是由用户代码在第一次执行的时候带入的。请注意,该变量的类型是一个指向void的指针。这是为了允许用户应用程序传递任何类型的数据给任务。这个指针好比一辆万能的车子,如果需要的话,可以运载一个变量的

8、地址,或一个结构,甚至是一个函数的地址。也可以建立许多相同的任务,所有任务都使用同一个函数(或者说是同一个任务代码程序), 见第一章的例1。例如,用户可以将四个串行口安排成每个串行口都是一个单独的任务,而每个任务的代码实际上是相同的。并不需要将代码复制四次,用户可以建立一个任务,向这个任务传入一个指向某数据结构的指针变量,这个数据结构定义串行口的参数(波特率、I/O口地址、中断向量号等)。 C/OS-可以管理多达64个任务,但目前版本的C/OS-有两个任务已经被系统占用了。作者保留了优先级为0、1、2、3、OS_LOWEST_PRIO-3、OS_LOWEST_PRI0-2,OS_LOWEST_

9、PRI0-1以及OS_LOWEST_PRI0这8个任务以被将来使用。OS_LOWEST_PRI0是作为定义的常数在OS_CFG.H文件中用定义常数语句#define constant定义的。因此用户可以有多达56个应用任务。必须给每个任务赋以不同的优先级,优先级可以从0到OS_LOWEST_PR10-2。优先级号越低,任务的优先级越高。C/OS-总是运行进入就绪态的优先级最高的任务。目前版本的C/OS-中,任务的优先级号就是任务编号(ID)。优先级号(或任务的ID号)也被一些内核服务函数调用,如改变优先级函数OSTaskChangePrio(),以及任务删除函数OSTaskDel()。 为了使

10、C/OS-能管理用户任务,用户必须在建立一个任务的时候,将任务的起始地址与其它参数一起传给下面两个函数中的一个:OSTastCreat或OSTaskCreatExt()。OSTaskCreateExt()是OSTaskCreate()的扩展,扩展了一些附加的功能。,这两个函数的解释见第四章,任务管理3.2任务状态 睡眠态(DORMANT)指任务驻留在程序空间之中,还没有交给C/OS-管理,-把任务交给C/OS-是通过调用下述两个函数之一:OSTaskCreate()或OSTaskCreateExt()。当任务一旦建立,这个任务就进入就绪态准备运行。任务的建立可以是在多任务运行开始之前,也可以是

11、动态地被一个运行着的任务建立。如果一个任务是被另一个任务建立的,而这个任务的优先级高于建立它的那个任务,则这个刚刚建立的任务将立即得到CPU的控制权。一个任务可以通过调用OSTaskDel()返回到睡眠态,或通过调用该函数让另一个任务进入睡眠态。调用OSStart()可以启动多任务。OSStart()函数运行进入就绪态的优先级最高的任务。就绪的任务只有当所有优先级高于这个任务的任务转为等待状态,或者是被删除了,才能进入运行态。 正在运行的任务可以通过调用两个函数之一将自身延迟一段时间,这两个函数是OSTimeDly()或OSTimeDlyHMSM()。这个任务于是进入等待状态,等待这段时间过去

12、,下一个优先级最高的、并进入了就绪态的任务立刻被赋予了CPU的控制权。等待的时间过去以后,系统服务函数OSTimeTick()使延迟了的任务进入就绪态(见3.10节,时钟节拍)。 正在运行的任务期待某一事件的发生时也要等待,手段是调用以下3个函数之一:OSSemPend(),OSMboxPend(),或OSQPend()。调用后任务进入了等待状态(WAITING)。当任务因等待事件被挂起(Pend),下一个优先级最高的任务立即得到了CPU的控制权。当事件发生了,被挂起的任务进入就绪态。事件发生的报告可能来自另一个任务,也可能来自中断服务子程序。正在运行的任务是可以被中断的,除非该任务将中断关了

13、,或者C/OS-将中断关了。被中断了的任务就进入了中断服务态(ISR)。响应中断时,正在执行的任务被挂起,中断服务子程序控制了CPU的使用权。中断服务子程序可能会报告一个或多个事件的发生,而使一个或多个任务进入就绪态。在这种情况下,从中断服务子程序返回之前,C/OS-要判定,被中断的任务是否还是就绪态任务中优先级最高的。如果中断服务子程序使一个优先级更高的任务进入了就绪态,则新进入就绪态的这个优先级更高的任务将得以运行,否则原来被中断了的任务才能继续运行。 当所有的任务都在等待事件发生或等待延迟时间结束,C/OS-执行空闲任务(idle task),执行OSTaskIdle()函数。任务控制块

14、(Task Control Blocks, OS_TCBs) 一旦任务建立了,任务控制块OS_TCBs将被赋值(程序清单3.3)。任务控制块是一个数据结构,作用(当任务的CPU使用权被剥夺时,C/OS-用它来保存该任务的状态)。当任务重新得到CPU使用权时,任务控制块能确保任务从当时被中断的那一点丝毫不差地继续执行。OS_TCBs全部驻留在RAM中。读者将会注意到笔者在组织这个数据结构时,考虑到了各成员的逻辑分组。任务建立的时候,OS_TCBs就被初始化了(见第四章任务管理)。程序清单 L 3.3 C/OS-II任务控制块.#if OS_TASK_CREAT_EXT_EN 0 typedef

15、struct INT32U OSFree; /Numbers of free bytes on the stack INT32U OSUsed; /Numbers of bytes used on the stack OS_STK_DATA;#endiftypedef struct os_tcb OS_STK *OSTCBStkPtr;#if OS_TASK_CREATE_EXT_EN void *OSTCBExtPtr; OS_STK *OSTCBStkBottom; INT32U OSTCBStkSize; INT16U OSTCBOpt; INT16U OSTCBId;#endif st

16、ruct os_tcb *OSTCBNext; 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;#endif INT16U OSTCBDly; INT8U OSTCBStat; INT8U OSTCBPrio; INT8U OSTCBX; INT8U OSTCBY; INT8U OSTCBBitX; INT

17、8U OSTCBBitY;#if OS_TASK_DEL_EN BOOLEAN OSTCBDelReq;#endif OS_TCB;.OSTCBStkPtr是指向当前任务栈顶的指针。C/OS-允许每个任务有自己的栈,尤为重要的是,每个任务的栈的容量可以是任意的。有些商业内核要求所有任务栈的容量都一样,除非用户写一个复杂的接口函数来改变之。这种限制浪费了RAM,当各任务需要的栈空间不同时,也得按任务中预期栈容量需求最多的来分配栈空间。OSTCBStkPtr是OS_TCB数据结构中唯一的一个能用汇编语言来处置的变量(在任务切换段的代码Context-switching code之中,)把OSTCB

18、StkPtr放在数据结构的最前面,使得从汇编语言中处理这个变量时较为容易。.OSTCBExtPtr 指向用户定义的任务控制块扩展。用户可以扩展任务控制块而不必修改C/OS-的源代码。.OSTCBExtPtr只在函数OstaskCreateExt()中使用,故使用时要将OS_TASK_CREAT_EN设为1,以允许建立任务函数的扩展。例如用户可以建立一个数据结构,这个数据结构包含每个任务的名字,或跟踪某个任务的执行时间,或者跟踪切换到某个任务的次数(见例3)。注意,笔者将这个扩展指针变量放在紧跟着堆栈指针的位置,为的是当用户需要在汇编语言中处理这个变量时,从数据结构的头上算偏移量比较方便。.OS

19、TCBStkBottom是指向任务栈底的指针。如果微处理器的栈指针是递减的,即栈存储器从高地址向低地址方向分配,则OSTCBStkBottom指向任务使用的栈空间的最低地址。类似地,如果微处理器的栈是从低地址向高地址递增型的,则OSTCBStkBottom指向任务可以使用的栈空间的最高地址。函数OSTaskStkChk()要用到变量OSTCBStkBottom,在运行中检验栈空间的使用情况。用户可以用它来确定任务实际需要的栈空间。这个功能只有当用户在任务建立时允许使用OSTaskCreateExt()函数时才能实现。这就要求用户将OS_TASK_CREATE_EXT_EN设为1,以便允许该功能

20、。.OSTCBStkSize存有栈中可容纳的指针数目而不是用字节(Byte)表示的栈容量总数。也就是说,如果栈中可以保存1,000个入口地址,每个地址宽度是32位的,则实际栈容量是4,000字节。同样是1,000个入口地址,如果每个地址宽度是16位的,则总栈容量只有2,000字节。在函数OSStakChk()中要调用OSTCBStkSize。同理,若使用该函数的话,要将OS_TASK_CREAT_EXT_EN设为1。.OSTCBOpt把“选择项”传给OSTaskCreateExt(),只有在用户将OS_TASK_CREATE_EXT_EN设为1时,这个变量才有效。C/OS-目前只支持3个选择项

21、(见uCOS_II.H):OS_TASK_OTP_STK_CHK, OS_TASK_OPT_STK_CLR和OS_TASK_OPT_SAVE_FP。 OS_TASK_OTP_STK_CHK 用于告知TaskCreateExt(),在任务建立的时候任务栈检验功能得到了允许。OS_TASK_OPT_STK_CLR表示任务建立的时候任务栈要清零。只有在用户需要有栈检验功能时,才需要将栈清零。如果不定义OS_TASK_OPT_STK_CLR,而后又建立、删除了任务,栈检验功能报告的栈使用情况将是错误的。如果任务一旦建立就决不会被删除,而用户初始化时,已将RAM清过零,则OS_TASK_OPT_STK_

22、CLR不需要再定义,这可以节约程序执行时间。传递了OS_TASK_OPT_STK_CLR将增加TaskCreateExt()函数的执行时间,因为要将栈空间清零。栈容量越大,清零花的时间越长。最后一个选择项OS_TASK_OPT_SAVE_FP通知TaskCreateExt(),任务要做浮点运算。如果微处理器有硬件的浮点协处理器,则所建立的任务在做任务调度切换时,浮点寄存器的内容要保存。.OSTCBId用于存储任务的识别码。这个变量现在没有使用,留给将来扩展用。.OSTCBNext和.OSTCBPrev用于任务控制块OS_TCBs的双重链接,该链表在时钟节拍函数OSTimeTick()中使用,用

23、于刷新各个任务的任务延迟变量.OSTCBDly,每个任务的任务控制块OS_TCB在任务建立的时候被链接到链表中,在任务删除的时候从链表中被删除。双重连接的链表使得任一成员都能被快速插入或删除。.OSTCBEventPtr是指向事件控制块的指针,后面的章节中会有所描述(见第6章)。.OSTCBMsg是指向传给任务的消息的指针。用法将在后面的章节中提到(见第6章)。.OSTCBDly当需要把任务延时若干时钟节拍时要用到这个变量,或者需要把任务挂起一段时间以等待某事件的发生,这种等待是有超时限制的。在这种情况下,这个变量保存的是任务允许等待事件发生的最多时钟节拍数。如果这个变量为0,表示任务不延时,

24、或者表示等待事件发生的时间没有限制。.OSTCBStat是任务的状态字。当.OSTCBStat为0,任务进入就绪态。可以给.OSTCBStat赋其它的值,在文件uCOS_II.H中有关于这个值的描述。.OSTCBPrio是任务优先级。高优先级任务的.OSTCBPrio值小。也就是说,这个值越小,任务的优先级越高。.OSTCBX, .OSTCBY, .OSTCBBitX和 .OSTCBBitY用于加速任务进入就绪态的过程或进入等待事件发生状态的过程(避免在运行中去计算这些值)。这些值是在任务建立时算好的,或者是在改变任务优先级时算出的。这些值的算法见程序清单L3.4。程序清单 L 3.4 任务控

25、制块OS_TCB中几个成员的算法OSTCBY= priority 3;OSTCBBitY= OSMapTblpriority 3;OSTCBX= priority & 0x07;OSTCBBitX= OSMapTblpriority & 0x07;.OSTCBDelReq是一个布尔量,用于表示该任务是否需要删除,用法将在后面的章节中描述(见第4章 任务管理) 应用程序中可以有的最多任务数(OS_MAX_TASKS)是在文件OS_CFG.H中定义的。这个最多任务数也是C/OS-分配给用户程序的最多任务控制块OS_TCBs的数目。将OS_MAX_TASKS的数目设置为用户应用程序实际需要的任务数可

26、以减小RAM的需求量。所有的任务控制块OS_TCBs都是放在任务控制块列表数组OSTCBTbl中的。请注意,C/OS-分配给OS_N_SYS_TASKS特别的OS_TCB用于内部使用。目前,一个分配于空闲任务,另一个分配于统计任务(如果OS_TASK_STAT_EN是设为1的)。在C/OS-初始化的时候,如图3.2所示,所有任务控制块OS_TCBs被链接成单向空任务链表。当任务一旦建立,空任务控制块指针OSTCBFreeList指向的任务控制块便赋给了该任务,(即每当建立一个任务时,就从该链表中取出一个空闲事件控制块,并对它进行初始化。)然后OSTCBFreeList的值调整为指向下链表中下一

27、个空的任务控制块。一旦任务被删除,它的OS_TCB就还给空任务链表。与信号量、邮箱和消息队列不同的是:信号量、邮箱和消息队列一旦建立就不能删除,所以事件控制块也不能放回到空闲事件控制块链表中就绪表(Ready List) 每个任务被赋予不同的优先级等级,从0级到最低优先级OS_LOWEST_PRIO,包括0和OS_LOWEST_PRIO在内(见文件OS_CFG.H)。当C/OS-初始化的时候,最低优先级OS_LOWEST_PRIO总是被赋给空闲任务idle task。注意,最多任务数目OS_MAX_TASKS和最低优先级数是没有关系的。用户应用程序可以只有10个任务,而仍然可以有32个优先级的

28、级别(如果用户将最低优先级数设为31的话)。 每个任务的就绪态标志都放入就绪表中的,就绪表中有两个变量OSRdyGrp和OSRdyTbl。在OSRdyGrp中,任务按优先级分组,8个任务为一组。OSRdyGrp中的每一位表示8组任务中每一组中是否有进入就绪态的任务。任务进入就绪态时,就绪表OSRdyTbl中的相应元素的相应位也置位。就绪表OSRdyTbl数组的大小取决于OS_LOWEST_PRIO(见文件OS_CFG.H)。当用户的应用程序中任务数目比较少时,减少OS_LOWEST_PRIO的值可以降低C/OS-对RAM(数据空间)的需求量。 为确定下次该哪个优先级的任务运行了,内核调度器总是

29、将OS_LOWEST_PRIO在就绪表中相应字节的相应位置1。OSRdyGrp和OSRdyTbl的关系见图3.3,是按以下规则给出的:当OSRdyTbli中的任何一位是1时,OSRdyGrp的第i位置1。i从0到7。程序清单3.5中的代码用于将任务放入就绪表。Prio是任务的优先级。程序清单 L3.5 使任务进入就绪态OSRdyGrp |= OSMapTblprio 3;OSRdyTblprio 3 |= OSMapTblprio & 0x07; (有问题:读者可以看出,任务优先级的低三位用于确定任务在总就绪表OSRdyTbl中的所在位。接下去的三位用于确定是在OSRdyTbl数组的第几个元素

30、)应该是低三位为用于确定是在OSRdyTbl数组的第几个元素,接下三位为SRdyTbl中的那一行共八行(也是OSRdyGrp的值),。OSMapTbl是在ROM中的(见文件OS_CORE.C)屏蔽字,用于限制OSRdyTbl数组的元素下标在0到7之间,见表3.1表 T3.1 OSMapTblIndex的值IndexBit Mask (Binary)000000001100000010200000100300001000400010000500100000601000000710000000如果一个任务被删除了,则用程序清单3.6中的代码做求反处理。程序清单 L3.6 从就绪表中删除一个任务if

31、 (OSRdyTblprio 3 &= OSMapTblprio & 0x07) = 0) OSRdyGrp &= OSMapTblprio 3; 以上代码将就绪任务表数组OSRdyTbl中相应元素的相应位清零,而对于OSRdyGrp,只有当被删除任务所在任务组中全组任务一个都没有进入就绪态时,才将相应位清零。也就是说OSRdyTblprio3所有的位都是零时,OSRdyGrp的相应位才清零。为了找到那个进入就绪态的优先级最高的任务,并不需要从OSRdyTbl0开始扫描整个就绪任务表,只需要查另外一张表,即优先级判定表OSUnMapTbl(256)(见文件OS_CORE.C)。OSRdyTbl中每个字节的8位代表这一组的8个任务哪些进入就绪态了,低位的优先级高于高位。利用这个字节为下标来查OSUnMapTbl这张表,返回的字节就是该组任务中就绪态任务中优先级最高的那个任务所在的位置。这个返回值在0到7之

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

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