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

Loading in 2 Seconds...

play fullscreen
1 / 80

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


  • 112 Views
  • Uploaded on

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

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

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


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
slide1

嵌入式系统

AnIntroductiontoEmbeddedSystem

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

μC/OS II/III分析

浙江大学计算机学院

陈天洲

2009.6.18

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

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

slide2

课程大纲

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

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

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

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

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

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

调度(Dispatcher)

  • 这是操作系统的主要职责之一,它决定该轮到哪个任务运行了。
  • 在嵌入式中调度一般是基于优先级的,根据其重要不同被赋予任务不同的优先级。 CPU总是让处在就绪态的优先级最高的任务先运行。
  • 何时让高优先级任务掌握CPU的使用权,有两种不同的情况,这要看用的是什么类型的内核,
    • 非抢占式内核
    • 抢占式内核
slide6
一般调度
  • 非抢占式(non-preemptive)
  • 非占先式调度法也称作合作型多任务(cooperative multitasking),各个任务彼此合作共享一个CPU。
  • 中断服务可以使一个高优先级的任务由挂起状态变为就绪状态。但中断服务以后控制权还是回到原来被中断了的那个任务,直到改任务主动放弃CPU的使用权时,那个高优先级的任务才能获得CPU的使用权。
slide7

低优先级任务

(2)

(1)

ISR

(3)

TIME

(4)

中断服务程序使

高优先级任务就绪

(5)

(6)

高优先级任务

(7)

低优先级任务释放

CPU使用权

非抢占式任务切换过程

slide8
实时调度

抢占式(preemptive)

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

中断服务程序使

高优先级任务就绪

低优先级任务

(2)

(1)

高优先级任务

ISR

(3)

TIME

(4)

(5)

高优先级任务得到

CPU使用权

(6)

抢占式任务切换过程

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

课程大纲

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

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

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

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

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

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

C/OS的性能特点

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

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

课程大纲

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

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

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

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

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

slide19

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

任务是一个无限循环

slide23

void YourTask (void *pdata)

{

/* 用户代码 */

OSTaskDel(OS_PRIO_SELF);

}

任务完成后自我删除
  • 当任务完成以后,任务可以自我删除。
    • 注意任务代码并非真的删除了,μC/OS-Ⅱ只是简单地不再理会这个任务了,这个任务的代码也不会再运行,如果任务调用了OSTaskDel(),这个任务绝不返回什么。
slide24
运行任务可调用的内核函数
  • 延迟一段时间使这个任务进入等待状态:
    • OSTimeDly(),OSTimeDlyHMSM()。
    • 等待的时间过去以后,系统服务函数OSTimeTick()使延迟的任务进入就绪态
  • 运行的任务期待某一事件发生时,可调用以下3个函数之一进入等待:
    • OSSemPend(),OSMboxPend(),或OSQPend()。
    • 调用后任务进入了等待状态(WAITING)。
    • 当任务因等待事件被挂起(Pend),下一个优先级最高的任务立即得到了CPU的控制权。当事件发生了,被挂起的任务进入就绪态。事件发生的报告可能来自另一个任务,也可能来自中断服务子程序。
slide25
中断任务
  • 运行的任务是可以被中断的
    • 响应中断时,正在执行的任务被挂起,中断服务子程序控制了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
slide28
任务控制块主要结构

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

事件控制块的指针

任务的状态字

任务延时参数

slide29
建立任务的二个服务
  • OS TaskCreate()
  • OSTaskCreateExt ()
slide30

分配给任务的优先级

任务代码指针

任务参数指针

分配任务堆栈的栈顶指针

check

Set up task stack

Initialize TCB

Set pointer if level is free

Option to extend functionality

If called from a task

slide31
空任务列表

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

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

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

优先级最高任务

优先级最低任务

(空闲任务)

任务优先级号

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

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

slide36
使任务进入就绪态算法
  • Prio是优先级编号,也是任务的识别号
  • 任务就绪
    • 将任务号放入就绪表,任务就进入就绪态
    • 其方法是:

OSRdyGrp |=OSMapTbl[prio>>3];

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

假设优先级为12—1100b

OSRdyGrp |=0x02;

OSRdyTbl[1] |=0x10;

slide37
使任务脱离就绪态算法
  • 将任务就绪表OSRdyTbl[prio>>3]相应元素的相应位清零,
    • 如果OSRdyTbl[prio>>3]中的所有位都为零时,即全组任务中没有一个进入就绪态时
    • OSRdyGrp的相应位才为零。

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

OSRdyGrp&=OSMapTbl[prio>>3];

就绪表清”0”

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

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

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

找到优先级最高的任务

该任务是否正在运行

任务切换

slide43
任务切换
  • 将被挂起的任务寄存器入栈
  • 将较高优先级任务的寄存器出栈
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

存贮器高地址

存贮器高地址

slide46

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)

存贮器高地址

存贮器高地址

slide47

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从新堆栈中弹出;

执行中断返回指令;

}

slide49

