约定文档中提到的路径,均相对于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进行,该批处理应该用VxWorksDevelopmentShell运行,而不是cmd。下面描述都假设是在common目录下。从基本原理那能看出,编译vxsim.out需要编译vxsim目录下的.c文件和编译库文件(.a文件)。其中主要的工作是编译库文件。1.2.1.库文件编译编译一个库文件的方法是vxsim.batlibname,其中libname指的是模块的名称,在module目录下应该有一个libname.module文件。比如:最终生成的库文件是存放在lib\gnu\vxworks\SIMNT目录下,也即当前编译的库文件优先于publib的库文件。一般而言,公共的库文件(rdvp/support/rcis/simssp)在publib目录下已经存在稳定的版本,不用另外编译。各自只需要编译自己当前开发/调试的模块即可。ROS5和ROS5M编译库文件略有不同。ROS5M下的代码是全的,各个组件可以正常编译,比如需要编译命令行库文件,只需要运行vxsim.batcli即可。其余各个组件的编译方法类似。由于cli目录下存在大量的未组件化模块的命令行,编写不甚规范,在ROS5下是编译不过的(ROS5M可以编过),因此ROS5下应该使用publib下的cli库文件。但是publib下的cli库文件并不包含正在开发的模块命令行,为了解决这个问题,可按如下步骤进行:1、ROS5的cli库文件应该起一个新名称,比如qoscli。只需要复制一份module下的cli.module文件,然后改个名即可,比如改成qoscli.module。注意该文件不能受控。2、在cli目录下增加一个filter.txt文件,里面写一行ROSCFILES=xxx.c,比如,这样表示该目录(cli)下只编译erpsCli.c这个文件,可以写多个,中间用空格隔开,大小写敏感,比如ROSCFILES=erpsCli.celpsCli.c3、编译新增加的命令行库文件,比如这样在lib目录下就会生成一个libqoscli.a。之所以要改名,是因为如果这里也用cli这个名称,根据优先原则,publib下的libcli.a将不会被链接,导致其他模块的命令行链接不进来。mib虽然在ROS5下也能编译通过,但是建议采用和cli类似的处理方法。1.2.2.编译.out文件库文件编译好了之后,即可编译vxsim.out文件了,执行vxsim.batdev即可:如果编译成功,则在vxsim目录下会生成一个vxsim.out文件,这个就是我们用来调试的文件。1.3.常见问题编译问题这里不再赘述,按照一般的编译问题定位方法即可,这里说模拟器比较典型的两个问题:缺少定义和重复定义。缺少定义也就是我们常见的“undefinedreferencetoxxxx”这种错误。模拟器的编译是不会报这种错误的,只有在运行的时候才会出现这种错误。上面说了,现在模拟器是分成了两部分,系统的vxworks文件和模块的vxsim.out文件。编译vxsim.out文件的时候,如果某些变量找不到定义,会假定其在vxworks文件中,因此不会报错只有等运行的时候才会报错。重复定义,也就是我们常见的“multipledefinitionxxxx”这种错误,常见于组件开发过程,特别是那些未组件化的模块组件化的时候。因为在libothers.a中存在一份定义,然后新开发的模块中也有一份定义。但是,正常情况下,即使有重复定义,如果模块的独立性没问题,那么也不会出现重复定义的问题。如果出现了这个问题,可以打开vxsim目录下的vxsim.map文件查看原因。里面列出了各个.o被引用的原因。正常情况下,由于lib目录优先,publib下的libothers.a中的旧模块应该是不会被引用的。2.编写ssp【本节暂时作废,先别看】和设备类似,模拟器也有自己的ssp,用于硬件的一些行为。当前模拟器的ssp放在ROS5\ssp\vxsim_ssp目录下,ROS5M不做复制,仅做映射。vxsim_ssp下有两个目录,一个src一个include,分别用于存放源文件和头文件。一般而言,每个模块应该有两个源文件和一个头文件。定义的规则如下:定义一个xxx.c,名字和hwapi头文件的名称一样,比如有一个maclibHwApi.h,则定义一个maclibHwApi.c用于存放hwapi的7个(pvset,pvget,svget,svset,ssget,ssset,ssdel)函数(部分模块可能只有7个中的部分)。然后再定义一个xxxVxsim.c,用于存放功能代码,xxx为模块的名称,取xxxhwapi.h的前面部分,比如maclibHwApi.h则对应的是maclibVxsim.c,头文件叫maclibVxsim.h,也放在src目录下。当前已经实现了一些基本的hwapi,比如mac,vlan和port,但是还很不完整,特别是收发包模块的转发功能,后续会根据大家的需求补全。具体的ssp功能如何编写这里没办法说,毕竟各个模块不一样,简单的说,就是要用软件来模拟硬件的功能。3.建立远端系统在Workbench的RemoteSystems窗口下建立远端系统【如果已经有远端系统且正确配置,这一步省略】,如下图(如果找不到RemoteSystems这个窗口,请参考附录A):点击图中的红色方框内的按钮即可新建一个远端系统。远端系统类型选“WindRiverVxWorks6.xSimulatorConnection”,如下图:下一步,然后配置启动参数,如下图:这里需要配置两个参数,一个是选择镜像文件,请选择ROS5\vxsim\vxWorks。另一个是“Processornumber”,这个相当于远端系统的编号。每个远端系统相当于一台设备,如果需要调试一些需要多设备联调的模块,就需要建立多个远端系统,各个远端系统之间的“Processornumber”不能重复。下一步,配置内存选项,如下图:红色方框内的是内存大小选项,默认是32,需要修改为一个更大的值,推荐128,如果调试的是很大的模块,建议改的更大,具体数值请根据各个模块的内存使用情况。下一步,配置其他参数,如下图:这里主要配置三个参数:临时目录的路径,选择vxsim\wb目录;是vxsim的进程优先级,建议修改为“Normal”;其他选项,这里我们主要配置simnet接口。以-ni开头,留一个空格,然后后面配置各个simnet接口的IP地址,各个simnet接口之间用分号隔开。simnet接口的命名按照simnet+接口号的格式进行。simnet接口介绍请参考附录Bsimnet简介。至此,远端系统就算建立好了,上述的各个配置在建立好了之后也可以修改,修改的方式为右击一个远端系统,然后选择“Properties”。4.建立调试配置调试配置主要需要以下事情:选择远端系统选择.out文件配置入口函数步骤如下:菜单:RunDebugConfigurations…右击左边窗口的VxWorksKernelTask,选择New:在“LaunchContext”标签页下需要做几个配置:1、选择远端系统;2、输入入口函数,ROS5统一为sysAppInit;3、Debug栏下的两个复选框选上。在“Download”标签页下选择.out文件:点击“Add”按钮,会弹出一个对话框,点击浏览按钮,选择对应的.out文件。至此,调试配置建立完毕。附录AWorkbench下打开某个窗口的方法如果当前view下没有找到需要的窗口,可以选择菜单中的WindowShowView。在弹出的下拉菜单里面有各种窗口,如果没有找到想要的,则点击最下面的Other…,如下图:点击Other…之后会弹出一个ShowView的窗口,如下图:可以在typefiltertext框里面输入过滤字符串,即可找到想要的窗口。附录Bsimnet简介simnet用于模拟远端系统之间的网络连接。如果两个simnet接口的IP地址网段相同,那么这两个接口就是连通的,不管是同一个远端系统内还是不同的远端系统之间。比如远端系统A配置了simnet1=192.168.1.1,远端系统B配置了simnet1=192.168.1.2,远端系统C配置了simnet2=192.168.1.3,那么A:simnet1、B:simnet1、C:simnet2就是连通的。注意,simnet接口的IP地址不是随便配的,其网段是有限制的,具体请参考后面章节。在ROS5里面,我们用simnet来模拟端口,simnet0模拟SNMP口,simnet1-6模拟1-6口。在上面的例子里面A的端口1,B的端口1,C的端口2是连通的,它们中任意一个发出的报文都能被另外两个收到。上面说了,simnet的IP地址是有限制的,simnet能否互通依赖于一个服务,大家打开自己的Windows服务管理窗口,如果看到下图红色框内的服务,则表示已经安装:如果没看到则需要安装该服务,在vxworksshell下运行vxsimnetds_inst.exe即可安装该服务。如果安装成功则在Windows的服务管理里面应该能看到该服务。停止该服务,然后在启动参数里面输入:-fxxxx,其中xxxx表示的是simentds的配置文件,格式在后面讲,如下图:,将启动类型修改为自动。这个步骤只需要在安装了simnetds服务之后执行一次即可。配置文件格式如下:SUBNET_STARTsub1{SUBNET_ADDRESS=192.168.1.0;SUBNET_EXTERNAL=yes;SUBNET_EXTPROMISC=yes;};SUBNET_STARTsub2{SUBNET_ADDRESS=192.168.2.0;SUBNET_EXTERNAL=yes;SUBNET_EXTPROMISC=yes;};每个子网配置包含三部分,可以配置多个子网。关键看“SUBNET_ADDRESS”段,这里配置的是一个子网地址,最后一位是0。上面说的simnet的IP地址是有限制的,意思是只能配置在在配置文件中定义了的子网地址,比如上面的配置文件中,simnet只能配置192.168.1和192.168.2网段的IP地址。建议大家根据需要来配置网段的数目,少了不够用,多了浪费内存(每个网段约1M)。附录C模拟器和实际设备联调这里简单介绍一下如果将模拟器和实际设备连接起来。这里需要用到虚拟网卡,在介绍虚拟网卡安装方法之前,先介绍一下拓扑:上面介绍了,模拟器可以配置simnet接口用来模拟物理端口,相同网段的simnet接口是互通的,如果虚拟网卡的IP地址网段也相同,那么simnet接口和虚拟网卡也是连通的。因此,只要模拟器上有一个1-6之间的simnet接口的IP地址网段和虚拟网卡的相同,就意味着模拟器有一个“端口”连接到虚拟网卡上了。开发了一个桥接程序(依赖于winc