nucleus 嵌入式操作系统

25
Nucleus Nucleus 嵌嵌嵌嵌嵌嵌嵌嵌嵌嵌嵌嵌

Upload: gilles

Post on 18-Mar-2016

365 views

Category:

Documents


8 download

DESCRIPTION

Nucleus 嵌入式操作系统. 主要内容 :. 1 、 嵌入式系统概述 2 、 Nucleus 嵌入式操作系统介绍 3 、 Nucleus 提供的主要服务 4 、 Rftest 中的操作系统代码分析. 与普通的操作系统相比,它的主要特点有: ⑴、微型化。嵌入式系统芯片内部存储器的容量通常不是很大 (1MB) ,加上电源容量较小,以及外部设备的多样化,因而并不允许嵌入式操作系统占用很多资源。 ⑵、实时性。由于对嵌入式实时操作系统的共同要求是系统能够快速响应事件,具有较强的实时性,所以嵌入式实时操作系统的内核都是可剥夺的。 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Nucleus 嵌入式操作系统

NucleusNucleus 嵌入式操作系统嵌入式操作系统

Page 2: Nucleus 嵌入式操作系统

主要内容 :1、嵌入式系统概述2、Nucleus嵌入式操作系统介绍3、Nucleus提供的主要服务4 、 Rftest 中的操作系统代码分析

Page 3: Nucleus 嵌入式操作系统

什么是嵌入式实时操作系统什么是嵌入式实时操作系统 ??与普通的操作系统相比,它的主要特点有:与普通的操作系统相比,它的主要特点有:⑴⑴ 、微型化。嵌入式系统芯片内部存储器的容量通常不是很大、微型化。嵌入式系统芯片内部存储器的容量通常不是很大

(1MB)(1MB) ,加上电源容量较小,以及外部设备的多样化,因而并,加上电源容量较小,以及外部设备的多样化,因而并不允许嵌入式操作系统占用很多资源。不允许嵌入式操作系统占用很多资源。⑵⑵ 、实时性。由于对嵌入式实时操作系统的共同要求是系统能、实时性。由于对嵌入式实时操作系统的共同要求是系统能够快速响应事件,具有较强的实时性,所以嵌入式实时操作系够快速响应事件,具有较强的实时性,所以嵌入式实时操作系统的内核都是可剥夺的。统的内核都是可剥夺的。⑶⑶ 、可裁剪性。嵌入式操作系统运行的硬件平台多样化,所以、可裁剪性。嵌入式操作系统运行的硬件平台多样化,所以要求嵌入式系统提供的各个功能模块可以让用户选择使用。要求嵌入式系统提供的各个功能模块可以让用户选择使用。⑷⑷ 、高可靠性。、高可靠性。⑸⑸ 、易移植性。为了适应各种各样的硬件平台,嵌入式系统可、易移植性。为了适应各种各样的硬件平台,嵌入式系统可在不做大量修改的情况下能稳定地运行于不同的平台。在不做大量修改的情况下能稳定地运行于不同的平台。

Page 4: Nucleus 嵌入式操作系统

嵌入式操作系统的地位:嵌入式操作系统的地位:

用户进程1 用户进程2文件管理服务器进程

内存管理服务器进程

微内核

客户通过内核向服务器发送消息来请求服务

微内核:微内核:

嵌入式系统的应用软件

嵌入式操作系统

嵌入式系统硬件

常见的嵌入式实时操作系统有:常见的嵌入式实时操作系统有: μc/OS-Ⅱμc/OS-Ⅱ ,, RTLinuxRTLinux ,, NucleusNucleus ,, ARM-LinuxARM-Linux ,, KURTKURT (源码开放)(源码开放) VxWorksVxWorks ,, QNXQNX ,, pSOSpSOS ,, WindowsCEWindowsCE (商业软件)(商业软件)

提供的服务主要包括进程管提供的服务主要包括进程管理、存储管理、文件管理、理、存储管理、文件管理、设备管理等设备管理等

返回

Page 5: Nucleus 嵌入式操作系统

