前言(Surface): 随着国内使用VxWorks的用户越来越多,为了方便VxWorkers少走一些弯路,特别推出了中文FAQ,其中 很多的FAQ来自comp.os.vxworks和原创。(很多FAQ都可以在该新闻组找到英文版) 文档的FAQ总共分为7大类: 1.入门FAQ 2.Tornado工具FAQ 3.BSP FAQ 4.文件系统 FAQ 5.网络 FAQ 6.VxWorks操作系统 FAQ 7.其它 FAQ 基本涵盖了Tornado/VxWorks使用中的主要方面。 文档组织本身没有逻辑上的关联,经过分类,只是松散的组合在一起,可根据你的需要选择阅读某一部 分。 为了保持本文档的开放性和可扩充性,欢迎大家把自己曾经碰到过的问题及其解决办法按分类加到文档 里来。在修改本文档时,请把修改记录加到历史记录里。 欢迎任何人指出文档中的错误之处,请把错误之处发到附录B里的任一个EMAIL里,在此对那些问题的提 出者、回答者以及文档的维护者一并表示感谢! 当前版本(Current Version): version 0.1 历史(History): 2002-08-27 wys205 create 0.1 version 目录(Content): 1.入门FAQ 1.1 概念 1.2 环境 1.3 编程 2.Tornado工具FAQ 2.1 编译器和链接器 2.2 调试器 2.3 FTP 2.4 主机工具 2.5 安装 2.6 MAKEFILE 2.7 工程 2.8 目标机服务器 2.9 Shell 2.10 Telnet 2.11 Tornado 2.12 版本控制 2.13 Visual Studio集成 2.14 Windsh 2.15 WindView 3.BSP FAQ 3.1 不同BSP 3.2 处理器 3.2.1 Power PC 3.2.2 I960 3.2.3 MIPS 3.2.4 ARM 3.2.5 x86 3.3 Bootstrap 3.4 配置你的VxWorks 3.5 VME 3.6 VxWorks环境 environment 3.6.1 usrSerial.c 3.6.2 prj_vxworks.tcl 3.7 PCI 3.8 网卡 4.文件系统 FAQ 4.1 Dos文件系统 4.2 Flash文件系统 4.3 Floppy-disk文件系统 4.4 RAM-disk文件系统 4.5 基本文件系统问题 5.网络 FAQ 5.1 配置问题 5.2 ARP 5.3 DHCP 5.4 FTP和TFTP 5.5 PPP 5.5.1 PPP on Windows 95 5.5.2 PPP on Windows NT 5.5.3 PPP on Solaris 5.6 Sockets 5.7 Telnet 5.8 SNMP 5.9 其它网络相关问题 6.VxWorks操作系统 FAQ 6.1 C++ issues 6.2 Communication problems 6.3 Interrupts 6.4 LoadModule problems 6.5 pthreads 6.6 Reboot 6.7 Semaphores 6.8 Simulator (VxSim) 6.9 Task related items 6.10 Time/timer related items 6.11 Wind Web Server related items 6.12 Zinc/windML related items 6.13 Other items 6.14 VxWorks AE issues 6.15 I/O 操作 7.其它 FAQ 7.1 Hard delay 7.2 Memory leaks 7.3 Corba engines 7.4 Web servers 7.5 NTP usage 7.6 Performace / Benchmarks 7.7 SNMP 7.8 Lint 7.9 Encryption 7.10 其它 附录A.一些有用的连接 附录B.维护 1.入门FAQ 1.1 概念 1.1.0 什么是VxWorks? A: VxWorks是风河公司为分布式环境设计的具备网络功能的实时操作系统。它可以运行在不同的平台上, 如:MC680x0, MC683xx, Intel i960, Intel i386, R3000, SPARC, Fujitsu SPARClite, and TRON Gmicro 等系统上。它要求采用主机来开发程序,支持的主机有Sun3, Sun4, HP9000, IBM RS-6000, DEC, SGI, 和MIPS等。 它不在目标机上运行开发系统软件如:编译器、连接器、编辑器等。开发环境是基于交叉开发或远程开发 的办法。你需要某种类型的主机如UNIX等来运行编译器和调试器,编译后的代码能下载到目标机上,作为 VxWorks映象的一部分。在开发过程中,独立的目标代码可以动态下载到运行的目标机系统上。最终的 应用程序被写到ROM中。 1.1.1 最近刚开始学习VXWORKS,越看越迷糊: 1)BSP,bootImage,VxWorksImage三者的关系是什么?BSP是BootImage的一部分还是VxWorksImage 的一部 分?对于可以自启动的系统是不是三者合在一起生成一个VxWorks Image? 2)应用程序代码是和VxWorks内核一起编译生成一个VxworksImage吗? 以上问题是针对于代码存放在rom介质上的系统(如flash)。希望各位大侠不吝赐教!谢谢。。。 A:BSP 是用来支持你的硬件的软件, 它包含在你的VxWorksImg里面. 对于ROM启动的系统来说, BootImg是ROM里代码的第一部分, 用来 在开机时首先运行. 如果你的所有代码都在ROM上, 则引导程序把 VxWorksImg拷贝到系统内存, 然后再跳转的系统内存去执行. BSP的作用屏蔽不同的硬件结构(如CPU和外围芯片)向VxWorks的Kernel提供 它所需要的一个统一的接口调用(如时钟) (by 泡泡) bsp: 板级支持包,主要完成目标硬件的初始化工作,提供操作系统一个统一的接口,负责硬件操作, 如中断处理,启动,停止,等工作。Bootimage:引导镜像,我向如果把boot翻译成启动不是很是当的说法, 这是一个引导程序,负责把目标系统环境初始化,最小的程度,如启动了串口,或者网络接口,可以使用这 些接口现在程序,与主机通信,然后获取你需要的OS-vxworksimage vxworksimage-包含vxworks内核以及 各种组件的镜像,也就是object images,这是真正的操作系统,通常bootimage负责获取这个镜像,然后跳 到镜像所在的位置开始执行。(by hongwind ) 1.1.2 如何学习VXWORK,PSOS入门? A:初次上站,感觉大家水平一般,入门级选手较多,实时多任务操作系统和以前大家使用的低端产品,如51 机在原理上是不同的,因此大家最好先学习多任务操作系统的原理。否则无法深入学习。 推荐一本书:坦尼博姆著:《操作系统》,各地都有的卖,主要是讲MINIX的原理,其实就是UNIX系列操作 系统的实现原理,由于VXWORKS和PSOS都是这个系列的操作系统,因此理解了这本书,也就理解了它们的工 作原理。必将事半功倍,而且对你理解WINDOWS的工作原理也很有好处。 (by bruin) 1.1.3 BSP和驱动的关系? A: BSP主要完成硬件和系统的初始化工作: CPU初始化; 总线初始化; 内存控制器初始化; 将代码、数据拷贝到RAM; 中断控制器初始化; 系统时钟初始化; 初始化操作系统; 调用驱动程序初始化函数; 创建设备; Device Driver主要是按照设备模型管理设备,并把自己挂到操作系统的适当模块上(I/O系统,文件系统或 者直接向应用程序提供接口): 块设备驱动:挂到文件系统上; 字符设备:挂到I/O系统上; 串行设备:挂到TTY模块上; 网络设备:挂到网络模块上。 1.1.4 IBM PowerPC 和 Motorola PowerPC有什么不同? A: PowerPC是早期Motorola和IBM联合为Apple的MAC机开发的CPU芯片,IBM PowerPC 和 Motorola PowerPC 的内核都是采用PowerPC,主要用于嵌入式系统。 1.1.5 什么是H.GOMMA原则? A:任务划分原则: 对不同的外设,应划分为不同的任务; 对于突发性事件,应划分为不同优先级的不同任务; 含有大量运算的事件归为一个任务; 存在功能耦合或偶然耦合的事件,划为一个任务; 对于经常重复发生的事件,不同发生频率的事件划分为不同任务。 1.2 环境 1.2.1 斑竹tornado都是支持那些cpu??能列一下吗或哪里能找到 斑竹tornado都是支持那些cpu??能列一下吗或哪里能找到!!! A:开发平台: Windows NT, Sun Solaris, SunOS, HP-UX, Win95 支持处理器: x86, 68k, PPC, CPU 32, i960, SPARC, SPARCLite, SH, ColdFire, R3000, R4000, C16X, ARM, MIPS ... 1.3 编程 1.3.1 vxworks,bsp中有些定义怎么找不到用到的地方,还有些定义找不到在哪里定义过了,比如 MAMR_PTA_SHIFT,哪位大侠给解答一下。不胜感激! A:在h/drv/multi/ppc860Siu.h里。看代码还是用Source Insight (by vxfree) 1.3.2 当文件名为*.C时,TORNADO不能正常编译该文件? A: 把文件名改为*.c后,就可以了。 1.3.3 inline的含义? A:在调用函数的 地方直接嵌入函数的代码,主要用于加快代码执行。gcc中为__inline__ ANSI C中为inline. 2.Tornado工具FAQ 2.1 编译器和链接器 2.1.1 当我把多个目标文件链接成一个时,出现了一个错误: ldppc:built in linker script:43: syntax error 我怎么样才能消除这个错误? A:请确定你的链接器使用了-r参数。 (From: weber.dirk@t-online.de) 2.1.2 我怎样使用新版本的编译器? A:参看如下连接,有一个PPC的编译器 http://www.newgcc4vxworks4ppc.cjb.net/ 2.1.3 当用另一个编译器编译代码时,得到更多的错误和警告,怎样才能让GCC生成更多的警告信息? A:首先用-Wall参数打开所有警告开关;另一种生成更多报告的方法就是把文件看作是C++文件,参数为 -x c++.(From: Claudio Ortega, cortega@sinfomed.org.ar) -Wall不能真正打开所有的警告,我采用由Bruce Evans推荐的参数 而且在FreeBSD环境下,BDECFLAGS变量比较固定。 # BDECFLAGS are a set of gcc warning settings that Bruce Evans has suggested # for use in developing FreeBSD and testing changes. They can be used by # putting "CFLAGS+=${BDECFLAGS}" in /etc/make.conf. -Wconversion is not # included here due to compiler bugs, eg: mkdir()'s mode_t argument. # BDECFLAGS= -W -Wall -ansi -pedantic -Wbad-function-cast -Wcast-align / -Wcast-qual -Wchar-subscripts -Winline / -Wmissing-prototypes -Wnested-externs -Wpointer-arith / -Wredundant-decls -Wshadow -Wstrict-prototypes -Wwrite-strings This set of flags is *much* pickier than -Wall alone. (From: W Gerald Hicks) 2.1.4 当编译我的模块时一切都是好的,但是当我试图下载时得到一个错误:missing symbol "__eabi"? A:在你的模块里可能有个main函数,根据PPC "extended Application Binary Interface" (eabi) 标准,main函数必须调用__eabi函数,该函数为运行你的程序设置必要的运行环境。 由于这个原因GNU编译器在main函数里插入 __eabi函数。 Tornado不提供该函数,因为在实时环境下,你不必写main函数。VxWorks在应用程序运行前已经设置 好运行环境了,不再需要main函数了。 (From: Ilia, iliab@telegate.co.il) 2.1.5 我生成了2.95.2版本的编译器,一切正常,但当我开始链接我的映象时,出现了错误,下面是我 链接ctdt表时的错误: ctdt.o(.data+0x3c):fake: undefined reference to `global constructors keyed to _constructor_name_ ... 许多类似的错误,有谁见过这种错误吗? A: 该问题是由gcc(ver2.7.2-2.95.2)试图改变它得到静态构造函数的方法引起的。它不再对每个构造静 态对象的模块消除函数,该方法是vxworks在编译链接过程中采用的方法。 你可以按如下修改gcc 2.95.2源代码后,恢复原先的操作。 in [source code dir]/gcc/config/arm/vxarm.h, at the very end, add:- /* More DK patches: we undef these two in order to force the */ /* compiler to output our static constructors and destructors */ /* in the fashion to which it is accustomed.... */ #undef ASM_OUTPUT_CONSTRUCTOR #undef ASM_OUTPUT_DESTRUCTOR /* This one is so that GLOBAL_THING gets a $ in it's name */ #undef NO_DOLLAR_IN_LABEL 现在更换到你的编译目录,敲入make clean命令,然后重新编译和安装编译器。我采用这种方法是可以的 ,PPC版本的。它使得编译器使用老的方法来making munchable constructors。 希望对你也有帮助。 (From: Dave Korn) 2.1.6 在我编译时,我在编译窗口看到如下输出: nm386 -g partialImage.o @B:/Sources/Components/Common/Common_Geni_Test/Src/prjObjs.lst | / wtxtcl D:/Tornado/host/src/hutils/munch.tcl -asm 386 > ctdt.c ... cc386 -nostdlib -r -Wl,-X partialImage.o ctdt.o -o VxWorksGeniServerTestExe.out 最后一步(linking partialImage.o to ...out)花了很长时间(半个小时),谁有解决办法? A: 这个可能是munching过程,而不是链接,花了半小时。有人曾贴了一个小窍门来加速。 在munch命令管道里使用"grep GLOBAL"如: nm386 -g partialImage.o @B:/Sources/Components/Common/Common_Geni_Test/Src/prjObjs.lst | grep GLOBAL | / wtxtcl D:/Tornado/host/src/hutils/munch.tcl -asm 386 > ctdt.c (From: Dave Korn) 2.1.7 怎样定义一个没有空洞的结构。 Q: How do define a structure without holes in it? A: 我在vxworks中使用GNU编译器 struct ex { INT8 source; INT32 txSize; INT32 datSize; INT16 cmd; } __attribute__ ((packed)); typedef struct ex PackedStruct; 注意:如果可能,避免使用-fpack-struct编译器开关。我门最近移除了这个选项,使得我们的C++程序提 高了30%-100%的性能。这是因为每次存取结构或类里多字节值时,都是一个一个字节操作的。可以使用 __attribute__ ((packed)) 方法代替。 (From: Mark Fanara, mfanara@home.cNOSPAMMom, and Francisco Pataro, fpataro@dnaent.com) 2.1.8 我怎样在一个C程序文件里调用一个C++函数? A: 如果你想在一个C程序文件里调用一个C++函数,C++函数必须用extern "C"声明;否则编译器将破坏函数 名,把参数类型说明加在函数名末尾,并返回该函数。 (From: Dave Korn) 2.1.9 -fvolatile开关真的需要吗? A: WRS建议我们在编译kernel/BSP时,使用-fvolatile开关。它通常缺省打开某个target/h/make/目录下的 文件。 我们也在我们的应用程序编译过程中使用-fvolatile开关,因为我们参考一些tornado的makefile。 当我们移除该开关后,就碰到一些微妙的BUG,如果你编写驱动程序应当小心。 -fvolatile开关使编译器生成非常conservative的代码。通过指针使变量值增加(p->x++)不可能如你 想象的在一条指令里完成(68k example): addql #1,a0@(8) 如果采用-fvolatile 开关你会得到: movel a0@(8),d0 addql #1,d0 movel d0,a0@(8) movel a0@(8),d0 You can imagine what a C++ application using the "this" pointer everywhere gets compiled into! (From: Chris Varlese, cv@no.mail.net) 2.1.10 我链接了许多档案文件,现在链接器在解析文件之间的交叉参考时出现了问题? A: 试试下面的方法 1、把$(LIBS)替换成$(LD_PARTIAL) -o vxWorks.tmp $(MACH_DEP) usrConfig.o version.o $(LIBS) (在target/h/rules.bsp文件中)。 Now LD_PARTIAL is ccxxx, so you need to specify -Wl, --group-start to get cc to pass the argument to ld. 2、Try adding a -Usymbol for each symbol that has to be pulled in early. 3、如果办法2 make ld行太笨拙,生成一个.s文件,包含每个没定义的符号和加到链接里的。 4、如果你工作UNIX下,它应该可能得到ld生成没有定义的所要求的列表。你需要加一个循环,就象下面一 样: /*这是原文,我翻译不好。 1、$(LIBS) is substituted into: $(LD_PARTIAL) -o vxWorks.tmp $(MACH_DEP) usrConfig.o version.o $(LIBS) (in target/h/rules.bsp for a non-project build). Now LD_PARTIAL is ccxxx, so you need to specify -Wl,--group-start to get cc to pass the argument to ld. 2、Try adding a -Usymbol for each symbol that has to be pulled in early. 3、If (2) make the ld line too unwieldy, generate a .s file that contains: .extern symbol for each undefined symbol and include that into the link before the libraries 4、If your building on unix, it ought to be possible get ld to generate the required list of undefines! You need to add a loop! Something like this might work: */ [ ! -f undefs.s ] && echo "#" >undefs.s while $(CC) -c $(CFLAGS) undefs.s $(LD_PARTIAL) -o vxWorks.tmp $(MACH_DEP) usrConfig.o version.o / undefs.o $(LIBS) $(NM) vxWorks.tmp | grep ' __' | $(MUNCH) > ctdt.c $(MAKE) CC_COMPILER="-fdollars-in-identifiers" ctdt.o do $(LD) $(LDFLAGS) -e $(SYS_ENTRY) $(LD_LOW_FLAGS) -o vxWorks / dataSegPad.o vxWorks.tmp ctdt.o tad_hook_list.o 2>&1 | tee ld.errs | while read file undef ref to symbol do [ "$undef" = "undefined" ] || continue [ "$ref" = "reference" ] || continue [ "$to" = "to" ] || continue oifs="$IFS" IFS="'/`" symbol="`echo $symbol`" IFS="$oifs" echo "/t.extern/t$symbol" done | sort -u - undefs.s >undefs.new cmp -s undefs.s undefs.new && break mv undefs.new undefs.s done cat ld.errs 当然它需要另一系列的ESC和; /在每一行,以使得可以在make下运行。 (我也重新构造了原始的rules.bsp内容,我的可能与vxWorks原来的有些不同。) (From: David Laight, dsl@tadpole.co.uk) 2.1.11 警告"trigraphs occured"是什么意思? A: 对Tornado或Vxoworks没什么要做的。 你可能在你代码(也可能在注释里)中有三字符序列--参看K&R (Kernighan & Ritchie; A12.1 - 这是 ANSI 新引进的。-- 但是GNU手册里提示"You don't want to know about this brain-damage..." 使用-ansi或-trigraphs开关,或更好的办法消除任何包含三字符序列'??X'的注释。 (参看K&R书中对X 的定义)。 (From: Michael.Ben-Ari@ecitele.com) 2.1.12 为什么编译的最后步骤时间这么长? 生成.out步骤如下: 1) 链接应用程序和库到partialImage.o 2) 使用partialImage.o解析出所有静态类(munch) 3) 编译上面发现的(ctdt.o) 4) 用ctdt.o链接第一个obj文件partialImage.o 我们的应用程序.out文件有10M,但是多数是调试信息,size386返回只有1M。 我们的下载文件生成需要超过5分钟,Step #1-3正常需要35秒!但是step #4 需要很多时间,整个过程需 要5分30秒。 A: 我不知道为什么这样?但是我们在step #4不重新使用partialImage.o 而是重新生成它,整个过程45s. (是ld386没有对符号过滤进行优化的原因吗?) 我只是修改了tornado/target/h/make/rules.vxApp文件,它包含制作应用程序的规则。我修改了上面 提到的step $4代码如下: 把$(LD_PARTIAL) $(LD_PARTIAL_LAST_FLAGS) partialImage.o ctdt.o -o $@ 替换成$(LD_PARTIAL) $(PRJ_OBJS_FOR_LD_PARTIAL) $(PRJ_LIBS) ctdt.o -o $@ (From: Ole Asbjorn Fadum, OleAsbjornF@scanmar.no) Some more information. For a variety of reasons I've had to do a few build on a slow system. One bit that seemed exceptionally slow is the 'binToAsm' call (just after the 'deflate' generating vxWorks.Z.s). This is done by od -bv $infile | sed -e "s/^[0-9]*[ ]*//; s/ /, 0/g; /^[0-9a-fA-F][0-9a-fA-F]/s/^/ .byte 0/" (ie use od to generate a list of octal bytes, remove the offset, change the spaces to comma, add the directive - an extra 0 is added to each number to ensure they are octal). The above is terribly slow... Slightly faster (under solaris) is: od -An -v -tu1 $infile | tr ' ' ',' | sed -e 's/,00*/([0-9]/)/,/1/g;s/^,/ .byte /' However it is clear that a C program would be even faster... It was still sluggish using printf, so... char map[256][4]; for (count = 0; count <= 256; count++) sprintf( map[ count ], "%d", count ); for (;;) { count = read( input_fd, buf, BLK_SZ ); if (count <= 0) break; for (off = 0; off < count; off++) { if (off & 15) putchar( ',' ); else fputs( "/n .byte ", stdout ); fputs( map[ buf[ off ] ], stdout ); } } now the system is spending very little of its time doing this bit (it was a lot slower than the deflate!). If you are using gcc/gas you can pipe EXTRACT_BIN, COMPRESS, BINTOASM directly into AS - saving that massive intermediate file... Build (compiling one small object) just took 6m50 - was over 10 minutes before I played with binToAsm! Ages ago I sped up 'munch' - by grepping out most of the symbols it isn't interested in... nmarm vxWorks.tmp | tee vxWorks.nm | grep " __" | munch > ctdt.c (I use the symbol table from this stage for a variety of things...) (From: David Laight, David.Laight@btinternet.com) 2.1.13 怎样把一个段装载到特定的绝对地址? A: 我曾包含一个脚本做这些工作,最方便得到这个脚本的方法是使用--verbose开关运行你的链接器,例 如: "ldarm --verbose". 编辑这个文件加入类似如下的段落, .text 0x8000 : { [omit] . = ALIGN(0x8000); /* Create a 8k section of all 0xffff, first value is jump. */ FILL(0xffff); LONG(0xeb000004); . = ALIGN(0x2000); [...] 这将把数据放到任何你想放的地方,在程序被链接时新的链接器脚本必须使用-T参数。 (From: Bill Pringlemeir, bpringlemeir@yahoo.com) 2.1.14 我在使用C++类型的注释时,出现错误,怎样改变它? A: 一种方法是移除-ansi开关。然而,你可能希望保留你的源代码与ANSI兼容;所以我更喜欢代码能在每 个地方都能编译。传递"-Wp,-lang-c"参数只能使CPP的注释方法可以使用。下面来自预编译器文档 `-lang-c', `-lang-c89', `-lang-c++' `-lang-objc', `-lang-objc++' Specify the source language. `-lang-c' is the default; it allows recognition of C++ comments (comments that begin with `//' and end at end of line), since this is a common feature and it will most likely be in the next C standard. `-lang-c89' disables recognition of C++ comments. `-lang-c++' handles C++ comment syntax and includes extra default include directories for C++. `-lang-objc' enables the Objective C `#import' directive. `-lang-objc++' enables both C++ and Objective C extensions. These options are generated by the compiler driver gcc, but not passed from the `gcc' command line unless you use the driver's `-Wp' option . (From: Bill Pringlemeir, bpringlemeir@yahoo.com) 2.1.15 我在编译时碰到了关于cc1参数/选项的错误? A: 这个可能是由于安装了Cygwin 或DJGPP引起的。当该版本的编译器在路径里先于Tornado版本Cygwin的 GCC被调用时,这个版本不知道这些参数或选项。这个问题可以通过卸载该软件或确定Tornado版本的编译器 在路径环境变量里是头一个后解决。 2.2 调试器 2.2.1 我怎么使用GDB的plain版本去调试我的目标机,而不用Tornado? A:gdb compiles 'out of the box' for vxworks. 去cygnus(sourceware.cygnus.com)下载最新的'insight'软件,该软件是gdb + cygnus的UI(译者:可能是用 户接口)运行 "configure --target=mips-wrs-vxworks". 把mips改成你的处理器,然后运行make. 这样就可以在安装了cygwin的win32平台上运行了,在UNIX系统平台上也类似。 RDB是windriver以前的调试协议,现在变成WDB了。好象没公布wdb的比特,尽管Tornado使用了gdb。你可能 不得不配置RDB。包含RDB组件(INCLUDE_RDB) ,并移除WDB组件(remove INCLUDE_WDB),以使得调试可以进 行。(From: Don Bowman, don@pixstream.com) 2.2.2 我怎么在创建一个任务后停止它,以使得我能从开始对它进行调试? A: 菜单tools->options,选择debugger页,选择always halt after attaching a task和Auto Attach to task -> Always 现在输入一个全局断点(Shift F9),在它碰到断点后,它将从mainTask中分离。 (From: Chacha Hindustani, Gurudev@mediaone.net) 2.2.3 为什么当我使用SHELL检查内存时,看不到断点? A: shell是一个不可中断的任务,所以任何时间它都在运行在无断点的环境。当任务切换引起一个中断的任 务运行时,断点将被重新安装。所以如果查看内存中的断点,只是简单使用d()或l()命令,它在一个中断任 务中可以运行,你将看到一个magic code插入并引起异常。 The shell is an unbreakable task, so all the time it is running the breakpoints are not installed. When a context switch causes a breakable task to run, the breakpoints will be resinstated. So, to see the breakpoint in memory simply spawn the d() command or l() command. That will then run in a breakable task, and you should see the magic code inserted to cause an exception. (From: John, john_94501@yahoo.com) 2.2.100 任务级调试和系统级调试的不同? A:任务调试模式: 1.只能调任务,不能调ISR 2.缺省时,断点仅作用于被Attached的任务 3.当被Attached的任务停下来的时候,其他任务和ISR继续执行 4.Target Server和WDB Agent中的任务模块以中断方式通讯 系统调试模式: 1.能调任务,ISR和初始程序 2.缺省时,断点作用于整个系统 3.当系统停下来时,WDB Agent中的外部模块把中断禁止,所以 调试的只能通过查询的驱动程序通讯。 补充一下: 在使用系统调试模式下时,一旦系统停下来时(不管是由于断点还是人工interrupt debug),所有的任务 都停下来了,此时如果进行查看变量、寄存器等操作,由于此时屏蔽中断了,所以wdb agent用来和target server进行通信的底层driver(如串口的driver或END driver)必须工作在poll mode下。 wdb agent用来和target server进行通信的底层driver都有2种工作模式:poll mode和interrupt-driven mode。当使用系统调试模式时,wdb agent将底层driver切换到(switch to)poll mode,当使用任务调试模 式时,wdb agent将底层driver切换到interrupt-driven mode。 2.3 FTP 参看5.4 2.4 主机工具 2.4.1 我制作了一个基于rom的VxWorks(vxWorks_rom),但是当我试图用elftobin把它转换成bin格式的 (vxworks_rom.bin),得到了如下错误: C:/project/Project3/default/elftobin <vxWorks_rom> vxWorks_rom.bin seg1 : Expected load address 0xfff00100 but file address is 0x00111670 我怎样才能把这个文件转成二进制格式? A: 这个问题只在PPC版本中出现过,问题编号为SPR#8845. 已经有个更新版本的elftobin解决了这个问题。 请联系你的销售代理或服务工程师。 2.4.2 我怎样写一个WTX工具? A: 我曾经在Tornado 1.0.1 和Windows NT 4.0环境下写过一个WTX工具,按下面的例子和Tornado API参考 开始,甚至不用关闭build.让它独自按我的步骤工作。就是我使用VC++6编译,但仍有许多东西丢掉了,不 论编译器是什么版本。我知道我能更熟练的使用路径里的环境变量。但有时你只需要它工作,所以下面澄清 一下: 原代码放在$(WIND_BASE)/host/src/wtxtest下,我的安装目录或任何其它人的安装目录里没有例子源码。 按手册源代码按如下修改(大多是信号处理代码修改和增加includes,其它修改在我的程序里说明) 把下面的设置加到工程设置、 C/C++, Preprocessor: include目录(路径按实际情况修改): C:/Tornado_03/share/src/wtx,C:/Tornado_03/host/include 预处理定义:HOST 把下面的设置加到工程设置,Link,General: C:/Tornado_03/host/x86-win32/lib/wtxapidll-d.lib 增加环境变量WIND_REGISTRY,设为我的注册位置。 许多痛苦就在发现这个。手册里参考wtxEnvironSet()调用,Windsurf说它是不存在的,但手册为这个不存 在的函数使用提供了许多参考。我的机器上没设置WIND_REGISTRY,所有的Tornado工具都可以不使用它而正 常工作。我的工具不能发现注册,设置它并关闭它(Set it and poof)!注册发现了,工具可以工作。 确信起调用了wtxProbe()去检查注册(并且变量被设置),它可以避免许多痛苦。 我也修改那个工具例子代码。代码在此#代码连接#http://www.xs4all.nl/~borkhuis/vxworks/wtxSample.c (From: Christopher A Leddy, caleddy@west.raytheon.com) 2.4.3 当我执行wtxwish时,碰到了一个关于init.tcl文件的错误? A: 不要忘记把TCL_LIBRARY和TK_LIBRARY环境变量设置为 $(WIND_BASE)/host/tcl/tcl and $(WIND_BASE)/host/tcl/tk. init.tcl文件位于TCL_LIBRARY路径。tk.tcl文件位于目录。 不要使用 $(WIND_BASE) 变量,而是实际路径。然后从你的TCL/TK目录执行: wtxwish <yourTclFile> (From: DrDiags, drdiags@flashcom.net) 2.4.4 我试图在windows NT4.0 SP5环境下运行Tornado2.0带的vxsys程序,碰到一个错误: "the system try to access directly to the disk, this is not possible ....." A: vxsys是DOS程序,不能工作windows环境下,你应该从DOS窗口下运行它。 (From: Andray Kaganovsky, andreyk@home.com) 2.4.5 怎样创建加密密码? A: 你可以使用Tornado自带的创建密码程序vxencrypt,但是它功能很弱。 sum( p[i] * i ^ i )) * 0x1e3a1d5将HEX字符集转化成ASCII(假定认为你有超过2^32加密密码)。我能 用钢笔和纸来把它做反变换。 你也可以使用loginEncryptInstall()安装自己的加密算法,对一个强密码[1],加密知道使用密码作为KEY。 UNIX传统使用DES,但需要适当的代码。我使用TEA参看http://vader.brad.ac.uk,因为它是不受妨碍的。 [1] problematical since you have difficulty protecting the password file as none of the vxWorks filesystems support user-ids. (From: David Laight) 2.5 安装 2.5.1 当我试图安装GNU源光盘时,出现了一个关于文件aux.h的错误:permission denied。但该文件并不 存在,是怎么回事? A: 在微软SW环境下存在这个问题,"AUX"是保留字,所以任何以"AUX."开头的都不能存在。任何以设备名 开始的文件名也是不能存在的,例如你不能打开一个叫"LPT1.TXT"的文件。 2.5.2 在我安装完Tornado或它的补丁后,我所有的C文件类型都被移除了,而使用Tornado作为打开该文件 的工具。我怎样能恢复到原来的编辑器? A:Tornado覆盖注册表中的实体。你可以用下面的.reg恢复。 警告:在使用这个文件前必须小心!首先读一下该文件,如果你不理解它就不要使用它。 警告:我在windows95和NT下测试过,如果有时间我会在别的的平台测试的。如果你在98、2000下使用后可 以工作,请告诉我。 首先下载该文件,仔细阅读它,修改它,使她执行你需要的编辑器,然后执行它。你怎么修改它? 一个方法是执行这个文件,然后去浏览器View->Options->File Types.这里你可搜索"C源文件"和"C头文件"。 修改打开命令为你想要的。现在编辑文件c-files.reg,并移除20行后的部分,第一行以 [HKEY_CLASSES_ROOT/c_source_file]开始。再次执行,、将把所有文件类型恢复成你选择的。 另一种方法:在你的文件类型里找到你的确省编辑器,把这行COPY到文件c-files.reg中vim行(BTW:vim 是非常好的编辑器,你可以到http://www.vim.org查询更多信息)。 文件: c-files.reg#文件连接#http://www.xs4all.nl/~borkhuis/vxworks/c-files.reg 2.5.3 当我每次双击一个文件,都打开一个Tornado.我想所有的文件都用一个Tornado打开,怎么做? A:是的,这是可能。下面的注册文件将完成这个工作。 警告:在使用这个文件前必须小心!首先读一下该文件,如果你不理解它就不要使用它。 编辑该文件,修改Tornado的安装路径为你机器上的安装路径。 文件: TornadoFileTypes.reg#文件连接#http://www.xs4all.nl/~borkhuis/vxworks/TornadoFileTypes.reg 2.5.4 能把多个CPU平台安装到一个目录下吗? A:可以,但是需要注意几点: 只能把同一版本的安装到同一目录下。这意味着Tornado 2.0.1 for ARM不能同其它版本安装到同一个目录。 也不能把2.0和2.0.2混合在一起。我发现的唯一不兼容的是MIPS。在安装了idts134 BSP后,下面的文件会 带来问题: 1)host/resource/tcl/wtxcore.tcl 在最后的函数里设置tool为sfgnu替换为gnu.在if结构里增加设置tool为sfgnu.现在只有MIPS这个工具变量 被改变。这样更让人满意,如果你只使用MIPS版本它是可以工作的。 2)host/resource/tcl/app-config/Browser: 在line 138 有个目录为obj...sfgnuvx,对其它CPU来说它是obj...gnuvx. 问题可以通过把这行替换为如 下行解决: This problem can be solved by replacing this line with the follwoing lines: if { $cpuType($cpuId) == "RC32364" } { set name [wtxPath target lib obj$cpuType($cpuId)sfgnuvx]spyLib.o } else { set name [wtxPath target lib obj$cpuType($cpuId)gnuvx]spyLib.o } 然后替换RC32364为你处理器类型的名称。 2.6 MAKEFILE 2.6.1 Make不能发现我自己的INCLUDE目录? A:在C/C++编译选项里,使用-I<dir>选项增加目录,现在在build属性里包含如下内容: 宏名称:VPATH 值:$(filter-out -I.,$(filter -I%,$(CFLAGS))) 在修改了include目录后需要更新编译器选项,VPATH自动被上面规则更新。 在选项改变保存到工作区并确认改变生效后,重新生成依赖关系和开始编译器。 Bob Baker (Bob@dskti.com)曾写过他关于这个问题的经验: 我们在使用Tornado 2编译一个应用程序时碰到了很多问题,如'No rule to make target'。尝试了所有有 用的办法。如:使用":"替代空格作为VPATH的分隔符。使用" :"或": "或" : "改变宏的顺序。"/","/","//" (原文:E.G. using ':' for VPATH separators instead of spaces. Using 'space :' or ': space' or 'space : space', changing the order of the macro's, forward slashes, back slashes, double slashes, pointing the PC screen south at dawn etc the problem turned out to be incompatibility between tornado 2 and win95/98. )证明在Tornado2和WIN95/98上是不兼容的。 简单拷贝包含整个应用和工程的整个目录结构到NT,可以解决问题,并生成一个完整的build。拷贝到另一 个win95和win98上,则建立失败。失败的原因是build过程试图存取一个网络驱动器的共享库文件。我尝试了 所有的在VPATH里的分隔符组合,他们都可以在NT下工作。 2.6.2 为什么make没有在我修改了BSP目录里的文件(比如sysSerial.c)后重新生成我的工程? A: 在Tornado里你能定义不必扫描的include目录。其中缺省的目录之一是BSP目录(target/config)。如果 你从不包含列表里移除它,BSP文件将出现在依赖列表里。在你选择生成依赖关系后选择"高级"按扭,会弹 出一个窗口,包含一个选项"Read-only dependency path"从列表中移除...../target/config。关闭窗口, 重新生成所有的依赖关系。下次BSP文件被修改后就会正确生成了。 (From: gerard.kerkhofs@nicolet.NOSPAM.nl) 另一个解决办法是不要删除该项,但是用...../target/config/comps替换它。现在你得到所有的BSP目录里 的文件,而不是comps目录里的,该目录里放置了许多标准文件。 2.6.3 我怎样在我的工程里生成一个连接器列表(linker list)? A: 在build属性里的缺省连接器命令不被make采用。未了使用额外的连接选项make,把如下内容加入到build 属性里: Macros: Name: LD_PARTIAL_FLAGS_FOR_PARTIALIMAGE Value: -Wl,-Map,$(basename $(notdir $(PRJ_FILE))).link 然后修改$(PROJECT_OUT)文件rules.vxApp里的连结器命令行的LD_PARTIAL: $(LD_PARTIAL) $(LD_PARTIAL_FLAGS_FOR_PARTIALIMAGE) / $(PRJ_OBJS_FOR_LD_PARTIAL) $(PRJ_LIBS) -o partialImage.o 这会在输出目录里生成一个linker输出文件--<Project>.link。在这个文件名字映射为原始.o文件而不是 partialImage.o。如果文件使用最终的连接命令生成,它会生成partialImage.o文件的。 2.6.4 怎样生成C和汇编混合文件? A: 在你makefile文件添加如下规则: %.out: %.o @objdump$(TOOLENV) -S $< < $@ 这 This will generate a file called <file>.out containing C and assembly code. You need to have the -g flag for the compiler to get debug informtion in the output file. This information is needed by objdump. But this is probably not enough. By default VxWorks puts a name in the object file. This name consists of the absolute path of the project directory with the complete path of the file name appended to it. (This can be seen with the command "objdump$(TOOLENV) --debugging <object file>", in the first few lines the filename is given.) This is caused by the fact that the compiler is called with the complete path of the sourcefile. This can be changed to ".." in the Makefile. But the Makefile is generated each time the configuration is changed. To correct this the file prj_vxApp.tcl can be changed to write ".." to the Makefile istead of the complete path. This is done in the function makeGen. The original line in this function is: puts $fd "PRJ_DIR = [file dir [prjInfoGet $hProj fileName]]" This should be changed to: puts $fd "PRJ_DIR = .." (With assistance from Bill Pringlemeir, bpringlemeir@yahoo.com) 2.6.5 怎样把额外的.o文件加入到我的工程里? A: 把文件加到宏EXTRA_MODULES。文件名用空格分开。确定在同一目录有目标文件。它也可能把文件放到你 的源文件目录里。在宏里你应该使用../<object files name>格式。这样做的优点是你能make clean或 rebuild所有文件而没有松散你的目标文件。 2.6.6 我想使用make man在我的BSP里生成额外的文档,但只有sysLib.c的文档被更新了。我把我的文件加 到BSP Makefile里DOC_FILES行? A:在make环境下DOC_FILES变量没被使用。应该做如下改变: 1) 把你的文件和makefile里的文件加到DOC_FILES里,应该类似下面的行: DOC_FILES = sysLib.c sysTffs.c tycoDrv.c myFile.c 2) 修改rules.x86-win32文件包含DOC_FILES变量的使用,修改如下: from: docs: @echo Processing @for %f in (sysLib sysTffs tyCoDrv) do @if exist %f.c @echo %f.c & / $(CPP) $(CASFLAGS) -C $(DOCFLAGS) %f.c > %f.i & / to: docs: @echo Processing @for %f in ($(basename $(DOC_FILES))) do @if exist %f.c @echo %f.c & / $(CPP) $(CASFLAGS) -C $(DOCFLAGS) %f.c > %f.i & / 到现在,我看到该问题只发生在windows平台,unix平台并没有这种情况。 2.6.100 MAKEFIEL文件里的疑问? 有谁知道在$(WIND_BASE)/host/include/make/generic2.mh文件里,[! -d ./$(HOST) ]代码的含义。 请大虾指点。 ..... objdircre: if [! -d ./$(HOST) ]; then / mkdir ./$(HOST); / fi .... 备注: HOST=x86-win32 A:该makefile是在编译tornado的host工具时用到的,这个判断是在cygwin的shell中执行,意思是如果 该目录不存在着创建该目录。注意:tornado的host工具很多是用cygwin的工具编译的,所以其风格是unix 的。 (by bestracer) 2.7 工程 2.7.1 当我修改了usrConfig.c后,我的应用程序并没改变,怎样能把改变编译到应用程序里? A:Tornado 2.0的工程不使用usrConfig.c,它使用配置面板,文件可以在target/config/comps下发现,如 果你喜欢用usrConfig.c,make target/config/yourBsp目录下的 Makefile文件,就可以了。 (From: Roie Geron, roie@ecitele.com) 2.7.2 怎样不用Tornado重新生成工程文件? A: 使用如下命令重新生成那些bootable工程文件: wtxtcl <Tornado base>/host/src/hutils/configGen.tcl <Project>.wpj 这个命令也可以被Tornado使用。当配置改变时,这个命令可以作为build的第一个执行命令。 对downloadable工程,没有标准命令。一个修改过的configGen也可以被使用,文件名为makeGen.tcl (连接#http://www.xs4all.nl/~borkhuis/vxworks/makeGen.tcl#),把这个文件拷贝到../host/src/hutils 目录。Makefile文件可用如下命令生成: wtxtcl <Tornado base>/host/src/hutils/makeGen.tcl <Project>.wpj 请确认你使用了<Project>.wpj的完整路径。 2.7.3 当我生成依赖关系时,一些依赖关系丢失了。它们不在Tornado树中,但include目录用-I包含和使用 VPATH宏? A:我们以前也碰到同样的问题,你可以把#include "xxx/xxx/xxx.h"改成#include "xxx/xxx/xxx.h", 然后在试试。(From: ellin_lin@263.net) 2.8 目标机服务器 2.8.1 怎样不用Tornado启动target server? A:首先创建一个DOS窗口的快捷方式,然后在Tornado里配置你的target server,使得它能正常启动,并把 配置窗口里的配置文本拷贝到DOS快捷方式的属性里。即可。 (From: John Finley, john@kivala.com) 2.8.2 我的程序正常装载需要几秒钟,但现在装载一个小的应用程序却需要很长时间。我怎样加速下载过程? A:增加你target server的Cache容量,缺省是1M,增加容量将减少下载时间。 (From: Wade Oram, oram_w_t@ifrinternational.co.uk) 2.8.3 当我启动target server时,碰到WTX错误,告诉同步停止,我怎么修正它? A:一个解决问题的办法是使用远程registry,即使你在你本机上运行target server,这可以通过使用真实IP 设置远程registry解决。 基本上"localhost"得到存储在Windows registry中的运行registry的机器名。主机上的WTX工具把 localhost解析成127.0.0.1,并把它传给目标机,然后目标机尝试与127.0.0.1通信,以便符号表的同步和结 束只与自己联系而不与主机联系。很好的特性。 如果你的Windows主机有多个网口,并且目标机连在一个次要接口上,这还不足够。机器名被解析成IP地 址,否则目标机不知道。在连接目标机进行符号表同步前,你需要在目标机上使用routeNetAdd命令。 (From: Markus Mitterer, markus.mitterer@sbu1.storkgroup.com and lori@rti.com) 2.8.4 当我在SHELL里输入一个命令时,出现"The target system is not initialized yet. Can't roceed." A:当你在目标机配置项里的"Core filea"指定一个"vxWorks"文件作为核心文件(core file),该问题将解决。 我指定了"vxWorks_rom"文件,并选择了"synchronize host/target symbol table"项,它工作的很好。 2.9 Target Shell 2.9.1 当我从我的工程里移除shell组件时,我碰到一个dosFsDevInit执行错误,怎样能不包含shell而包含 DOSFS组件? A:首先它看起来可能是wierd,后来我想起来老的dosFsLib使用在RAM中的文件名数据库(使用HASH表), 所以如果你移除任何可能连接到hashLib中的符号表,就可能不能初始化。 一个可能的原因就是没有人注意到它,因为通常都包含 INCLUDE_STAT_SYM_TBL (也是一种符号表)。所以 你应该增加 INCLUDE_STAT_SYM_TBL 或简单的在dosFsInit前调用hashLibInit() 。 (From: Leonid Rosenboim, leonid@bitband.com) 2.9.2 在启动windshell时,一般是通过执行 windsh.tcl来实现的,我在.wind目录下创建了这个文件,但它 没执行,我什么地方做错了? A:没有,这是windshell的一个bug,它不去搜索Tornado的安装目录,只搜索C:上的,所以你应该把你的 windsh.tcl移动到c:/.wind目录下,它将执行。 2.9.3 当我ping 我的"myHost"时,shell好象丢掉许多内存,为什么? A:目标机上的shell为字符串分配内存(字符串的地址被传送给函数)。shell不能决定何时可以安全的释放 内存,所以它就把它留在那里,那块内存也不能重新使用。所以下次ping的时候,它又会分配内存。 你可以试试使用一个变量: pingaddress = "myHost" memShow ping pingaddress memShow (From: Urban Lindberg, urbanl@my-deja.com) 2.9.4 怎样重复使用一个不断增加的参数的命令? A:你可以写一个扩展的重复命令。在/target/src/usr/usrLib.c 文件里有repeat的源码,应该是很简单的。 (From: Werner Schiendl,ws-news@gmx.at) 2.9.5 怎样使用"lkup"列出2个字符的符号? A:lkup "^[a-z][a-z]$",如果需要3个或更多,lkup "^[a-z][a-z][a-z]$" (From: p_lavarre@my-deja.com) 2.9.6 怎样增加SHELL的最大行长(128字符)? A:我也碰到同样的问题,我把一些更长的字符串放到变量里,然后在命令行里使用该命令,这样可以突破 128个字符。可能通过设置环境变量也可以实现,但第一个方法更简单。 (From: Don Small, dmsmall@sandia.gov) 2.9.7 怎样能让我的程序去SHELL正在使用的端口上读数据? A:我发现不用SHELL接口,扫描用户输入。唯一的方法是先删除SHELL任务,然后读数据,再重新生成SHELL。 /*******************************************************/ shelltid = taskNameToId("tShell"); taskDelete(shelltid); for( ; ; ) { // read } shellInit(0,TRUE); /*******************************************************/ (From: Mridul Gupta, mridulgupta1@yahoo.com) 2.9.8 有shell的替换程序吗? A:在如下地址http://www.xmission.com/~bgeer/bgsh.html: BGSH: A VxWorks Shell With Command Line Editing. 可以发现。 (From: Pekka Taipale, pjt@iki.fi) 2.9.9 怎样能在我的程序中执行SHELL命令,并使用它的输出? A:我写了一个函数来实现该功能,它把命令作为字符串,并把执行结果输出到文件里。 -> shellToFile("ifShow","ifShow.out") 你可以按你的需求修改它。 // // // This function runs a shell command and captures the output to the // specified file // extern int consoleFd; typedef unsigned int (*UINTFUNCPTR) (); extern "C" int shellToFile(char * shellCmd, char * outputFile) { int rtn; int STDFd; int outFileFd; outFileFd = creat( outputFile, O_RDWR); printf("creat returned %x as a file desc/n",outFileFd); if (outFileFd != -1) { STDFd=ioGlobalStdGet(STD_OUT); ioGlobalStdSet(STD_OUT,outFileFd); rtn=execute(shellCmd); if (rtn !=0) printf("execute returned %d /n",outFileFd); ioGlobalStdSet(STD_OUT,STDFd); } close(outFileFd); return (rtn); } (From: RonnoBonno, RHNAssociates@yahoo.com) 2.9.10 怎样检查静态变量? A:在映象上执行nmxyz,并提出变量地址,你可以随后导出它的内容。 #> nmppc vxWorks | grep ftpsActive 0023dc60 d ftpsActive (From: Toni Kurzberger, gonozal@gmx.at) 2.9.100为什么在主程序里的printf语句输出到shell下,而在任务里prinf语句却输出到vxworks simulator里? A:在任务里标准输入输出是重定向到SIMULATOR里的。(by wys 2002/4/27) 2.10 Telnet 参看5.7 2.11 Tornado 2.11.1 怎样重定向虚拟控制台到文件里? A:以下是由Dave Gurak dmgd@eci-esyst.com写的文章, 我使用ioGlobalStdSet成功的重定向IO到虚拟控制台,然而由于NT平台的tgtsvr无法重定向到文件里, (ala Unix xterm)... 当我意识到windsh是个tcl解释器,/vio/1回应windsh,我发现一个解决方案。我所做的只是把windsh中 VIO_WRITE_Handler {event}的定义写到一个文件里,通过把"memBlockWriteFile $mblk -" 改成 "memBlockWriteFile -append $mblk log.txt" 这里是我的windsh.tcl(http://www.xs4all.nl/~borkhuis/vxworks/windsh.tcl),希望能有用。 2.11.2 怎样重定向标准IO到另外的设备上? A;Aaron Kunze提供了一些重定向标准IO的例子, http://www.xs4all.nl/~borkhuis/vxworks/stdio_rd.c 2.11.3 怎样在主机的SHELL下重复有一个参数不断增加的命令? A:你可以使用TCL解释器,在SHELL下输入?进入TCL模式。如下: -> ? tcl> for {set x 0} {$x<100} {incr x} { tcl> shParse "dumpBlock $x" tcl> } tcl> ? -> ... ?可以在TCL和C模式间切换。 (From: Markku Kotiaho kotiaho@m_a_i_l.com) 2.11.4 我试图报告一个TSR(附带一个文件),TSR发送工具出错? A:技术支持请求工具(Support Request tool)的MAPI在发送有附件的邮件时有问题,如果可能,尽可能用 SMTP接口发送。 2.11.5 WINDOWS下的调试器突然消失,当我按下工具按钮或从菜单下选择调试,但什么也没发生? A:WINDOWS可能丢屏(off-screen),把它重新显示在屏幕上的一个办法就是用程序给窗口发送一个 "Move Window"的命令,一个粗鲁的办法就是使用如下程序(我曾用它把不同的WINDOWS重新显示在屏幕上) /* (C) Johan Borkhuis, 1999 */ #include <wtypes.h> #include <winuser.h> void main(void) { MoveWindow((HWND)0x194, 10,10, 94, 88, TRUE); } The parameters to MoveWindow are: 1)Window Handle: Fill in the right window handle. This can be obtained by (for example) Spy++, which is shipped with Microsoft Visual C++. 2)X and Y coordinate where the window has to be moved to. 3)X and Y size of the window. These should be the same as the size of the original window. These parameters can also be obtained from Spy++. 4)Boolean indicating that the window should be redrawn. 2.11.6 当我在build时,build在某处被停止(比如在执行命令vxrm时)? A:答案是禁止你的防病毒软件,很多已知问题是由Macaffee引起的,当我禁止了我的Norton和voila,我 又可以build了。 有意思的是,我运行和build很长时间,突然它停止了,我的同学也是这样。我不知道是什么问题引起的 可能与工程的大小有关。 查看TSR 159521 (From: mchug06@attglobal.net) 2.11.7 当我在win2000下build的时候好象出错了,但我在WIN9X和NT下工作的很好? 注意: WindRiver有个补丁查看http://www.wrs.com/csdocs/kplocator/patchList.shtml得到更详细的信息。 A:在WIN2000下安装resource kit,它有一个应用兼容工具(Application Compatibility tool)。你可以 用它告诉TORNADO,当前运行在NT环境下。它位于win2k CD的support目录.你要运行apcompat.exe,让它告诉 TORNADO运行于NT环境。选择"Make the abov check box settings permanent"项。 更多关于应用兼容工具的信息查看Microsoft's online knowledge base 的Q251062文章。 另一个解决办法是使用IP地址而不是使用主机名进行远程注册。(参看问题2.8.3). (From: Niall Leonard (niall@exchange.Scotland.ncr.com), Kirk Davies (kirk.davies@pobox.com), Arik Halperin (arikh@hlan.com) and Adam) 2.11.100 如何在TORNADO环境里添加按扭? A:编写完类似如下的TCL文件后,把相关文件都放到(ENV)/.wind/目录下,从新启动TORNADO即可。 # crosswind.tcl - user customization file for CrossWind controlCreate crosswindTB / [list toolbarbutton -name cwToggleBrkPt -separator -tooltip "Toggle Global Breakpoint" / -cmduicallback "onCmdUIDebugItem toggleBrkpt" -callback "onToggleBreakpoint 1 gbreak" / -bitmap [format "%s/.wind/%s" h:/tornado toggleGBreak.bmp]] 2.11.101 如何把文件编译成库形式? A:做一个download的project,在Builds的Rules里选择archive 再编译即生成.a的库文件。 2.12 版本控制 2.12.1 Q: After I check out a project no files are shown in the workspace window. A: The project files (.wpj and .wsp) should be saved in "Unix"-style with only LF characters. Some version control systems (VSS for example) convert text files to DOS text files, with CR/LF. In VSS the project files and workspace files should be marked as binary. This can be done when clicking in the files, or by adding *.wpj and *.wsp to the list of binary files in the Tools->Options->FileTypes screen. Another solution is to modify the TCL files that read and generate the project files. Within these file there is a command to set the mode to 'LF'-only. The command to do this is 'fconfigure'. In several files in the directory tornado/host/resource/tcp/app-config/Project the line: fconfigure $fd -translation lf appears. This line can be deleted (ot turned in to commentary by adding a hash sign at the start of the line). Then all project files will be saved in DOS file format and will also be read in DOS files format. This line appears in the following files: gnuInfoGen.tcl (1 time) prjLib.tcl (4 times) prj_vxApp.tcl (1 time) prj_vxWorks.tcl (4 times) (From: Stas Maximov, stmax@pigeonpoint.com) 2.12.2 是否应该把Tornado整个目录都使用版本控制? A:我认为把target目录作为一个整体是个好注意, The biggest advantage is, that service packs and patches are propagated automatically to other team members and _even_more_important_ to the build machine. An other advantage is, that if you need to debug something in an old version, you have the correct header files and libraries. WARNING: If you check in the library files of VxWorks (which we did, for the reasons mentioned) - do not forget to check them out _before_ installing an add on package like WindWeb Server. Otherwise the installer will SILENTLY fail to update your libraries :-) From: Werner Schiendl, ws-news@gmx.at) 2.13 Visual Studio集成 2.13.1 能把Visual Studio做为编辑器集成到T2中吗?(Tools --> options --> External Editor),怎样 管理它? A: 我们使用Visual studio IDE来编译vxworks程序,特别在Tornado中丢失的浏览信息。 在msdev工程设置里把nmake改成make,设定当前浏览文件名和输出文件名(../bin/sys.bsc resp. ../bin/sys.out),并在rebuild所有项里添加rebuild。把所需的目录和文件添加到你的msdev的工作区。 在tools->options菜单里添加你的include目录和tornado执行目录,并把它们放到列表首位。 警告: 我不得不用3.02版本的sed.exe替换Tornado中的2.05版本。msdev's的编译器(6.0)不认识某些头文件里的 "long long int"类型,我在regsI86.h做了一些改变。 #ifdef _MSC_VER __int64 base; __int64 mask; #else long long int base; long long int mask; #endif 并按你的需求调整Makefile(http://www.xs4all.nl/~borkhuis/vxworks/Makefile),例如用cpp代替c. Gerald van Kampen (kam@oce.nl): 2.13.2 Visual Studio不把filetype .cc类型的文件认做C文件,怎样能告诉Visual Studio这种文件也是C 文件?以便"source browser"和"class view"能识别它。 A:缺省,CPP和C文件自动被MS编译器识别,如果让编译器识别别的类型的文件,使用/Tp或/tp选项声明该 类型文件也是CPP文件。我认为/Tc选项声明该类型文件是C文件。 (From: Don Wade, donwade@nortelnetworks.com) 2.13.3 当使用Visual Studio作为开发环境时,Visual Studio不能识别GNU编译器的输出? A:使用如下程序过滤GNU编译器的输出,文件为gnu2msdev.cpp (http://www.xs4all.nl/~borkhuis/vxworks/gnu2msdev.cpp)编译该文件的规则如下,可执行文件为 gnu2msdev.exe(http://www.xs4all.nl/~borkhuis/vxworks/gnu2msdev.exe) %.o : %.cpp -$(CXX) $(C++FLAGS) $(ADD_FLAGS) -c $< -o $(@F) 2> $(TMP)/ccerr.txt @type $(TMP)/ccerr.txt | gnu2msdev (From: f.pertin@staubli.com) 2.14 Windsh 2.14.1 怎样给winshe创建一个启动文件? A:在%HOME%/.wind目录下创建一个windsh.tcl文件,如果变量%HOME%不存在,在你的启动文件里创建它。 一个可能就是使用Tornado目录下的.wind目录或你工程目录下的一个目录。为了避免把工程的特别项放到 Tornado目录树里,在windsh.tcl文件里,你应该在开始执行如下命令。 例如:cd "whatever directory" 请确定目录使用的是"/"而不是"/"。 (From: Mike Beede, mbeede@ciprico.com) 2.14.2 当我在windsh调用一个有浮点参数的函数时出现参数引用错误? A:shell缺省每个变量都是整型,你可以声明你的参数为浮点型,就好了。如: foo((float) 20.01) (From: ywu@imatron.com) 2.14.3 怎样改变命令提示符? A:执行如下命令: shellPromptSet "VxWorks command prompt .... " 2.14.4 怎样从主机SHELL下得到目标机上的目录显示? A:在命令前加"@",它将在目标机端执行,而不是在主机端。所以命令'@ls'显示当前目标机的目录。等等。 甚至还可以使用主机SHELL下没有的命令。 2.14.5 当我试图执行一个函数时出现"undefined symbol"错误,执行过程如下: -> ld <router value = 134204756 = 0x7ffcd54 = bgpNode + 0x310 -> sp ace_main undefined symbol: ace_main -> lkup "ace_main" ace_main(unsigned int) 0x07cbd934 text (router) global constructors keyed to ace_main(unsigned int) 0x07cc0c80 text (router) global destructors keyed to ace_main(unsigned int) 0x07cc0c48 text (router) value = 0 = 0x0 A:一个可能是你的ace_main是一个munged C++符号,如果它在CPP文件里编译的,改成C类型的(extern "C") 尝试按如下例子来解决问题: extern "C" int ace_main(unsigned int) { ... code here... } 再重新编译、连接。 (From: ddewar@my-deja.com) 另一个解决办法是,执行sp ace_main,并在你按下回车键前,按下Ctrl+D把签名加到mangled C++名字末尾。 (From: Dave Korn) 2.15 WindView 2.15.1 当我使用WindView查看时间时,有时它好象定时器中断一样花了很多时间,是什么引起的? A:WindView这个错误已经被WindRiver公司修正了。 (From: Anthony D. Truong, AnthonyDTruong@email.msn.com) 2.15.2 怎样创建WindView用户事件? A:WindView 2.0.1的用户手册关于用户事件的说明是错误的,经过实践,下面的方法可以工作的很好。 首先,函数/过程必须象如下格式出现在eventbase.tcl文件里 proc userFormat00060 eventData { } 你的例子显示你的用户事件是包含两个整数的结构。一种把它们格式化的方法如下: proc userFormat00060 eventData { set data1 [string range $eventData 0 7] set data2 [string range $eventData 8 15] return [format "int1 is %s/r/n int2 is: %s" $data1 $data2] } 另一种如下: proc userFormat00060 eventData { set data [userEventFormat $eventData {n4 n4}] set data1 [lindex $data 0] set data2 [lindex $data 1] return "int1 = $data1, int2 = $data" } 如果你的主机和目标机字节序不同,你应该转换数据。你可以仔细查看TORNADO目录下的TCL文件,以便得到 更多信息。 (From: Lori Fraleigh, lori@rti.com) 2.15.2 怎样把raw hex格式的数据改成缺省数据格式? A:如下信息可能有帮助,http://www.xs4all.nl/~borkhuis/vxworks/windview.html (From: DrDiags, drdiags@covad.net) 2.15.3 任务在WindView中被列出几次? A:如果你使用过去的mortem模式,这个问题是已知的。缓存在被填满前被upload,并开始循环。WRS告诉我们 的解决办法是右击每个第二个显示,并隐藏它。 (From: Tim Shaw, Tim.Shaw@dsto.defence.gov.au) 3.BSP FAQ 3.1 不同BSP 3.2 处理器 3.2.1 Power PC 3.2.1.1 问题关于MPC860BSP(新手上路):在读前辈程序的时候遇到这样一些语句: lis r3, 0x0090 ori r3, r3, 0x0000 #plp=9, 50M clk stw r3, PLPRCR(r4) #PLPRCR 不知道LIS、ORI、STW是什么语言?望指教!谢谢 A:是PowerPC汇编, lis r3, 0x0090 ;放数据0x0090到r3 Rejoicer:应该将立即数附给r3,然后左移位,注意,低位就为0 ori r3, r3, 0x0000 #plp=9, 50M clk ;后两数之间取"或"放入前面r3 Rejoicer:r3低位或0x00(立即数) stw r3, PLPRCR(r4) #PLPRCR ;PLPRCR(r4)按位右移#PLPRCR,放入r3 Rejoicer: 将r3的内容写到 地址 r4 + PLPRCR 指向的寄存器(PLPRCR寄存器)中,(估计r4放的IMMR值) 3.2.1.2 如果要在mpc860上加一个硬盘,用什么方法呢? 谢谢! A:你加一个网络文件系统,然后通过网络文件系统可以访问你机器的硬盘 3.2.1.3 mpc860在下载中遇到的问题,我用veisionice仿真器下载程序的时候,发现程序老是下不下去。 在检查中,我发现CLKOUT只有1。25M。我用的是外围5M晶体振荡器,MODCK [1-2] 设置为10。[MF+1]为8。 我的主频是40M。应当说在没有程序运行的情况下,CLKOUT应该为5M。这是怎么回事?请大家指教。 A:clkout的输出(输入CLK的分频系数)也是通过860的一个寄存器配置来得到的,你可以查一下860的相关 的寄存器看一下。 3.2.1.4 860中的程序调用,在860的BSP文件 romInit.s中,在程序末尾有条指令是跳转到 romStart(), 在这之前有个计算 romstart() 入口地址的公式. romstart入口地址= romstart - romInit + ROM_TEXT_ADRS 我对这个公式的理解不是很明白,谁能解释一下,在汇编里调用某个C函数,那该怎么来实现或/ 计算跳转地址.单独在一个汇编程序里,我可以理解,但一个汇编调用一个C程序我糊涂了 who can help me ? thanks A:可以这样理解ROM_TEXT_ADRS=romInit,这样则romstart=romstart,上述些方式为了防止ROM_TEXT_ADRS 不等于romInit情况下,还能得到正确的romstart地址. 这里不涉及C程序还是汇编程序.只是传了一个 地址.romstart已在前面声明为一个外部函数. 原标号只是相对地址,不信你自己跟一下,或查看一下生成 的bootrom.bin文件,分析一下机器码你所提到的三个地址:romInit,romStart,ROM_TEXT_ADRS,其实只有 第三个是绝对地址,前两个都只是标号,也即相对地址.在romIinit.s中由于取指令还得从NVRAM中取, 所以必须用绝对地址,那么romStart的绝对地址在哪里呢?只有算一算了,我们只知道romInit肯定是在 ROM_TEXT_ADRS所标识的地址,而且肯定是bootRom目标程序中的最低地址,所以romStart的绝对地址是 (romStart - romInit) + ROM_TEXT_ADRS 3.2.1.5 vxworks下,是否有api可以获取网卡mac地址呢? A1:如果是MPC860,可以试一下这个函数 char macBuffer[8]; // MAC地址 sysCpmEnetAddrGet(0, macBuffer); 或直接读网卡MAC地址的寄存器. A2:为什么一定要用api呢, 不管是860 scc 口,还是8260 Fcc口,都可以读参数区的PADDR1_H,-M -L得到嘛, 如果你是做BSP的,一般都会从利用这个变量unsigned char sysFccEnetAddr [6] syslib.c A3:vxworks操作系统是通过BSP来了解自己的网口地址的,具体说是通过系统函数sysCpmEnetAddrGet(), 这个函数属于BSP的范畴,它的函数实现是可以修改的。 3.2.2 I960 在GNU中是否有编译选项或其它编译方法,针对i960实现字节对齐的工程?我使用如下编译开关 -mno-code-align, -mno-strict-align, 但是没用? A: 我有类似的问题,我花了很多时间来解决问题,这个文档可能对你有帮助。 http://www.xs4all.nl/~borkhuis/vxworks/i960struct.html (From: Fred Roeber, froeber@bbn.com) 3.2.3 MIPS 当我编译时,我碰到碰到许多 "... uses different e_flags ..." 消息,这些消息是什么意思? A: 来自Windriver的解释 (From: Xjasartist@yahoo.com) The message "uses different e_flags ... fields than previous modules ..." can occur for MIPS and PowerPC architectures. It should not cause any problems for MIPS processors most of the time. If you look in the release notes for your MIPS BSP, you may find a comment something like: There are several types of warnings generated by compiler. These are harmless. During compilation of vxWorks image: uses different e_flags (0x0) fields than previous modules (0x10000001) For the case of MIPS, what's happening is that each ELF object module keeps track of which OMF affecting flags were used or specified anywhere in the original source file. Inside the linker, there is a function which copies the appropriate flags from the original object module to the one which is being created. For MIPS, the function is mips_elf_merge_private_bfd_data(). If two different files have different sets of flags, this might be a sign of a problem, so when the compiler finds this condition it prints the warning message above. Usually when this error message comes up with MIPS, it is from one of two different flags. First is 0x1, which specifies that somewhere in the code a .noreorder directive was given. For MIPS, the name of this flag is EF_MIPS_NOREORDER. There should not be any problems related to this flag differing between the original object modules and the final module. Second is 0x10000000, which is E_MIPS_ARCH_2. What this means is that some modules were compiled to use the ARCH 2 functionality. When you are using an ARCH 2 or ARCH 3 processor, this should also not be a problem. The MIPS specific flags are: /* Processor specific flags for the ELF header e_flags field. */ /* At least one .noreorder directive appears in the source. */ #define EF_MIPS_NOREORDER 0x00000001 /* File contains position independent code. */ #define EF_MIPS_PIC 0x00000002 /* Code in file uses the standard calling sequence for calling position independent code. */ #define EF_MIPS_CPIC 0x00000004 /* Four bit MIPS architecture field. */ #define EF_MIPS_ARCH 0xf0000000 /* -mips1 code. */ #define E_MIPS_ARCH_1 0x00000000 /* -mips2 code. */ #define E_MIPS_ARCH_2 0x10000000 /* -mips3 code. */ #define E_MIPS_ARCH_3 0x20000000 In case you have the GNU source and want to find out more about this from there, this can be found in the file .../include/elf/mips.h below the top level GNU source directory. For PowerPC, the same error message may come up from the function ppc_elf_merge_private_bfd_data(). If this happens then the basic cause of the problem is the same as for MIPS, namely that the ELF output e_flags are different from the input flags. However, at this time our records do not contain indications about the differences in e_flags which actually occur, or even indications that this condition has ever occurred for PowerPC at all. Also, the PPC processor specific flags do not give any indication of similar conditions to the NOREORDER condition mentioned for MIPS above. If you find this error message when using PowerPC, please contact Wind River support. 3.2.4 ARM 3.2.4.1 我碰到如下错误:"unresolved symbol ___fixunsdfsi".但我从没有使用过这个符号? A: ___fixunsdfsi转换double为unsigned int类型。因为某些原因, ___fixunsdfsi和___fixunssfsi (single to uint)都不在vxworks映象中。下面的汇编可能可以实现工作。(没有测试)。 #define SGN_BIT 0x80000000 /* sign bit */ #define MNT_SZ 20 /* mantissa bits in first word */ ___fixunsdfsi: movs r12,r0,asr #MNT_SZ /* get sign and exponent */ movmi r12,#0 /* convert -ve to zero */ /* extract top 32 bits of mantissa */ mov r0,r0,lsl #31 - MNT_SZ mov r1,r1,lsr #MNT_SZ + 1 orr r0,r0,r1 orr r0,r0,#SGN_BIT /* add hidden bit */ sub r12,r12,#0x400 rsbs r12,r12,#0x1e /* unbiassed and negated */ bmi 10$ mov r0,r0,lsr r12 mov pc,lr 10$: /* overflow */ mvn r0,#0 mov pc,lr 我写上述代码是作为测试strongArm系统中FP程序性能测试的一部分,但这个子程序没有用。可能有几种 方法要比由gnu C FP库生成的代码要少的多。 (From: David Laight, dsl@tadpole.co.uk) 3.2.4.2 在StrongARM上实现PCMCIA的信息? A: Implementing the pcmcia on the SA1110/SA1111 is painful to say the least. We have that hardware combination with 2 pcmcia sockets. PCIC.C/TCIC.c are the driver files, you need to write a similar file for the SA-1111. This is the hardware specific file. I found the pcic and tcic to be much more complicated than the SA- 1111, so my driver file was simpler. Once the driver is implemented and working then you define an pcmcia adapter for the card, which references the functions in your driver. pcmciaLib.c, cisLib.c, pccardLib.c these are the higher level functions for the pcmcia, they had to be modified in various places to accomodate the hardware. I ended up making a local copy of all the files to work on. Here are some of the issues encountered. I don't know if you'll have the same problems or not. BTW, this is just a high level pass at the information, the devil is in the details. VXWORKS implementation assumes a PC architecture. They assume both pcmcia slots used the same address space. I had to modify cislib.c (and problaby another file). So that it would reference the right address space for the socket. Interrupts. The SA1111 uses edge interrupts therefore it detects inserts (rising edge) or removals (falling edge or vice versa). I had to add a polling routing to reliably detect the card insert. SA1111 bug. We're using ATA cards. We found a problem where the Card does not handle 8 bit reads at odd addresses. I had to use a 16 bit read and mask off the appropriate bit. This causes a problem because the ATA spec. has data that is only valid with an 8-bit odd read. This is just the tip of the iceberg but I hope it gets you started. I'm still struggling with getting it to work smoothly and reliable. I found the book "PCMCIA Developer's guide" to be useful. (From: Ann Davis, adavis@lightchip.com) 3.2.5 x86 3.2.5.1 请问在Vxworks for x86下怎么读取BIOS的信息,请教各位大侠, 在Vxworks for x86下怎么读取目标机BIOS的信息?我现在想得到目标机的工作状态, 如目标机CPU的温度,以及风扇的转速,看门狗等。我采用的目标机是ADLINK公司的NuPP0-760, 在系统启动时,加入BIOS可以看到这些信息,但是请问我如何在我自己编写的程序中动态得到这些参数值? 多谢各位大侠了!! A:似乎比较困难。 关键是BIOS运行在实模式下,而VxWorks运行在保护模式下;并且VxWorks起来后,BIOS就不存在了。 另外我们买主板的时候,似乎都不带什么主板编程手册之类的东西,否则直接读写主板上的寄存器应该就 可以了。(by vxfree) 我曾经用sysinbyte()和sysoutbyte()读BIOS中的内容,用0X70和0X71,相关的地址你可以参考硬件手册. (by dongdd) 3.3 Bootstrap 3.3.1 怎样改变启动中记数值? A: 修改在bootConfig.c文件里定义的TIMEOUT值为你所要的,重新编译bootstrap,并装载它到目标机上。 3.3.2 怎样在没有串口连接到目标机上情况下,启动时改变启动参数? A: 通过telnet或rlogin在target shell或host shell下使用命令"bootChange" 。 (From: Pete Kockritz (petekz@my-deja.com) 3.4 配置你的VxWorks 3.5 VME 3.6 VxWorks环境 environment 3.6.1 usrSerial.c 当我定义超过10个串口时,我只能发现10个串口? A:在usrSerial.c文件里有个错误,在itos函数里,应该把如下行 val = val - (val %= 10); 改为 val = (val - (val % 10))/10; 3.6.2 prj_vxworks.tcl 当我创建一个bootable工程时,vxworks的所有组件都标明"not installed",我怎样解决它? A:这是由你定义在BSP Makefile文件的额外库(LIB_EXTRA = ...)引起的。该工程只由第一个库生成,并查找 BSP所需要的的目标文件。 可能能改变它。工程由prj_vxWorks.tcl生成。该文件在host/resource/tcl/app-config-Project目录下 把该文件按如下修改: *** prj_vxWorks.tcl-old Mon Jan 24 12:08:26 2000 --- prj_vxWorks.tcl Mon Aug 7 14:33:51 2000 *** 895,905 **** set wcc [file tail $bspDir] wccCreate $hProj $wcc wccCdfPathSet $hProj $cdfPath foreach lib [bspMakeGet LIBS] { ! if {[string match *lib[bspMakeGet CPU]*.a $lib]} { ! set mxrLibs [file tail $lib] ! break ! } } if {![info exists mxrLibs]} { set mxrLibs lib[bspMakeGet CPU][bspMakeGet TOOL]vx.a --- 895,905 ---- set wcc [file tail $bspDir] wccCreate $hProj $wcc wccCdfPathSet $hProj $cdfPath + set mxrLibs "" foreach lib [bspMakeGet LIBS] { ! if {[string match *lib[bspMakeGet CPU]*.a $lib]} { ! lappend mxrLibs [file tail $lib] ! } } if {![info exists mxrLibs]} { set mxrLibs lib[bspMakeGet CPU][bspMakeGet TOOL]vx.a 3.7 PCI 3.7.100 关于PCIPCI总线上的设备怎么查找?是用pciFindDevice()函数吗?如何映射PCI内存?如何读 PCI设备内存中的内容?谢谢 A:使用pciFindDevice查找设备;使用pciConfigInByte/Word/Long, pciConfigOutByte/Word/Long读写配置 空间;修改sysLib.c::sysPhysMemDesc[]映射地址空间;使用pciIntConnect连接PCI中断(也可以使 用intConnect)。 3.8 网卡 3.8.1 如何在vxWorks里增加新的网卡驱动,如rtl8139? A:下面以rtl8139为例。 1) 驱动的编译 把相应文件解压到相应目录下后,在target/src/drv/en/unsupported 下运行make CPU=PENTIUM 在target/lib/objPENTIUMgnuvx下增加了rtl81x9.o文件。 2) 驱动的添加 在target/src/config/bspname/configNet.h文件中 #ifdef INCLUDE_RTL_81X9_END /* * load string format * <devMemAddr>:<devIoAddr>:<pciMemBase:<vecnum>:<intLvl>:<memAdrs>: * <memSize>:<memWidth>:<csr3b>:<offset>:<flags> */ #define RTL_81X9_BUFF_LOAN_0 1 #define RTL_81X9_LOAD_FUNC sysRtl81x9EndLoad /* Specifies the name of your driver’s endLoad()entry point. For example, if * your driver’s endLoad() entry point were ln7990EndLoad(), you would edit * config.h to include the line: * #define LOAD_FUNC_n ln7990EndLoad */ #define RTL_81X9_LOAD_STR_0 endLoadStr[0] /* First entry loc */ /* Specifies the initialization string passed into muxDevLoad() during network * initialization as the initString parameter. This string contains information that * is passed along blindly to the endLoad()function of the driver, and its contents * depend on what the driver expects. */ #define RTL_81X9_LOAD_COUNT 4 IMPORT END_OBJ * RTL_81X9_LOAD_FUNC (char *, void *); char endLoadStr [RTL_81X9_LOAD_COUNT] [END_DESC_MAX]; #endif /* INCLUDE_RTL_81X9_END */ #ifdef INCLUDE_EL_3C90X_END /// 在表endDevTbl[]中添加 #ifdef INCLUDE_RTL_81X9_END {0, RTL_81X9_LOAD_FUNC, RTL_81X9_LOAD_STR_0, TRUE, NULL, FALSE}, #endif /* INCLUDE_RTL_81X9_END */ 3.8.2 网卡驱动中POLL驱动的作用? A: BSD是UNIX下的网络设备模型,而END是VxWorks提出的增强型模型。主要特点是END支持轮询发送和接收, 这对WDB的系统级调试是关键的。 因为WDB工作在系统级模式时要关闭中断,这时通过网口的通信只能靠轮 询。基本上也只有WDB需要轮询支持,上层协议不需要。 4.文件系统 FAQ 4.1 Dos文件系统 4.1.100 如何从dos的root directory读出的32字节中算出文件建立时间? 我现在用的是fat16,并可以从root directory中读出文件最后一次修该时间的16进制数, 但是如何从这个16位的数中算出文件最后一次修改的时间,我怎么都弄不明白, 还请高手指教,或者相关资料去那里找? A:32字节中,偏移量为16H的代码意义(2字节):时间=小时*2048+分钟*32+秒+2 偏移量为18H的代码意义(2字节):日期=(年份-1980)*512+月份*32+日 (by zongj) 4.2 Flash文件系统 4.3 Floppy-disk文件系统 4.4 RAM-disk文件系统 4.5 基本文件系统问题 4.5.100 通过网络方式引导的vxworks,文件系统好象是主机的,本身没有文件系统? A:硬盘缺省是没有启动的,一般看到的文件是主机FTP目录下的文件。加载文件系统方法如下: 在SHELL下敲入命令 usrAtaConfig(0,0,"/ata0/")即可。如果要访问硬盘文件,在命令前加@。eg: ->ls "/ata0/." 4.5.101 如何在目标机的内存上安装文件系统? A: 通过在SHELL下做。请这样试一下: -> pBlkDev = ramDevCreate(0, 512, 400,400,0) -> pVolDesc = dosFsMkfs ("/DEV1",pBlkDev) -> devs (看一下是否有DEV1 ) -> pwd (看一下当前工作路径) -> fp=fopen("/DEV1/myfile","w") (建立文件myfile) -> fprintf(fp,"what you want to write to file...") -> fclose(fp) 4.5.102 如何加载目标机上硬盘的文件系统? A:在SHELL下敲入命令 usrAtaConfig(0,0,"/ata0/")即可。如果要访问硬盘文件,在命令前加@。eg: ->ls "/ata0/." 5.网络 FAQ 5.1 配置问题 5.100 如何在VxWorks下配置双网卡? A:以NE2000双网卡为例 NE2000(5,0X320)和NE2000(9,0X300) BSP如下配置: bsp/config.h: #define IO_ADRS_ENE 0x320 #define INT_LVL_ENE 0x05 #define IO_ADRS_ENE1 0x300 #define INT_LVL_ENE1 0x9 #define INT_VEC_ENE1 (INT_VEC_GET (INT_LVL_ENE1)) bsp/confignet.h: #ifdef INCLUDE_ENE_END {0,END_ENE_LOAD_FUNC,END_ENE_LOAD_STRING,END_ENE_BUFF_LOAN, NULL, FALSE}, {1, END_ENE_LOAD_FUNC,END_ENE_LOAD_STRING, END_ENE_BUFF_LOAN, NULL, FALSE}, #endif /* INCLUDE_ENE_END */ bsp/sysNe2000End.c if (pParamStr[0] == '0') sprintf (cp, ne2000ParamTemplate, IO_ADRS_ENE, INT_VEC_ENE, INT_LVL_ENE, ENE_BYTE_ACCESS, ENE_USE_ENET_PROM, ENE_OFFSET); else if (pParamStr[0] == '1') sprintf (cp, ne2000ParamTemplate, IO_ADRS_ENE1, INT_VEC_ENE1, INT_LVL_ENE1, ENE_BYTE_ACCESS, ENE_USE_ENET_PROM, ENE_OFFSET); printf ("ne2000EndLoad: %s./n", paramStr); if ((pEnd = ne2000EndLoad (paramStr)) == (END_OBJ *)ERROR) { printf ("Error: NE2000 device failed ne2000EndLoad routine./n"); } In the Project Menu, find the object name IP_MAX_UNITS, change it to 2. and build it . 使用ipAttach和usrNetIfConfig setup the second network cards. 5.2 ARP 5.3 DHCP 5.4 FTP和TFTP 5.5 PPP 5.5.1 PPP on Windows 95 5.5.2 PPP on Windows NT 5.5.3 PPP on Solaris 5.6 Sockets 5.7 Telnet 5.7.100 如何把TELNET/RLOGIN password protection 密码算法改成自己的? A: install an encryption routine Example: #ifdef INCLUDE_SECURITY loginInit (); /* initialize login table */ shellLoginInstall (loginPrompt, NULL); /* install shell security */ loginEncryptInstall (encryptRoutine, NULL); /* install encrypt. routine */ #endif 5.8 SNMP 5.8.1 利用snmp协议开发网络管理软件,谁能帮忙说一下利用snmp协议开发网络管理软件的流程。mib这个库 还需要自己写程序维护吗?另外,是不是做网络管理软件只需要开发一个client把网络单元所有的信息收集 起来进行分析就可以了?本人是这方面的新手。望指教! A:MIB库是嵌在硬件设备里的,由OEM提供,不需要自己写程序维护,SNMP软件开发主要是安SNMP协议的定义编 程对硬件设备参数进行设置(IP等),信息查询(工作状态..),信息接收(出错...)等. 一般不需要对这些信息分析,只是显示出来即可.如一个用户要用打印机打印,查询打印状态,会知道该打印机 是否繁忙.如打印机不工作,会给客户端显示原因(塞纸等).可以为打印机设置IP,语言支持等. 再问:由谁能否为我解释一下SNMP中的OID是如何定义的?我如何得到相关的信息? A: OID是MIB树上面的节点,形如1.3.6.1.2.1.....每个数字表示MIB树的一层,向下递推. MIB分两种,一种是标准MIB,是有国际标准的MIB-1,MIB-2,可查看RFC文档,另一种是私有MIB,有设备生产商定 义提供. 5.9 其它网络相关问题 5.9.100 VxWorks下ping局域网为何不通? 我使用Tornado2 prototyper for NT,在NT4的环境调试。已按要求安装了ULIP,地址"90.0.0.254".建立一 个bootable Imag project,并加载了网络组件,包括PING。 在shell下调试,ping "90.0.0.254",4,0 ping "90.0.0.1",4,0 均正常,但ping我的局域网就是不 通,没有应答。哪位同志帮帮我,谢谢了! A: ping的时候,因为它需要ULIP转发,要在两边的机器上用ROUTE ADD增加路由表,以对方的网卡做路由,并将 IP FORWARDING选中.(by besea) 讲讲我的具体设置 在TCP/IP属性里 我的物理网卡地址:168.8.8.6,子网掩码:255.255.0.0 网关地址:168.8.8.66。 ULIP虚拟适配器地址:90.0.0.254,子网掩码:255.255.255.0 网关地址:168.8.8.6。(本机) 在VxWork下,ping 168.8.8.66,用Sniffer抓包看到: source address: 90.0.0.1 destination address: 168.8.8.66 我试了一下,只能发包不能收包,收不到ECHO REPLAY 请大家帮忙解答一下,谢谢!(by explore) 6.VxWorks操作系统 FAQ 6.1 C++ issues 6.1.100 请教Vxworks中类的用法: 我的程序中包含如下内容,编译时全通过,但下载时显示 Errors while downloading D:/Tornado/target/proj/simtest/SIMNTgnu/simfun.out: ___6mytest __$_6mytest 请问各位高人如何处理. extern"C" { class mytest { public: mytest(); ~mytest(); int add(int x,int y) { return (x+y); } }; mytest tmyt; } A:一看你的文件名后缀是否为cpp(必须为小写) 去掉语句extern"C" ,文件后缀名改为.cpp! 6.1.101 请教帮主c and c++,tornado支持c and c++ ,但当我用c++写好程序test.cpp,然后想在 srAppinit.c中调用我写好的myFuc();时,不能编译通过。但我把test.cpp改成test.c后则可以通过。这是 为什么? A:文件后缀为.cpp时编译器会认为是C++文件,这样有些定义类型为C的函数在编译或下载时不被认可。 解决方法是把这些不被认可的C类型函数用语句extern "C"说明一下为C函数就行了. 6.2 Communication problems 6.2.100 关于消息队列(Message Queues) 我知道用msgQReseive()从队列中接受信息,用msgQSend()向队列发送信息。但有两个问题: 1. 接收到的和发出的是什么信息? 2. 如何接收,如何发送? A:使用队列接收和发送消息前,要先创建一个队列,这个队列实际上是一个FIFO的管道。发送任务从管道的 一端发送消息,需要取得消息的任务从另一端接收消息。其中msgQReceive是一个阻塞的系统调用,当队列 中有消息时,函数调用取的消息。如果没有消息,则该任务处于等待消息的状态,直到接收到消息,才继续 执行。(by bruin) 6.3 中断(Interrupt) 6.3.1 VxWorks是如何调用ISR的? 能否具体描述一下当VxWorks收到外部中断信号时是怎么调用中断服务程序的?据说是在MUX层实现的,正 确否? 不同的cpu处理不一定相同,你是不是说网络设备的中断处理?(by superme ) 是这样的,比如对于一个网络设备,物理层和MAC层分别由不同的CPU处理,两个CPU之间的通信机制是靠 共享内存,当物理层的消息要发往MAC层的时候就先给MAC发一个中断,MAC的CPU收到中断后就要调用相应 的ISR,可我现在只能看到MAC的ISR是在intConnect()函数里被调用,然后就看不到什么了,(我没有物理 层的程序,只有MAC层的程序)我就是想知道当一个外部中断来了以后VxWorks是如何处理的,如何调用ISR 的。据说是在MUX层里把中断号跟ISR捆绑在一起的,可我又没找到确切证据。哪位大侠给指点一下? 不胜感激!(by moonlight ) 终于有个大侠给我回复了这个问题,我将之贴出来与大家共享: 外部中断产生时,处理流程是: >1。根据CPU内部寄存器的中断允许位决定是否响应; >2。x86CPU根据总线上的中断号查找中断向量表,得到中断向量; > PowerPC只有一个外部中断0x500,跳到0x500处执行; >3。CPU进入中断处理,执行的是操作系统预先安装的一个stub程序, > stub负责保存中断现场等工作,然后调用intConnect()时所 > 安装的ISR;对于PowerPC,stub调用的是BSP中断控制器驱动程序的 > 一个函数,这个函数查询中断控制器的寄存器,得到中断号, > 再去查找中断向量,得到的中断向量就是intConnect()安装的 > 函数; >4。调用ISR。返回后,stub继续执行,恢复中断现场。结束中断。 > >对于END driver,它有函数xxEndLoad()和xxEndStart()。 >MUX则有函数muxDevLoad()和muxDevStart()。系统(BSP)在 >初始化的时候调用过程是: > muxLibInit(); > muxDevLoad(xxEndLoad,...); > muxDevStart(pXxEndObj); > >在muxDevLoad()时,会调用到xxEndLoad,并通过字符串传递参数, >xxEndLoad初始化一个END设备; >在muxDevStart()时,会调用到xxEndStart,在xxEndStart里会 >进行intConnect, intEnable等工作。 > >过程是这样的。严格来说,并不是在mux层的代码里链接中断,而是 >在END driver中完成的。mux并不和任何硬件直接联系。 (by moonlight ) 6.3.2 请教中断问题,偶用ADS测试ARM中断式,当有IRQ中断产生时,程序转到中断入口0x18处 0x00000018: B IRQ_Handler却不跳转到中断服务程序IRQ_Handler处,可能是什么原因请大侠指点! 注:中断已经enable A:这很有可能是中断和中断程序没有绑定在一起 再问: 偶程序里有一个Install_Handler不知道算不算是绑定,偶是菜鸟,请多多指点。谢谢! unsigned Install_Handler (unsigned routine, unsigned *vector) { unsigned vec, oldvec; vec = ((routine - (unsigned)vector-0x8)>>2); if (vec & 0xff000000) { printf ("Installation of Handler failed"); exit(1); } vec = 0xea000000 | vec; oldvec = *vector; *vector = vec; return (oldvec); } A:用下面方法查一下 1)确定一下是否中断发生,在中断发生时,查中断标志寄存器INTST1中相应的IRQ为是否置1, 或用示波器量该IRQ管脚。有中断产生且中断enable,就应该执行相应的ISR。 2)如上面没有问题,仍不执行,再查一下是否有比该IRQ等级更高的中断持续发生屏蔽了该IRQ中断。 特别要注意一些FIQ中断,在ARM中FIQ中断永远高于IRQ,可能会导致IRQ中断不被执行。 在中断屏蔽寄存器INTMR1中屏蔽所有优先级高于该IRQ的FIQ,会disable这些FIQ. 希望这些对你有所帮助 6.4 LoadModule problems 6.5 pthreads 6.6 Reboot 6.7 Semaphores 6.8 Simulator 6.8.1 在simulator环境里如何模拟中断?? 我想在simulator环境下,写一个ISR程序,但是无法模拟中断的产生。不知有何解决办法。 TIA (by wys205) A:vxworks下的ISR程序: 参考我写的一个程序,另外需要另一个程序向simulator窗口发消息。 如果需要这个程序,请发mail。 #include "vxWorks.h" #include "intLib.h" #include "iv.h" #include "taskLib.h" #include "logLib.h" #include "stdio.h" #include "semLib.h" void myISR(int); void myTask(); SEM_ID myBinary; #define MY_INUM 0xC011 /* Windows message, in fact */ /*-----------------------------------------------------------------------*/ void vxmain() { printf("inum = 0x%x, ivec = 0x%x/n", MY_INUM, INUM_TO_IVEC(MY_INUM)); myBinary = semBCreate(SEM_Q_FIFO, SEM_EMPTY); taskSpawn("tMyTask", 80, 0, 20000, (FUNCPTR)myTask, 0,0,0,0,0,0,0,0,0,0); if (intConnect((VOIDFUNCPTR *)INUM_TO_IVEC(MY_INUM), (VOIDFUNCPTR)myISR, 0) != OK) perror("intConnect()"); } /*-----------------------------------------------------------------------*/ void myISR(int param) { logMsg("task is %s/n", (int)taskName((int)taskIdCurrent), 0, 0, 0, 0, 0); semGive(myBinary); } void myTask() { int count = 0; while (1) { semTake(myBinary, WAIT_FOREVER); printf("myTask: semaphore taken, count = %d/n/n", count++); } } (by vxfree) 向simulator发送消息的程序: 哈哈,我已经试成功了,原来向simulator发送消息如此简单,请vxfree指正。 void CAboutDlg::OnButton1() { // TODO: Add your control notification handler code here HWND hwnd ; hwnd= ::FindWindow(NULL,"VxWorks Simulator for Windows"); if(hwnd!=NULL) ::SendMessage (hwnd,0xC011,0,0); } (by wys205) 6.8.2 vxworks中文件操作异常区区最近正学vxworks,编译一例子,通过,在tornado下仿真运行,系统 提示异常发生。文件如下,哪位兄台可以提示一下?谢谢 ....... int teststdio() { char buffer[10]; char *tn = "tmpxxx"; //是不是这里的问题? FILE *pf = NULL; int result = 0; /*fpos_t fp1; long off;*/ /* opening a file for both reading and writing */ result += ASSERT((pf = fopen(tn, "w+")) != NULL); /* closing the file */ result += ASSERT(fclose(pf) == 0); /* reopening the file and attaching the standard input stream to the file */ result += ASSERT(freopen(tn, "r", stdin) == stdin); ..... / A:char *tn = "tmpxxx"; //是不是这里的问题? 你没指定文件所在的设备, simNT环境里,一般设备为"host:" 所以格式为char *tn="host:/myFile"; (by wys205) 6.8.100 怎样增加SIMULATOR中的内存? A:使用命令行vxworks /r(your memory size),注意之间没有空格,而且大小应该为十进制,而不是16进制。 6.9 Task related items 6.10 Time/timer related items 6.11 Wind Web Server related items 6.12 Zinc/windML related items 6.12.100 WindML(UGL2.0)文档里提到把文件`ugl_WinLib.o'包含在vxWorks映象里。我安装了WindML (for simnt和其它),但没发现该文件。只发现同名的一个头文件。有人知道它在哪里吗? A:那个文件现在改名叫'simLib.o'(thank-you objdump and grep)... 6.12.101 怎样在simulator环境下安装WindML? A: 1) 安装Tornado. 2) 安装WindML 2.0 3) 使用WindML配置工具编译通用图形驱动 4) 在simualtor工程的Makefile文件里添加如下语句: MACH_EXTRA= $(WIND_BASE)/target/lib/objSIMNTgnuvx/simLib.o 5) 编译它即可 (by wys205) 6.13 Other items 6.13.100 问一下在vxworks里面如何看ErrNo的解释, 谢谢 A: -> printErrno(0x0001) 0x1 = S_errno_EPERM value = 0 = 0x0 -> malloc(0x7fffffff) value = 0 = 0x0 -> printErrno 0x110001 = S_memLib_NOT_ENOUGH_MEMORY value = 0 = 0x0 (by vxfree) 6.13.101 在bootconfig.c文件中的go()函数中的(entry) ();语句之前加了printf打印,为什么大不出来呢? 放在printf ("Starting at 0x%x.../n/n", (int) entry);这句后面就好了。为什么? A:在printf后面加了taskdelay就出来了 (by tonyzh) 这个不难理解。printf实际上把字符串交给底层驱动程序去打印。 entry();这个调用并不简单,它是启动vxWorks,一进入vxWorks,bootrom和它 里面的驱动程序马上就消失了,当然来不及打印了。 (by vxfree) 6.13.102 vxWorks的启动过程是怎样的? A:VxWorks 的启动过程因程序映像的不用,启动时跳转入口略有不同,以下是ROM版本VxWorks映像的加载启 动过程,是相对简单的启动过程,需要详细了解的同仁可以给我Mail,再交流。 VxWorks ROM版本首先从系统上电的时候提供的入口地址开始执行,然后系统会自动把ROM中的版本加载到 RAM中执行。具体过程如下: ※romInit.s:romInit() 系统上电之后,首先调用的函数就是romInit(); 禁止中断; 把启动类型(冷启动/热启动)放在堆栈上 清除cache 直接跳转到bootInit.c:romStart() ※bootInit.c:romStart() 把代码段和数据段从bootrom复制到RAM当中 完成程序映象的解压缩(如果映象是压缩版本的) 跳转到sysALib.s:sysInit() ※sysALib.s:sysInit() 重新进行CPU内核(主要是cache)的初始化。这些工作在romInit()里面曾经进行过,由于系统刚刚进入RAM 中执行,需要再次初始化。 无论使用何种系统(包括仿真器)引导,RAM版本的VxWorks都是从这里开始执行的。 控制权移交给 usrInit() ※usrConfig.c/bootConfig.c:usrInit() VxWorks 中第一个C语言完成的代码。执行操作系统内核所必须的初始化程序。 Cache程序库的初始化 清零系统的BSS段 初始化中断向量表 使硬件工作在一个“安静”的状态,尽量不产生各种中断或者异常 控制权移交给KernelInit() ※libcputoolvx.a:kernelInit() /* 对于MPC8260是libPPCEC603gnuvx.a */ 初始化多任务环境,不再返回 传递给这个函数的参数有: 被启动的任务:“usrRoot()” 堆栈的大小 可用内存的起始点 内存的顶端地址 ※usrConfig.c and bootConfig.c:usrRoot() 初始化I/O系统 初始化驱动程序 创建设备 设置网络接口 用来产生用户的应用 RTOS从这里开始启动运行 《End》 6.13.103 怎样热启动vxWorks? A: 把config.h文件的SYS_WARM_TYPE改变,例如:#define SYS_WARM_TYPE SYS_WARM_ATA 6.14 VxWorks AE issues 6.15 I/O 操作 6.15.1 查看serial device的状态,又是异常! 文件如下,注释有它的说明,编译后,在shell输入: -> pDevHdr = iosDevFind ("/tyCo/0",0) Exception number 0: Task: 0x4bbc8e8 (t1) General Protection Fault Program Counter: 0x0041eba5 Status Register: 0x00010202 还是想得到各位兄台的指点,谢谢! ...... void tyShow ( TY_DEV * pTyDev ) { /* read - ring buffer and semaphores */ printf ("Address of pTyDev->rdBuf = 0x%08x./n", &pTyDev->rdBuf); printf ("Address of pTyDev->rdSyncSem = 0x%08x./n", &pTyDev->rdSyncSem); printf ("Address of pTyDev->mutexSem = 0x%08x./n/n", &pTyDev->mutexSem); /* rdState */ printf ("pTyDev->rdState.xoff = 0x%02x./n", pTyDev->rdState.xoff); printf ("pTyDev->rdState.pending = 0x%02x./n", pTyDev->rdState.pending); printf ("pTyDev->rdState.canceled = 0x%02x./n", pTyDev->rdState.canceled); printf ("pTyDev->rdState.canceled = 0x%02x./n", pTyDev->rdState.canceled); /* write - ring buffer and semaphores */ printf ("Address of pTyDev->wrtBuf = 0x%08x./n", &pTyDev->wrtBuf); printf ("Address of pTyDev->wrtSyncSem = 0x%08x./n/n", &pTyDev->wrtSyncSem); ..... A: ->buf=malloc(100) ->pDevHdr=iosDevFind("/tyCo/0", buf) (by vxfree) 7.其它 FAQ 7.1 Hard delay 7.2 Memory leaks 7.3 Corba engines 7.4 Web servers 7.5 NTP usage 7.6 Performace / Benchmarks 7.7 SNMP 7.8 Lint 7.9 Encryption 7.10 其它 7.10.1 VxWorks下编程的几个误区。(by vxfree) 1)Tornado使用标准C语言吗?为什么没有提供inb(), outb()等函数? Tornado缺省使用GNU编译器,支持ANSI/ISO C, C++,以及AT&T语法汇编(非Intel)。由于C++很庞大, 而且在不断发展,所以有些标准C++的特征可能GNU不支持(基本没有编译器支持所有C++特征)。程序员一 般只要掌握常用部分就能编出不赖的程序了。inb(),outb()是Turbor C/DOS下的,不属于标准C。Tornado在 BSP中提供了相应的sysInByte(),sysOutByte()等函数,参考BSP下的sysALib.s。 (我看到前两年的2级C语言还在考DOS操作。sigh 我担心B.Gate会考满分,而D.Ritchie不及格) 2) VxWorks下怎么访问A:盘,C:盘(PC机环境)? A:,C:是M$对PC机设备的命名方式,目的是让傻瓜用户方便理解。 VxWorks下叫/fd0和/ata0。 3)目标机没有键盘和显示器,printf()打印到哪里去了? 打印到标准输出设备上了。至于标准设备是什么,如果你用PC终端,就到屏幕上;否则到系统中第一个串 口去;还有可能被重定向到别的设备上了,比如磁盘文件或telnet端口。如果什么都没有,打印的字符串被 丢弃。 C语言中,3个标准设备的文件描述符为STD_IN, STD_OUT, STD_ERR;文件指针为stdin, stdout, stderr; C++中有cin, cout, cerr对象。 4) 怎么在VxWorks下用(段:偏移地址)方式访问端口? VxWorks for X86工作在保护模式下,应用程序不用关心段的存在。直接用线性地址访问即可,例如: *(unsigned short *)0xb8000 = 0xAA55; 可以访问Video RAM。 (8086,DOS真是害人的玩艺儿,是不是现在大学里还在教) 5) 在中断服务程序(ISR)中调用printf()打印调试信息。 程序死机是正常的,没有烧坏硬件算幸运的了。VPG里规定了哪些函数是可以调用的。关键是printf()会引 起任务阻塞,而中断不是任务。可以用logMsg()。 6)不用I/O函数,写汇编直接访问串口。 最好使用open()/close(),read()/write()访问串口。这样程序不依赖于硬件,好移植。有人对移植性不以 为然,实际上老板们都希望以前的程序不用改就能重用,尤其是老程序已经通过严格测试,并经过了实践检 验。 如果你的程序没有移植性需求,可能的原因有: - 程序太烂,不值得移植,不如重写; - 程序太乱,且缺少文档,没办法移植;(可以让老板不敢炒你鱿鱼;)) - 产品在市场上惨败,公司已决定不再开发类似产品,可能要大规模裁员。 有人认为自己写专用驱动效率高,灵活。错了! 效率高是因为功能弱。为了让驱动和APP交换数据,你必须设计类似ring-buffer的数据结构并使用信号量机 制;为了支持同时监视多个串口,必须设计类似select的机制;必须管理所有串口的细节。最后发现,你不 过是在从头发明轮子。 串口是一种古老而缓慢的通信方式,指望在它身上挤出一点效率,我看不出有什么实际意义。如果速度实在 不够,也许你应该选用USB。 open()/close()函数是C程序员都应该会用的,而专用驱动接口只有你自己会用。不要因为不会使用I/O函数, 就牺牲多数人的灵活性以换取少数人的灵活性。可能你对8250或SCC很熟,但别指望每个人都是。有可能在 另外一种硬件环境下的串口你也不懂。 7)分不清fopen(),fread()和open(),read()的区别。 fwrite等是带缓冲的,最好别用在串口或音频等设备上。写串口的意思是希望串口立即把数据发送出去,而 不是放在缓冲区中。另外,工作在LINE_MODE下的串口驱动本身就具有缓冲能力。 8)反复查询标志变量以确定等待的事件或超时发生。 最没有效率的做法。尽量使用信号量、select()或watchdog。只有在特殊情况下,例如硬件不支持中断,或 延迟一小段时间,才有理由这样做。 9)在程序中频繁调用malloc()/free()。 桌面系统和嵌入式系统的一个很大区别是,桌面系统的user是人,人对系统实时性,稳定性要求相对并不 高。程序死机时,大不了结束进程或重新关机开机。嵌入式系统的user基本上是大系统中的其它部分,实时 性或稳定性不好会导致重要数据丢失,甚至发生重大事故。卫星在天上飞时,如果系统瘫痪,遥控系统都失 灵了,你总不能亲自爬上去关机开机吧。(不过象这种系统都有备份,出错时可以启动备份系统)。 VxWorks是实时操作系统,并不表示你写的程序就一定是实时的。malloc()/free()非常灵活,但它每次需 要进行搜索算法,需要的时间是不确定的。另外它导致内存碎片,导致性能下降或内存不足,写得差的程序 还可能发生内存泄漏或悬空指针。 实时性要求高的应用,或多或少都会采用静态分配,即在程序中事先定义好可能需要的全部变量,或者在 程序启动时一次分配好,以后就不再分配/释放了,或者是写专用的内存管理函数。利用率和灵活性是差了些 ,得到的是性能。 在风河公司的另一款基于OSEK/VDX的操作系统OSEKWorks中,你甚至不能在程序中创建任务,分配资源。所 有都在编译前静态指定。OSEKWorks主要用于汽车工业。试想malloc()返回NULL的情况,你还能怎么办呢? 方向盘附近有个显示面板,倒可以在上面打印: "内存不足,请关闭部分任务或稍后再试!"可能开车子的还没有看到这个提示就已经车毁人亡了。 7.10.2 各位大侠: 我的程序写好了,系统如何启动我的应用程序。tornado 2 帮助里有这一段: Linking the application with VxWorks is really a two-step process. You must add an entry point to the application in usrConfig.c, and you must modify the makefile to link the application statically with VxWorks. To start your application during system initialization, add code to the usrRoot( ) routine in usrConfig.c. You can call application initialization routines, create additional I/O devices, spawn application tasks, and so on, just as you do from the Tornado shell during development. An example is provided in usrConfig.c. This file includes and initializes a simple demo if the preprocessor constant INCLUDE_DEMO is defined in one of the configuration files. In that situation, usrRoot( ) spawns usrDemo( ) as a task as the last step in booting the system. You can simply insert the appropriate initialization of your application after the conditional code to start the demo. For example: /* spawn demo if selected */ #if defined(INCLUDE_DEMO) taskSpawn ("demo", 20, 0, 2000, (FUNCPTR)usrDemo, 0,0,0,0,0,0,0,0,0,0); #endif taskSpawn ("myMod", 100, 0, 20000, (FUNCPTR)myModEntryPt, 0,0,0,0,0,0,0,0,0,0); To include your application modules in the bootable system image, add the names of the application object modules (with the .o suffix) to MACH_EXTRA in Makefile. For example, to link the module myMod.o, add a line like the following: MACH_EXTRA = myMod.o ... Building the system image with the application linked in is the final part of this step. In the target directory, execute the following command: make vxWorks 按上面的步骤,我用tornado 2的rebuild All命令生成vxWorks,考到硬盘里通过bootrom.sys 启动vxWorks;vxWorks启动了,可我的应用没有。各位大侠,如何启动应用程序呢? 请指点。 小弟非常感谢! ※ 作 者: zhangjiaxue 02-8-21 18:09:18 ※ Re:哪位大侠做过把应用绑定到vxWorks系统去 <--- 〖回复该帖子〗 1).在启动系统时启动用户定制的任务 假设有一个MultiTask.c的程序,该程序使用消息队列来传递不同task之间的消息,其中:主task为Init, 负责建立两个从task,监控和传递推出消息,并释放从进程需要的资源。 将此文件加入到制作vxworks的工程中(注意这里的MultiTask.c同样不能放在带空格的路径下), 修改usrAppInit.c,在开头加入: extern void Init(void); 在函数结束前加入: Init(); 重新编译生成vxworks,重启目标机,可以看到任务自动执行。 2).关于usrconfig.c 有些帮助文件中提到可以修改c:/tornado/target/config/all/usrconfig.c中的usrRoot函数来改变启动 画面和启动用户任务。但在vxworks的faq中提到:"Tornado2.0不使用usrconfig.c,而是用 target/config/comps下的 configulettes,如果需要使用usrconfig,必须"make" c:/tornado/target/config/pentiumpro下的makefile文件。事实上,在帮助文件里大量地提到了修改 usrconfig,例如在不通过网络而是从rom启动vxworks,使用flash ram等。 实际上就tornado2.0来说,分为两种情况: <1>用户自己建立的bootable image 这时不使用usrconfig,用户通过对工程可视化的修改,就可以裁减内核。如果在project里面去掉了默认 的dependence,可以看到target/config/comps下的一些*.c,*.h文件其实是被引用的。通过对它们的修改, 可以起到类似于修改usrconfig.c的作用,编译时使用的是系统自动在工程所在目录下产生的makefile, 对这个makefile的修改将不会产生作用。 <2>系统默认的bootable image 这时使用安装时自带usrconfig。用于通过对configAll.h和config.h中define或undef宏INCLUDE_XXX来 裁减内核。这时对启动化面的修改是通过对usrconfig.c的修改实现的。用户定制任务如下实现。: 在 #else #if defined(INCLUDE_DEMO) /* create demo w/o shell */ taskSpawn ("demo", 20, 0, 2000, (FUNCPTR)usrDemo, 0,0,0,0,0,0,0,0,0,0); #endif /* mips cpp no elif */ #endif /* INCLUDE_SHELL */ 后面添加 taskSpawn("tInit", 1, 0, 10000, (FUNCPTR)Init, 0,0,0,0,0,0,0,0,0,0); 这里使用的是c:/tornado/target/config/bspname下的makefile。 定制任务还需要在makefile里添加: MACH_EXTRA = MultiTask.o 这个MultiTask.o是在另外一个downloadable application project里编译产生的。这个project里仅含有 一个MultiTask.c,将MultiTask.o拷贝到c:/tornado/target/config/bspname下供makefile使用。可以参 照下面vxWorks.st_rom的产生方法产生一个可以standalone的vxWorks.st,也可以在tornado集成环境中选 择toolsèoptionsèprojectèshow Tornado1.0.1 menu items(如果安装时选择使用tornado1.0,则这个选项 默认被选中),然后选择builtèstandard bsp buildsèpcPentiumPro、vxWorks.st,这两种方法生成的 vxWorks.st都在c:/tornado/target/config/bspname目录下。 7.10.100 Q:如何对.o文件进行反汇编? A: $(WIND_BASE)/host/x86-win32/bin/objdumpxxx -d x.o simpc/386 7.10.101 VxWorks可以制作不需要BIOS的自启动方式吗? A: 可以的。 我知道有人用VxWorks在没有BIOS下启动,CPU是386EX(PC104)。 不过对于pentium以上的PC机,可能要复杂很多。 参考Tornado/target/unsupported/config/frc386 7.10.102 DS21554 volatile * X的含义? A: DS21554 volatile * X; 首先X是个指针(*),其次X所指之处的内容是易变的(volatile),最后X所指之处是个DS21554类型的结构。 似乎这样写也可以: volatile DS21554 * X; 但如果这样写: DS21554 * volatile X; 那就是X(指针)是易变的而不是内容易变。 volatile主要用于硬件寄存器,或者程序共享区域等。volatile关键字告诉编译器不要对此变量进行优化。 比如你写: while (*hw_reg & 0x0001) { //... } 如果hw_reg指向的寄存器没有申明为易变的,如果你的编译器很聪明但却不足够聪明的话,那么它产生的 代码每次循环时,可能会从某个寄存器或堆栈中取值,而不是从硬件取值。 7.10.103 如何字节对齐? A: typedef struct { char c1 __attribute__((packed)); char c2 __attribute__((packed)); long l __attribute__((packed)); short s __attribute__((packed)); } Struct1; or typedef struct { char c1; char c2; long l; short s; } __attribute__((packed)) Struct2; 注意只对GNU有效。 7.10.104 如何解释#include "a.c"这样的语句? A: #include 一个文件时,对编译器来说,相对于把这个文件嵌入到当前文件中,原则上可以#include 任何文件。#include一个常规的.c文件的问题是,如果多次包含,产生的目标码中就会有被包含模块的 多个拷贝,连接时就会冲突。如果不包含,编译器会抱怨函数原型找不到(ANSI)。所以一般情况下我们 包含一个.h. 附录A.一些有用的连接 中文: http://bbs.edw.com.cn/
VxWorks中文FAQ(转载)
最新推荐文章于 2024-09-26 19:40:54 发布