Question regarding END_RCV_RTN_CALL - VxWorks
This is a discussion on Question regarding END_RCV_RTN_CALL - VxWorks ; I have written an Ethernet driver (integrated with VxWorks) on ARM926
EJ_S.
There are following problems that I am facing:
a) VxWorks Network Stack Alignment problem: This is a standard problem
with VxWorks Network Stack. The stack crashes if the ...
-
Question regarding END_RCV_RTN_CALL
I have written an Ethernet driver (integrated with VxWorks) on ARM926
EJ_S.
There are following problems that I am facing:
a) VxWorks Network Stack Alignment problem: This is a standard problem
with VxWorks Network Stack. The stack crashes if the payload is not
word aligned. To circumvent this problem I am currently coyping the
incoming ethernet packet from one buffer to another with a 2-byte
offset. Is there any other solution to this?
b) The END_RCV_RTN_CALL that is being used in the Receive function of
the driver is taking hell lot of time. I instrumented the receive call
with WindView Graphs and found out that most of the time is being spent
in this call. The entire receive function takes on average 220 us and
the contribution of this function is approx 193 us. The amount of time
being taken by the receive function is very high and is unacceptable.
I need to reduce the time being taken by the receive function
drastically, anybody who can tell me an alternative to
END_RCV_RTN_CALL!!!!!!!!
Thanks in advance.
P.S. END_RCV_RTN_CALL is used to pass the incoming packet to the upper
layers(protocol).
END_RCV_RTN_CALL(pEnd,pMblk)
Where pEnd is END_OBJ * and pMblk is M_BLK_ID.
-
Re: Question regarding END_RCV_RTN_CALL
a) I deal with this issue on MIPS. Rather than copying, adjust the
offset when you get a packet buffer. That way when you copy the data in
it is already aligned and you can avoid the redundant copy for
alignment.
b) You did say that you wrote the end driver, right? The MACRO just
calls the receiveRtn() function of your end driver.
>From endlib.h:
#define END_RCV_RTN_CALL(pEnd,pMblk) \
if ((pEnd)->receiveRtn) \
{ \
(pEnd)->receiveRtn ((pEnd), pMblk,NULL,NULL,NULL,NULL); \
}
-
Re: Question regarding END_RCV_RTN_CALL
>> a) I deal with this issue on MIPS. Rather than copying, adjust the
>> offset when you get a packet buffer. That way when you copy the data in
>> it is already aligned and you can avoid the redundant copy for
>> alignment.
You can do this by asking the MAC to receive at
pBuf+VXW_RCV_BUF_OFFSET. I assume VXW_RCV_BUF_OFFSET would be 2 for
MIPS. So your actual data (pData) will start at pBuf+VXW_RCV_BUF_OFFSET
netClBlkJoin(pClBlk, pData - VXW_RCV_BUF_OFFSET, MAX_FRAME_SIZE);
netMblkClJoin(pMblk, pClBlk);
pMblk->mBlkHdr.mFlags |= M_PKTHDR;
pMblk->mBlkHdr.mLen = len;
pMblk->mBlkHdr.mData = pData ;
pMblk->mBlkPktHdr.len = len;
END_RCV_RTN_CALL (&endObj, pMblk);
I just repeated what ifdef said with code.
>> b) You did say that you wrote the end driver, right? The MACRO just
>> calls the receiveRtn() function of your end driver.
>> >From endlib.h:
>>
>> #define END_RCV_RTN_CALL(pEnd,pMblk) \
>> if ((pEnd)->receiveRtn) \
>> { \
>> (pEnd)->receiveRtn ((pEnd), pMblk,NULL,NULL,NULL,NULL); \
>> }
I think most drivers do not write this routine themselves - but use
muxTkReceive( ) as pEnd->receiveRtn. From the Network Protocol Toolkit
Programmer's guide appendix A:
A) Explanation of END_OBJ's receiveRtn:
A function pointer that references a receive routine in the MUX. The
MUX supplies this pointer when the driver is loaded. Any time after the
completion of the muxDevLoad( ) call, the driver can use this
receiveRtn( ) to pass data up to the protocol layer. The prototype for
this receive routine is:
STATUS receiveRtn
(
void * pCookie, /* The cookie passed in to endLoad() */
M_BLK_ID pMblk /* The packet, as an mblk chain */
)
B). Explanation of muxTkReceive( ):
Typically, a driver includes an interrupt handling routine to process
received packets. It should keep processing to a minimum during
interrupt context and then arrange for processing of the received
packet itself within task context.
Once the frame has been validated, it should be passed to the MUX with
muxTkReceive( ).***1 The muxTkReceive( ) function forwards the data to
the network service sublayer by calling the stackRcvRtn( ) registered
for that sublayer.
The footnote ***1 is:
1: This function is registered by the MUX as the receiveRtn in the
END_OBJ data structure for the device. The driver should make a call to
this reference rather than calling muxTkReceive( ) directly.
-
Re: Question regarding END_RCV_RTN_CALL
I haven't written receiveRtn() function and as Abhijit also says
pEnd->receiveRtn calls muxTkReceive. Does it mean that whatever
function I have written for receiving a packet is actually the
pEnd->receiveRtn. I am not very clear on this point. Can anybody
illustrate it?
Thanks in advance.
-
Re: Question regarding END_RCV_RTN_CALL
No pEnd->receiveRtn is not your driver receive routine but it is set to
muxTkReceive when muxDevLoad is called for the driver:
Read:
http://www.eelab.usyd.edu.au/tornado...DLDrivers.html
Section 10.1.3:
10.1.3 The Datalink-to-MUX Interface
To add an END or NPT device to the MUX, call muxDevLoad( ) for each
driver you want to add. This is done for you automatically in the
standard network initialization code if you name the driver's load
function in the endDevTbl[ ]. The stack initialization code uses this
function name as input to a muxDevLoad( ) call.
Internally, the driver's load function must allocate and partially
populate an END_OBJ structure and a NET_FUNCS structure. The END_OBJ
structure provides the MUX with a description of the device, and the
NET_FUNCS structure provides the MUX with pointers to the driver's
standard MUX interface functions, xStart( ), xStop( ), xReceive( ),
xIoctl( ), and so on.
After a driver is loaded in to the MUX and has been bound to a
protocol, it can pass received packets up to the MUX by calling
muxReceive( ), if it is an END, or muxTkReceive( ), in NPT
drivers.1****
=====================================
The footnote 1**** (bottom of the page) is:
1: The mux[Tk]Receive( ) calls in the shipped ENDs and the template
END are hard to identify as such when casually reading the code. When
passing a packet up to the MUX, each of these drivers uses the function
pointer referenced in the receiveRtn member of its END_OBJ. An earlier
call to muxDevLoad( ) set the receiveRtn member to muxReceive( ) or
muxTkReceive( ), whichever was appropriate.
========================
Also read:
Section 10.2.2.
-
Re: Question regarding END_RCV_RTN_CALL
Can I somehow see the code for pEnd->receiveRtn, can I change it some
how?????
Thanks in advance.