OpenVINOTM,给你看得见的未来!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » How to replace the vxWorks network stack

共1条 1/1 1 跳转至

How to replace the vxWorks network stack with a third party TCP/IP stack

菜鸟
2002-07-28 18:37:00    评分
How to replace the vxWorks network stack with a third party TCP/IP stack This article cannot be a step-by-step guide for a network stack porting job. FAE consulting and/or source code for at least some of the network initialization libraries may be required. Below are some files that may be needed for understanding/debugging problems: netLib.c sockLib.c bsdSockLib.c The Network Protocol Toolkit, available from Sales, is one resource. Another is to study the way the vxworks network stack is initialized. If vxWorks is built using the Tornado 101 way, namely defining macros in config.h, then the place to look is in target/src/config/usrNetwork.c What are some of the hurdles? 1. Please note that even if you have the same BSD files, you still have many hurdles to overcome. vxWorks is not UNIX. Some function names may be the same, but the implementation has been changed/optimized for embedded systems. Semaphores, timers, and scheduling are different. 2. Replacing the vxWorks stack requires a good understanding of how the network is initialized. You will have to look at bootConfig.c and usrNetwork.c. Under Tornado 2.0, using the Tornado 1.0.1 Build method, will use the initialization sequence defined in usrNetwork.c. From the project facility: Tools->Options->Project Click Show Tornado 1.0.1 Menu items. Then under Build->Standard Build-> you can build images like vxWorks, or vxWorks.st. NETWORK INITIALIZATION PROCESS In Tornado/target/config/all/configAll.h you will find a complete list of all the macros used to configure vxWorks with the corresponding explanation of what they are for. In the booting process, in usrRoot, target\config\all\usrConfig.c, (bootConfig does something similar for bootrom images) there is a section that calls usrNetInit if INCLUDE_NET_INIT is defined. usrNetInit is in file target\src\config\usrNetwork.c which does the following: 1. Pulls in header files based on the configuration macros defined in Tornado/target/config/all/configAll.h, and Tornado/target/config/bsp directory/config.h file. 2. Declares and initializes some global variables that control default values for the protocols, and network memory pool. 3. Gets the boot prompt parameters left by the bootrom image. 4. Initializes the host library. 5. Initializes socket, mbufs, and protocol libraries. 6. Attaches and initializes network interface specified by the boot device parameter. The selection of functions to call is different based on whether the driver is an end driver, or not. BSD43 and BSD44 drivers are a little bit different, but the differences are inside the driver code. The external interface is the same. There is support also for booting from floppy, or backplane interfaces. 7. Add routes to the host. 8. Creates network devices for remote file access. 9. Attaches loopback interface. 10. Initialize libraries that spawn server tasks for optional components like telnet server, ftp server, and tftp server. SOCKET LAYER - I/O INTERFACE In usrNetInit from target/src/config/usrNetwork.c, the following calls are made: sockLibInit (NUM_FILES) which allocates an array of SOCK_FUNC pointers. sockLibAdd ((FUNCPTR) bsdSockLibInit, AF_INET_BSD, AF_INET) which adds the bsd socket library backend. sockLibInit, and sockLibAdd, from sockLib.c, install a socket backend. This is the interface between the I/O system and the socket layer. This is where, for example, the translation between a write, issued on a socket file descriptor, is mapped to the socket function "write", which eventually results in a call to sendto. All of the routines in the sockLib library are simply entry points to installed backends. Each backend has a unique domain value provided by the second parameter to the sockLibAdd() routine. Currently, the only backends available are the standard BSD sockets (AF_INET_BSD [= 101]) and STREAMS sockets (AF_INET_STREAMS [= 102]). The current settings are defined in the ./target/h/sys/socket.h include file. Internally, those protocols can still be referenced with a specific (not necessarily unique) domain value provided by the parameter. The first parameter to the sockLibAdd() routine is a FUNCPTR to an initialization routine which provides access to the parallel versions of the sockLib routines. The prototype is: SOCK_FUNC * mySockLibInit (void); The structure to which it returns a pointer must be supplied by each backend. It provides pointers to the domain-specific implementations of the sockLib routines and is defined in the ./target/h/sockFunc.h include file. Besides providing unique implementations for each address family, that structure also allows the new domain's socket API to duplicate the existing function names from sockLib.c to indicate their dependence. The prototypes for each routine match the sockLib entries. When a socket() call is issued, the sockLib routine searches for a backend with a parameter that matches the given domain. If found, the equivalent socket creation routine from the SOCK_FUNC structure is called, substituting the argument for the original domain value and leaving the and entries unchanged. This is the only routine in sockLib which does not relay the provided arguments directly to the backend counterpart. That socket routine must obtain and return a unique file descriptor which is not in use by any other backends. Any later calls to the other sockLib routines will use that value to access the entries in the returned SOCK_FUNC structure directly so that the search for the correct backend is not repeated. The parameters to those routines are passed directly through to the backend. Below are snippets of code from sockLib.c, and bsdSockLib.c. Please contact your FAE or sales representative for source code. From sockLib.c: /* globals */ SOCK_FUNC ** pSockFdMap = NULL; /****************************************************************** * * sockLibInit - initialize a socket library back-end library. * * RETURNS: OK, or ERROR if the back-end could not be initialized. * * NOMANUAL */ STATUS sockLibInit ( int fdMax /* maximum file descriptors */ ) { ... /* allocate fd-to-pSockFunc mapping array */ if ((pSockFdMap = (SOCK_FUNC **) calloc (1, fdMax * sizeof (SOCK_FUNC **))) == NULL) return (ERROR); From target/h/sockFunc.h: typedef struct sockFunc /* SOCK_FUNC */ { FUNCPTR libInitRtn; /* sockLibInit() */ FUNCPTR acceptRtn; /* accept() */ FUNCPTR bindRtn; /* bind() */ FUNCPTR connectRtn; /* connect() */ FUNCPTR connectWithTimeoutRtn; /* connectWithTimeout() */ FUNCPTR getpeernameRtn; /* getpeername() */ FUNCPTR getsocknameRtn; /* getsockname() */ FUNCPTR listenRtn; /* listen() */ FUNCPTR recvRtn; /* recv() */ FUNCPTR recvfromRtn; /* recvfrom() */ FUNCPTR recvmsgRtn; /* recvmsg() */ FUNCPTR sendRtn; /* send() */ FUNCPTR sendtoRtn; /* sendto() */ FUNCPTR sendmsgRtn; /* sendmsg() */ FUNCPTR shutdownRtn; /* shutdown() */ FUNCPTR socketRtn; /* socket() */ FUNCPTR getsockoptRtn; /* getsockopt() */ FUNCPTR setsockoptRtn; /* setsockopt() */ } SOCK_FUNC; /******************************************************************************* * * sockLibAdd - add a socket library back-end * * RETURNS: OK, or ERROR if the socket back-end could not be added. * * NOMANUAL */ STATUS sockLibAdd ( FUNCPTR sockLibInitRtn, /* back-end init routine */ int domainMap, /* address family */ int domainReal /* address family */ ) { SOCK_LIB_MAP * pSockLibMap; /* back-end mapping entry ptr */ ... if ((pSockLibMap = (SOCK_LIB_MAP *) malloc (sizeof (SOCK_LIB_MAP))) == NULL) return (ERROR); /* init socket back-end */ if ((sockLibInitRtn == NULL) || ((pSockLibMap->pSockFunc = (SOCK_FUNC *) (sockLibInitRtn) ()) == NULL)) { free (pSockLibMap); /* back-end error */ return (ERROR); } pSockLibMap->domainMap = domainMap; /* stuff mapping address family */ pSockLibMap->domainReal = domainReal; /* stuff real address family */ ... /******************************************************************************* * * bsdSockLibInit - install the BSD "socket driver" into the I/O system * * bsdSockLibInit must be called once at configuration time before any socket * operations are performed. * * RETURNS: a pointer to the BSD socket table, or NULL. * * NOMANUAL */ SOCK_FUNC * sockLibInit (void) { if (bsdSockDrvNum >; 0) return (&bsdSockFunc); if ((bsdSockDrvNum = iosDrvInstall ((FUNCPTR) NULL, (FUNCPTR) NULL, (FUNCPTR) NULL, (FUNCPTR) bsdSockClose, (FUNCPTR) bsdSockRead, (FUNCPTR) bsdSockWrite, (FUNCPTR) soo_ioctl)) == ERROR) return (NULL); bsdSockDev.drvNum = bsdSockDrvNum; /* to please I/O system */ bsdSockDev.name = bsdSockName; /* for iosFdSet name optimiz. */ return (&bsdSockFunc); } From bsdSockMap.h: #define sockLibInit bsdSockLibInit #define accept bsdAccept ... From bsdSockLib.c: /* locals */ LOCAL DEV_HDR bsdSockDev; /* BSD-specific device header */ LOCAL int bsdSockDrvNum; /* BSD socket driver number */ LOCAL char * bsdSockName = "(socket)" /* file name of BSD sockets */ /* declare BSD socket interface function table */ SOCK_FUNC bsdSockFunc = { (FUNCPTR) sockLibInit, (FUNCPTR) accept, (FUNCPTR) bind, (FUNCPTR) connect, (FUNCPTR) connectWithTimeout, (FUNCPTR) getpeername, (FUNCPTR) getsockname, (FUNCPTR) listen, (FUNCPTR) recv, (FUNCPTR) recvfrom, (FUNCPTR) recvmsg, (FUNCPTR) send, (FUNCPTR) sendto, (FUNCPTR) sendmsg, (*FUNCPTR) shutdown, (FUNCPTR) socket, (FUNCPTR) getsockopt, (FUNCPTR) setsockopt }; /******************************************************************************* * * socket - open a socket * * This routine opens a socket and returns a socket descriptor. * The socket descriptor is passed to the other socket routines to identify the * socket. The socket descriptor is a standard I/O system file descriptor * (fd) and can be used with the close(), read(), write(), and ioctl() routines. * * Available socket types include: * .IP SOCK_STREAM 18 * Specifies a connection-based (stream) socket. * .IP SOCK_DGRAM * Specifies a datagram (UDP) socket. * .IP SOCK_RAW * Specifies a raw socket. * .LP * * RETURNS: A socket descriptor, or ERROR. */ int socket ( int domain, /* address family (for example, AF_INET) */ int type, /* SOCK_STREAM, SOCK_DGRAM, or SOCK_RAW */ int protocol /* socket protocol (usually 0) */ ) { SOCK_LIB_MAP * pSockLibMap; int newFd; ... /* search for a suitable back-end library entry */ for (pSockLibMap = pSockLibMapH; (pSockLibMap != NULL) && (pSockLibMap->domainMap != domain); pSockLibMap = pSockLibMap->pNext) ; /* found library map entry ? */ if ((pSockLibMap == NULL) || (pSockLibMap->pSockFunc->socketRtn == NULL)) { netErrnoSet (ENOTSUP); return (ERROR); } /* call back-end to open a socket */ if ((newFd = (pSockLibMap->pSockFunc->socketRtn) (pSockLibMap->domainReal, type, protocol)) == ERROR) return (ERROR); pSockFdMap[newFd] = pSockLibMap->;pSockFunc; /* stuff fd map array */ return (newFd); } HOST TABLE INITIALIZATION hostTblInit (); /* initialize host table */ MBUF AND PROTOCOL INITIALIZATION usrNetProtoInit (); /* SENS only: initialize various protocols */ netLibInit (); In the SENS stack, some of the protocol parameters are set by the user. usrNetProtoInit calls, for example, tcpLibInit to initialize the values that will be used by TCP such as: #ifdef INCLUDE_TCP TCP_CFG_PARAMS tcpCfgParams = /* tcp configuration parameters */ { TCP_FLAGS_DFLT, /* include rfc1323 support */ TCP_SND_SIZE_DFLT, /* default send buffer size */ TCP_RCV_SIZE_DFLT, /* default recv buffer size */ TCP_CON_TIMEO_DFLT, /* initial connection time out */ TCP_REXMT_THLD_DFLT, /* retransmit threshold */ TCP_MSS_DFLT, /* default maximum segment size */ TCP_RND_TRIP_DFLT, /* default round trip time */ TCP_IDLE_TIMEO_DFLT, /* idle timeouts before first probe */ TCP_MAX_PROBE_DFLT /* max no. probes before dropping */ }; #endif /* INCLUDE_TCP */ #ifdef INCLUDE_TCP tcpLibInit (&tcpCfgParams); /* tcp protocol initialization */ #ifdef INCLUDE_NET_SHOW tcpShowInit (); #endif /* INCLUDE_NET_SHOW */ netLibInit, from netLib.c, initializes the mbuf pool, the watchdog timers for the protocols, calls the init function for the internet protocols, and spawns tNetTask. tNetTask has a work queue, where drivers, or protocols can add functions to be called at task level to do packet processing that should not be done at interrupt level. tNetTask runs at priority 50, which should be higher than the priority of any task that uses the network. Application tasks usually run at priority 100.



关键词: replace     vxWorks     network     s    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]