NucleusNucleus 嵌入式操作系统嵌入式操作系统 NucleusNucleus 实时操作系统是实时操作系统是 Accelerater TechnologyAccelerater Technology 公司开发的嵌入式公司开发的嵌入式 RTRT

OSOS 产品。只需一次性购买产品。只需一次性购买 LicensesLicenses 就可以获得源码。它的 核心是一个实时就可以获得源码。它的 核心是一个实时多任务内核——多任务内核—— Nucleus PLUSNucleus PLUS ,性能介于,性能介于 μc/OS-Ⅱμc/OS-Ⅱ 和和 VxWorksVxWorks 之间。之间。 Nucleus PLUS Nucleus PLUS 是为实时嵌入式应用而设计的一个抢先式多任务操作系统内是为实时嵌入式应用而设计的一个抢先式多任务操作系统内核,其核,其 9595 %的代码是用%的代码是用 ANSI CANSI C 写成的,因此非常便于移植并能够支持大写成的,因此非常便于移植并能够支持大多数类型的处理器。从实现角度来看,多数类型的处理器。从实现角度来看, Nucleus PLUS Nucleus PLUS 是一组是一组 CC 函数库,应函数库,应用程序代码与核心函数库连接在一起,生成一个目标代码,下载到目标板用程序代码与核心函数库连接在一起,生成一个目标代码,下载到目标板的的 RAMRAM 中或直接烧录到目标板的中或直接烧录到目标板的 ROMROM 中执行。在典型的目标环境中,中执行。在典型的目标环境中, NN

ucleus PLUS ucleus PLUS 核心代码区一般不超过核心代码区一般不超过 20K20K 字节大小。字节大小。 Nucleus PLUS Nucleus PLUS 采用了软件组件的方法。每个组件具有单一而明确的目的,采用了软件组件的方法。每个组件具有单一而明确的目的,通常由几个通常由几个 CC 及汇编语言模块构成,提供清晰的外部接口,对组件的引用及汇编语言模块构成,提供清晰的外部接口,对组件的引用就是通过这些接口完成的。除了少数一些特殊情况外,不允许从外部对组就是通过这些接口完成的。除了少数一些特殊情况外,不允许从外部对组件内的全局进行访问。件内的全局进行访问。 Nucleus PLUS Nucleus PLUS 的组件包括任务控制、内存管理、任务间通信、任务的同步的组件包括任务控制、内存管理、任务间通信、任务的同步与互斥、中断管理、定时器及与互斥、中断管理、定时器及 I/OI/O 驱动等。驱动等。

Page 6: Nucleus 嵌入式操作系统

Nucleus plusNucleus plus 的组件结构:的组件结构:缺点:实时性不够,定时中断管理不可靠,缺点:实时性不够,定时中断管理不可靠, I/OI/O 管理管理太简单,操作系统调太简单,操作系统调试工具很少等等。试工具很少等等。

Nucleus plus 使用了软件组件方法学,每个组件有单一的清晰的目的。软件组件往往包括几个 C 或汇编程序,每个组件软件提供定义非常好的外部接口,通过使用外部接口来利用组件。 组件包含的文件或文件名约定如下:文件 含义

XX_D.H

XX_DEFS.H

XX_EXTR.H

XX_I.H

XX_F.H

XX_C.H

XX_CE.H

组件的常量和数据类型的定义

组件的外部接口的定义

组件的静态和全局变量的定义

组件的初始化定义

提供被组件管理的对象的信息

组件的核心函数

组件的核心函数的错误处理外壳函数

Page 7: Nucleus 嵌入式操作系统

Nucleus plus 中使用的数据类型: UNSIGNED 32 位无符号整数 (UNSIGNED LONG) SIGNED 32 位有符号整数 (Long) OPTION 最小的易于使用的整数 (UNSIGNED CHAR) DATA_ELEMENT 与 OPTION 相同 UNSIGNED CHAR 8 位无符号的字符 CHAR 8 位的字符 STATUS 与目标 C编译器的有符号整数 INT 类型等价 INT 整数数据类型,具有 WORD 的大小 UNSIGNED_PTR 指向一个 UNSIGNED指针 BYTE_PTR 指向一个 UNSIGNED CHAR指针 Nucleus plus 的组件有: 通用服务组件 (CS) 、初始化组件 (IN) 、线程调度组件 (TC) 、定时组件 (TM) 、邮箱组件 (MB) 、队列组件 (QM) 、管道组件 (PI)信号量组件 (SM) 、事件组件 (EV) 、存储分配组件 (PM) 、动态存储组件 (DM) 、输入输出组件 (IO) 等 返回

