1 / 80

嵌入式系统 AnIntroductiontoEmbeddedSystem 第十一课 嵌入式实时操作系统 μC /OS II/III 分析 浙江大学计算机学院 陈天洲 2009.6.18

嵌入式系统 AnIntroductiontoEmbeddedSystem 第十一课 嵌入式实时操作系统 μC /OS II/III 分析 浙江大学计算机学院 陈天洲 2009.6.18 2010 夏 学期, 周四上午 3-5; 周五上午 3-5 玉泉曹光彪 西 301( 多媒体 + 实验室 ). 课程大纲.  实时操作系统的几个重要概念  实时操作系统 μC/OS 简介  实时操作系统 μ C/OS-II 的内核结构  实时操作系统 μ C/OS-II 中的中断与任务通讯  实时操作系统 µC/OS-II 在 ARM7 上的移植.

minda
Télécharger la présentation

嵌入式系统 AnIntroductiontoEmbeddedSystem 第十一课 嵌入式实时操作系统 μC /OS II/III 分析 浙江大学计算机学院 陈天洲 2009.6.18

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 嵌入式系统 AnIntroductiontoEmbeddedSystem 第十一课 嵌入式实时操作系统 μC/OS II/III分析 浙江大学计算机学院 陈天洲 2009.6.18 2010夏学期,周四上午3-5;周五上午3-5 玉泉曹光彪西301(多媒体+实验室)

  2. 课程大纲  实时操作系统的几个重要概念  实时操作系统μC/OS简介  实时操作系统μC/OS-II的内核结构  实时操作系统μC/OS-II中的中断与任务通讯  实时操作系统µC/OS-II在ARM7上的移植

  3. 嵌入式操作系统的管理对象

  4. 实时OS主要目标与功能(内核) • MON(Monitor)与OS(Operating System) • 控制与移动应用的实时 • 目标 • 对外部请求在严格时间范围内作出反应 • 高可靠性、安全性、完整性 • 功能(内核) • 任务管理、任务间同步与通讯、存储器优化管理(ROM)、中断管理、实时时钟 • 实时系统一般用于先进制造业及控制系统

  5. 调度(Dispatcher) • 这是操作系统的主要职责之一,它决定该轮到哪个任务运行了。 • 在嵌入式中调度一般是基于优先级的,根据其重要不同被赋予任务不同的优先级。 CPU总是让处在就绪态的优先级最高的任务先运行。 • 何时让高优先级任务掌握CPU的使用权,有两种不同的情况,这要看用的是什么类型的内核, • 非抢占式内核 • 抢占式内核

  6. 一般调度 • 非抢占式(non-preemptive) • 非占先式调度法也称作合作型多任务(cooperative multitasking),各个任务彼此合作共享一个CPU。 • 中断服务可以使一个高优先级的任务由挂起状态变为就绪状态。但中断服务以后控制权还是回到原来被中断了的那个任务,直到改任务主动放弃CPU的使用权时,那个高优先级的任务才能获得CPU的使用权。

  7. 低优先级任务 (2) (1) ISR (3) TIME (4) 中断服务程序使 高优先级任务就绪 (5) (6) 高优先级任务 (7) 低优先级任务释放 CPU使用权 非抢占式任务切换过程

  8. 实时调度 抢占式(preemptive) • 当系统响应时间很重要时,要使用抢占式(preemptive)内核 • 最高优先级的任务一旦就绪,总能得到CPU的控制权。 • 当优先级高的任务进入了就绪态,当前任务的CPU使用权就被剥夺了,或者说被挂起了,那个高优先级的任务立刻得到了CPU的控制权。 • 中断服务以后控制权不是回到原来被中断了的那个任务,而是高优先级任务得到CPU使用权

  9. 中断服务程序使 高优先级任务就绪 低优先级任务 (2) (1) 高优先级任务 ISR (3) TIME (4) (5) 高优先级任务得到 CPU使用权 (6) 抢占式任务切换过程

  10. 代码的临界区 • 代码的临界区也称为临界区,指处理时不可分割的代码 • 一旦这部分代码开始执行,则不允许任何中断打入。 • 在进入临界区之前要关中断,而临界区代码执行完以后要立即开中断(在任务切换时,地址、指令、数据等寄存器堆栈保护)。

  11. 课程大纲  实时操作系统的几个重要概念  实时操作系统μC/OS简介  实时操作系统μC/OS-II的内核结构  实时操作系统μC/OS-II中的中断与任务通讯  实时操作系统µC/OS-II在ARM7上的移植

  12. 实时操作系统C/OS简介 • 1992年美国人Jean Labrosse开发了C/OS • 用于照相机、医疗器械、音响设备、发动机控制、高速公路电话系统、自动提款机等诸多应用领域 • 1998年推出C/OS-II • 目前的版本C/OS -II V2.88 • 2009年推出C/OS-III • 只提供库,不开源 • 抢先式多任务处理,无数目限制的任务及优先级,时间片轮番调度法允许多任务具有相同的优先级 • 2000年,得到美国航空管理局(FAA)的认证,可以用于飞行器中 • 网站www.ucos-II.com(www.micrium.com)

  13. C/OS的性能特点 • 开源代码 • 可移植性(Portable) • C/OS-II源码主要用ANSI C写,移植性很强的。 • 只有和微处理器硬件相关的那部分直接用汇编语言写的,汇编语言写的部分已经压到最低限度 • C/OS-II可以在绝大多数8位、16位、32位以至64位微处理器、微控制器 、数字信号处理器(DSP)上运行。 • 可固化(ROMable) • C/OS-II是为嵌入式应用而设计的,内核可以裁剪得很小,可以嵌入到任何产品中 • 可裁剪(Scalable) • 通过条件编译,可以根据应用需要只使用C/OS-II中的部分那些系统服务。

  14. C/OS的性能特点-2 • 抢占式(Preemptive)实时结构 • 多任务 • C/OS-II可以管理64个任务,其中保留8个给系统。应用程序最多可以有56个任务 • 可确定性 • 全部C/OS-II的函数调用与服务的执行时间是可确定的。 • 任务栈 • 每个任务有自己单独的栈, 允许每个任务有不同的栈空间,以便减少应用程序对RAM的需求。 • 系统服务 • C/OS-II提供很多系统服务,例如邮箱、消息队列、信号量、块大小固定的内存的申请与释放、时间相关函数等。 • 中断管理 • 中断可以使正在执行的任务暂时挂起,如果优先级更高的任务被该中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,中断嵌套层数可达255层。 • 稳定性与可靠性

  15. µC/OS-II提供的系统服务 • 信号量 • 带互斥机制的信号量 • 减少优先级倒置的问题 • 事件标志 • 消息信箱 • 消息队列 • 内存管理 • 时钟管理 • 任务管理

  16. µC/GUI and µC/FS • µC/GUI • 嵌入式的用户界面 • 用ANSI C书写 • 支持任何8, 16, 32-bits CPU • 彩色,灰、度,等级或黑白显示 • 代码尺寸小 • µC/FS • 嵌入式的文件系统用ANSI C书写 • 支持任何8, 16, 32-bits CPU • 支持SMC, MMC, SD, CF, IDE, Flash, RAM其他介质

  17. µC/OS-II的商业应用 • 全世界有数百种产品在应用: • Avionics • Medical • Cell phones • Routers and switches • High-end audio equipment • Washing machines and dryers • UPS (Uninterruptible Power Supplies) • Industrial controllers • GPS Navigation Systems • Microwave Radios • Instrumentation • Point-of-sale terminals

  18. 课程大纲  实时操作系统的几个重要概念  实时操作系统μC/OS简介  实时操作系统μC/OS-II的内核结构 实时操作系统μC/OS-II中的中断与任务通讯  实时操作系统µC/OS-II在ARM7上的移植

  19. C/OS-II的内核结构 • 任务管理 • 中断处理 • 时间管理 • 任务之间通信与同步

  20. C/OS-II的任务(task) • C/OS-II中任何工作都是用任务来构成的 • 典型的任务一个无限循环。 • void mytask(void *pdata) • { • for (;;) { • do something; • waiting; • do something; • } • } • 每个任务对应一个特定的优先级。优先级越高,任务编号数字越小。 • 系统占用了8个任务 • 保留优先级为0、1、2、3、OS_LOWEST_PRIO-3、 OS_LOWEST_PRIO-2、 OS_LOWEST_PRIO-1、 OS_LOWEST_PRIO-0。

  21. 删除任务 等待或挂起 收到消息 挂起时间到 等待消息 挂起 创建任务 任务调度 中断 休眠 就绪 运行 中断服务 任务被占先 中断结束 删除任务 删除任务 C/OS-II中任务状态

  22. void YourTask (void *pdata) { for (;;) { /* 用户代码 */ 调用uC/OS-II的某种系统服务: OSMboxPend(); OSQPend(); OSSemPend(); OSTaskDel(OS_PRIO_SELF); OSTaskSuspend(OS_PRIO_SELF); OSTimeDly(); OSTimeDlyHMSM(); /* 用户代码 */ } } 任务代码 任务代码 一个或多个系统 任务调用 参数指针,用于传递数据 C/OS-II的任务结构(Task Structure) 任务是一个无限循环

  23. void YourTask (void *pdata) { /* 用户代码 */ OSTaskDel(OS_PRIO_SELF); } 任务完成后自我删除 • 当任务完成以后,任务可以自我删除。 • 注意任务代码并非真的删除了,μC/OS-Ⅱ只是简单地不再理会这个任务了,这个任务的代码也不会再运行,如果任务调用了OSTaskDel(),这个任务绝不返回什么。

  24. 运行任务可调用的内核函数 • 延迟一段时间使这个任务进入等待状态: • OSTimeDly(),OSTimeDlyHMSM()。 • 等待的时间过去以后,系统服务函数OSTimeTick()使延迟的任务进入就绪态 • 运行的任务期待某一事件发生时,可调用以下3个函数之一进入等待: • OSSemPend(),OSMboxPend(),或OSQPend()。 • 调用后任务进入了等待状态(WAITING)。 • 当任务因等待事件被挂起(Pend),下一个优先级最高的任务立即得到了CPU的控制权。当事件发生了,被挂起的任务进入就绪态。事件发生的报告可能来自另一个任务,也可能来自中断服务子程序。

  25. 中断任务 • 运行的任务是可以被中断的 • 响应中断时,正在执行的任务被挂起,中断服务子程序控制了CPU的使用权 • 从中断服务子程序返回之前,μC/OS-Ⅱ要判定,被中断的任务是否还是就绪态任务中优先级最高的。 • 如果中断服务子程序使一个优先级更高的任务进入了就绪态,则新进入就绪态的这个优先级更高的任务将得以运行,否则原来被中断了的任务才能继续运行。 • 空闲任务(idle task) • 当所有的任务都在等待事件发生时μC/OS-Ⅱ执行OSTaskIdle()函数。

  26. 任务控制块(Task Control Blocks, OS­­TCBs) • 任务控制块 OS_TCB是一个数据结构 • 保存该任务的相关参数,包括任务堆栈指针,状态,优先级,任务表位置,任务链表指针等。 • 任一旦任务建立了,任务控制块OS­­_TCBs将被赋值 • 任务建立的时候,OS_TCBs被初始化了 • 当任务的CPU使用权被剥夺时,μC/OS-Ⅱ用它来保存该任务的状态。 • 当任务重新得到CPU使用权时,任务控制块能确保任务从当时被中断的那一点丝毫不差地继续执行。 • OS­­_TCBs全部驻留在RAM中。 • 所有的任务控制块分为两条链表,空闲链表和使用链表。

  27. . typedef struct os_tcb { OS_STK *OSTCBStkPtr; #if OS_TASK_CREATE_EXT_EN void *OSTCBExtPtr; OS_STK *OSTCBStkBottom; INT32U OSTCBStkSize; INT16U OSTCBOpt; INT16U OSTCBId; #endif struct 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; INT8U OSTCBBitY; #if OS_TASK_DEL_EN BOOLEAN OSTCBDelReq; #endif } OS_TCB; 任务控制块数据结构Task Control Blocks, OS_TCBs

  28. 任务控制块主要结构 Struct os_tcb { OS_STK *OSTCBStkPtr; struct os_tcb *OSTCBNext; struct os_tcb *OSTCBprev; OS_EVENT *OSTCBEventPtr; void *OSTCBMsg; INT16U OSTCBDly; INT8U OSTCBStat; INT8U OSTCBPrio; INT8U OSTCBX, OSTCBY, OSTCBBitX, OSTCBBitY; } OS_TCB 事件控制块的指针 任务的状态字 任务延时参数

  29. 建立任务的二个服务 • OS TaskCreate() • OSTaskCreateExt ()

  30. 分配给任务的优先级 任务代码指针 任务参数指针 分配任务堆栈的栈顶指针 check Set up task stack Initialize TCB Set pointer if level is free Option to extend functionality If called from a task

  31. 空任务列表 所有的任务控制块都被放置在任务控制块列表数组OSTCBTbl[]中,系统初始化时,所有任务控制块被链接成空任务控制块的单向链表,任务建立后,空任务控制块指针OSTCBFreeList指向的任务控制块就赋给了该任务,然后OSTCBFreeList的值调整为指向链表中的下一个空任务控制块。

  32. 任务级的任务调度--OSSched • C/OS是占先式实时多任务内核 • 优先级最高的任务一旦准备就绪,则拥有CPU的所有权开始投入运行。 • C/OS中不支持时间片轮转法 • 每个任务的优先级要求不一样且是唯一的,所以任务调度的工作就是:查找准备就绪的最高优先级的任务并进行上下文切换。 • C/OS任务调度所花的时间为常数,与应用程序中建立的任务数无关

  33. OSRdyGrp OSRdyTbl[7] 7 6 5 4 3 2 1 0 X [0] 7 6 5 4 3 2 1 0 [1] 15 14 13 12 11 10 9 8 [2] 23 22 21 20 19 18 17 16 [3] 31 30 29 28 27 26 25 24 Y [4] 39 38 37 36 35 34 33 32 [5] 47 46 45 44 43 42 41 40 [6] 55 54 53 52 51 50 49 48 [7] 63 62 61 60 59 58 57 56 任务优先级 0 0 Y Y Y X X X 根据优先级找到任务在就绪任务表中的位置 每个就绪的任务都放入就绪表中(ready list)中,就绪表有两个变量:OSRdyGrp、OSRdyTbl[] 优先级最高任务 优先级最低任务 (空闲任务) 任务优先级号

  34. 根据优先级确定就绪表(1) • 假设优先级为12的任务进入就绪状态,12=1100b,则OSRdyTbl[1]的第4位(bit4)置1,且OSRdyGrp的第1位(bit1)置1,相应的数学表达式为: OSRdyGrp |=0x02; OSRdyTbl[1] |=0x10; • 而优先级为21的任务就绪21=10 101b,则OSRdyTbl[2]的第5位置1,且OSRdyGrp的第2位置1,相应的数学表达式为: OSRdyGrp |=0x04; OSRdyTbl[2] |=0x20; OSRdyGrp: OSRdyGrp:

  35. 根据优先级确定就绪表(2) • 从上面的计算我们可以得到:若OSRdyGrp及OSRdyBbl[]的第n位置1,则应该把OSRdyGrp及OSRdyBbl[]的值与2n 相”或”(or)。 • C/OS中,把2n的n=0-7的8个值先计算好,存在数组OSMapTbl[7]中,即: OSMapTbl[0] =20=0x01(0000 0001) OSMapTbl[1] =21=0x02(0000 0010) …… OSMapTbl[7] =27=0x80(1000 0000)

  36. 使任务进入就绪态算法 • Prio是优先级编号,也是任务的识别号 • 任务就绪 • 将任务号放入就绪表,任务就进入就绪态 • 其方法是: OSRdyGrp |=OSMapTbl[prio>>3]; OSRdyTbl[prio>>3] |=OSMapTbl[prio & 0x07]; 假设优先级为12—1100b OSRdyGrp |=0x02; OSRdyTbl[1] |=0x10;

  37. 使任务脱离就绪态算法 • 将任务就绪表OSRdyTbl[prio>>3]相应元素的相应位清零, • 如果OSRdyTbl[prio>>3]中的所有位都为零时,即全组任务中没有一个进入就绪态时 • OSRdyGrp的相应位才为零。 If((OSRdyTbl[prio>>3]&=OSMapTbl[prio&0x07])==0); OSRdyGrp&=OSMapTbl[prio>>3]; 就绪表清”0”

  38. 任务调度--根据就绪表确定最高优先级 • 两个关键: • 优先级数分解为高三位和低三位分别确定; • 高优先级有着小的优先级号 ;

  39. OSRdyGrp OSRdyTbl[7] 0 0 1 0 0 1 0 0 X [0] 7 6 5 4 3 2 1 0 [1] 15 14 13 12 11 10 9 8 [2] 0 0 0 1 0 0 1 0 [3] 31 30 29 28 27 26 25 24 Y [4] 39 38 37 36 35 34 33 32 [5] 47 46 45 44 43 42 41 40 [6] 55 54 53 52 51 50 49 48 [7] 63 62 61 60 59 58 57 56 任务优先级 0 0 0 1 0 0 1 0 任务调度--根据就绪表确定最高优先级 • 通过OSRdyGrp值确定高3位 • 设OSRdyGrp=0x24=100 100b, →对应OSRdyTbl[2]和OSRdyTbl[5] • 选择高优先级在OSRdyTbl[2]组内 • 通过OSRdyTbl[2]的值来确定低3位, 假设为OSRdyTbl[2]=0x12=010 010b, →对应第2个和第5个任务,取高优先级为2,则最高优先级的任务为2×8+2-1=17

  40. C/OS-II源代码中使用了查表法 查表法具有确定的时间,增加了系统的可预测性,C/OS中所有的系统调用时间都是确定的 High3 =OSUnMapTbl[OSRdyGrp]; Low3 =OSUnMapTbl[OSRdyTbl[High3]]; Prio =(High3<<3)+Low3;

  41. 优先级判定表OSUnMapTbl[256] 举例: 如OSRdyGrp的值为01101000B,即0x68,则查得OSUnMapTbl[OSRdyGrp]的值是3,它相应于OSRdyGrp中的第3位置1; 如OSRdyTbl[3]的值是11100100B,即0xE4,则查OSUnMapTbl[OSRdyTbl[3]]的值是2,则进入就绪态的最高任务优先级 Prio=3×8+2=26 INT8U const OSUnMapTbl[] = { 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 };

  42. Task scheduler 检查是否中断调用和允许任务调用 找到优先级最高的任务 该任务是否正在运行 任务切换

  43. 任务切换 • 将被挂起的任务寄存器入栈 • 将较高优先级任务的寄存器出栈

  44. 任务级的任务切换OS_TASK_SW() 通过sc系统调用指令完成 保护当前任务的现场 恢复新任务的现场 执行中断返回指令 开始执行新的任务

  45. 调用OS_TASK_SW()前的数据结构 低优先级任务 OS_TCB 高优先级任务 OS_TCB OSTCBCur (1) OSTCBHighRdy (3) 存贮器低地址 存贮器低地址 CPU (2) SP (4) 堆栈方向 R1 R2 R3 R4 PC (5) PSW 存贮器高地址 存贮器高地址

  46. R4 R3 R2 R1 PC PSW 保存当前CPU寄存器的值 低优先级任务 OS_TCB 高优先级任务 OS_TCB OSTCBCur OSTCBHighRdy (3) (3) 存贮器低地址 存贮器低地址 CPU SP (4) R1 R2 R3 堆栈方向 R4 (2) PC (5) PSW (1) 存贮器高地址 存贮器高地址

  47. R4 R4 R3 R3 R2 R2 R1 R1 PC PC PSW PSW 重新装入要运行的任务 低优先级任务 OS_TCB 高优先级任务 OS_TCB OSTCBCur OSTCBHighRdy OSTCBCur (1) (2) (3) 存贮器低地址 存贮器低地址 CPU SP (4) R1 R2 (3) R3 堆栈方向 R4 PC PSW (4) (1) (4) 存贮器高地址 存贮器高地址

  48. 任务切换OS_TASK_SW()的代码 Void OSCtxSw(void) { 将R1,R2,R3及R4推入当前堆栈; OSTCBCurOSTCBStkPtr = SP; OSTCBCur= OSTCBHighRdy; SP= OSTCBHighRdy OSTCBSTKPtr; 将R4,R3,R2及R1从新堆栈中弹出; 执行中断返回指令; }

  49. 课程大纲  实时操作系统的几个重要概念  实时操作系统μC/OS简介  实时操作系统μC/OS-II的内核结构  实时操作系统μC/OS-II中的中断与任务通讯  实时操作系统µCOS-II在ARM7上的移植

  50. C/OS-II中的中断 • 中断:由于某种事件的发生,而导致程序流程的改变。产生中断的事件称为中断源。 • CPU响应中断的条件: • 至少有一个中断源向CPU发出中断信号; • 系统允许中断,且对此中断信号未予屏蔽 • 中断类型: • 硬件中断 • 外部中断 • 陷井中断 • 现场控制量的中断

More Related