vxworks653编程手册
- 格式:docx
- 大小:410.86 KB
- 文档页数:21
一. V x W o r k s653运行时系统1.1. 运行时层一个vxworks653模块由下面四层组成:■core OS—必需■partition—至少需要一个(vThreads 或COIL-based),每个都在一个分区的操作系统之中■APEX shared library—ARINC 653 应用所需■POSIX shared library—POSIX 应用所需1.1.1.Core OS层核心操作系统提供服务给分区。
缺省的,核心操作系统使用ARINC653规范中的时间抢占的调度(TPS)来调度分区。
Vxworks653的核心操作系统还可以采用APPS调度策略在TPS调度的空闲时间内调度优先级抢占调度(PPS)使能的分区。
核心操作系统提供给每个VThreads分区操作系统的服务包括:●分区系统资源●调度分区●代表分区的操作系统执行trap异常●定义和强制分区边界●装载分区●使用端口和通道在分区间传递消息●处理I/O●代表应用完成系统调用●支持分区的调试●监控分区和系统的健康1.1.2.vThreads 层vThreads分区操作系统在核心操作系统分配给该分区的时间内调度vThreads中的线程。
vThreads不直接与设备交互,而是通过核心操作系统的系统调用。
1.1.3.APEX 层构建在vThreads之上,遵循ARINC653规范,并且提供相应功能和API。
1.1.4.POSIX层构建在vThreads之上,遵循用于实时扩展的POSIX标准(1003.1b)。
1.2. 装载和启动当目标板加电时,按照下面的步骤进行装载和启动●初始的启动码装载核心操作系统,分区操作系统,共享库,以及应用●核心操作系统初始化自身,启动它自己的子系统●核心操作系统创建分区●核心操作系统启动分区调度器,并且让应用初始化自身核心操作系统可以在初始化完成之后下载在线装载的应用程序到分区。
应用可以在分区运行之时装载到分区。
Document: CTI_SIO_Install Revision: 1.01Date: January 4, 2010 VxWorksDriver InstallationVxWorks Driver Installation1.H ISTORY (3)2.H ARDWARE R EQUIREMENTS (4)3.D RIVER F ILES (4)4.C ONFIGURATION (4)4.1. BSP Files (4)4.1.1. config.h (4)4.1.1.1. INCLUDE_CTI_U550 (4)4.1.1.2. INCLUDE_CTI_U650 (5)4.1.1.3. INCLUDE_CTI_U850 (5)4.1.1.4. INCLUDE_CTI_EXAR17XX5XPCI (5)4.1.1.5. CTI_PCI_MAXBOARDS (5)4.1.1.6. CTI_PCI_MAXCHANS (5)4.1.1.7. INCLUDE_CTI_AUTO485POLLER (5)4.1.1.8. CTI_DEFAULT_BAUD (6)4.1.1.9. CTI_AUTO485SWITCHBAUD (6)4.1.1.10. CTI_AUTO485POLLER_DELAY (6)4.1.1.11. CTI_SYS_PCI_INTCONNECT() (6)4.1.1.12. CTI_SYS_INTCONNECT() (6)4.1.1.13. CTI_SYS_INTENABLE() (7)4.1.1.14. CTI_SYS_IN_BYTE() (7)4.1.1.15. CTI_SYS_OUT_BYTE() (7)4.1.1.16. CTI_SYS_IN_WORD() (8)4.1.1.17. CTI_SYS_OUT_WORD() (8)4.1.1.18. CTI_SYS_IN_LONG() (8)4.1.1.19. CTI_SYS_OUT_LONG() (9)4.1.2. sysLib.c (9)4.1.2.1. sysHwInit() (9)4.1.2.2. sysHwInit2() (10)4.2. Driver Files (10)4.2.1. sysCTISerial.c (10)4.2.1.1. Storage (10)4.2.1.2. Configuration (11)4.2.1.3. Interrupts (12)4.2.1.4. Enumeration (13)4.3. Tornado Projects (14)4.3.1. Connect Tech Inc. SIO (14)4.3.2. Use alternate base name (14)5.E XAMPLES (14)5.1. pcP3CTI_1 (14)5.2. pcP3CTI_2 (14)5.3. pcP3CTI_3 (15)6.I NSTALLATION C HECKLIST (16)1. HistoryOriginal draft.Added installation checklist.Added 3rd sample BSP.Fixed minor mistakes.Adapted for both Tornado and Workbench builds.2. Hardware RequirementsThis driver supports the following products:Xtreme/104 switchableXtreme/104 232BlueStorm/LPXtreme/104-Plus3. Driver FilesCopy the following files into your BSP directory (<WIND_INST>\target\config\<BSP_NAME>):00cti.cdfctiSio.cctiSio.hsysCTISerial.cusrCTISerial.c4. Configuration4.1. BSP FilesThe following files should be modified to support the CTI SIO driver. These modifications can be done in any other way as appropriate, but the following are suggestions made based on the Pentium III BSP. For sample modified files, refer to the files (of the same name) located within the driver distribution package. Sample files are from the Pentium III BSP. Note; file names and locations of information may differ in your BSP.<WIND_INST>\target\config\<BSP_NAME>\config.h<WIND_INST>\target\config\<BSP_NAME>\sysLib.cThe sample files included with the driver package should not be copied over any files in your BSP. These sample files are included only so that you can see the required changes in the context of complete files.4.1.1.config.hAdd a section to your config.h file so that there is a place for the driver options. If your config.h has an “if-def” block used to determine when to define INCLUDE_PCI, it is advised that you place this new section above that “if-def” block. This suggestion is made so that the “if-def” section can be modified to define INCLUDE_PCI when needed by any included CTI boards. The section for CTI driver configuration should surrounded by a check forINCLUDE_CTI_SIO being defined.For example:/* Connect Tech Inc. serial driver options */#if defined(INCLUDE_CTI_SIO)#define INCLUDE_CTI_U550/* support for 550 UARTs */#endif/* defined(INCLUDE_CTI_SIO) */A complete list of the available configuration options follows:4.1.1.1.INCLUDE_CTI_U550Define INCLUDE_CTI_U550 to include support for Xtreme/104 products that utilize 550 UARTs. This can be determined by examining the UART chips on the Xtreme/104 board itself, or by contacting CTI support staff.Usage:#define INCLUDE_CTI_U5504.1.1.2.INCLUDE_CTI_U650Define INCLUDE_CTI_U650 to include support for Xtreme/104 products that utilize 650 UARTs. This can be determined by examining the UART chips on the Xtreme/104 board itself, or by contacting CTI support staff.Usage:#define INCLUDE_CTI_U6504.1.1.3.INCLUDE_CTI_U850Define INCLUDE_CTI_U850 to include support for Xtreme/104 products that utilize 850 UARTs. This can be determined by examining the UART chips on the Xtreme/104 board itself, or by contacting CTI support staff.Usage:#define INCLUDE_CTI_U8504.1.1.4.INCLUDE_CTI_EXAR17XX5XPCIDefine INCLUDE_CTI_EXAR17XX5XPCI to include support for BlueStorm/LP and Xtreme/104-Plus products. You should also include you BSP’s PCI support if these pr oducts are to be used.Usage:#define INCLUDE_CTI_EXAR17XX5XPCI4.1.1.5.CTI_PCI_MAXBOARDSCTI_PCI_MAXBOARDS is used to define the maximum number of CTI PCI boards that can be enumerated. If not defined the default is 1.Usage:#define CTI_PCI_MAXBOARDS X/* where X is the maximum number of boards */4.1.1.6.CTI_PCI_MAXCHANSCTI_PCI_MAXCHANS is used to define the maximum number of serial channels that can be used by enumerated CTI PCI devices. This number is not the maximum per CTI PCI device, it is the maximum total number of channels across all CTI PCI devices. If not defined the default is 8.Usage:#define CTI_PCI_MAXCHANS X/* where X is the maximum number of channels */4.1.1.7.INCLUDE_CTI_AUTO485POLLERWhen using half-duplex RS485, the receiver and transmitter need to be toggled on and off depending on whether data is being sent or received. On CTI products that do not utilize UARTs with the capability to do this automatically, the driver must perform the toggling.This can be done in one of two ways; Using the interrupt service routine (ISR) of thechannel; Using a watchdog timer as a poller. In order to use the watchdog timerINCLUDE_CTI_AUTO485POLLER must be defined.Usage:#define INCLUDE_CTI_AUTO485POLLER4.1.1.8.CTI_DEFAULT_BAUDCTI_DEFAULT_BAUD is used to define the default baud rate when the serial channels are initialized. If not defined the default is 9600.Usage:#define CTI_DEFAULT_BAUD X/* where X is the default baud rate in bps */4.1.1.9.CTI_AUTO485SWITCHBAUDWhen using the CTIAUTO485SWITCHED auto 485 direction control method,CTI_AUTO485SWITCHBAUD defines the baud rate used to switch between ISR and poller methods. When the baud rate is less than CTI_AUTO485SWITCHBAUD the ISR method is used, else the poller method is used. If not defined the default is 9600.Usage:#define CTI_AUTO485SWITCHBAUD X/* where X is the baud rate in bps */4.1.1.10.CTI_AUTO485POLLER_DELAYWhen the poller auto 485 direction control method is being used a watchdog timerperforms a polling operation to look for the end of a transmit. This watchdog timer is set to expire every CTI_AUTO485POLLER_DELAY ticks. If not defined the default is 1.Usage:#define CTI_AUTO485POLLER_DELAY X/* where X is the delay in ticks */4.1.1.11.CTI_SYS_PCI_INTCONNECT()The CTI_SYS_PCI_INTCONNECT() macro is used to connect a PCI device interrupt to an interrupt service routine. The default definition of this macro uses pciIntConnect().Usage:/** _intLevel_ - interrupt level to connect _isr_ to* _isr_ - interrupt service routine to connect to _intLevel_* _arg_ - argument to be passed to _isr_* _result_ - STATUS result of the macro*/#define CTI_SYS_PCI_INTCONNECT(_intLevel_, _isr_, _arg_, _result_) \{ \/* place desired code here */ \}4.1.1.12.CTI_SYS_INTCONNECT()The CTI_SYS_INTCONNECT() macro is used to connect a device interrupt to an interrupt service routine. The default definition of this macro uses intConnect().Usage:/** _intLevel_ - interrupt level to connect _isr_ to* _isr_ - interrupt service routine to connect to _intLevel_* _arg_ - argument to be passed to _isr_* _result_ - STATUS result of the macro*/#define CTI_SYS_INTCONNECT(_intLevel_, _isr_, _arg_, _result_) \{ \/* place desired code here */ \}4.1.1.13.CTI_SYS_INTENABLE()The CTI_SYS_INTENABLE() macro is used to enable an interrupt level. The defaultdefinition of this macro uses sysIntEnablePIC().Usage:/** _intLevel_ - interrupt level to enable* _result_ - STATUS result of the macro*/#define CTI_SYS_INTENABLE(_intLevel_, _result_) \{ \/* place desired code here */ \}4.1.1.14.CTI_SYS_IN_BYTE()The CTI_SYS_IN_BYTE() macro is used to read an 8 bit value. The default definition of this macro uses sysInByte() for port I/O and does a direct assignment for memory I/O.Usage:/** _ioMode_ - I/O mode (CTIIOPORT or CTIIOMEM)* _address_ - address to read from* _value_ - receives 8 bit value read from _address_*/#define CTI_SYS_IN_BYTE(_ioMode_, _address_, _value_) \{ \if((_ioMode_) == CTIIOPORT) { \/* place port I/O code here */ \} \else { \/* place memory I/O code here */ \} \}4.1.1.15.CTI_SYS_OUT_BYTE()The CTI_SYS_OUT_BYTE() macro is used to write an 8 bit value. The default definition of this macro uses sysOutByte() for port I/O and does a direct assignment for memory I/O.Usage:/** _ioMode_ - I/O mode (CTIIOPORT or CTIIOMEM)* _address_ - address to write to* _value_ - 8 bit value to write to _address_*/#define CTI_SYS_OUT_BYTE(_ioMode_, _address_, _value_) \{ \if((_ioMode_) == CTIIOPORT) { \/* place port I/O code here */ \} \else { \/* place memory I/O code here */ \} \}4.1.1.16.CTI_SYS_IN_WORD()The CTI_SYS_IN_WORD() macro is used to read a 16 bit value. The default definition of this macro uses sysInWord() for port I/O and does a direct assignment for memory I/O.Usage:/** _ioMode_ - I/O mode (CTIIOPORT or CTIIOMEM)* _address_ - address to read from* _value_ - receives 16 bit value read from _address_*/#define CTI_SYS_IN_WORD(_ioMode_, _address_, _value_) \{ \if((_ioMode_) == CTIIOPORT) { \/* place port I/O code here */ \} \else { \/* place memory I/O code here */ \} \}4.1.1.17.CTI_SYS_OUT_WORD()The CTI_SYS_OUT_WORD() macro is used to write a 16 bit value. The default definition of this macro uses sysOutWord() for port I/O and does a direct assignment for memory I/O.Usage:/** _ioMode_ - I/O mode (CTIIOPORT or CTIIOMEM)* _address_ - address to write to* _value_ - 16 bit value to write to _address_*/#define CTI_SYS_OUT_WORD(_ioMode_, _address_, _value_) \{ \if((_ioMode_) == CTIIOPORT) { \/* place port I/O code here */ \} \else { \/* place memory I/O code here */ \} \}4.1.1.18.CTI_SYS_IN_LONG()The CTI_SYS_IN_LONG() macro is used to read a 32 bit value. The default definition of this macro uses sysInLong() for port I/O and does a direct assignment for memory I/O.Usage:/** _ioMode_ - I/O mode (CTIIOPORT or CTIIOMEM)* _address_ - address to read from* _value_ - receives 32 bit value read from _address_*/#define CTI_SYS_IN_BYTE(_ioMode_, _address_, _value_) \{ \if((_ioMode_) == CTIIOPORT) { \/* place port I/O code here */ \} \else { \/* place memory I/O code here */ \} \}4.1.1.19.CTI_SYS_OUT_LONG()The CTI_SYS_OUT_LONG() macro is used to write a 32 bit value. The default definition of this macro uses sysOutLong() for port I/O and does a direct assignment for memory I/O.Usage:/** _ioMode_ - I/O mode (CTIIOPORT or CTIIOMEM)* _address_ - address to write to* _value_ - 32 bit value to write to _address_*/#define CTI_SYS_OUT_LONG(_ioMode_, _address_, _value_) \{ \if((_ioMode_) == CTIIOPORT) { \/* place port I/O code here */ \} \else { \/* place memory I/O code here */ \} \}4.1.2.sysLib.cAdd a section to your sysLib.c file that includes the file sysCTISerial.c. This file includes the CTI SIO driver and defines routines used to configure the CTI serial channels. This section should come after the PCI configuration files have been included and should be surrounded by a check for INCLUDE_CTI_SIO being defined.For example:#if defined(INCLUDE_CTI_SIO)#include "sysCTISerial.c"#endif/* defined(INCLUDE_CTI_SIO) */In addition to including the driver and driver configuration routines, the routines sysHwInit() and sysHwInit2() need to be modified to call the serial configuration routines defined in sysCTISerial.c.4.1.2.1.sysHwInit()During sysHwInit(), sysCTISerialHwInit() should be called to initially configure the CTIserial channels. This call should be made after any PCI initialization in order for CTI PCI adapters to be configured.For example:#if defined(INCLUDE_CTI_SIO)sysCTISerialHwInit();#endif/* defined(INCLUDE_CTI_SIO) */4.1.2.2.sysHwInit2()During sysHwInit2(), sysCTISerialHwInit2() should be called to connect and enableinterrupts used by the CTI serial channels.For example:#if defined(INCLUDE_CTI_SIO)sysCTISerialHwInit2();#endif/* defined(INCLUDE_CTI_SIO) */4.2. Driver FilesThe file sysCTISerial.c, which is included into sysLib.c, needs to be configured to properly match the setup of your system.4.2.1.sysCTISerial.csysCTISerial.c contains rountines used to configure any CTI serial adapters you have. The configuration includes:storage for board and channel structuresboard/channel configuration and initializationinterrupt connecting and enablingchannel enumerationThe code in this section is only meant to serve as a short example. For a more complete sample refer to the sample BSP’s provided with the driver files. For a description of routine parameters refer to the documentation for that routine.4.2.1.1.StorageEach board and channel must have a corresponding structure allocated for it. This istypically done by declaring local variables in the file sysCTISerial.c.Typically one board structure (CTI_BOARD) is defined for each non-PCI CTI adapter.For example:LOCAL CTI_BOARD ctiXt1Board;LOCAL CTI_BOARD ctiXt2Board;For each of the non-PCI adapters, an array of channel structures should be defined aswell. The size of these arrays depends on the number of channels supported by theadapters.For example:LOCAL CTI_CHAN ctiXt1Chans[8];LOCAL CTI_CHAN ctiXt2Chans[4];For PCI adapters, only one instance of CTI_PCI_DEVICESET need be defined. The maximum number of supported adapters and channels should be defined with CTI_PCI_MAXBOARDS and CTI_PCI_MAXCHANS (see section 4.1.1 - config.h for more information onCTI_PCI_MAXBOARDS and CTI_PCI_MAXCHANS).For example:#if defined(INCLUDE_PCI)LOCAL CTI_PCI_DEVICESET ctiPciDevset;#endif/* defined(INCLUDE_PCI) */4.2.1.2.ConfigurationDuring sysHwInit() sysCTISerialHwInit() should be called. This is where the board andchannels structures declared in the previous section are configured and initialized.Each non-PCI board structure should be configured using ctiBoardConfig() and initialized using ctiBoardHrdInit().PCI adapters should be enumerated and initialized using ctiPciConfig() and ctiPciHrdInit().For example:void sysCTISerialHwInit(void){if(OK == ctiBoardConfig(&ctiXt1Board,CTIU650,CTIIOPORT,0x300,0x340, /* 0 if status port not being used */0x05,7372800,4, /* 1 if using extended baud rates */ctiXt1Chans,8,NULL,NULL,0xFF)){if(sysBp) {ctiBoardHrdInit(&ctiXt1Board);}}if(OK == ctiBoardConfig(&ctiXt2Board,CTIU850,CTIIOPORT,0x200,0x240, /* 0 if status port not being used */0x0A,7372800,4, /* 1 if using extended baud rates */ctiXt2Chans,4,NULL,NULL,0xF)){if(sysBp) {ctiBoardHrdInit(&ctiXt2Board);}}#if defined(INCLUDE_PCI)if(OK == ctiPciConfig(&ctiPciDevset, NULL, NULL)) {if(sysBp) {ctiPciHrdInit(&ctiPciDevset);}}#endif/* defined(INCLUDE_PCI) */}4.2.1.3.InterruptssysCTISerialHwInit2() should be called during sysHwInit2() and is responsible for connecting and enabling interrupts used by the CTI adapters.The operations of connecting an interrupt to an interrupt service routine as well asenabling the interrupt have been encapsulated into driver rountines ctiBoardIntConnect() and ctiPciIntConnect(). The behaviour of these routines is controlled by the macrosCTI_SYS_INTCONNECT(), CTI_SYS_PCI_INTCONNECT(), and CTI_SYS_INTENABLE(). These macros can be redefined from their default behaviour. See section 4.1.1 - config.h formore information on CTI_SYS_INTCONNECT(), CTI_SYS_PCI_INTCONNECT(), andCTI_SYS_INTENABLE(). These routines do not have to be used and in some cases may not be sufficient. The specifics of their operation can be seen in ctiSio.c.For example:void sysCTISerialHwInit2(void){ctiBoardIntConnect(&ctiXt1Board);ctiBoardIntConnect(&ctiXt2Board);#if defined(INCLUDE_PCI)ctiPciIntConnect(&ctiPciDevset);#endif/* defined(INCLUDE_PCI) */}4.2.1.4.EnumerationEach serial channel must be associated with a device. The CTI serial channels areenumerated using sysCTISerialChanGet(). This routine takes an index value specifyingwhich channel structure to retrieve, and effectively acts as a look-up table for thechannels. The order in which the channels are returned determines the order in which the channels are associated with device names.For example:SIO_CHAN* sysCTISerialChanGet(int channel/* serial channel */){if((channel >= 0) && (channel < 8)) {return((SIO_CHAN*)&ctiXt1Chans[channel]);}else if((channel >= 8) && (channel < (8 + 4))) {return((SIO_CHAN*)&ctiXt2Chans[channel - 8]);}#if defined(INCLUDE_PCI)else if((channel >= (8 + 4)) &&(channel < (8 + 4 + hans))){return((SIO_CHAN*)&(ctiPciDevset.pChans[channel - 8 - 4]));}#endif/* defined(INCLUDE_PCI) */return((SIO_CHAN*)ERROR);}The total number of channels needs to be reported using sysCTISerialGetNumChans(). This routine simply needs to return the total number of channels being used across all CTIadapters.For example:UINT16sysCTISerialGetNumChans(void){UINT16retVal = 0;retVal += 8;retVal += 4;#if defined(INCLUDE_PCI)retVal += hans;#endif/* defined(INCLUDE_PCI) */return(retVal);}4.3. Tornado/WorkBench ProjectsBootable VxWorks image projects based on a BSP containing the CTI driver files will have a new folder available under hardware\peripherals\serial called “Connect Tech Inc.”. This folder contains components for controlling the CTI serial driver. A description of the components follows:4.3.1.Connect Tech Inc. SIOThis component controls INCLUDE_CTI_SIO (used earlier when including the CTI serial driver in the BSP).e alternate base nameIf this component is not included, the CTI serial channels will be named “/tyCo/X” where X is the channel index value and is based on the defined NUM_TTY value so that the names do not collide with other serial devices. However, it may be desireable to use a different base name. By including the Use alternate base name component, the default behaviour is to name the CTI serial channels “/tyCTI/X” where X is the channel index value starting at 0.The Use alternate base name component has a parameter called CTI_TY_NAME_BASE which can be used to set a base name other than “/tyCTI/”.5. ExamplesIncluded with the driver files are three example BSP’s. These example BSP’s are based on the Pentium III BSP from WindRiver. A description of each of the example BSP’s follows:5.1. pcP3CTI_1This example is based on the following CTI serial adapters:Xtreme/104 RS-2328 channels.Base I/O address is 0x300.IRQ is 10.Status port is in use.Extended baud rates not in use.BlueStorm/LP RS-2324 channels.5.2. pcP3CTI_2This example is based on the following CTI serial adapters:Xtreme/104 14 RS-232 channels.Base I/O address is 0x300.IRQ is 10.Status port is in use.Extended baud rates not in use.Xtreme/104 28 channels.Base I/O address is 0x200.Channels 1, 3, 5, and 7 are on IRQ 5, channels 2, 4, 6, and 8 are on IRQ 9. SeeMode 2 in the Interrupt Selection section of the Xtreme/104 manual.Status port is not in use.Extended baud rates in use.Channels 1 and 2 are RS-232, channels 3, 4, and 5 are RS-485 full-duplex,channels 6, 7, and 8 are RS-485 half-duplex.Xtreme/104-Plus Switchable4 channels.Channels 1 and 2 are RS-485 full-duplex, channels 3 and 4 are RS-232.5.3. pcP3CTI_3This example is based on the following CTI serial adapters:BlueStorm/LP8 RS-232 channels.6. Installation Checklist。
约定文档中提到的路径,均相对于ROS5(M)目录而言。
1.编译模拟器1.1.基本原理为了节省时间,模拟器不像设备那样编译一个完整的vxworks镜像文件,而是把系统和模块分开。
系统存放在vxsim\vxWorks文件中,该文件由系统组负责维护。
模块则编译在vxsim\vxsim.out文件中,这个文件由各自编译。
为了编译理解,我们可以和Windows系统做一个对比,vxworks文件相当于Windows系统,.out文件相当于一个exe文件。
我们开发一个exe文件的时候,并不需要编译整个Windows系统。
因此我们只需要编译出vxsim.out 文件即可。
vxsim.out的编译过程如下:1、编译vxsim目录下的所有.c文件,生成对应的.o文件2、链接步骤1生成的.o文件和lib\gnu\vxworks\SIMNT、publib\gnu\vxworks\SIMNT目录下的所有.a文件。
如果两个目录有同名文件,则使用lib目录下的。
1.2.编译vxsim.out当前模拟器的编译不再使用Workbench工程,完全使用批处理common\vxsim.bat进行,该批处理应该用VxWorks Development Shell运行,而不是cmd。
下面描述都假设是在common 目录下。
从基本原理那能看出,编译vxsim.out需要编译vxsim目录下的.c文件和编译库文件(.a 文件)。
其中主要的工作是编译库文件。
1.2.1.库文件编译编译一个库文件的方法是vxsim.bat libname,其中libname指的是模块的名称,在module目录下应该有一个libname.module文件。
比如:最终生成的库文件是存放在lib\gnu\vxworks\SIMNT目录下,也即当前编译的库文件优先于publib的库文件。
一般而言,公共的库文件(rdvp/support/rcis/simssp)在publib目录下已经存在稳定的版本,不用另外编译。
VxWork介绍及编程一.嵌入式操作系统VxWorks简介VxWorks操作系统是美国WindRiver公司于1983年设计开发的一种嵌入式实时操作系统(RTOS),是嵌入式开发环境的关键组成部分。
良好的持续发展能力、高性能的内核以及友好的用户开发环境,在嵌入式实时操作系统领域占据一席之地。
它以其良好的可靠性和卓越的实时性被广泛地应用在通信、军事、航空、航天等高精尖技术及实时性要求极高的领域中,如卫星通讯、军事演习、弹道制导、飞机导航等。
在美国的 F-16、FA-18 战斗机、B-2 隐形轰炸机和爱国者导弹上,甚至连1997年4月在火星表面登陆的火星探测器上也使用到了VxWorks。
WindRiver公司网址实时操作系统和分时操作系统的区别从操作系统能否满足实时性要求来区分,可把操作系统分成分时操作系统和实时操作系统。
分时操作系统按照相等的时间片调度进程轮流运行,分时操作系统由调度程序自动计算进程的优先级,而不是由用户控制进程的优先级。
这样的系统无法实时响应外部异步事件。
实时操作系统能够在限定的时间内执行完所规定的功能,并能在限定的时间内对外部的异步事件作出响应。
分时系统主要应用于科学计算和一般实时性要求不高的场合。
实时性系统主要应用于过程控制、数据采集、通信、多媒体信息处理等对时间敏感的场合。
VxWorks的特点•可靠性操作系统的用户希望在一个工作稳定,可以信赖的环境中工作,所以操作系统的可靠性是用户首先要考虑的问题。
而稳定、可靠一直是VxWorks的一个突出优点。
自从对中国的销售解禁以来,VxWorks以其良好的可靠性在中国赢得了越来越多的用户。
•实时性实时性是指能够在限定时间内执行完规定的功能并对外部的异步事件作出响应的能力。
实时性的强弱是以完成规定功能和作出响应时间的长短来衡量的。
VxWorks 的实时性做得非常好,其系统本身的开销很小,进程调度、进程间通信、中断处理等系统公用程序精练而有效,它们造成的延迟很短。
VxWorks开发简明培训教程ManualVxWorks是美国Wind River Systems开发的一款实时操作系统,常被使用在嵌入式系统中,其广泛的应用领域包括航空航天,自动驾驶,医疗设备等。
为了更好地了解VxWorks的开发及应用,在这里针对其开发进行简明培训教程。
1. 环境准备在使用VxWorks进行开发之前,需要先进行相关环境的准备。
首先是设备的准备,需要一块支持VxWorks的开发板。
其次是软件的准备,可以从Wind River Systems官网上下载VxWorks开发软件。
2. 创建项目在进行VxWorks开发前,需要创建一个新的项目。
在Eclipse或者Wind River Workbench中,可以通过点击New Project来创建新的项目。
在这一步中,需要选择合适的CPU类型和操作系统类型,以及选择开发板的型号。
3. 创建任务在VxWorks操作系统中,任务是一个非常重要的概念。
任务可以看做是一个运行在操作系统上的程序,可以控制任务的创建和销毁。
通过在代码中调用taskSpawn函数可以创建一个新的任务,该函数包含任务名称、任务优先级、任务属性、栈大小等参数。
4. 任务管理在VxWorks中,可以通过taskDelete和taskSuspend等函数来分别删除或者挂起一个任务。
在对任务进行管理时,需要注意任务的优先级和业务流程,确保任务的执行顺序和执行时间。
5. 中断处理在嵌入式系统中,中断是一个非常重要的概念。
VxWorks 提供了中断处理机制,可以在中断的发生时进行处理。
通过对中断处理函数进行编写,可以实现对中断信号的处理和相应,从而保证系统的稳定性和安全性。
6. IO操作在嵌入式系统中,IO操作是必不可少的一部分。
VxWorks 提供了相关的函数,可以对设备进行读写操作。
比如,通过open函数打开设备,通过read函数读取设备数据,通过write 函数将数据写入设备。
VxWorks编程常用函数说明VxWorks编程常用函数说明一、官方的Program Guide位于安装目录下:\\docs\\vxworks\\guide\\index.html二、常用的库:#include "taskLib.h" /* 任务 */#include "msgQLib.h" /* 消息队列 */#include "semLib.h" /* 信号量 */#include "ioLib.h" /* IO */#include "wdLib.h" /* Watch dog */#include "logLib.h" /* 信息输出 */#include "socket.h" /* 网络套接字 */三、IO系统:ioLib.h1、系统中的IO设备,包括键盘、串口、文件等,都用统一的接口访问。
第一步通常先得到文件描述符,然后进行读写或者设置的工作,最后关闭该描述符。
creat:建立文件open:得到文件或设备的描述符read:读文件或设备write:写文件或设备ioctl:设置参数close:关闭文件描述符remove:删除文件2、内存文件memDrv( ) - 初始化伪内存设备memDevCreate( ) - 建立伪内存设备memDevCreateDir( ) - 建立一组伪内存设备memDevDelete( ) - 删除伪内存设备Init() {uchar_t buffer[1024];int fd;memDrv( );memDevCreate("/mem/mem1", buffer, sizeof(buffer));if ((fd = open("/mem/mem1", O_RDWR, 0644)) != ERROR) { write(fd, &data, sizeof(data));… …close(fd);}memDevDelete("/mem/mem1");}3、通过Select函数实现多个IO监听:selectLib.h当等待多个IO时,我们可以使用Select函数,fd为文件描述符:int select(int width, /* 最大的fd,或直接FD_SETSIZE (2048) */fd_set * pReadFds, /* 读的fd集合 */fd_set * pWriteFds, /* 写的fd集合 */fd_set * pExceptFds, /* vxWorks不支持,NULL */struct timeval * pTimeOut /* 等待时间, NULL = forever */ )还有几个宏:FD_SET(fd, &fdset) 设置fd的监听位FD_CLR(fd, &fdset) 清除fd的监听位FD_ZERO(&fdset) 清除所有监听位FD_ISSET(fd, &fdset) fd是否有数据例子,其中MAX意为取最大值:Init() {struct fd_set readFds;int fds[4];int width;fds[0] = open(..);… …;fds[3] = open(..); /* 打开IO */width = MAX(fd s[0], … … , fds[3])+1; /* fd的最大值+1 *//* FOREVER {*/FD_ZERO(&readFds); /* 设置fd_set结构 */FD_SET(fds[0], & readFds);… …; FD_SET(fds[3], & readFds);if (select(width, &readFds, NULL, NULL, NULL) == ERROR) { /*监听*/close(fds[0]); … …; close(fds[3]);return;}for(i=0; iif (FD_ISSET(fds[i], &readFds)) {… …; /* 进行读写操作 */}}/* } */}四、多任务环境的编程:1、任务控制:taskLib.htaskSpawn( ) - 创建任务taskInit( ) -初始化任务,用户自己指定栈和PCB地址taskActivate( ) - 激活已经初始化的任务exit( ) - 在任务中结束 (ANSI)taskDelete( ) - 删除任务taskDeleteForce( ) - 强制删除,即使被保护taskSuspend( ) - 挂起任务taskResume( ) - 恢复挂起的任务taskRestart( ) - 重新启动任务taskPrioritySet( ) - 改变任务优先级taskPriorityGet( ) - 读取任务优先级taskLock( ) - 禁止任务调度taskUnlock( ) - 允许任务调度taskSafe( ) - 保护任务不被删除taskUnsafe( ) - 解除保护taskDelay( ) - 延时taskIdSelf( ) - 得到当前任务的ID taskIdVerify( ) - 任务ID是否存在taskTcb( ) - 得到任务控制块(TCB)的地址taskOptionsSet( ) - 改变任务选项taskOptionsGet( ) - 得到任务当前选项taskRegsGet( ) - 得到任务TCB中寄存器的信息taskRegsSet( ) - 设定任务TCB中寄存器的信息taskName( ) - 得到任务名称taskNameToId( ) - 由名称得到ID taskIdDefault( ) - 设置默认的任务ID taskIsReady( ) - 任务是否就绪taskIsSuspended( ) - 任务是否挂起taskIdListGet( ) - 得到活动的任务列表2、任务互斥 - 信号量:semLib.h semGive( ) –释放一个信号量semTake( ) –获取一个信号量,会阻塞semFlush( ) –使所有阻塞在本信号量上的任务变为就绪状态semDelete( ) –删除一个信号量1)二进制信号量:semBCreate可用于任务同步和互斥,但常用于任务同步2)互斥信号量:semMCreate专门用于任务互斥的信号量,保护临界资源3)计数信号量:semCCreate多实例资源的访问控制3、任务同步1)消息队列:msgQLib.h消息队列msgQCreate( ) - 创建消息队列msgQDelete( ) - 删除消息队列msgQSend( ) - 发送消息msgQReceive( ) - 接受消息,调用后阻塞msgQNumMsgs( ) - 得到消息队列中的消息数量Init() {/* 创建消息队列 */if ((msgQID = msgQCreate(8, 1, MSG_Q_FIFO)) == NULL) { printf("Message queue create failed!\");}}taskSend() {if (OK != msgQSend(msgQID, "A", 1, NO_WAIT, MSG_PRI_NORMAL)) {printf("Message send failed!");}}taskReceive() {uchar_t ch;msgQReceive(msgQID, &ch, 1, WAIT_FOREVER); /* 这里任务会阻塞 */printf("Received from msgq: %c ", ch);}2)管道:ioLib.h,系统默认包含了pipe驱动组件pipeDevCreate( ) - 创建管道pipeDevDelete( ) - 删除管道由于管道属于IO,所以可以使用Select监听,消息队列不是IO,不能使用SelectInit() {/* 创建管道 */if (pipeDevCreate("/pipe/mypipe", 8, 1) != OK) {printf("/pipe/mypipe create fialed!\");}/* 创建互斥信号量 */if ((semMID = semMCreate(SEM_Q_FIFO)) == NULL){printf("Mutex semaphore create failed!\");}}taskSend() {int pd; /* pipe的描述符 */if ((pd = open("/pipe/mypipe", O_WRONLY, 0644)) == ERROR) {printf("Open pipe failed!");}if (semTake(semMID, NO_WAIT) == ERROR) {printf("Pipe in use!");}write(pd, "a", 1);semGive(semMID);close(pd);}taskReceive() {int pd; /* pipe的描述符 */uchar_t ch;if ((pd = open("/pipe/mypipe", O_RDONLY, 0644)) == ERROR) {printf("Open pipe failed!");}if (read(pd, &ch, 1)>0) { /* 这里任务会阻塞 */printf("Received from pipe: %c", ch);}}3)二进制信号量Init() {/* 创建二进制信号量 */if ((semBID = semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL) {printf("Binary semaphore create failed!\");}}taskSend() {semGive(semBID);}taskReceive() {semTake(semBID, WAIT_FOREVER); /* 这里任务会阻塞 */}4)事件:eventLib发送事件要指定目标任务的IDeventReceive( ) - 等待事件eventSend( ) - 发送事件eventClear( ) - 清除当前任务的事件.taskSend() {if (OK != eventSend(taskReceiveID, 0×00000001)) {printf("Event send failed!");}}taskReceive() {UINT32 Ev;if (OK!=eventReceive(0×00ffffff, EVENTS_WAIT_ANY, WAIT_FOREVER, &Ev)) {printf("eventReceive Error!\");}else {Ev &= 0×00000001;if (Ev) {printf("Event %d received!", Ev);}}}五、Watch dog :wdLib.h系统提供了软看门狗定时器,使用也简便:wdCreate( ) - 创建看门狗wdDelete( ) - 删除wdStart( ) - 启动wdCancel( ) - 停止Init() {/* 创建看门狗 */if ((wdID = wdCreate()) == NULL) {printf("Watch dog create failed!\");}}task() {if (OK != wdStart(wdID, sysClkRateGet()*5, proc_wd, 0)) {printf("Watch dog start failed!\");}}int proc_wd(int param) {logMsg(… …);}六、网络编程:sockLib.h使用标准的BSD Socket套接字,使用TCP或者UDP协议进行通讯。
一.V xWorks653运行时系统1.1. 运行时层一个vxworks653模块由下面四层组成:■core OS—必需■partition—至少需要一个(vThreads 或COIL-based),每个都在一个分区的操作系统之中■APEX shared library—ARINC 653 应用所需■POSIX shared library—POSIX 应用所需1.1.1.Core OS层核心操作系统提供服务给分区。
缺省的,核心操作系统使用ARINC653规范中的时间抢占的调度(TPS)来调度分区。
Vxworks653的核心操作系统还可以采用APPS调度策略在TPS调度的空闲时间内调度优先级抢占调度(PPS)使能的分区。
核心操作系统提供给每个VThreads分区操作系统的服务包括:●分区系统资源●调度分区●代表分区的操作系统执行trap异常●定义和强制分区边界●装载分区●使用端口和通道在分区间传递消息●处理I/O●代表应用完成系统调用●支持分区的调试●监控分区和系统的健康1.1.2.vThreads 层vThreads分区操作系统在核心操作系统分配给该分区的时间内调度vThreads中的线程。
vThreads不直接与设备交互,而是通过核心操作系统的系统调用。
1.1.3.APEX 层构建在vThreads之上,遵循ARINC653规范,并且提供相应功能和API。
1.1.4.POSIX层构建在vThreads之上,遵循用于实时扩展的POSIX标准(1003.1b)。
1.2. 装载和启动当目标板加电时,按照下面的步骤进行装载和启动●初始的启动码装载核心操作系统,分区操作系统,共享库,以及应用●核心操作系统初始化自身,启动它自己的子系统●核心操作系统创建分区●核心操作系统启动分区调度器,并且让应用初始化自身核心操作系统可以在初始化完成之后下载在线装载的应用程序到分区。
应用可以在分区运行之时装载到分区。
1.3. 运行时模型核心操作系统处理来自每个分区的系统调用,并且在运行系统调用前校验每个系统调用的语句。
使用vThreads分区操作系统的应用拥有完全的vThreads任务间通信机制。
APEX库提供了遵循ARINC653规范的分区管理,进程管理以及时间管理;为分区间通信提供了消息,通道,端口;为分区内通信提供缓冲区,黑板,信号量以及事件。
端口映射允许在VxWorks653模块之外通信。
二.开发APEX应用APEX是位于应用程序和支持ARINC653规范的操作系统之间的API。
对于VxWorks653,操作系统是vThreads分区操作系统和核心操作系统。
APEX给vThreads分区提供了时间、进程管理以及管理周期性和非周期性进程的能力。
APEX提供如下服务:●管理分区●管理进程●管理时间●与其他分区通信(使用消息,端口和通道)●分区内的通信(使用缓冲区,黑板,信号量以及事件)●监控健康2.1. 分区管理分区的管理包含分配分区内存以及依据ARINC653规范初始化分区。
2.1.1.分配分区内存每个分区的资源分配都定义在基于XML的配置和编译过程中,根据指定在该规范中的分区需求,为每个分区分配唯一的物理内存。
通过禁止对超过该分区的内存区域的写访问来确保内存分区。
2.1.2.初始化分区:冷和热启动冷启动:当VxWorks653模块加电并且创建分区时,使用冷启动分区操作模式。
在冷启动模式下,分区对象被分配并且初始化。
热启动:热启动分区操作模式导致一个分区重新初始化或者由于遇到错误重新启动。
在热启动模式下,持久数据不会重新初始化,分区代码也不会重新装载。
每个分区所使用的资源(如通道、进程、队列、信号量或事件等)在系统编译时指定。
在分区的初始化阶段,创建分区所需的资源,然后分区进入NORMAL模式。
2.1.3.分区属性分区属性定义在XML配置文件中。
固定的分区属性包括:●标识符:定义在VxWorks653模块上唯一的分区标识符。
●内存需求:分配给分区的物理内存●周期:分区的激活周期。
用来确定核心操作系统的整个时间帧内的分区激活的运行时位置。
●持续时间:分区的每个周期内核心操作系统给予的处理器时间。
●关键级别:分区的RTCA/DO-178B认证级别。
●通信需求:分区与其他分区通信的通信通道●分区健康监控表(健康监控配置):健康监控器对于故障的动作指令。
2.1.4.获得分区状态GET_PARTITION_STATUS函数可以获得当前情况下的分区状态。
type PARTITION_STATUS_TYPE is recordIDENTIFIER : PARTITION_ID_TYPE;PERIOD : SYSTEM_TIME_TYPE;DURATION : SYSTEM_TIME_TYPE;LOCK_LEVEL : LOCK_LEVEL_TYPE;OPERATING_MODE : OPERATING_MODE_TYPE;START_CONDITION : START_CONDITION_TYPE;end record;type OPERATING_MODE_TYPE is (IDLE, COLD_START, WARM_START, NORMAL);type START_CONDITION_TYPE is (NORMAL_START,PARTITION_RESTART,HM_MODULE_RESTART,HM_PARTITION_RESTART);Where:NORMAL_START is a normal power-up.PARTITION_RESTART is either due to COLD_START or WARM_START by the partitionitself, through the SET_PARTITION_MODE service.HM_MODULE_RESTART is a recovery action taken at module level by the HM.HM_PARTITION_RESTART is a recovery action taken at partition level by the HM.2.1.5.设置分区模式SET_PARTITION_MODE函数可以设置分区模式为IDLE,COLD_START,WARM_START,NORMAL。
其中IDLE模式:分区关闭。
分区未被初始化,没有进程正在运行,但是分配给该分区的时间窗口未被改变。
COLD_START模式:分区重启使用冷启动初始化。
WARM_START模式:分区重启使用热启动初始化。
NORMAL模式:激活的进程被调度。
2.1.6.控制分区中的抢占进程的LOCK_PREEMPTION函数可以为分区中的抢占上锁。
该函数增加了分区的锁级,使得进程不能在分区中重调度。
当进程访问临界区时,或资源被同一分区中的多个进程共享时,这个能力十分重要。
LOCK_PREEMPTION函数不会影响其他分区的调度。
如果一个位于临界区的进程由于分区窗口结束而被中断时,当分区再次运行时仍然是该进程最先运行。
UNLOCK_PREEMPTION函数可以解锁分区的抢占。
这个函数降低了分区的锁级,仅当锁级达到零时,进程的重调度才能恢复。
2.1.7.分区调度对于时间分区,ARINC653提供了两级调度机制。
在核心模块级,采用预先确定的基于时间窗的循环调度算法来调度各个分区,分区没有优先级。
核心操作系统根据每个分区的周期与持续时间信息,维护一个固定时间长度的主时间帧,该主时间帧的时间长度为所有分区周期的最小公倍数。
静态调度算法为每个分区生成该主时间帧内相应的分区调度窗口,每个分区调度窗口由从主时间帧开始的偏移和期待的持续时间来定义。
分区的调度窗口事先定义在配置表中。
每个分区在其分区调度窗口内被激活并占用CPU,并保证每个分区在其调度窗口内运行时不被其他分区打断。
主时间帧在模块的运行期内周期性的重复,每个主时间帧中拥有相同的分区调度窗口执行次序。
2.2. 进程管理APEX进程是包含在APEX分区内的编程单元。
同一分区内的进程可以并发执行。
进程由可执行程序、数据和栈、程序计数器、栈指针以及优先级期限组成。
进程管理包含创建进程、改变进程当前优先级、得到进程的当前状态、得到进程ID、挂起和恢复进程、停止和启动进程、控制抢占等函数。
2.2.1.进程类型●周期性进程●非周期性进程2.2.2.进程调度在分区级,调度单元是APEX进程。
每个进程拥有优先级,调度算法是优先级抢占的。
分区级操作系统总是选择处于就绪状态且具有最高优先级的进程获得处理器资源。
如果多个进程拥有相同的优先级,则分区操作系统选择就绪队列中第一个进程。
进程将控制处理器资源直到另一个进程重调度事件发生。
2.2.3.进程状态变迁2.3. 时间管理2.3.1.调度分区见2.1.7分区调度2.3.2.系统时钟时间系统时钟时间为系统提供了唯一的时间。
GET_TIME函数可以获得系统时钟时间。
2.3.3.请求资源和超时当进程请求一个APEX资源(例如信号量或事件)时,可以指定下列超时类型之一:●INFINITE_TIME_VALUE从不过期。
永久等待●ZERO_TIME_VALUE不等待资源。
如果资源不可得,则返回一个错误●Finite value of timeout等待一个资源的最大时间超时单元是SYSTEM_TIME_TYPE类型,纳秒单位。
2.3.4.调度进程APEX时间管理函数让分区来控制进程。
在每个处理周期(cycle)的末尾,一个周期性的进程请求PERIODIC_WAIT服务来获得一个新的期限。
通过这个进程的下个周期的释放点来计算新的期限。
对于所有进程,TIMED_WAIT服务让进程将自己悬挂一段时间。
在等待时间过去后,进程能够被调度。
REPLENISH服务让进程将它的当前期限推迟一段已过的时间。
分区内的每个进程可以指定一段逝去的时间(叫做时间能力)。
时间能力用来设置处理期限时间,vThreads周期性的评估该时间以确定是否进程在分配的时间内能够完成它的处理。
2.3.5.期限每个进程关联了一个固定的时间能力,表示分配给它的响应时间用于满足它的处理需求。
期限时间可以确定是否进程能够在它的时间能力内完成它的处理。
可以通过REPLENISH服务增加期限时间,在下一次激活时将创建新的期限。
有三种类型的期限:●硬期限如果进程不能在一个指定的时间周期内满足一个硬期限,vThreads将采取补救动作●软期限如果进程不能在一个指定的时间周期内满足一个软期限,失效将被记录,并且处理继续●没有期限如果进程不能在一个指定的时间周期内完成处理,将不采取任何动作对于一个周期性进程,当进程的激活周期开始时,期限时间的倒计时也同时开始。