Page 8: Nucleus 嵌入式操作系统

三个层次的初始化

Int_initialize (基于目标系统硬件的初始化 )

Inc_initialize (Nucleus 组件的初始化 )

Application_initialize ( 应用环境的初始化 )

Nucleus Plus 中的初始化INT_Initialize初始化以下内容:

初始化处理器的控制寄存器中断向量表全局 C数据元素一些Nucleus plus变量系统堆栈指针

INC_Initialize

对Nucleus Plus的组件进行初始化

调用每个Nucleus Plus的组件的初始化应用

子程序

用户提供的初始化子程序 Application_initialize: 初始化应用任务,邮箱,队列,信号量,管道,事件集,内存池等

初始化任务安排表

Page 9: Nucleus 嵌入式操作系统

Nucleus Plus 的任务 任务就是目的明确的半独立程序段。大多数现代实时应用都要求多任务。另外,这些任务的重要等级经常变化。管理这些竞争、实时任务的运行是 Nucleus PLUS 的主要目的。

任务控制块

每个任务都有五种状态:运行、就绪、挂起、终止、完成

Nucleus 对任务的调度需要任务控制块 (TCB) ,任务控制块是一种结构体,该结构体中包含了任务的各种信息。 任务堆栈

Nucleus 的任务堆栈用来保存任务切换时的上下文,包括任务切换时的PC 、各寄存器以及堆栈的当前值,此外任务堆栈还用来存储任务运行时的临时变量。

任务状态

Page 10: Nucleus 嵌入式操作系统

任务的优先级任务的优先级 任务优先级在任务创建期间定义,范围 0~ 255 ,用来定义 Nulceus PLUS 任务的重要性,数字越小优先级越高。在任务运行中可以动态设置优先级。 Nucleus PLUS 在低优先级任务前运行更高优先级任务。同等优先级任务按照进入就绪状态的先后顺序运行。 不同优先级任务调度不同优先级任务调度

采用任务抢占模式。就是当更高优先级的任务就绪时挂起低优先级的任务的行为。任务抢占可以被设置为禁止,那么这时任务会一直运行到完成直到任务主动挂起或者使能抢占。相同优先级的任务调度相同优先级的任务调度1 、主动放弃模式。在任务中调用 NU_Relinquish() 。2 、采用时间片模式。当任务创建时设置的时间片( Time Slices) 到来时,其他的所有就绪且在同一优先级的任务获得 CPU 而运行。

Page 11: Nucleus 嵌入式操作系统

任务的调度任务的调度 Nucleus 是以链表来管理已创建的任务的 TCB 的。而且 Nucleus把每个就绪任务以任务的优先级高低为顺序放在就绪任务表中,在调度的时候它可以从就绪任务表中找出就绪的优先级最高的任务,然后通过链表访问它的 TCB ,从而运行该任务。任务的切换过程任务的切换过程 任务切换的实质是断点数据的切换,断点数据的切换也就是处理器堆栈指针的切换。

被中止任务的TCB

tc_stack_pointer

被中止任务堆栈

待运行任务TCB

tc_stack_pointer

待运行任务堆栈

SPR1R2…

RnPC

PSW

CPU各寄存器

② ③

Page 12: Nucleus 嵌入式操作系统

主要的任务函数介绍主要的任务函数介绍STATUS NU_Create_Task ( 创建一个任务 NU_TASK *task, CHAR *name, VOID (*task_entry)(UNSIGNED, VOID *), UNSIGNED argc, VOID *argv, VOID *stack_address, UNSIGNED stack_size, OPTION priority, UNSIGNED time_slice, OPTION preempt, OPTION auto_start)

