1、实时系统定义:是指那些产生系统输出的时间对于系统是至关重要的系统。
实时系统可根据时限对其性能(或效益)影响程度的不同,分为软实时系统SRT和硬实时系统HRT。
软时限是指时限的错过不会损害系统的完整性。
还可以根据应用领域的不同,将实时系统分为实时信息数据处理系统和实时控制系统。实时信息数据处理系统一般为软实时系统,一般不需要用嵌入式系统实现;
实时控制系统,一般属于硬实时系统。大部分硬实时系统是嵌入式系统。
嵌入式实时系统特点:
专用的嵌入式CPU;
专用性和算法的唯一性;
多种技术的结合体;
硬件与软件的相互依赖性;
系统对用户是透明的;
嵌入式计算机系统大多是实时控制系统;
系统配置专一,机构紧凑,坚固可靠,一般来说计算机资源(存储容量和速度)有限;
许多嵌入式计算机系统采用分布式系统实现;
2、软件特征:
响应时间快;具有异步处理并发事件的能力;具有快速启动、出错处理和自动复位能力、嵌入式系统软件的应用软件与操作系统之间界线模糊,往往是一体化设计的程序、软件开发困难,要使用交叉开发环境。
开发平台叫宿主系统,而嵌入式系统的运行系统叫目标系统。嵌入式系统的软件交叉开发环境对开发安全可靠、高性能和复杂的嵌入式系统起着非常重要的作用。
嵌入式实时软件的开发过程:
需求分析-->软件模型建立-->任务划分-->任务分配-->调度设计-->语言实现-->模块集成测试-->系统集成测试。
实时多任务操作系统:RTOS
是嵌入式应用软件的基础和开发平台。
RTOS是针对不同处理器优化设计的高效率实时多任务内核,基于RTOS上的C语言程序具有极大的可移植性。
RTOS是一个标准的内核,将CPU时间、中断、I/O、定时器等资源都包装起来,留给用户一个标准的API,并根据各个任务的优先级,合理地在不同任务之间分配CPU时间,从这个意义上而言,操作系统的作用是资源管理器。
实时操作系统与分时操作系统有明显的区别。分时操作系统,软件的执行在时间上的要求并不严格。实时操作系统的重要特点是具有系统的可确定性,即系统能对运行情况的最好和最坏等情况作出精确的估计。
一个实时操作系统仅能允许我们开发一个硬实时系统,但这样的RTOS并不能保证系统所有的时限都能得到满足!系统时限的满足还需要软件合理设计。不存在硬实时操作系统或软实时操作系统。
RTOS最关键的部分是实时多任务内核,基本功能包括任务管理、定时器管理、存储器管理、资源管理、事件管理、系统管理、消息管理、队列管理、信号量管理等,这些是通过内核服务函数形式交给用户调用的,也就是RTOS的API。
3、实时操作系统中的重要概念:
系统响应时间:系统发出处理要求到系统给出应答信号的时间;
任务切换时间:任务之间切换而使用的时间;
中断延迟:计算机接收到中断信号到操作系统做出响应,并完成切换转入中断服务程序的时间。
4、任务:实时操作系统中的任务TASK等同于分时操作系统汇总的进程的概念。系统中的任务一般有四种状态:运行Executing、就绪READY、挂起Suspended、睡眠Dormant。
标准Linux内核有许多制约实时性的因素,要将Linux系统用于实时环境,必须对其进行改进。目前改进Linux实时性的方案有两种:直接修改内核法、双内核法。
直接修改内核法,通过对Linux 原理与源代码的分析,通过对内核的进程调度、中断服务程序等代码进行修改与优化,提高系统的实时性能,并且为了保证系统的通用性,需要按照POSIX
的相关标准来进行改动。利用这种方法可以获得较好的性能提升,并且因为与标准的Linux 内核使用相同的应用程序接口,所以有良好的兼容性。目前,采用修改内核方法改进Linux 实时性的产品很多,如 Kurt-Linux、TimesysLinux 和 Ingo's RTpatch 等。
双内核法,通过在Linux 内核与硬件中断之间增加一个可抢先的实时内核,把标准的Linux 内核作为该实时内核的一个优先级最低的进程来调度,它可以被实时进程抢断,正常的
Linux 进程仍可以在 Linux 内核上运行,这样既可以使用标准分时操作系统即Linux 的各种服务,又能提供低延时的实时环境。RT-Linux是采用双内核法改造Linux 实时性的典型代表。
5、在RTOS设计中,其占用内存大小是一个很重要的指标,是与其他操作系统设计的明显区别之一。
比较出色的商用嵌入式实时操作系统:QNX、Lynx、Concurrent、VxWorks、Microware、Vrtx、pSOS、eCos等。
选择准则:
是否支持目标硬件平台;
与其他开发工具能否相互关系;
能否满足应用的关键要求;
Tornado是为开发VxWorks应用系统提供的集成开发环境。
6、实时应用的特征:
专用资源:一个专用的实时应用系统使用一个或多个计算机来解决一个特定的问题或相关问题的集合。它将系统所有的资源用于该实时应用;不提供分时的服务,这种应用通常称为硬实时应用。
分布式处理:可以充分有效地利用计算机资源;
高I/O吞吐量:指计算机系统处理输入输出数据的速率。它依赖于CPU、I/O设备的速度、特性以及I/O总线的带宽。要求高I/O吞吐的实时应用需要大量的数据的连续处理。
网络:与其他系统通信和共享资源;
ROM:一些实时系统必须从ROM加载;
自满足:指系统同时具备实时和分时的能力。
稳定性:稳定和可预测的。
7、VxWorks系统运行环境支持的CPU包括PowerPC、68K、CPU32、SHARC、i960、x86、Mips等,同时支持RISC、DSP技术。其微内核wind是一个具有较高性能的、标准的嵌入式实时操作系统内核,其特点是:快速多任务切换、抢占式任务调度、任务间通信手段多样化等。
有较好的可剪裁的能力。通过交叉开发环境方便地进行配置。
支持应用程序的动态链接和动态下载,有较好的兼容性。
VxWorks操作系统包括了进程管理、存储管理、设备管理、文件管理、网络协议及系统应用等几个部分。
8、VxWorks由以下几个主要部分组成:
高性能的实时操作系统核心---Wind:使用中断驱动和基于优先级的调度方式。提供信号量作为任务间同步和互斥的机制,二进制信号量、计数信号量、互斥信号量和POSIX信号量。对于进程间通信,也提供诸如消息队列、管道、套接字和信号灯机制。
I/O系统
快速灵活的与ANSI C兼容的I/O系统,包括UNIX标准的缓冲I/O和POSIX标准的异步I/O。
包括以下驱动程序:
网络驱动:以太网,共享内存;
管道驱动:任务间通信;
RAM盘驱动:用于常驻内存的文件;
SCSI驱动:用于SCSI硬盘、软盘、磁带、光驱;
键盘驱动;
显示驱动:用于x86 VGA文本显示。
磁盘驱动;
并口驱动:用于PC风格的目标机。
文件系统
DosFs用于软、硬盘。
cdromFs用于CDROM驱动器。
9、动态的链接和加载功能是Tornado系统的核心功能。
VxWorks的任务可以直接或共享访问大多数系统资源,同时拥有足够的分离的上下文来维护各自的控制线程。任务的上下文保存在任务控制块TCB中。
一个任务的上下文包括以下内容:
任务的执行点、也就是任务的程序计数器;
CPU寄存器和浮点计数器;
动态变量和函数调用的堆栈;
标准输入输出和错误的I/O分配;
一个延时定时器;
一个时间片定时器;
内核控制结构;
信号处理器;
调试和性能监视值。
与windows系统不同,VxWorks操作系统的内存是线性的,所有代码执行在单一的公共的地址空间内,因而内存地址空间不属于任务的上下文。
10、任务状态转换
任务状态反映任务当前系统所处的情形。内核负责维护系统中所有任务的当前状态。
当创建时,任务处于挂起suspended状态,为使创建的任务进入就绪ready态,必须要激活该任务。激活阶段相当快,因此应用程序先创建任务,并在适当的时候将其激活。另一种方法是使用发起spawning原语,类似UNIX中fork调用。它使用一个单一的函数调用,创建并激活一个任务。任务可以在任何状态下被删除。
PEND阻塞 SUSPENDED挂起
wind任务调度
调度针对多任务系统而言,是根据一定的约束规则,将CPU分配给符合条件的任务使用,这些约束规则就是所谓的一个调度算法。多任务系统使用条多算法来给处于就绪态的任务分配CPU。
wind内核默认采用基于优先级的抢占式调度算法,同时还可以选用轮转round-robin调度算法(相同优先级)。
控制任务调度的函数调用:
kernelTimeSlice()控制轮转调度;
taskPrioritySet()改变任务的优先级;
TaskLock()禁止任务调度;
taskUnlock()允许任务调度;
11、wind内核有256个优先级,编号0~255,优先级0最高,255最低。任务的优先级在创建时指定。vxworks允许任务动态改变自己的优先级:当任务执行时,它可以调用taskPrioritySet()改变自己的优先级。
轮转调度算法试图让优先级相同的、处于就绪态的任务公平的分享使用CPU。
轮转调度使用时间片来实现相同优先级任务CPU公平分配的。这种调度算法特别适用于通用操作系统,如windows操作系统。
kernelTimeSlice()控制轮转调度,参数是时间片的长度。时间片是每个任务在放弃CPU给另一个相同优先级任务之前,系统允许他运行的时间长度。
并不是每次抢占都是合理的,提供了避免抢占的机制:
TaskLock()禁止任务调度;
taskUnlock()允许任务调度;
TaskLock():将不会发生基于优先级的抢占式调度;
抢占上锁只能防止任务上下文的切换,并不能禁止中断。抢占上锁可用来实现互斥,但应尽量使上锁时间最小。
12、任务错误状态:C库函数当产生错误时将一个全局整数errno设置某个合适的值,告诉系统发生了什么错误。这种惯例也是ANSI C标准的一部分。
errno作为一个宏也定义在errno.h中。
错误返回约定:几乎所有的vxworks函数遵循一个约定,由函数实际返回的值来简单地指示函数操作的成功与否。许多函数仅仅返回状态值OK(=0)或ERROR(=-1)。有些函数正常时返回一个非负整数,如open()返回一个文件描述符;出错时返回ERRPR。对于那些返回类型为指针的函数,通常返回NULL(=0)来指明发生了错误。
VXWORKS程序不会清除全局变量errno,因此它的值总是由最后发生的错误状态设置。
在调试时可以检查errno来作为一种手段。
如果errno对应一个字符串,可以调用函数printErrno()来显示。
13、在vxworks中,errno值编码由四个字节组成,两个高字节表示产生错误的模块,指明产生错误的库(对应一个头文件);低两个字节表示错误号,指示在这个库中(头文件)特定的错误。所有的vxworks模块从1~500编码,errno值为0的模块用来与源兼容。target/h/vwModNum.h定义了高16位对应的模块(头文件)。找到对应的模块,对应文件就能找到低16位错误号对应的意思。
14、任务异常处理:
程序代码或数据错误可能引起硬件异常状态,如:非法指令、总线或地址错、除数为0等。
默认的异常处理挂起(suspends)引起异常的任务,保存这个任务在异常点的状态。
vxworks同时允许任务使用信号功能激活自己的异常处理程序。如果一个任务已经提供一个异常的信号处理程序,系统提供的上述的默认的异常处理程序不再执行。想发送硬件异常信号那样,信号也可用来发送软件异常信号。
15、共享代码必须是可重入的。
一个子程序是可重入的,如果该程序的单个拷贝可以被多个任务同时调用而不会发生冲突。
冲突典型发生在一个子程序修改了全局或者静态变量,由于系统中仅有一份拷贝,该子程序指向这些变量的地址可能与其他任务的上下文重叠。
VxWorks所有以name_r()命名的子程序被认为是不可重入的。
大部分VxWorks程序使用下面的重入机制:
动态堆栈变量;连结链库:lstLib:由于每个任务只是在自己的堆栈内进行操作,相互不干扰;
由信号量保护的全局或静态变量;互斥机制;由semLib提供的信号量;
任务变量。允许在任务上下文中增加4字节变量,因此每次上下文交换时,改变量的值被保存。
16、VxWorks系统任务
根任务tUsrRoot是内核执行的第一个任务,其入口点是installDir/target/config/all/usrConfig.c
文件中的usrRoot()初始化VxWorks系统的主要功能,发起诸如日志任务、异常处理任务、网络任务和tRlogind后台任务。正常情况下,在所有初始化完成之后,根任务终止并被删除。用户可以向根任务*的添加任何必需的初始化代码。
日志任务:tLogTask用来记录系统信息的任务。
异常处理任务:tExcTask提供异常处理包,完成在中断级不能执行的功能。必须具备系统最高的优先级。不需要挂起、删除、改变其他任务的优先级。
网络任务:tNetTask后台处理网络需要的任务级功能处理。
17、VxWorks任务编程接口
任务控制功能的函数调用包含在taskLib库中。
taskSpawn()创建并激活一个新任务:共15个参数:新任务名字、优先级、任务选项字、堆栈大小、任务入口函数、作为启动参数传给入口程序的10个参数。返回任务的ID号。
Shell中使用命令i,显示任务信息,包含每个任务的名字;分配的堆栈大小应该是个偶数,包含了任务控制块TCB和任务名。剩余的内存是任务堆栈。每个字节用0xEE填充,主要用于任务堆栈检查函数checkStack();
taskSpawn()包含了定位分配、初始化和激活等一些低级操作。初始化功能由taskInit()【初始化一个新任务】与激活功能由taskActivate()【激活一个已初始化的任务】完成。仅仅当应用对分配定位和激活需要更多控制时,才使用这两个函数。
1)任务名和ID号
任务创建时,返回一个四字节的指向任务数据结构的任务ID号。约定ID号0表示调用任务(指调用该函数的任务);大多数VxWorks程序使用任务ID号定位某个任务。
所有从目标机启动的任务以字母t开头命名,从主机启动的任务以字母u开头命名。
用于管理任务名称和ID号的函数:
taskName()由任务号得到任务名称;
taskNameToId()任务名得到任务ID号;
taskIdSelf()得到调用任务的ID号;
TaskIdVerify()证实一个特定任务的存在。
2)任务删除和删除安全
任务可以动态地从系统中删除。注意:确保不要在一个不合适的时刻删除任务,任务被删除前,该任务必须释放它所持有的所有资源。
任务可以在任何时候调用exit()杀死自身。一个任务可以调用taskDelete()删除其他任务。当任务被删除时,删除不会通知给任何任务。taskSafe()保护任务不会被其他任务删除。任务访问临界区时就需要这种保护。保护操作仅对当前调用的任务有效,一个任务不能对其他任务保护或解除保护。
POSIX与Wind调度方法的差异
POSIX调度基于进程,Wind调度基于任务。
进程与任务区别:
任务可以直接内存访问,而进程不行。进程仅仅是继承了父进程的特定特征,而任务则操作在与父任务完全一样的环境中。
二者相似之处是都可以被单独调度。
VxWorks文档使用基于优先级的抢占式调度,而POSIX标准则使用FIFO。而这都是基于相同的优先级策略。
POSIX优先级编号方案与Wind相反。POSIX中,优先数越高,优先级越高。Wind方案中,优先数越低,优先级越高,0是最高的优先级。
10、VxWorks操作系统配置
\host是宿主机工作文件目录;\target是目标系统的目录与文件。配置主要是通过对目标系统目录树下相关配置文件进行编辑与修改来完成的。
配置目录
10.1.1 \target\config包含的文件是用来配置和生成一个专用vxworks系统,包括系统相关的模块和用户可修改的模块。被分配到几个子目录下:
all包含了所有的公共执行模块(独立于系统的模块);bspname包含了对于指定目标机硬件的模块(系统相关的模块)。
config\all
含有系统配置模块,主要由以下几个文件组成:
bootInit.c该程序是系统初始化模块,根据引导方式,将ROM程序拷贝到RAM中,如果是从ROM引导,完成系统所需工作区的初始化;
configAll.h该文件包含所有目标系统公共的配置参数定义,用户可以根据目标系统的特殊要求,编辑或修改该文件的配置参数。
usrConfig.c:用户可定义的系统配置模块源程序,包含根任务、基本的系统初始化、网络初始化、时钟中断程序等。
bootConfig.c:ROM引导的VxWorks系统配置模块源程序。
对于上述两个源程序,可以通过编辑和修改配置文件进行裁剪。
config\bspname:
包含有一个与特定目标机系统相关的vxworks配置模块,主要包括:
Makefile:为特定目标系统生成ROM引导与vxworks系统映像,该文件定义了系统编译规则,生成引导映像的文件格式。
sysALib.s:用汇编语言编写的系统相关的模块,包含有系统基本的端口读写函数、CPU检测函数和系统GDT(全局描述符表)的访问函数。端口字节、字、长字的读写.
sysLib.c:包含系统相关的库函数,提供特定目标系统的可编程芯片驱动程序,如i8250uart串行通信、定时器、中断控制器、PCI总线驱动、网卡驱动等。该文件提供内存映像数据结构,用户可以编辑该结构完成特殊设备的安装。
sysSerial.c:目标板上串行口初始化程序,主要是com1、com2设备的初始化。串口I/O驱动程序在src/drv/sio目录下。
config.h:硬件配置参数头文件。
bspname.h目标板参数配置头文件,详细描述目标系统所有的资源配置,如端口地址、中断号等。
target.txt:目标板的参考信息。
romInit.s:用汇编语言编写的初始化代码源程序,是ROM引导vxworks和基于ROM版本的vxworks入口,该程序初始化系统寄存器,由实地址模式切换到平面保护模式。
vxworks和vxworks.sym:连接完成的二进制目标码vxworks系统文件和根据配置文件建立的vxworks的符号表文件。
bootrom:从ROM引导vxworks的引导目标模块,当建立宿主机/目标机环境时,由宿主机通过串行线或网络将vxworks系统映像加载到目标机。
10.1.2 目标系统头文件 \target\h
该目录包含了vxworks提供的所有头文件,在编制应用程序时,必须包含它们中的一部分或全部。
h\arch
包含与硬件结构相关的头文件子目录(i86),当开发环境配置模拟器时,该子目录提供模拟目标系统的头文件目录(simnt)。
h\arpa
包含了使用inetLib库的头文件,主要是Initernet头文件。
h\drv
包含了指定的硬件(主要是驱动程序)的头文件,如软驱、硬盘、串行口、计时器、并口、PCI设备、SCSI、DMA、WDB、增强型网络接口等。
h/make
包含文件描述了针对每一CPU和工具箱的makefiles规则。
h\net
包含了使用vxworks网络时所包括的所有内部头文件;网络驱动程序必须要包括它们,应用模块可以不用。
h\netinet
包含了特定的因特网头文件。
h\private
包含了vxworks私有代码的头文件。
h\rpc
当应用系统使用远程过程调用函数库时,必须包括该子目录下包含的头文件。
h\sys
该子目录包含有POSIX标准制定的头文件。
h\types
包含了各种类型定义的头文件。
10.1.3目标系统函数库子目录\target\lib
该目录包含独立于机器的目标库和由vxworks提供的模块。
主要有:
objcputoolvx
包含了以单独文件形式的vxworks目标模块,适合于将模块动态下载到目标机。
objcputoolcf
在该目录下,对于使用可选的wind C++编译器而生成的vxworks目标模块版本是可以改变的。而其他目标模块是使用默认的GNU C++编译器生成的。
libcputoolvx.a
存档格式的库文件包含有生成vxworks的目标模块。
10.2vxworks的板级支持包BSP
config\bspname
包含了在指定目标系统上运行vxworks的硬件描述文件,如板上串行口、并行口、键盘、显示等。可以修改并移植。
Makefiel、sysLib.c、sysALib.c、romInit.s、bspname.h、config.h。
系统库sysLib.c
该系统库中子程序或函数模块是由在目录config\all下的配置模块usrConfig.c和bootConfig.c调用的。设备驱动程序使用某些存储器映像的子程序和总线函数。
BSP初始化模块:
有两个文件:
romInit.s和sysALib.s.
10.3vxworks的配置文件与配置项
配置文件分为:配置头文件与配置模块文件
配置头文件有\target\config\all\configAll.h和\target\config\bspname\config.h,配置模块文件主要有\target\config\all\usrConfig.c模块与\target\src\config目录下初始化模块。
\target\config\all\configAll.h称为全局配置头文件,包含了WRS公司所提供的所有目标机的默认定义;\target\config\bspname\config.h是与BSP确定的目标系统相关的头文件,含有确定目标机参数与选项定义。
一般不要修改configAll.h文件的选项定义。如果应用系统需要,则在config.h文件中进行定义。
\target\config\all中的文件不要常去修改。
config.h包含:
从ROM引导的默认的引导参数字符行;
系统时钟和校验出错的中断向量;
设备控制器I/O地址,中断向量和中断级;
共享内存网络参数;
各种存储器地址和常量。
要包含ANSI C声明库,一定要定义INCLUDE_ANSI_ASSERT
要包含网络文件系统NFS工具,一定要定义INCLUDE_NFS.
初始化序列:
sysALib.s--->sysInit()系统初始化函数
usrConfig.c---->usrInit()调用下列2函数
usrKernel.c--->usrKernelInit()核心库初始化函数
kernelInit()内核初始化函数,调用下述函数
usrRoot()初始化I/O系统,安装设备驱动,根据配置文件configAll.h和config.h中的配置,创建指定的设备。
建立系统时钟中断处理,初始化系统时钟频率。
(具体启动过程查看vxworks另一篇文章)