1.多任务:允许一个实时应用作为一系列独立任务来运行,各任务有各自的线程和系统资源。
3.任务切换之前要保存上下文。
4.优先级是动态的0~255,0级最高。
5.Wind内核taskLock()和taskUnlock()禁止和解除抢占,但对中断不起作用。
6.异常处理:VxWorks异常处理包,一般是将引起异常的任务休眠,保存任务在异常出错处的状态值。内核和其它任务继续执行。
7.为什么要共享存储区: 任务间通信的最简单的方法是采用共享存储区,也即相关的各个任务分享属于它们的地址空间的同一内存区域。
8. 为什么要互斥: 当某一地址空间用于数据交换时,为了避免冲突,对于内存的锁定是非常重要的。一般来说,关中断是最有效的解决互斥的方法。但这对于实时应用来说,它阻止系统对外部事件的响应,无法满足实时性的要求。同样,中断延迟也是不能接受。因为它们没有实时性。所以要用信号量来完成互斥,主要是二进制信号量,并且二进制信号量不仅能完成互斥而且能完成同步!,但是关中断应该用到程序的初始化过程中。
9.信号量: VxWorks信号量提供最快速的任务间通信机制,它主要用于解决任务间的互斥和同步。针对不同类型的问题,有以下三种信号量:
⊙二进制信号量 使用最快捷、最广泛,主要用于同步或互斥;
⊙互斥信号量 主要用于优先级继承、安全删除和回溯;
⊙计数器
VxWorks还提供POSIX信号量和多处理器上信号量的应用。
10.消息队列,任务之间利用消息队列发送和接收消息。
11.管道:管道是一种灵活的消息传送机制,它比消息队列强在有一个select()
12.信号量的创建与删除:
semBCreate() 创建(产生并激活)一个二进制信号量
semMCreate() 创建(产生并激活)一个互斥信号量
semCCreate() 创建(产生并激活)制一个计数信号量
semDelete() 中止并自由信号量
semTake() 获得信号量
semGive() 给出信号量
semFlush() 解锁所有正等待某一信号量的任务
13.消息队列的创建与删除:
msgQCreate() 创建(产生并激活)消息队列
msgQDelete() 中止并自由信号量
msgQSend() 向消息队列发送消息
msgQReceive() 从消息队列接收消息
14.网络通讯:与其它主机进行通信。
15. 套接口Sockets:套接字(sockets)来实现Vxworks系统和网络协议的接口.套接口是通讯的基础,应用程序一般仅在同一类的套接口间通讯。主要的两种套接口:流套接口(采用TCP协议)和数据报套接口(采用UDP协议),两者都是双向传输,且流套接口提供有序和无重复的数据流服务,虽然数据报套接口没有提供有序和无重复的数据流服务,但是它的最大的特点是记录边界。
16.套接口(socket)通信的最大优点是:过程间的通信是完全对等的,不管网络中过程的定位或主机所运行的操作系统。
17.套接口Socket的函数:
socket() 创建一个套接口
bind() 给套接口分配名称
listen() 打开TCP套接口连接
accept() 完成套接口间连接
connect() 请求连接套接口
shutdown() 关闭套接口间连接
send() 向TCP套接口发送数据
recv() 从TCP套接口接收数据
select() 完成同步I/O传输
read() 从套接口读取信息
write() 向套接口写入信息
ioctl() 完成对套接口的控制
close() 关闭套接口
前面四个函数相当于网络驱动。
18. 实时系统中硬件中断处理是至关重要的,因为它是以中断方式通知系统外部事件的发生。为了快速响应中断,中断服务程序ISR运行在特定的空间,有自己的上下文。不同于其它任何任务,因此中断处理没有任务的上下文切换。
中断函数:
intConnect() 将C函数和中断向量联结
intCount() 得到当前中断套叠深度
intLevelSet() 设置程序中断级别
intLock() 使中断禁止(关中断)
intUnlock() 开中断
intVecSet() 设置异常向量
intVecGet() 得到异常向量
在程序中用的最多的就是关开中断了,intLock()和intUnlock().
所有的中断服务程序使用同一中断堆栈,它在系统启动时就已根据具体的配置参数进行了分配和初始化,必须保证它的大小,以使它能满足最坏的多中断情况。因此在程序设计初,即程序入口处就要设定中断堆栈的大小,而这个大小没有什么的定的公式可循,只能依据经验。
中断也有缺陷:ISR不运行在常规的任务上下文,它没有任务控制块。对于ISR的基本约束就是它们不能激活那些可能使调用程序阻塞的函数,例如,它不能获取信号量,因如果该信号量不可利用,内核会试图让调用者切换到悬置态。然而,ISR能给出信号量。因为调用者就是ISR,是中断被悬置,这是很不好的。不过这只是它为了满足实时性的一个约束条件。不能算是缺陷哈。
19.ISR到任务的通讯和同步:
Ж. ISR很少作为信息的接收者,它不可以等待接收信息包或事件.ISR通常作为通信或同步的发起者,它通常返回一个信号量、向队列发送一个信息包或事件给一个任务。
Ж. ISR内的系统调用总是立即返回ISR本身。例如,即使ISR通过发送信息包唤醒了一个很高优先级的任务,它也首先必须返回ISR。这是因为ISR必须先完成。
20. 时钟管理功能:
┓维护系统日历时钟;
┓在任务等待消息包、信号量、事件或内存段时的超时处理;
┓以一定的时间间隔或在特定的时间唤醒或发送告警到一个任务。
┓处理任务调度中的时间片轮循。
这些功能都依赖于周期性的定时中断,离开实时时钟或定时器硬件就无法工作。时钟管理的系统调用有:
tickAnnounce() 通知系统内核时钟“滴答”
tickSet() 设定内核时钟计数器值
tickGet() 得到内核时钟计数器值
timer_create() 创建时钟
timer_gettime() 获得时钟器给定值的当前剩余值
timer_settime() 设定时钟值
timer_connect() 联系用户函数和时钟信号
timer_cancel() 取消一个时钟
sysClkRateSet() 系统时钟速率设置
21.看门狗Watch Dog的作用:
VxWorks看门狗定时器作为系统时钟中断服务程序的一部分,允许C语言函数指明某一时间延迟。(我还以为只是有关safe(看门)的作用呢:))。
被看门狗定时器激活的函数运行在系统时钟中断级。然而,如果内核不能立即运行该函数,函数被放入tExcTask工作队列中。在tExcTask工作队列中的任务运行在最高优先级0。
看门狗定时器调用函数:
wdCreate() 分配并初始化看门狗定时器
wdDelete() 中止并解除看门狗定时器
wdStart() 启动看门狗定时器
wdCancel() 取消当前正在计数的看门狗定时器
22.Tanado集成开发环境:
Tornado环境采用主机--目标机交叉开发模型,应用程序在主机(的Windows环境)下开发(编译链接生成可执行文件),在目标机上调试(下载到目标机,通过主机上的目标服务器与目标机上的目标代理程序的通信完成对应用程序的调测、分析)。
即应用程序在主机上开发,在目标机上调试~!
23. Tonado个集成组件的功能:
⊙Tornado开发环境:
Tornado是集成了编辑器、编译器、调试器于一体的高度集成的窗口环境,同样也可以从Shell窗口下发命令和浏览。
⊙WindConfig:Tornado系统配置
通过WindConfig可选择需要的组件组成VxWorks实时环境,并生成板级支持包BSP的配置。
⊙WindSh:Tornado外壳
WindSh是一个驻留在主机内的C语言解释器,通过它可运行下载到目标机上的所有函数,包括VxWorks和应用函数。Tornado外壳还能解释常规的工具命令语言TCL。
⊙浏览器
Tornado浏览器可查看内存分配情况、系统目标(如任务、消息队列、信号量等)。这些信息可周期性地进行更新。
⊙CrossWind:源码级调试器——提供交叉调试
源码级调试器CrossWind提供了图形和命令行方式来调试,可进行指定任务或系统级断点设置、单步执行、异常处理。
⊙驻留主机的目标服务器
目标服务器管理主机与目标机的通信,所有与目标机的交互工具都通过目标服务器,它也管理主机上的目标机符号表,提供目标模块的加载和卸载——在主机与目标机通讯时使用。
⊙Tornado注册器
所有目标服务器注册其提供的服务在注册器中。注册器映射用户定义的目标名到目标服务器网络地址——应需提前设置。
⊙VxWOrks
Tornado包含了VxWorks操作系统。
⊙目标代理程序
目标代理程序是一个驻留在目标机中的联系Tornado工具和目标机系统的组件。一般来说,目标代理程序往往是不可见的。
23. 系统启动:
在实时应用系统的开发调测阶段,往往采用以PC机作为目标机来调测程序。主机PC和目标机PC之间可采取串口或是网口进行联结。由于大多数目标已配有网卡,网络联结成为最简单快速的连接方式。串口联结虽通信速率不高,也有它自己的优点,系统级任务调试(如中断服务程序ISR)需使通信方式工作在Polled 模式,网口联结就不支持。因此就有两种通讯方式下的启动方式来制作Vxworks启动盘,它和Windows系统不同的,Vxworks操作系统是需要定制的,裁掉不需要的系统,这样可以使系统更小,满足目标板的内存约束。
24. 串口通信时目标机VxWorks系统启动盘的制作步骤:
1.修改通用配置文件.
在config.h文件中加入以下宏定义:
#undef WDB_COMM_TYPE
#define WDB_COMM_TYPE WDB_COMM_SERIAL /*定义通信方式为串口联结*/
#define WDB_TTY_CHANNEL 1 /*通道号*/
#define WDB_TTY_BAUD 9600 /*串口速率,可设置至38400*/
并且修改#define DEFAULT_BOOT_LINE中vxWorks为vxWorks.st。
2.在Tornado集成环境中点取Project菜单,选取Make PC486,选择Common Target,先进行clean操作;再选择 Boot Rom Target,进行bootrom_uncmp操作;再选择VxWorks Target,进行vxworks.st操作。
3.拷贝至下;
4.重命名文件bootrom_uncmp为bootrom;
5.准备一张已格式化的空盘插入软驱;
6.在目录下执行命令 mkboot a: bootrom ;
7.拷贝.*至软盘;
8.将系统制作盘插入目标机软驱,加电启动目标机即载入VxWorkst系统。
25. 网口通信时目标机VxWorks系统启动盘的制作步骤:
1.配置目标机网卡,设置其中断号和输入输出范围(I/O地址);
2.修改通用配置文件.
针对不同的网卡,其名称不同,如NE2000及其兼容网卡为ENE,3COM以太网卡为ELT,Intel网卡为EEX。
在config.h文件中修改相应网卡类型(如网卡为3COM网卡)的定义部分:
#define IO_ADRS_ELT 网卡I/O地址
#define INT_LVL_ELT 网卡中断号
并且修改#define DEFAULT_BOOT_LINE的定义:
#define DEFAULT_BOOT_LINE \
"elt(0,0)主机标识名:C:\\tornado\\target\\config\\pc486\\vxWorks h=主机IP e=目标机IP u=登录用户名 pw=口令 tn= 目标机名"
3.主机信息的确定
主机操作系统Win95安装目录下有一文件hosts.sam,向其中加入:
主机IP 主机名
目标机IP 目标机名
4.在Tornado集成环境中点取Project菜单,选取Make PC486,选择Common Target,先进行clean操作;再选择 Boot Rom Target,进行bootrom_uncmp操作;再选择VxWorks Target,进行vxworks操作。
5.拷贝至下;
6.重命名文件bootrom_uncmp为bootrom;
7.准备一张已格式化的空盘插入软驱;
8.在目录下执行命令 mkboot a: bootrom ;
9.启动Tornado组件FTP Server,在WFTPD窗口中选择菜单Security中的User/right...,在其弹出窗口中选择New User...,根据提示信息输入登录用户名和口令,并且要指定下载文件vxWorks所在根目录;还必选取主菜单 Logging中Log options,使Enable Logging、Gets 、Logins 、Commands 、Warnings能。
10.将系统制作盘插入目标机软驱,加电启动目标机即通过FTP方式从主机下载VxWorkst系统。
26. 串口联结时主机Tornado开发环境的目标服务器配置操作如下:
1.在Tornado集成环境中点取Tools菜单,选取Target Server,选择config...;
2.在Configure Target Servers窗口中先给目标服务器命名;
3.在配置目标服务器窗口中的"Change Property"窗口中选择Back End,在"Available Back"窗口中选择wdbserial, 再在"Serial Port"窗口中选择主机与目标机连接所占用的串口号(COM1,COM2),再在"Speed(bps)"窗口中选 择主机与目标机间串口速率。
4. 在配置目标服务器窗口中的"Change Property"窗口中选择Core File and Symbols,
选择File为BSP目标文件所在目录(本例为PC486目录)的VxWorks.st,并选取为All Symbols.
5.在配置目标服务器窗口中的"Change Property"窗口中的其它各项可根据需要选择。
27. 网口联结时主机Tornado开发环境的目标服务器配置操作如下:
1.在Tornado集成环境中点取Tools菜单,选取Target Server,选择config...;
2.在Configure Target Servers窗口中先给目标服务器命名;
3.在配置目标服务器窗口中的"Change Property"窗口中选择Back End,在"Available Back"窗口中选择wdbrpc,在 "Target IP/Address"窗口中输入目标机IP。
4. 在配置目标服务器窗口中的"Change Property"窗口中选择Core File and Symbols,
选择File为BSP目标文件所在目录(本例为PC486目录)的VxWorks,并选取为All Symbols.
5.在配置目标服务器窗口中的"Change Property"窗口中的其它各项可根据需要选择。
28. 应用系统配置:运行在目标板上的系统映象是个二进制模块。系统映象占用空间较大。所以可根据需要裁剪系统配置,降低系统占用资源。
29.板级支持包BSP负责目标板硬件的初始化,实时内核的载入等。
30. VxWorks的系统任务:
目标板加电启动成功后,有如下几个任务已开始运行。
根任务:tUsrRoot
内核首先执行根任务tUsrRoot,其入口点为文件config/all/usrConfig.c中的usrRoot()函数,它负责初始化 VxWorks工具,并创建注册、异常处理、网络通信任务和tRlogind等任务。一般来说,在所有的初始化工 作完成后,根任务tUsrRoot被删除。
注册任务:tLogTask
注册任务tLogTask被VxWorks模块用于传送不需I/O操作的系统消息。
异常处理任务:tExcTask
异常处理任务tExcTask有最高优先级,它负责系统的异常情况出错处理,不能被悬置、删除或是改变其优 先级。
网络通信任务:tNetTask
网络通信任务tNetTask负责系统级任务的网络通信。
目标代理任务:tWdbTask
如果目标代理程序运行在任务模式,目标代理任务tWdbTask被创建,用来响应主机目标服务器的请求。
31. 防止死锁,饥饿和优先级翻转:
死锁是指多个任务因为等待进入对方占据的临界区而导致的不可自行恢复的运行终止。在程序设计是要注意对死锁的预防,一个是尽量使互斥资源在相同优先级任务中使用,必须在不同优先级任务中使用时,要注意对死锁的解锁处理。
饥饿是指优先级较低的任务长期得不到系统资源(主要是指CPU资源)而造成的任务长期得无法运行。造成饥饿的主要原因是优先级较高的任务调度过于频繁或占用时间太长。合理的分配任务的优先级和对较高优先级任务的合理调度是解决饥饿的不二法门。
任务的优先级翻转是实时多任务操作系统的热门话题,它是指高优先级任务因等待低优先级任务占用的互斥资源而被较低优先级(高于低优先级但低于高优先级)的任务不断抢占的情况。有些实时多任务操作系统自身提供保护机制可对优先级翻转进行预防。在操作系统未提供保护的情况下,就需要编程人员在编程的时候注意避免优先级翻转的情况发生(如在同一优先级内使用互斥资源),或采取相应的手段进行处理(如动态的进行优先级提升)。
注:VRTX和VxWorks提供自身的防止优先级翻转机制,pSOS未提供保护机制。
32. 函数的可重如性(Reantrancy):
在一个多任务环境中,函数的可重入性是十分重要的。可重入函数是一个可以被多个任务调用的过程,任务在调用时不必担心数据是否会出错。在写函数时只要考虑到尽量用局部变量(例如寄存器、堆栈中的变量),对于要使用的全局变量要加以保护(例如采用关中断、信号量等),这样构成的函数就一定是一个可重入的函数。
此外,编译器是否有可重入函数的库,与它所服务的操作系统有关,例如DOS下的Borland C和Microsoft C/C++等就不具备可重入的函数库,这是因为DOS是一个单用户单任务的操作系统。为了确保每一个任务控制自己的私有变量,在一个可重入的C函数中,须将这样的变量声名为局部变量。C编译器将这样的变量存放在调用栈上或寄存器里。
在VxWorks中,多个任务可调用同一子函数或函数库。VxWorks系统动态连接工具使这相当容易,这种共享代码让系统更加高效,易于维护。