指向一个任务控制块指向一个任务的任务名指向任务函数的入口地址传递初始化信息到任务指向任务堆栈的地址任务堆栈的大小任务的优先级时间片 (1 – 4,294,967,293)任务的抢占模式任务的初始启动配置STATUS NU_Suspend_Task (NU_TASK *task) 无条件挂起一个任务STATUS NU_Resume_Task (NU_TASK *task) 恢复一个任务

主动放弃时间片以便同优先级的就绪任务运行挂起一个任务,直到 time ticks 到来STATUS NU_Sleep (UNSIGNED ticks)

VOID NU_Relinquish (VOID) 删除一个已创建的任务STATUS NU_Delete_Task(NU_TASK *task)

Page 13: Nucleus 嵌入式操作系统

Nucleus Plus 任务间的通信 任务需要一定的机制来实现与其他任务的通信。 Nucleus PLUS 为通信目的提供邮箱 (mailbox),队列 (queues), 管道 (pipes) 。邮箱,队列,管道是独立的公共设备。任务之间和其他系统设备之间的联系由应用程序确定。这些通信设备之间主要的差别是数据通信的类型。 邮箱 (mailbox) 邮箱为传输简单数据提供低消耗方案。每个邮箱可以保持 4 个 32 位字大小的单一消息。消息以(数)值方式发送和接受。 任务可以在邮箱内挂起,其原因有:⒈试图从空邮箱接受消息的任务;⒉试图向满邮箱发送消息的任务; 多个任务可以在一个邮箱上挂起,挂起顺序有两种:一是按照优先级顺序挂起,二是按照 FIFO 的形式挂起。

Page 14: Nucleus 嵌入式操作系统