课程大纲

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

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

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

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

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

slide50

C/OS-II中的中断

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

C/OS-II中的中断

进入临界区(中断)

必要时须用汇编代码

退出临界区(中断)

slide53

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

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

中断反回过程与实时调度

slide54
中断与时钟节拍
  • μC/OS中提供了OSIntEnter() 和OSIntExit() 告诉内核进入了中断状态。
  • 时钟节拍是一种特殊的中断,操作系统的心脏
    • 32位的整数:OSTime+1
    • 对任务列表进行扫描,判断是否有延时任务应该处于准备就绪状态
    • 最后进行上下文切换。
slide55

令指针指向第一个任务

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

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

任务是否存在延时?

延时数减一

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

延时数是否为0?

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

如果条件合适,将该

任务放入就绪列表

对任务表进行扫描

令指针指向下一个任务

OSTime++

返回

是否是空闲任务?

时钟节拍中断流程

OSTimeTick( void )

slide56

1

25

50

时间

任务一

任务二

空闲任务

OSStart

Time Tick

Time Tick

Time Tick

slide57
任务间通信手段
  • C/OS中,采用多种方法保护任务之间的共享数据和提供任务之间的通信。
    • 提供OS_ENTER_CRITICAL和OS_EXIT_CRITICAL来对临界资源进行保护
    • OSSchedLock( )禁止调度保护任务级的共享资源。
    • 提供了经典操作系统任务间通信方法:信号量、邮箱、消息队列,事件标志。
slide58
事件控制块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()操作增加信号量的值。
slide60
时间管理
  • 五个系统时间服务
    • OSTimeDLY() 任务延时函数
    • OSTimeDLYHMSM() 按时分秒延时函数
    • OSTimeDlyResmue() 结束延时
    • OStimeGet()
    • OSTimeSet()
slide61
任务调度
  • For example1 创建2个任务,每个任务仅仅是进行延时,延时不同的时间片,不同优先级

void Task1(void) void Task2(void)

{ {

while(1) while(1)

{ {

blinkled1(); blinkled2();

Task1Data++; Task2Data++;

OSTimeDly(25); OSTimeDly(50);

} }

} }

slide62
多任务循环

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();

}

slide63
任务启动

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(); 让优先级最高的任务运行起来

}

}

slide64
任务调度

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();

}

slide65

嵌入式控制器硬件初始化

启动多任务调度

操作系统初始化

初始化用户界面、时钟

主任务

任务1

任务n

LCD初始化

创建任务

用户程序

……

装载字库

调用系统配置文件

消息处理

操作系统的启动和运行过程
slide66
什么也不做的空闲任务
  • 只是为了消耗CPU的时间片
  • void OSTaskIdle ( )
  • {
  • for (;;) {
  • OS_ENTER_CRITICAL();
  • OSIdleCtr++;
  • OS_EXIT_CRITICAL();
  • }
  • }
slide67

课程大纲

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

 实时操作系统μ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寄存器存储和读出到堆栈(或者内存)的指令
slide70
打开/关闭中断
  • C/OS-II是通过处理器产生的定时器的中断来实现多任务之间的调度的
    • ARM7TDMI的处理器上可以产生定时器中断。
    • ARM7TDMI处理器可以设置相应的寄存器来关闭或者打开系统的所有中断。
  • 在C/OS-II中开关中断函数:

OS_ENTER_CRITICAL ()

OS_EXIT_CRITICAL()

slide71
处理器支持中断并且能产生定时中断
  • C/OS-II是通过处理器产生的定时器的中断来实现多任务之间的调度的。ARM7TDMI的处理器上可以产生定时器中断。
  • 本系统工作在60MHz的主频下,定时器的中断的频率为1000Hz。也就是系统的响应时间为1ms。
slide72
处理器支持硬件堆栈
  • 硬件堆栈任务调度基础
    • 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)
slide74
设置与处理器和编译器相关的代码
  • OS_CPU.H
    • 中定义了与编译器相关的数据类型。
    • 如:INT8U、INT8S等。
  • 与 ARM处理器相关的代码
    • 使用OS_ENTER_CRITICAL() 和OS_EXIT_CRITICAL() 宏开启/关闭中断
  • 堆栈的增长方向
    • 堆栈由高地址向低地址增长
slide75
用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个函数为钩子函数,可以不加代码
slide76
用汇编语言编写四个与处理器相关的函数
  • OSStartHighRdy()
  • OSCtxSw()
  • OSIntCtxSw()
  • OSTickISR()
slide77
移植要点
  • 定义函数:OS_ENTER_CRITICAL和OS_ENTER_CRITICAL
  • 定义函数:OS_TASK_SW执行任务切换。
  • 定义函数:OSCtxSw实现用户级上下文切换,用纯汇编实现。
  • 定义函数:OSIntCtxSw实现中断级任务切换,用纯汇编实现。
  • 定义函数:OSTickISR。
  • 定义OSTaskStkInit:来初始化任务的堆栈。
slide78
 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等等
ad