|
The Transmit Thread (TT) is started from the RtndConfigure routine by calling CreateRealtimeThread. The RtndConfigure routine normally passes the local card information structure pointer as a parameter to the DrvRecvThread routine, though this is driver dependent and up to the driver developer.
The TT is responsible for completing the transmit packet processing by waiting for a transmit done event and then calling RtnTransmitDone. Note that a Transmit thread is not always needed by a driver. A Transmit thread should be started if the driver requires that a packet be completed (transmitted) before the next packet is handed to the RtndTransmit routine. In this case, a Transmit thread which calls RtnTransmitDone after the transmit done interrupt will be required. The driver Interrupt Service thread will notify the Transmit thread that the packet is complete with a SetEvent call.
NOTE: RtnTransmitDone cannot be called from the Transmit interrupt itself. This is very likely to invoke a deadlock with critical sections.
If the driver can handle queuing multiple packets within the driver transmit buffers, then it may safely call RtnTransmitDone in the RtndTransmit routine and there is no need to have a Transmit thread. In this case, the driver must copy the data from the packet passed to RtndTransmit into its local transmit buffer queue before calling RtnTransmitDone.
NOTE: RtnTransmitDone frees the most recent packet handed to RtndTransmit, so the data must either be sent or copied before calling RtnTransmitDone.
Syntax
static ULONG WINAPI DrvXmitThread( DRVDEV* pCardInfo );
Parameters
pCardInfo
Pointer to local card information structure for this instance of the driver.
Return Values
None - Does not actually return.
Process Context
DrvXmitThread always runs within the process context of the RtxTcpIp Protocol Stack.
static ULONG WINAPI DrvXmitThread ( DRVDEV* pCardInfo ) { for (;;) { // code here is optional; //if the ISR signals us when a packet has // been transmitted, we wait for it here WaitForSingleObject (pCardInfo->hXmitEvent, INFINITE); // if RtnTrandmitDone not called from RtndTransmit, then // call it here in response to a transmit done interrupt // from card. RtnTransmitDone (pCardInfo->ndp); } }