嵌入式系统
This presentation is the property of its rightful owner.
Sponsored Links
1 / 80

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


  • 77 Views
  • Uploaded on
  • Presentation posted in: General

嵌入式系统 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 上的移植.

Download Presentation

嵌入式系统 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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Anintroductiontoembeddedsystem c os ii iii 2009 6 18

嵌入式系统

AnIntroductiontoEmbeddedSystem

第十一课 嵌入式实时操作系统

μC/OS II/III分析

浙江大学计算机学院

陈天洲

2009.6.18

2010夏学期,周四上午3-5;周五上午3-5

玉泉曹光彪西301(多媒体+实验室)


Anintroductiontoembeddedsystem c os ii iii 2009 6 18

课程大纲

 实时操作系统的几个重要概念

 实时操作系统μC/OS简介

 实时操作系统μC/OS-II的内核结构

 实时操作系统μC/OS-II中的中断与任务通讯

 实时操作系统µC/OS-II在ARM7上的移植


Anintroductiontoembeddedsystem c os ii iii 2009 6 18

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


Anintroductiontoembeddedsystem c os ii iii 2009 6 18

实时OS主要目标与功能(内核)

  • MON(Monitor)与OS(Operating System)

    • 控制与移动应用的实时

  • 目标

    • 对外部请求在严格时间范围内作出反应

    • 高可靠性、安全性、完整性

  • 功能(内核)

    • 任务管理、任务间同步与通讯、存储器优化管理(ROM)、中断管理、实时时钟

  • 实时系统一般用于先进制造业及控制系统


Anintroductiontoembeddedsystem c os ii iii 2009 6 18

调度(Dispatcher)

  • 这是操作系统的主要职责之一,它决定该轮到哪个任务运行了。

  • 在嵌入式中调度一般是基于优先级的,根据其重要不同被赋予任务不同的优先级。 CPU总是让处在就绪态的优先级最高的任务先运行。

  • 何时让高优先级任务掌握CPU的使用权,有两种不同的情况,这要看用的是什么类型的内核,

    • 非抢占式内核

    • 抢占式内核


Anintroductiontoembeddedsystem c os ii iii 2009 6 18

一般调度

  • 非抢占式(non-preemptive)

  • 非占先式调度法也称作合作型多任务(cooperative multitasking),各个任务彼此合作共享一个CPU。

  • 中断服务可以使一个高优先级的任务由挂起状态变为就绪状态。但中断服务以后控制权还是回到原来被中断了的那个任务,直到改任务主动放弃CPU的使用权时,那个高优先级的任务才能获得CPU的使用权。


Anintroductiontoembeddedsystem c os ii iii 2009 6 18

低优先级任务

(2)

(1)

ISR

(3)

TIME

(4)

中断服务程序使

高优先级任务就绪

(5)

(6)

高优先级任务

(7)

低优先级任务释放

CPU使用权

非抢占式任务切换过程


Anintroductiontoembeddedsystem c os ii iii 2009 6 18

实时调度

抢占式(preemptive)

  • 当系统响应时间很重要时,要使用抢占式(preemptive)内核

    • 最高优先级的任务一旦就绪,总能得到CPU的控制权。

    • 当优先级高的任务进入了就绪态,当前任务的CPU使用权就被剥夺了,或者说被挂起了,那个高优先级的任务立刻得到了CPU的控制权。

    • 中断服务以后控制权不是回到原来被中断了的那个任务,而是高优先级任务得到CPU使用权


Anintroductiontoembeddedsystem c os ii iii 2009 6 18

中断服务程序使

高优先级任务就绪

低优先级任务

(2)

(1)

高优先级任务

ISR

(3)

TIME

(4)

(5)

高优先级任务得到

CPU使用权

(6)

抢占式任务切换过程


Anintroductiontoembeddedsystem c os ii iii 2009 6 18

代码的临界区

  • 代码的临界区也称为临界区,指处理时不可分割的代码

    • 一旦这部分代码开始执行,则不允许任何中断打入。

    • 在进入临界区之前要关中断,而临界区代码执行完以后要立即开中断(在任务切换时,地址、指令、数据等寄存器堆栈保护)。


Anintroductiontoembeddedsystem c os ii iii 2009 6 18