STATUS NU_Create_Mailbox( //创建一个邮箱 NU_MAILBOX *mailbox, //指向邮箱的控制块 CHAR *name, //指向邮箱名 OPTION suspend_type) // 多任务在邮箱的挂起方式

主要的邮箱函数

STATUS NU_Receive_From_Mailbox( // 从邮箱中接收消息 NU_MAILBOX *mailbox, //指向邮箱的控制块 VOID *message, // 接收消息的指针 UNSIGNED suspend) // 任务挂起类型

STATUS NU_Send_To_Mailbox( // 发送消息到邮箱 NU_MAILBOX *mailbox, //指向邮箱的控制块 VOID *message, // 要发送的消息指针 UNSIGNED suspend) // 任务挂起类型

STATUS NU_Delete_Mailbox( //删除一个邮箱 NU_MAILBOX *mailbox) //指向邮箱的控制块

Page 15: Nucleus 嵌入式操作系统

队列 (queues)

队列提供了传输多个消息的机制。队列传递消息类型是 Unsigned(即 32bit字),队列支持定长和不定长消息(支持不定长消息,需要一个 32 位的额外附加信息),消息可以放在对列的前端或队列的后端。 任务能在队列内因为几种原因挂起。一个试图从空队列中接受消息的任务可以被挂起。同样,一个试图发送消息至满队列的任务可以被挂起。 多任务能在一个队列上挂起。依靠创建队列的任务可以以 FIFO 或是优先级次序被挂起。STATUS NU_Create_Queue( //创建一个队列 NU_QUEUE *queue, //指向队列控制块 char *name, //指向队列名 VOID *start_address, //队列的起始地址 UNSIGNED queue_size, //队列的大小 OPTION message_type, //队列中消息的类型 ( 定长和不定长 ) UNSIGNED message_size, //消息的大小 OPTION suspend_type) // 多个任务在队列上的挂起方式

Page 16: Nucleus 嵌入式操作系统

STATUS NU_Send_To_Queue( // 发送消息到队列的末尾 NU_QUEUE *queue, ///指向队列的控制块 VOID *message, //指向要发送的消息 UNSIGNED size, // 发送消息的大小 UNSIGNED suspend) // 任务的挂起类型STATUS NU_Send_To_Front_Of_Queue( // 发送消息到队列的开头 NU_QUEUE *queue, VOID *message, UNSIGNED size, UNSIGNED suspend)

STATUS NU_Receive_From_Queue( // 从队列的前端取消息 NU_QUEUE *queue, //指向队列控制块 VOID *message, // 接收消息的指针 UNSIGNED size, //消息的大小 UNSIGNED *actual_size, // 接收到的实际消息大小 UNSIGNED suspend) // 任务的挂起类型

STATUS NU_Delete_Queue(NU_QUEUE *queue) //删除一个队列

Page 17: Nucleus 嵌入式操作系统

Nucleus Plus 任务间的同步

Data fifo

IN OUT

任务A 任务B

向fifo中写数据 从fifo中读数据

为了实现任务之间的合作和无冲突的运行,在有关联的任务之间必须建立一些制约关系。这些关系有两种: 1 、直接制约关系,源于任务之间的合作; 2 、间接制约关系,源于对资源的共享;

共享资源

任务A

任务B

信号量提供了一种机制来控制操作系统临界资源的分配。它的两个基本操作是 obtain 和 release , obtain 为减少信号量, release 为增加信号量。信号量最常见的应用就是资源分配。当多个任务试图 obtain信号量时会挂起,挂起方式有优先级和 FIFO 。

Nucleus PLUS 提供信号量( semaphores ),事件集( event groups )和信号( signals )解决信号同步问题。信号量( semaphores )

因此任务之间的这种合作运行机制就叫同步。

Page 18: Nucleus 嵌入式操作系统

互斥信号量带来的问题:优先级反转 互斥信号量就是一个初始值设置为 1 的信号量,它只允许一个任务独享其资源。 优先级反转就是低优先级的任务先于高优先级的任务运行的现象。一个优先级反转现象如下图所示:任务A(高) 任务C(低)任务B(中)

t

t6

t5

t4

t3

t2

t1

任务C获得信号量

任务C使用共享资源任务A等待的事件来临

任务A申请信号量

任务A因优先级高于任务C而运行

任务A因任务C未释放信号量而等待

任务A获得信号量

任务A因任务C释放信号量而运行

任务B等待的事件来临

任务B因优先级高于任务C而运行

任务C因任务A获得CPU而等待

任务C因任务A等待信号量而继续运行

任务C因任务B获得CPU而等

任务C因任务 B释放CPU而运行

信号量带来的另一个问题是死锁,解决方法是任务只允许一次占用一个信号量。

解决办法:提高任务 C 的优先级,使其运行不被打断。

Page 19: Nucleus 嵌入式操作系统

主要的信号量函数STATUS NU_Create_Semaphore( //创建一个信号量 NU_SEMAPHORE *semaphore, //指向信号量的结构体 CHAR *name, //信号量的名字 UNSIGNED initial_count, //信号量的初始值 OPTION suspend_type) // 多任务访问信号量的挂起方式STATUS NU_Obtain_Semaphore( // 获得信号量 NU_SEMAPHORE *semaphore, //指向信号量的结构体 UNSIGNED suspend) // 任务的挂起类型STATUS NU_Release_Semaphore(NU_SEMAPHORE *semaphore) //释放信号量事件组( event groups ) 事件组提供一个机制来描述一个指定系统事件的发生。每个事件组有 32个事件标志,每个事件标志在事件集中占一个 bit 。每个事件标志可以通过逻辑与 / 或结合来设置和清除。 一个任务企图接收一个没有出现的事件标志组合会让该任务挂起。

Page 20: Nucleus 嵌入式操作系统

主要的事件组函数STATUS NU_Create_Event_Group( //创建一个事件组 NU_EVENT_GROUP *group, //指向事件组的控制块 CHAR *name) // 事件组的名字 创建后事件组中的每个事件标志都被清 0 。STATUS NU_Set_Events( // 设置事件标志 NU_EVENT_GROUP *group, //指向事件组的控制块 UNSIGNED event_flags, // 设置的事件标志 OPTION operation) //逻辑操作类型 (And/Or)

例子:(逻辑操作 Or 和 And 的区别)NU_SET_EVENTS(&Event0,0x0001,NU_OR)NU_SET_EVENTS(&Event0,0x0010,NU_OR)

0x0001|0x0010=0x0011事件标志 1 和 2被置位NU_SET_EVENTS(&Event0,0x0001,NU_AND)NU_SET_EVENTS(&Event0,0x0010,NU_AND)

0x0001&0x0010=0x0000事件标志 1 和 2被清除

Page 21: Nucleus 嵌入式操作系统

STATUS NU_Retrieve_Events( // 获得事件标志组合 NU_EVENT_GROUP *group, //指向事件组控制块 UNSIGNED requested_events, //请求的事件标志 OPTION operation, //逻辑操作类型 UNSIGNED *retrieved_events, // 接收到的事件标志组合 UNSIGNED suspend) // 任务的挂起类型

逻辑操作类型包括: NU_AND , NU_AND_CONSUME , NU_OR , NU_OR_CONSUME.

信号( signals )与事件组类似,只是信号是异步的,而事件组是同步的。 对于事件组而言,当一个任务在获得事件标志组合时,如果获得的事件标志与请求的事件标志不匹配则任务挂起,直到匹配的事件标志出现。 而对于信号而言,一个任务的开始处定义了一个信号处理函数,在指定的信号没出现时任务可以执行其它操作,当信号到来时,任务才转去执行相应的信号处理函数,这就有点类似于中断处理函数。

Page 22: Nucleus 嵌入式操作系统

Nucleus Plus 的中断 中断是为外部和内部事件提供立即响应的机制。当中断发生时处理器立即挂起当前运行的程序,并且转移到适当的中断服务子程序 (ISR) 。 Nucleus 的中断分为管理的中断和非管理的中断。 非管理中断类似以前常见的中断服务程序,它不需要操作系统管理,直接将中断服务程序挂到中断向量表上。它不能使用绝大多数的 Nucleus 系统调用,因为这很可能破坏操作系统某些保护的数据结构。非管理的中断适合于那些比较频繁的中断,需要由用户自己写代码保存中断的上下文。 管理的中断需要向操作系统注册该中断向量。它又分为低级中断 (LISR) 和高级中断 (HISR) 。 低级中断服务子程序( LISR )和正常的 ISR 一样运行,包括使用当前堆栈。 Nucleus PLUS 在调用 LISR 之前保存上下文,在 LISR 返回之后恢复上下文。 LISR 主要完成硬件中断处理,及激活 HISR 。

Page 23: Nucleus 嵌入式操作系统

高级中断支持动态创建和删除。每个 HISR 由它自己的堆栈空间和控制块。每个的内存由应用程序提供。当然, HISR必须在 LISR激活之前被创建。 一旦 HISR 有自己的堆栈和控制块,如果它试图进入一个已经被访问 Nucleus PLUS 数据结构时就会被临时封锁。 HISR 的调度类似于任务,具有优先级,允许访问大多数的 Nucleus PLUS 服务,除了自挂起服务( self-suspension )。 HISR 有三个优先等级。在一个低优先级的 HISR 处理期间,如果一个更高优先等级的 HISR被激活,低优先级的 HISR 以与任务抢先方式相同的方式抢先。相同优先级的 HISR 以他们最初激活的顺序运行。主要的中断函数

VOID *NU_Setup_Vector(INT vector, VOID *new)

// 设置中断向量表,此项服务使用用户自定义中断服务子程序代替 vector指定的中断向量。服务返回先前中断向量内容。该函数主要用于非管理的中断,且用户提供的 ISR 需用汇编语言编写。

Page 24: Nucleus 嵌入式操作系统

STATUS NU_Register_LISR( //注册一个低级中断 INT vector, // 中断向量号 VOID(*lisr_entry)(INT), //ISR 函数入口地址 VOID (**old_lisr)(INT)) //旧的 ISR 函数入口地址STATUS NU_Create_HISR( NU_HISR *hisr, //指向高级中断控制块 CHAR *name, // 高级中断的名称 VOID (*hisr_entry)(VOID), // 高级中断处理程序的入口地址 OPTION priority, // 高级中断优先级 VOID *stack_pointer, // 高级中断的堆栈指针 UNSIGNED stack_size) //堆栈的大小STATUS NU_Activate_HISR (NU_HISR *hisr) //激活高级中断INT NU_Control_Interrupts(INT new_level) // 使能或是禁止一个中断

Page 25: Nucleus 嵌入式操作系统

Nucleus Plus 的内存分配