390 likes | 645 Views
Embedded System Design ---- Embedded OS. Zhaofeng SJTU-SoME 2007-11-02. OUTLINE. UNIX/Linux 发展历程 POSIX System Call 嵌入式操作系统的基本概念. UNIX 发展历程. 美国 AT&T (美国电话电报)公司的贝尔实验室于 1969 年在 DEC 的小型机 PDP-7 上开发成功 1973 年开发 C 语言并改写 UNIX 第 3 版 1974 年 7 月,” UNIX 分时系统”一文在美国权威杂志 CACM 上发表
E N D
Embedded System Design ---- Embedded OS Zhaofeng SJTU-SoME 2007-11-02
OUTLINE • UNIX/Linux发展历程 • POSIX • System Call • 嵌入式操作系统的基本概念
UNIX发展历程 • 美国AT&T(美国电话电报)公司的贝尔实验室于1969年在DEC的小型机PDP-7上开发成功 • 1973年开发C语言并改写UNIX 第3版 • 1974年7月,”UNIX分时系统”一文在美国权威杂志CACM上发表 • 最早可获得的UNIX是75年的UNIX 第6版 • 1978年的UNIX第7版,是当今UNIX的祖先 • 1983年AT&T公司公布了UNIX System V。
1968~1970 • 贝尔实验室的Ken Thompson和Dennis Ritchie和Joseph Ossanna 在开发MULTICS(MULTiplexed Information and Computing System时)遇到了失败,同时产生的副产品被戏称为UNICS(UNiplexed Information and Computing System),然后又逐渐演变为UNIX。 • PDP-7上汇编语言开发的单用户操作系统 • PDP-11上C语言开发 Ken Thompson
Dennis Ritchic • Dennis M.Ritchic是朗讯科技公司研发机构贝尔实验室计算机科学研究中心系统软件研究部主任,获得哈佛大学学士、硕士学位后,他于1968年加入贝尔实验室。 • Dennis M.Ritchic协助Ken Thompson创建了UNIX操作系统。他是C语言的主要设计者。目前,他仍然致力于操作系统和语言的研究工作。
BSD UNIX • 由大学开发的非AT&T系统UNIX是Berkeley分校(CSRG)运行在VAX-11机上的 UNIX BSD •最著名的是4.1BSD、4.2BSD、4.3BSD和4.4BSD,这些版本中加入页式虚存、长文件名、 网络协议TCP/IP等,在UNIX 发展中起了重要作用,已成为教学、科研、商用的主流系统。
AT&T 第1---第7版 (71---78年) SYSTEM III---V (82、83年) SVR2---SVR4 (84---89年) Berkeley分校 1BSD—4BSD (78—80年) 4.0SBD—4.4SBD (80—93年) UNIX主要变种 1989年: AT&T 与Berkeley分校两个分支的UNIX会合并且统一为SVR4
源代码版本的UNIX • Minix • 由Andrew Tanenbaum实现。是一个教学用的系统。在很多应用平台上都有相应的版本。 • 386BSD • 由Bill和Lynne Jolitz维护。 • FreeBSD • NetNSD • Linux • 由芬兰的Linus B. Torvalds开发,是目前最流行的免费UNIX系统。有望取代MS Windows成为PC的主流操作系统。
教堂与集市 • Cathedral:别忘了windows • 源代码锁定在有限范围内 • 新版本的发行由市场决定 • Bazaar: • 征集并充分利用早期的反馈 • 巨大数量的脑力资源进行平衡配置 • 开发理想的操作系统 • 享受工作的快乐,获得充分的自豪感 http://www.firstmonday.org/issues/issue3_3/raymond/#d4
有序的Linux开发 • Linux采用了双树结构 • Stable tree • Development tree(Unstable tree) • 源代码版本号:x.y.z • 2.3.12 • 2.4.0 http://www.kernel.org
OUTLINE • UNIX/Linux发展历程 • POSIX • System Call • 嵌入式操作系统的由来与特点 • 嵌入式操作系统的基本概念
POSIX标准 • POSIX标准: 1990年,IEEE拟定了一个UNIX标准,称作POSIX。它定义了相互兼容的UNIX系统必须支持的最少系统调用接口。该标准已被多数UNIX支持,同时,其他一些操作系统也在支持POSIX标准。 • POSIX(Portable Operating System Interface): 可移植操作系统接口,是操作系统的国际标准接口。 • POSIX对Linux的发展起了极大的作用
OUTLINE • UNIX/Linux发展历程 • POSIX • System Call • 嵌入式操作系统的由来与特点 • 嵌入式操作系统的基本概念
“Core” Kernel Applications System Libraries (libc) System Call Interface I/O Related Process Related File Systems Scheduler Modules Networking Memory Management Device Drivers IPC Architecture-Dependent Code Hardware
System Call(系统调用) • 用户程序用以请求内核提供的服务的特殊函数 • 除非一个汇编程序仅仅进行数学运算,否则其必须进行输入输出及退出等操作,而要进行这些操作就需要调用操作系统的服务。 • 在UNIX系统下有两种方式实现对系统调用的使用:通过经过封装的C库(libc)或者直接调用 • 其功能和性能很大程度上反映了操作系统的功能和性能
常用的系统调用 分为I/O处理、进程、时间、内存等 1、文件操作 2、进程控制 3、信号处理 4、高级I/O 5、网络通信 … 除特殊说明,所有函数返回负值表示失败。
进程相关的系统调用函数 • fork() • clone(), pthead_create() • exit() • wait() • pipe() • signal() • kill() • exec()
OUTLINE • UNIX/Linux发展历程 • POSIX • System Call • 嵌入式操作系统的基本概念
Status SP Priority Status SP Priority Status SP Priority SP 任务 • 一个任务,也称作一个线程,是一个简单的程序,该任务可以认为CPU完全只属该任务自己。实时应用程序的设计过程,包括如何把问题分割成多个任务,每个任务都是整个应用的某一部分,每个任务被赋予一定的优先级,有它自己的一套CPU寄存器和自己的栈空间。 TASK 1 TASK 2 TASK n Stack Stack Stack …… Memory CPU CPU Registers 多任务
多任务 • 多任务运行的实现实际上是靠CPU(中央处理单元)在许多任务之间转换、调度。CPU只有一个,轮番服务于一系列任务中的某一个。 • 多任务运行使CPU的利用率得到最大的发挥,并使应用程序模块化。在实时应用中,多任务化的最大特点是,开发人员可以将很复杂的应用程序层次化。
资源与共享 • 任何为任务所占用的实体都可称为资源。资源可以是输入输出设备,例如打印机、键盘、显示器,资源也可以是一个变量,一个结构或一个数组等。 • 可以被一个以上任务使用的资源叫做共享资源。为了防止数据被破坏,每个任务在与共享资源打交道时,必须独占该资源。
任务的状态 • 休眠态相当于该任务驻留在内存中,但并不被内核所调度。 • 就绪意味着该任务已经准备好,可以运行了,但由于该任务的优先级比正在运行的任务的优先级低,还暂时不能运行。 • 运行态的任务是指该任务掌握了CPU的控制权,正在运行中。 • 挂起状态也可以叫做等待(WAITING)事件态,指该任务在等待,等待某一事件的发生,(例如等待某外设的I/O操作,等待某共享资源由暂不能使用变成能使用,等待定时脉冲的到来或等待超时信号的到来以结束目前的等待,等等)。 • 发生中断时,CPU 提供相应的中断服务,原来正在运行的任务暂不能运行,就进入了中断状态。 挂起 休眠 运行 中断 就绪
任务切换 • 任务切换(Context Switch or Task Switch) • 当多任务内核决定运行另外的任务时,它保存正在运行任务的当前状态(Context),即CPU寄存器中的全部内容。这些内容保存在任务的当前状况保存区(Task’s Context Storage area),也就是任务自己的栈区之中。入栈工作完成以后,就是把下一个将要运行的任务的当前状况从该任务的栈中重新装入CPU的寄存器,并开始下一个任务的运行。这个过程叫做任务切换。 • 任务切换过程增加了应用程序的额外负荷。CPU的内部寄存器越多,额外负荷就越重。做任务切换所需要的时间取决于CPU有多少寄存器要入栈。 • 老板※行政※教师※工程师※Task Graph
内核(Kernel) • 多任务系统中,内核负责管理各个任务,或者说为每个任务分配CPU时间,并且负责任务之间的通讯。 • 内核提供的基本服务是任务切换。之所以使用实时内核可以大大简化应用系统的设计,是因为实时内核允许将应用分成若干个任务,由实时内核来管理它们。 • 内核本身也增加了应用程序的额外负荷,代码空间增加ROM的用量,内核本身的数据结构增加了RAM的用量。但更主要的是,每个任务要有自己的栈空间,这一块吃起内存来是相当厉害的。 • 内核本身对CPU的占用时间一般在2到5个百分点之间。 • 单片机一般不能运行实时内核,因为单片机的RAM很有限。通过提供必不可缺少 的系统服务,诸如信号量管理,邮箱、消息队列、延时等,实时内核使得CPU的利用更为有效。
调度(Scheduler) • 调度就是要决定该轮到哪个任务运行了。 • 多数实时内核是基于优先级调度法的。每个任务根据其重要程度的不同被赋予一定的优先级。 • 基于优先级的调度法,指CPU总是让处在就绪态的优先级最高的任务先运行。 • 究竟何时让高优先级任务掌握CPU的使用权,有两种不同的情况: • 不可剥夺型内核 • 可剥夺型内核。
不可剥夺型内核 • 不可剥夺型内核(或非抢占式内核,Non-Preemptive Kernel) • 不可剥夺型内核要求每个任务自我放弃CPU的所有权。 • 不可剥夺型调度法也称作合作型多任务,各个任务彼此合作共享一个CPU。 • 异步事件还是由中断服务来处理。中断服务可以使一个高优先级的任务由挂起状态变为就绪状态。但中断服务以后控制权还是回到原来被中断了的那个任务,直到该任务主动放弃CPU的使用权时,那个高优先级的任务才能获得CPU的使用权。
不可剥夺型内核运行原理 • 任务正在运行 低优先 级任务 • 中断到来,中断原来任务 ISR • 执行中断服务子程序,使一个 高优先级任务进入就绪状态 由于是不可剥夺型内核,低优 先级任务未执行完毕,高优 先级任务不能立即执行 低优 先级 任务 • 中断返回 • 继续执行原来任务 高优 先级 任务 • 任务执行完毕,控制权交给 高优先级、已就绪任务 • 高优先级任务开始执行
不可剥夺型内核缺点 • 不可剥夺型内核的最大缺陷在于其响应时间。高优先级的任务已经进入就绪态,但还不能运行,也许要等很长时间,直到当前运行着的任务释放CPU。 • 不可剥夺型内核的任务级响应时间是不确定的,不知道什么时候最高优先级的任务才能拿到CPU的控制权,完全取决于应用程序什么时候释放CPU。
可剥夺型内核 • 当系统响应时间很重要时,要使用可剥夺型内核(或抢占式内核,Preemptive Kernel)。 • 最高优先级的任务一旦就绪,总能得到CPU的控制权。 • 当一个运行着的任务使一个比它优先级高的任务进入了就绪态,当前任务的CPU使用权就被剥夺了,或者说被挂起了,那个高优先级的任务立刻得到了CPU的控制权。 • 如果是中断服务子程序使一个高优先级的任务进入就绪态,中断完成时,中断了的任务被挂起,优先级高的那个任务开始运行。
可剥夺型内核运行原理 • 低优先级任务正在运行 低优先 级任务 ISR • 中断到来,中断当前任务 高优 先级 任务 • 执行中断服务,把另一个任务 置为高优先级、就绪状态 • 中断服务完成,退出中断 进入新的优先级更高的任务 • 新任务执行 低优 先级 任务 • 新任务执行完毕, 控制权还给原来的任务 • 继续执行原来的任务
可剥夺型内核 • 使用可剥夺型内核,最高优先级的任务什么时候可以执行,可以得到CPU的控制权是可知的。 • 使用可剥夺型内核使得任务级响应时间得以最优化。 • 使用可剥夺型内核时,应用程序不应直接使用不可重入型函数。调用不可重入型函数时,要满足互斥条件,这一点可以用互斥型信号量来实现。如果调用不可重入型函数时,低优先级的任务CPU的使用权被高优先级任务剥夺,不可重入型函数中数据有可能被破坏。
可重入性(Reentrancy) • 可重入型函数可以被一个以上的任务调用而不必担心数据的破坏。 • 可重入型函数任何时候都可以被中断,一段时间以后又可以运行,而相应数据不会丢失。 • 可重入型函数只使用局部变量,即变量保存在CPU寄存器中或堆栈中。如使用全局变量,则要对全局变量予以保护。
可重入型函数 函数strcpy()做字符串的复制。因为参数保存在堆栈中,故函数可以被多个任务调用,不必担心各任务调用函数期间会破坏对方的指针。
高优先级 任务A Event Event 中优先级 任务 B 低优先级 任务 C 任务调度策略-抢占方式 Pre_empty:不同优先级的任务采用抢占方式
时间片 A A B B C C D D 任务调度策略-时间片轮转方式 Timeslice:相同优先级的任务采用时间片轮转方式
任务优先级 • 每个任务都有其优先级。任务越重要,赋予的优先级应越高。 • 静态优先级 • 应用程序执行过程中诸任务优先级不变,则称之为静态优先级。在静态优先级系统中,诸任务以及它们的时间约束在程序编译时是已知的。 • 动态优先级 • 应用程序执行过程中,任务的优先级是可变的,则称之为动态优先级。实时内核用之避免出现优先级反转问题。
任务优先级举例 优 先 级 ISR space 0 system task 230 task space user task 255 IDLE
优先级翻转与优先级继承 • 如果完全按照优先级来进行任务调度,则会发生如下情况: • 低优先级任务TaskB首先运行,调用 semTake()获得资源; • 高优先级任务TaskA就绪运行,调用semTake()申请资源,被阻塞; • 只有当taskB调用semGive()释放资源后,taskA才能继续运行
解决方法 • Priority inheritance protocol(优先级继承协议) • 让低优先级任务提高任务优先级,提高到和被阻塞高优先级任务同样的级别。 • Priority ceiling protocol (优先级限高协议). • 低优先级任务这次不是获得高优先级相同的优先级,而是获得某个预先设置好的优先级。而这个预先设置好优先级肯定不会比当前所有的存在的优先级低。在实现中,这个优先级一般被设置为实时系统中最高可能的优先级。