课程大纲

 实时操作系统的几个重要概念

 实时操作系统μC/OS简介

 实时操作系统μC/OS-II的内核结构

 实时操作系统μC/OS-II中的中断与任务通讯

 实时操作系统µC/OS-II在ARM7上的移植


Anintroductiontoembeddedsystem c os ii iii 2009 6 18

实时操作系统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)


Anintroductiontoembeddedsystem c os ii iii 2009 6 18

C/OS的性能特点

  • 开源代码

  • 可移植性(Portable)

    • C/OS-II源码主要用ANSI C写,移植性很强的。

    • 只有和微处理器硬件相关的那部分直接用汇编语言写的,汇编语言写的部分已经压到最低限度

    • C/OS-II可以在绝大多数8位、16位、32位以至64位微处理器、微控制器 、数字信号处理器(DSP)上运行。

  • 可固化(ROMable)

    • C/OS-II是为嵌入式应用而设计的,内核可以裁剪得很小,可以嵌入到任何产品中

  • 可裁剪(Scalable)

    • 通过条件编译,可以根据应用需要只使用C/OS-II中的部分那些系统服务。


Anintroductiontoembeddedsystem c os ii iii 2009 6 18

C/OS的性能特点-2

  • 抢占式(Preemptive)实时结构

  • 多任务

    • C/OS-II可以管理64个任务,其中保留8个给系统。应用程序最多可以有56个任务

  • 可确定性

    • 全部C/OS-II的函数调用与服务的执行时间是可确定的。

  • 任务栈

    • 每个任务有自己单独的栈, 允许每个任务有不同的栈空间,以便减少应用程序对RAM的需求。

  • 系统服务

    • C/OS-II提供很多系统服务,例如邮箱、消息队列、信号量、块大小固定的内存的申请与释放、时间相关函数等。

  • 中断管理

    • 中断可以使正在执行的任务暂时挂起,如果优先级更高的任务被该中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,中断嵌套层数可达255层。

  • 稳定性与可靠性


C os ii

µC/OS-II提供的系统服务

  • 信号量

  • 带互斥机制的信号量

    • 减少优先级倒置的问题

  • 事件标志

  • 消息信箱

  • 消息队列

  • 内存管理

  • 时钟管理

  • 任务管理


C gui and c fs

µ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其他介质


C os ii1

µ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


Anintroductiontoembeddedsystem c os ii iii 2009 6 18

课程大纲

 实时操作系统的几个重要概念

 实时操作系统μC/OS简介

 实时操作系统μC/OS-II的内核结构

实时操作系统μC/OS-II中的中断与任务通讯

 实时操作系统µC/OS-II在ARM7上的移植


Anintroductiontoembeddedsystem c os ii iii 2009 6 18

C/OS-II的内核结构

  • 任务管理

  • 中断处理

  • 时间管理

  • 任务之间通信与同步


