📄 vxw_pt4.html
字号:
<p>After installing the new driver binary, add the following to thesysDec*.c file in the MV2700 directory:<pre> sprintf (cp, decParamTemplate, (UINT) (iobaseCsr), /* device io base */ (UINT) PCI_SLV_MEM_BUS, /* pciMemBase */ irqvec, /* interrupt irq vector */ irqnum, /* interrupt irq number */ /*NET_END_USER_FLAGS);*/ NET_END_USER_FLAGS | DEC_USR_MII, 8, /* phyAddr*/ 0, /*pPhyTbl*/ /*phyFlags*/ DEC_USR_MII_10MB | DEC_USR_MII_100MB | DEC_USR_MII_HD | DEC_USR_MII_FD );</pre>This will allow the driver to properly negotiate **AND** setup thehardware for the correct mode. If the network link duplex changes whilethe system is booted, then the system will have to be reset in order forthe driver to properly update the hardware settings. Actually, thedriver works when changing from half to full but not from full to half.<br>(From: Greg Willden, gwillden@swri.edu)<p><hr WIDTH="50%"><a NAME="4.8-E"></a><p>Q: Is there any vxworks routine to get the default gateway address on a vxworks target?<p>A: I haven't seen an API routine, but... The data is globally available inthe kernels we use via the bootline parameters:<pre>BOOT_PARAMS params;extern char *sysBootLine;if (usrBootLineCrack (sysBootLine, &params) == OK){ if (params.gad[0] != EOS) { /* it is specified... */ routeAdd ("0.0.0.0", params.gad); }}</pre>(From: Edsel Harrell, eah@raytheon.com)<p><hr WIDTH="50%"><a NAME="4.8-F"></a><p>Q: How do I get the MAC address using the VxWorks API?<p>A: Here's how I do it:<pre> UINT8 macBuffer[8]; sysCpmEnetAddrGet(0, macBuffer); MacAddr = nlprintf("0x%02X%02X%02X%02X%02X%02X", macBuffer[0], macBuffer[1], macBuffer[2], macBuffer[3], macBuffer[4], macBuffer[5]);</pre>(From: Jim Way, Jway@datum.com)<p><hr WIDTH="50%"><a NAME="4.8-G"></a><p>Q: Is well-known port 7 implemented, and if not, how can I implement this?<p>A: As far as I know this is not implemented in release 5.4.Our implementation did a readfrom/sendtoas this gives you the source address<br>Here is the 'work part' of our echo daemon:<pre>struct sockaddr sa;char buffer[BUFFSIZE];int i,size;if((i=recvfrom(s,buffer,sizeof(buffer),0,&sa,&size))) < 0) return;(void) sendto(s,buffer,i,0,&sa,sizeof(sa)); return;</pre>Since the recvfrom is blocking, you just create a SOCK_DGRAM socketand bind it to port 7, then perform the above in a 'while(1)' loop.<br>From: Michael Baumann, baumann@optivus.com)<p><hr WIDTH="50%"><a NAME="4.8-H"></a><p>Q: When calling netPoolDelete,does the memory get freed?<p>A: The pNetPool memory will not be freed. It will be bzero'd beforenetPoolDelete returns. The pPoolStat, if non-null will be freed and the CL_POOLclTbl[CL_TBL_SIZE] will be checked and nulled after freeing entries thathave been malloc'd.<br>(From: DrDiags, drdiags@flashcom.net)<p><hr WIDTH="50%"><a NAME="4.8-I"></a><p>Q: How do I change the MAC-address of an interface?<p>A: This answer consists of 2 parts, the <A HREF="#4.8-I1">first</A> partdescribes how to change the MAC-address itself, the <A HREF="#4.8-I2">second</A>part describes how to propagate this change onto the network.<hr WIDTH="20%"><br><a NAME="4.8-I1"></a>I had to resolve this problem a while ago - in my case the result of someoneremoving one pcmcia network card and later adding a second.<br>On removal I call ipDetach() then ipAttach() and usrNetIfConfig() when a newcard is installed. (I don't even attempt to remove the driver from the mux. I'm not that brave.)<br>Anyway during the remove I remove everything from the arp table and route table.(arpFlush() and ifRouteDelete() get most of them).<br>However in order to generate correct ARP responses it is necessary to hack therelevant data area - vxWorks arp only requests the MAC address when an interfaceis linked. The following code will update the data item:<pre> IP_DRV_CTRL *ip_info; int unit; extern int ipMaxUnits; for (unit = 0; unit < ipMaxUnits; unit++) { ip_info = ipDrvCtrl + unit; if (strcmp( if_name, ip_info->idr.ac_if.if_name )) continue; if (if_unit != ip_info->idr.ac_if.if_unit) continue; bcopy( new_address, ip_info->idr.ac_enaddr, 6 ); break; }</pre>(From David Laight, dsl@tadpole.co.uk)<hr WIDTH="20%"><br><a NAME="4.8-I2"></a>Now you have to wait 5-20 minutes for the ARP tables on all the machines onthe local LAN to time out their entry for your IP address. OR you need tobroadcast an unsolicited or gratuitous ARP to update their ARP tables.There are a few ways you can do this:<ul><li>Bring the interface down then up. The TCP/IP stack should broadcast anunsolicited ARP when it brings up an interface with an IP address.</li><li>call ifAddrSet() on the interface. The stack broadcasts an unsolicited ARPwhen an IP address is assigned to an interface.</li><li>open a raw socket, create and populate your own unsolicited ARP packet, thenbroadcast it.</li></ul>(From: James Marshall, james_marshall@agilent.com)<p><hr WIDTH="50%"><a NAME="4.8-J"></a><p>Q: Is there a rsh deamon for VxWorks?<p>A: Yes, you can find it here: <a href="rshd.c">rshd.c</a><br>(From: Matt Wette, Matthew.R.Wette@jpl.nasa.gov)<p><hr WIDTH="50%"><a NAME="4.8-K"></a><p>Q: How to delelte a IP address added by ifAddrAdd()<p>A: The vxWorks routing API sucks because it is buggy. I have had myriadproblems with the mRoute* functions, so I refuse to use them anymore.ifAddrAdd works OK as long as you don't have any special needs.If you need to add an address to a point-to-point interface, forexample, ifAddrAdd doesn't work.<br>However, the underlying Berkeley API works just fine and is flexibleand powerful. It's less user-friendly, but that's a small price to payfor gaining the advantage of having code that actually works.<br>Here is an example of using the underlying API to implement the functionthat you need. And, yes, it is appalling that WRS did not supply afunction that is orthogonal to ifAddrAdd.<pre>STATUS ifAddrDel(char *pDevName, char *pIfAddr){ int sockFd; int err; struct ifreq ifr; u_long ifAddr; /* * Convert string to int */ ifAddr = inet_addr(pIfAddr); bzero ( (char *)&ifr, sizeof( struct ifreq ) ); strcpy(ifr.ifr_name, pDevName); /* the interface address to delete is ifAddr */ ifr.ifr_addr.sa_len = sizeof( struct sockaddr_in ); ((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET; ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr = ifAddr; if( (sockFd = socket( AF_INET, SOCK_RAW, 0 )) == NULL ){ /* 2, 3, 0 */ printf("ifAddrDel: couldn't open socket\n"); return( ERROR ); } /* * SIOCDIFADDR can be found in sys/ioctl.h. This is: * Socket IOControl Delete InterFace ADDress * * ioctl returns 0 on success, error code on failure */ err = ioctl( sockFd, SIOCDIFADDR, (int)&ifr ); close( sockFd ); if( err ){ printf("ifAddrDel: ioctl failed with error %d\n", err); return( ERROR ); } return( OK );}</pre>(From: Victor Sperry, vsperry@paradyne.com)<p><hr WIDTH="50%"><a NAME="4.8-L"></a><p>Q: How can I get the default gateway from the bootline to be thedefault gateway?<p>A: Thanks to a suggestion by Michael Lawnick Ipilfered some code from the bootConfig.c file and threw it intousrAppInit.c. This was to get the gateway from the bootline.... The systemnow works the way it should from the factory. Here is an excerpt of mycode:<pre>#include "vxWorks.h"#include "bootLib.h"#include "prjParams.h"void usrAppInit (void){ BOOT_PARAMS params;#ifdef USER_APPL_INIT USER_APPL_INIT; /* for backwards compatibility */#endif /* add application specific code here */ bootStringToStruct (BOOT_LINE_ADRS, &params); if ((sysNvRamGet (BOOT_LINE_ADRS, BOOT_LINE_SIZE, 0) == ERROR) || (*BOOT_LINE_ADRS == EOS)) { /* either no non-volatile RAM or empty boot line */ printf("Adding hardwired gateway\n"); routeAdd ("0.0.0.0", "155.34.103.1"); } else { printf("Adding gateway %s from bootline\n", params.gad); routeAdd("0.0.0.0", params.gad); }}</pre>(From: Joe Georger, jgeorger@ll.mit.edu)<p><hr WIDTH="50%"><a NAME="4.8-M"></a><p>Q: Problems with high speed networks and netTask.<p>A: I think you might be right about this point. The netJobAdd (and netTask)presents some problems especially in throughput and latency performance whenusing very high speed networks. I am at least partly responsible for thisunfortunately. The problem is a little more involved than just netTask.<br>One of the reasons why netTask exists is to allow packet handling to happenin task level code. Since most of kernel facilities (e.g. semTake) cannotbe called from within interrupt level code, it is necessary to make suremost of packet handling code (TCP/IP stack) happens in task level. Doing anetJobAdd() is one solution for this. netJobAdd() is nothing but a msgQ.You send a message to netTask to do the job (I got a packet, so process itat task level). It also helps to minimize interrupt latency (interrupts arelocked out for short time since most of the work is done in task level).<br>Another reason why netTask exists is because VxWorks TCP/IP stack is notre-entrant. The whole stack runs in non-reentrant fashion. So netTaskdoes a "hack" -- it takes a semaphore, runs code in TCP/IP stack, thenyields the semaphore.<br>These are not good reasons necessarily, but they are what they are.<p>The performance issues, especially in throughput performance case, aresignificant. It is possible to think of it this way: you have a system(VxWorks) which tries very hard to minimize interrupt latency and maintaingood response time (i.e. real-time). The inherent requirement here goessomewhat against the goal of high throughput. If you have to togglebetween interrupt and task level code back and forth for every packet, yourinterrupt latency is minimized, but you actually do more work per packet.The systems which I have worked on which emphasizes throughput overall donot work this way. The best throughput oriented system (e.g. NetworkAppliance file server appliances) uses combinations of cooperativemultitasking kernel and heuristic (hand-tuned) packet handling / schedulingto maximize throughput while keeping latency low. Such systems also employvery low overhead socket layer (direct access to mbufs from applications).<p>There are a lot of things to consider when trying for the optimalperformance (in both throughput and latency). VxWorks network stack isgood, but it is not the best performing stack. If you port Linux or BSD onthe same hardware and run TCP/IP benchmarks, you will see that Linux and BSDperform better in general. This is not just the VxWorks network stackissue either. It has to do with the overall architecture of VxWorks, beinga real-time system. It has to do certain things that other systems do not.Things like keeping latency low. But in reality, the artificial constraints(code!) turn out the end result which provides small benefit in terms oflatency with much larger throughput degradation. This is not to faultVxWorks at all, since it is very good at doing real-time stuff. But a lotof VxWorks usage nowadays is in the area of networking. And networking isnot necessarily real-time. The minute you throw TCP/IP and ethernet andwhat not into your OS, your OS is not really hard real-time, at least fromoverall perspective.<br>Since overall requirement nowadays seems to favor good balance of latencyand throughput performance in network portion of VxWorks, it makes a lot ofsense to think of how to achieve it. You cannot achieve this by addingzBuf. If you study the design and actual real life performance of the socalled zBuf, you will notice that it is no better or worse than normalbuffers. There are better ways of solving that "extra copy" problem --just use mbufs. Also, you cannot help solve this problem by adding a newdriver paradigm (END, SENS). You simply introduce more overhead in the codepath for very little benefit (if any).<p>In my opinion what should happen (what I should have done while at WRS) isto create alternate runtime behavior for the network traffic. If users wishto use VxWorks in non-realtime way, just for the goal of "fast networking",the users should be given a chance. This can be done. Some of thingsthat should happen :<ol><li>re-think netTask. At minimum, it should be demoted to smaller roll.Right now it is a central clearing house for all network I/O. A packetcomes in, netJobAdd'ed, and netTask does everything for the packet for itslifetime. This is done for all packets, all network interfaces, and theentire TCP/IP stack. Not only is this single point of failure (if somethingbad happens to netTask due to one of the network interfaces the wholenetwork subsystem of VxWorks is down), it is definitely not in the spirit ofkeeping the realtime nature of the system. At minimum, each networkinterface should be allowed to have its own task at a desired priority. Apacket comes in and handed off directly to each task. The handing off canbe done in a simple way, just semGive. Much lower overhead (but there isstill task switch overhead).</li><li>re-think overall runtime. Some attempts are made even in current code tominimize calls to netJobAdd() , at least in some drivers not all. Forexample, it is silly to call netJobAdd() for every packet that comes in. Ithelps to see if it is necessary to call netJobAdd() first. If netTask is
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -