vxWorks FAQ中文版收藏-转载之下

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
3.2.3 MIPS
3.2.4 ARM
3.2.5 x86
3.2.4.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.4 配置你的VxWorks
3.5 VME
3.6 VxWorks环境 environment
3.6.1 usrSerial.c
3.6.2 prj_vxworks.tcl
3.7 PCI
3.7.1 关于PCIPCI总线上的设备怎么查找?是用pciFindDevice()函数吗?如何映射PCI内存?如何读PCI设备内存中的内容?谢谢
A:使用pciFindDevice查找设备;使用pciConfigInByte/Word/Long, pciConfigOutByte/Word/Long读写配置空间;修改sysLib.c::sysPhysMemDesc[]映射地址空间;使用pciIntConnect连接PCI中断(也可以使用intConnect)。

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 基本文件系统问题


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.

--  作者:lxlong
--  发布时间:2005-6-25 13:12:05

--  

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.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.

--  作者:lxlong
--  发布时间:2005-6-25 13:12:45
--  

希望这些对你有所帮助
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()
{
// TOD 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.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.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.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

--  作者:lxlong
--  发布时间:2005-6-25 13:13:38

--  

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目录下。

附录A.一些有用的连接

中文:
http://bbs.edw.com.cn/
http://www.embed.com.cn/
http://drew.diy.163.com/    drew大虾的个人主页


英文:
http://www.xs4all.nl/~borkhuis/vxworks/vxworks.html  
(Johan Borkhuis的个人主页,本文中的FAQ大部分来自于该站点)
http://groups.google.com/groups?hl=zh-CN&lr=&ie=UTF-8&group=comp.os.vxworks
(VxWorks最热的新闻组)
Electronic Engineers\‘ Toolbox http://www.eg3.com/real/vxworks.htm
BGSH: A VxWorks Shell With Command Line Editing http://www.xmission.com/~bgeer/bgsh.html
Dave Korns page about updating GCC for the PPC http://www.newgcc4vxworks4ppc.cjb.net/
Embry-Riddle VxWorks 5.3(Tornado) Real-Time Laboratory Experiments
http://www.rt.db.erau.edu/experiments/vx/toc/TableOfContents.html
Introduction into realtime systems http://www.eventhelix.com/RealtimeMantra/default.htm
Unofficial VxWorks FAQ, by Hwa Jin Bae, http://www.xs4all.nl/~borkhuis/vxworks/vxfaq.html
VxWorks Exploder mailing list http://www-csg.lbl.gov/vxworks/
WindRiver Systems http://www.wrs.com/
Development examples of some realtime systems. http://www.eventhelix.com/ThoughtProjects
Instructions on how to build the ACE library for VxWorks:
http://www.gum.de/it/download_documents.htm
Article on memory testing http://www.netrino.com/Articles/MemoryTesting/
Building NTP for VxWorks http://chard.tuc.noao.edu/mpg/ntp/ntp.to.vxworks.html
VxWorks Under Linux http://chard.tuc.noao.edu/mpg/vxworks/linuxHostingVx.html


附录B.维护

wys205 [email protected]  SuccessIT Co..Ltd
vxfree [email protected] 

你可能感兴趣的:(汇编,application,include,任务,makefile,initialization)