C os ii task

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。


  • C os ii2

    删除任务

    等待或挂起

    收到消息

    挂起时间到

    等待消息

    挂起

    创建任务

    任务调度

    中断

    休眠

    就绪

    运行

    中断服务

    任务被占先

    中断结束

    删除任务

    删除任务

    C/OS-II中任务状态


    C os ii task structure

    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)

    任务是一个无限循环


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    void YourTask (void *pdata)

    {

    /* 用户代码 */

    OSTaskDel(OS_PRIO_SELF);

    }

    任务完成后自我删除

    • 当任务完成以后,任务可以自我删除。

      • 注意任务代码并非真的删除了,μC/OS-Ⅱ只是简单地不再理会这个任务了,这个任务的代码也不会再运行,如果任务调用了OSTaskDel(),这个任务绝不返回什么。


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    运行任务可调用的内核函数

    • 延迟一段时间使这个任务进入等待状态:

      • OSTimeDly(),OSTimeDlyHMSM()。

      • 等待的时间过去以后,系统服务函数OSTimeTick()使延迟的任务进入就绪态

    • 运行的任务期待某一事件发生时,可调用以下3个函数之一进入等待:

      • OSSemPend(),OSMboxPend(),或OSQPend()。

      • 调用后任务进入了等待状态(WAITING)。

      • 当任务因等待事件被挂起(Pend),下一个优先级最高的任务立即得到了CPU的控制权。当事件发生了,被挂起的任务进入就绪态。事件发生的报告可能来自另一个任务,也可能来自中断服务子程序。


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    中断任务

    • 运行的任务是可以被中断的

      • 响应中断时,正在执行的任务被挂起,中断服务子程序控制了CPU的使用权

        • 从中断服务子程序返回之前,μC/OS-Ⅱ要判定,被中断的任务是否还是就绪态任务中优先级最高的。

        • 如果中断服务子程序使一个优先级更高的任务进入了就绪态,则新进入就绪态的这个优先级更高的任务将得以运行,否则原来被中断了的任务才能继续运行。

    • 空闲任务(idle task)

      • 当所有的任务都在等待事件发生时μC/OS-Ⅱ执行OSTaskIdle()函数。


    Task control blocks os tcbs

    任务控制块(Task Control Blocks, OS­­TCBs)

    • 任务控制块 OS_TCB是一个数据结构

      • 保存该任务的相关参数,包括任务堆栈指针,状态,优先级,任务表位置,任务链表指针等。

    • 任一旦任务建立了,任务控制块OS­­_TCBs将被赋值

      • 任务建立的时候,OS_TCBs被初始化了

      • 当任务的CPU使用权被剥夺时,μC/OS-Ⅱ用它来保存该任务的状态。

      • 当任务重新得到CPU使用权时,任务控制块能确保任务从当时被中断的那一点丝毫不差地继续执行。

      • OS­­_TCBs全部驻留在RAM中。

    • 所有的任务控制块分为两条链表,空闲链表和使用链表。


    Task control blocks os tcbs1

    .

    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


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    任务控制块主要结构

    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

    事件控制块的指针

    任务的状态字

    任务延时参数


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    建立任务的二个服务

    • OS TaskCreate()

    • OSTaskCreateExt ()


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    分配给任务的优先级

    任务代码指针

    任务参数指针

    分配任务堆栈的栈顶指针

    check

    Set up task stack

    Initialize TCB

    Set pointer if level is free

    Option to extend functionality

    If called from a task


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    空任务列表

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


    Ossched

    任务级的任务调度--OSSched

    • C/OS是占先式实时多任务内核

      • 优先级最高的任务一旦准备就绪,则拥有CPU的所有权开始投入运行。

    • C/OS中不支持时间片轮转法

      • 每个任务的优先级要求不一样且是唯一的,所以任务调度的工作就是:查找准备就绪的最高优先级的任务并进行上下文切换。

    • C/OS任务调度所花的时间为常数,与应用程序中建立的任务数无关


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    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[]

    优先级最高任务

    优先级最低任务

    (空闲任务)

    任务优先级号


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    根据优先级确定就绪表(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:


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    根据优先级确定就绪表(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)


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    使任务进入就绪态算法

    • Prio是优先级编号,也是任务的识别号

    • 任务就绪

      • 将任务号放入就绪表,任务就进入就绪态

      • 其方法是:

        OSRdyGrp |=OSMapTbl[prio>>3];

        OSRdyTbl[prio>>3] |=OSMapTbl[prio & 0x07];

        假设优先级为12—1100b

        OSRdyGrp |=0x02;

        OSRdyTbl[1] |=0x10;


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    使任务脱离就绪态算法

    • 将任务就绪表OSRdyTbl[prio>>3]相应元素的相应位清零,

      • 如果OSRdyTbl[prio>>3]中的所有位都为零时,即全组任务中没有一个进入就绪态时

      • OSRdyGrp的相应位才为零。

        If((OSRdyTbl[prio>>3]&=OSMapTbl[prio&0x07])==0);

        OSRdyGrp&=OSMapTbl[prio>>3];

    就绪表清”0”


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    任务调度--根据就绪表确定最高优先级

    • 两个关键:

      • 优先级数分解为高三位和低三位分别确定;

      • 高优先级有着小的优先级号 ;


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    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


    C os ii3

    C/OS-II源代码中使用了查表法

    查表法具有确定的时间,增加了系统的可预测性,C/OS中所有的系统调用时间都是确定的

    High3 =OSUnMapTbl[OSRdyGrp];

    Low3 =OSUnMapTbl[OSRdyTbl[High3]];

    Prio =(High3<<3)+Low3;


    Osunmaptbl 256

    优先级判定表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

    };


    Task scheduler

    Task scheduler

    检查是否中断调用和允许任务调用

    找到优先级最高的任务

    该任务是否正在运行

    任务切换


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    任务切换

    • 将被挂起的任务寄存器入栈

    • 将较高优先级任务的寄存器出栈


    Os task sw

    任务级的任务切换OS_TASK_SW()

    通过sc系统调用指令完成

    保护当前任务的现场

    恢复新任务的现场

    执行中断返回指令

    开始执行新的任务


    Os task sw1

    调用OS_TASK_SW()前的数据结构

    低优先级任务

    OS_TCB

    高优先级任务

    OS_TCB

    OSTCBCur

    (1)

    OSTCBHighRdy

    (3)

    存贮器低地址

    存贮器低地址

    CPU

    (2)

    SP

    (4)

    堆栈方向

    R1

    R2

    R3

    R4

    PC

    (5)

    PSW

    存贮器高地址

    存贮器高地址


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    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)

    存贮器高地址

    存贮器高地址


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    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)

    存贮器高地址

    存贮器高地址


    Os task sw2

    任务切换OS_TASK_SW()的代码

    Void OSCtxSw(void)

    {

    将R1,R2,R3及R4推入当前堆栈;

    OSTCBCurOSTCBStkPtr = SP;

    OSTCBCur= OSTCBHighRdy;

    SP= OSTCBHighRdy OSTCBSTKPtr;

    将R4,R3,R2及R1从新堆栈中弹出;

    执行中断返回指令;

    }


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    课程大纲

     实时操作系统的几个重要概念

     实时操作系统μC/OS简介

     实时操作系统μC/OS-II的内核结构

     实时操作系统μC/OS-II中的中断与任务通讯

     实时操作系统µCOS-II在ARM7上的移植


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    C/OS-II中的中断

    • 中断:由于某种事件的发生,而导致程序流程的改变。产生中断的事件称为中断源。

    • CPU响应中断的条件:

      • 至少有一个中断源向CPU发出中断信号;

      • 系统允许中断,且对此中断信号未予屏蔽

    • 中断类型:

      • 硬件中断

      • 外部中断

      • 陷井中断

      • 现场控制量的中断


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    C/OS-II中的中断

    进入临界区(中断)

    必要时须用汇编代码

    退出临界区(中断)


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    中断响应过程与实时调度


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    Half context switch is done by interrupt response – i.e. registers saved

    搜索最高优先级 –与任务调度类似

    中断反回过程与实时调度


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    中断与时钟节拍

    • μC/OS中提供了OSIntEnter() 和OSIntExit() 告诉内核进入了中断状态。

    • 时钟节拍是一种特殊的中断,操作系统的心脏

      • 32位的整数:OSTime+1

      • 对任务列表进行扫描,判断是否有延时任务应该处于准备就绪状态

      • 最后进行上下文切换。


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    令指针指向第一个任务

    空闲任务总是最后一个任务

    任务没有延时的话忽略即可

    任务是否存在延时?

    延时数减一

    预定的延时到了,就应该在使任务处于就绪

    延时数是否为0?

    条件是:任务没有处于挂起态

    如果条件合适,将该

    任务放入就绪列表

    对任务表进行扫描

    令指针指向下一个任务

    OSTime++

    返回

    是否是空闲任务?

    时钟节拍中断流程

    OSTimeTick( void )


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    1

    25

    50

    时间

    任务一

    任务二

    空闲任务

    OSStart

    Time Tick

    Time Tick

    Time Tick


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    任务间通信手段

    • C/OS中,采用多种方法保护任务之间的共享数据和提供任务之间的通信。

      • 提供OS_ENTER_CRITICAL和OS_EXIT_CRITICAL来对临界资源进行保护

      • OSSchedLock( )禁止调度保护任务级的共享资源。

      • 提供了经典操作系统任务间通信方法:信号量、邮箱、消息队列,事件标志。


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    事件控制块ECB

    • 所有的通信信号都被看成是事件(event)

      • 一个称为事件控制块(ECB, Event Control Block)的数据结构来描述一个具体事件,ECB的结构如下

    typedef struct {

    void *OSEventPtr; /*指向消息或消息队列的指针*/

    INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /*等待任务列表*/

    INT16U OSEventCnt; /*计数器(当事件是信号量时)*/

    INT8U OSEventType; /*事件类型:信号量、邮箱等*/

    INT8U OSEventGrp; /*等待任务组*/

    } OS_EVENT;

    与TCB类似的结构,使用两个链表,空闲链表与使用链表


    Semaphore

    信号量semaphore

    • 信号量在多任务系统中用于:控制共享资源的使用权、标志事件的发生、使两个任务的行为同步。

    • uC/OS中信号量由两部分组成:信号量的计数值和等待该信号任务的等待任务表。信号量的计数值可以为二进制, 也可以是其他整数。

    • 系统通过OSSemPend( )和OSSemPost( )来支持信号量的两种原子操作P()和V()。P()操作减少信号量的值,如果新的信号量的值不大于0,则操作阻塞;V()操作增加信号量的值。


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    时间管理

    • 五个系统时间服务

      • OSTimeDLY() 任务延时函数

      • OSTimeDLYHMSM() 按时分秒延时函数

      • OSTimeDlyResmue() 结束延时

      • OStimeGet()

      • OSTimeSet()


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    任务调度

    • For example1 创建2个任务,每个任务仅仅是进行延时,延时不同的时间片,不同优先级

      void Task1(void) void Task2(void)

      { {

      while(1) while(1)

      { {

      blinkled1(); blinkled2();

      Task1Data++; Task2Data++;

      OSTimeDly(25); OSTimeDly(50);

      } }

      } }


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    多任务循环

    void main()

    {

    sysinit();

    OSInit ();

    OSTaskCreate ( Task1, (void *)&Task1Data,

    (void *)&Task1Stk[TASK_STK_SIZE],Task1prio);

    OSTaskCreate (Task2, (void *)&Task2Data,

    (void *)&Task2Stk[TASK_STK_SIZE],Task2prio);

    ticker_start(OS_TICKS_PER_SEC);

    OSStart();

    }


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    任务启动

    void OSStart (void)

    {

    INT8U y, x;

    if (OSRunning == FALSE) { 判断是否没有启动内核

    y = OSUnMapTbl[OSRdyGrp];

    x = OSUnMapTbl[OSRdyTbl[y]];

    OSPrioHighRdy = (INT8U)((y << 3) + x); 找到优先级最高的准备就绪任务

    OSPrioCur = OSPrioHighRdy; 当前运行任务优先级

    OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; 根据任务优先级找到任务

    OSTCBCur = OSTCBHighRdy;

    OSStartHighRdy(); 让优先级最高的任务运行起来

    }

    }


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    任务调度

    void OSSched (void)

    {

    INT8U y;

    OS_ENTER_CRITICAL();

    if ((OSLockNesting | OSIntNesting) == 0) { 调度锁,或者处于中断状态禁止调度

    y = OSUnMapTbl[OSRdyGrp];

    OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);

    获取准备就绪组里最高优先级的任务

    if (OSPrioHighRdy != OSPrioCur) {

    OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];

    设置运行任务为最高优先级任务

    OSCtxSwCtr++;

    OS_TASK_SW(); 执行上下文切换

    } }

    OS_EXIT_CRITICAL();

    }


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    嵌入式控制器硬件初始化

    启动多任务调度

    操作系统初始化

    初始化用户界面、时钟

    主任务

    任务1

    任务n

    LCD初始化

    创建任务

    用户程序

    ……

    装载字库

    调用系统配置文件

    消息处理

    操作系统的启动和运行过程


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    什么也不做的空闲任务

    • 只是为了消耗CPU的时间片

    • void OSTaskIdle ( )

    • {

    • for (;;) {

    • OS_ENTER_CRITICAL();

    • OSIdleCtr++;

    • OS_EXIT_CRITICAL();

    • }

    • }


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    课程大纲

     实时操作系统的几个重要概念

     实时操作系统μC/OS简介

     实时操作系统μC/OS-II的内核结构

     实时操作系统μC/OS-II中的中断与任务通讯

     实时操作系统µCOS-II在ARM7上的移植


    C os ii arm7

    C/OS-II在ARM7上的移植

    • 移植:指使一个实时操作系统能够在选定某个微处理器平台上运行

      • C/OS-II的主要代码都是由标准的C语言写成的,移植方便。


    Cos ii

    移植COS-II满足的条件

    • 处理器的C编译器能产生可重入代码

    • 在程序中可以打开或者关闭中断

    • 处理器支持中断,并且能产生定时中断(通常在10—1000Hz之间)

    • 处理器支承能够容纳一定量数据的硬件堆栈

    • 处理器有将堆栈指针和其他CPU寄存器存储和读出到堆栈(或者内存)的指令


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    打开/关闭中断

    • C/OS-II是通过处理器产生的定时器的中断来实现多任务之间的调度的

      • ARM7TDMI的处理器上可以产生定时器中断。

      • ARM7TDMI处理器可以设置相应的寄存器来关闭或者打开系统的所有中断。

    • 在C/OS-II中开关中断函数:

      OS_ENTER_CRITICAL ()

      OS_EXIT_CRITICAL()


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    处理器支持中断并且能产生定时中断

    • C/OS-II是通过处理器产生的定时器的中断来实现多任务之间的调度的。ARM7TDMI的处理器上可以产生定时器中断。

    • 本系统工作在60MHz的主频下,定时器的中断的频率为1000Hz。也就是系统的响应时间为1ms。


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    处理器支持硬件堆栈

    • 硬件堆栈任务调度基础

      • C/OS-II进行任务调度的时候,会把当前任务的CPU寄存器存放到此任务的堆栈中

      • 然后,再从另一个任务的堆栈中恢复原来的工作寄存器,继续运行另一个任务

      • 所以,寄存器的入栈和出栈是C/OS-II多任务调度的基础。

    • ARM7处理器中有专门的指令处理堆栈,可以灵活的使用堆栈。


    C os ii s3c44b0x

    例:C/OS-II在S3C44B0X上的移植

    • 设置OS_CPU.H中与处理器和编译器相关的代码

    • 用C语言编写六个操作系统相关的函数(OS_CPU_C.C)

    • 用汇编语言编写四个与处理器相关的函数(OS_CPU.ASM)


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    设置与处理器和编译器相关的代码

    • OS_CPU.H

      • 中定义了与编译器相关的数据类型。

      • 如:INT8U、INT8S等。

    • 与 ARM处理器相关的代码

      • 使用OS_ENTER_CRITICAL() 和OS_EXIT_CRITICAL() 宏开启/关闭中断

    • 堆栈的增长方向

      • 堆栈由高地址向低地址增长


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    用C语言编写六个操作系统相关的函数

    • void *OSTaskStkInit (void (*task)(void *pd),void *pdata, void *ptos, INT16U opt)

    • void OSTaskCreateHook (OS_TCB *ptcb)

    • void OSTaskDelHook (OS_TCB *ptcb)

    • void OSTaskSwHook (void)

    • void OSTaskStatHook (void)

    • void OSTimeTickHook (void)

    • 后5个函数为钩子函数,可以不加代码


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    用汇编语言编写四个与处理器相关的函数

    • OSStartHighRdy()

    • OSCtxSw()

    • OSIntCtxSw()

    • OSTickISR()


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

    移植要点

    • 定义函数:OS_ENTER_CRITICAL和OS_ENTER_CRITICAL

    • 定义函数:OS_TASK_SW执行任务切换。

    • 定义函数:OSCtxSw实现用户级上下文切换,用纯汇编实现。

    • 定义函数:OSIntCtxSw实现中断级任务切换,用纯汇编实现。

    • 定义函数:OSTickISR。

    • 定义OSTaskStkInit:来初始化任务的堆栈。


    Anintroductiontoembeddedsystem c os ii iii 2009 6 18

     C/OS的改进

    • 固定的基于优先级的调度

      • 不支持时间片,使用起来不方便

      • 固定任务基础上增加基于时间片的微型调度核

    • 临界资源的访问上使用关闭中断实现

      • 没有使用CPU提供的硬件指令,如测试并置位。

    • 系统时钟中断

      • 没有提供用户使用定时器,可以借鉴linux的定时器加以修改

    • 可以加上文件系统和TCP/IP协议栈


    C os iii

     C/OS-III的改进

    • μC/OS-III是可以抢占的多任务内核,始终运行进入就绪态的最重要的任务

    • μC/OS-III支持无限数量的任务,并允许在运行时,监测堆栈增长的任务

    • 支持无限数量的优先级

    • 允许无限数量的内核对象

    • 运行时可以配置

    • 支持的处理器包括:ARM7/9, Cortex-Mx, Nios- II, PowerPC, Coldfire, i.MX, Microblaze, H8, SH, M16C, M32C, Blackfin等等


  • Login