Home |
Function RTUStartIO |
Function RTUStartIORTUStartIO creates and starts a new transaction on a Bulk, Interrupt, or Isochronous pipe: typedef struct { void * Reserved; int ErrorCode; void * Data; int Len; } RTUIsoBuffer; int RTUStartIO(RTUPipeHandle Pipe, void * Data, int Len); ParametersPipeHandle to the pipe to communicate on. DataPointer to a buffer to store received data for RTUInput endpoints or a buffer from which data is sent for RTUOutput endpoints. For Isochronous endpoints with pipe option RTUIsoBufferList set, this parameter must point to an array of RTUIsoBuffer structures (see below for details). LenNumber of bytes pointed to by parameter Data. For RTUOutput endpoints, this value is always used. For RTUInput endpoints, this parameter must be a multiple of the endpoint's maximum packet size. A device may choose to send less data than requested. For Isochronous endpoints with pipe option RTUIsoBufferList set, this parameter must specify the length in bytes of the array pointed to by parameter Data. return valueIf the pipe handle is valid, the function returns RTU_SUCCESS, and RTU_INVALID_PIPE otherwise. RTUStartIO does not wait until any I/O is performed. It merely initiates the I/O transaction and then returns with code RTU_SUCCESS. If the pipe is in Asynch notification mode (which is the default), the application can use RTUIOWait or RTUIOWaitTimed to wait for the completion of the transaction. For other notification modes, see RTUSetPipeMsgQ and RTUSetPipeCallback, respectively. I/O is asynchronous. The application must ensure that the *Data buffer is not accessed and not deallocated while the transaction is in progress. Note that several I/O transactions can be pending at the same time, even on the same pipe. An application can call RTUStartIO again, even if a previous transaction has not completed yet. The order of transactions is preserved. All pending transactions on the same pipe will complete in the order RTUStartIO was called. Every started transaction will produce exactly one notification event. How the notification is delivered to the application depends on the notification mode established for the given pipe. Transactions which do not complete can be canceled explicitly by the application using RTUCancelIO which produces an RTU_CANCELED notification. An RTU_CANCELED notification is also generated if a pipe is closed with pending transactions. There is no time limit for a transaction and no RTU_TIMEOUT notification. Unless an application calls RTUCancelIO, each started transaction remains active until it completes (either successfully or with an I/O error) or the pipe is closed. Very large values for parameter Len should be avoided. The host controller drivers need RAM resources to manage I/O transactions. For example, the OHCI driver needs about 16 bytes per 8k I/O buffer. If a client requests a transaction to receive 1 megabytes of data on a Bulk endpoint, the driver must dynamically allocate 128 transfer descriptors with 2k total size. On Isochronous endpoints, the OHCI driver needs 4 bytes per frame. If parameter Pipe refers to an Isochronous endpoint, RTUSB-32 must choose a [micro]frame in which the transaction will start. If there is currently no transaction pending on the pipe, the transaction will start after RTUSBConfig.IsoDelay milliseconds (default 4 milliseconds). On the other hand, if at least one transaction is pending, the new transaction will commence on the next [micro]frame after the last currently pending transaction. Thus, a client can implement a contiguous data stream if it uses at least two simultaneous transactions. For Isochronous endpoints, at most 1 second worth of transactions may be pending at any given time (and much less is recommended). RTUSB-32 may not always be able to detect if more transactions are queued, causing undefined results. For High-Speed Isochronous endpoints, the amount of transaction time submitted in a single call to RTUStartIO must be an integral number of milliseconds. For example, if function RTUEndpointInterval reports that the endpoint is serviced every 2 microframes (i.e. ever 250 microseconds), then a multiple of 4 packets must be submitted in a single call to RTUStartIO. For Isochronous IN transactions on systems which do not implement cache coherence in hardware, the start of the receive buffer for the first frame must be an integral multiple of the system cache line size (value RTU_CACHE_LINE_SIZE in file Rtucfg.h). In addition, the allocated block of memory holding the buffer must have a size which is an integral multiple of the system cache line size. This restriction does not apply to x86 systems. For more information about Isochronous transfers, please refer to section Isochronous Transfers of chapter Advanced Topics in the RTUSB-32 Programming Manual. Pipe Option RTUIsoBufferListFor Isochronous endpoints with pipe option RTUIsoBufferList set, an array of RTUIsoBuffer structures must be passed to RTUStartIO. Each entry in this array describes the transfer for one [micro]frame. Each RTUIsoBuffer.Data must point to a buffer from/to which the transaction will be performed. for RTUOutput endpoints, RTUIsoBuffer.Len is the number of bytes to be sent in each respective [micro]frame. For RTUInput endpoints, RTUIsoBuffer.Len is ignored and assumed to be the maximum logical packet size of the endpoint. All frame buffers (RTUIsoBuffer.Data) to be used in a single transaction must be allocated from a single block of memory such that RTUIsoBuffer[i+1].Data is either (RTUIsoBuffer[i+0].Data + RTUIsoBuffer[i+0].Len) or (RTUIsoBuffer[i+0].Data + MaxPacketLen). After the transaction has been completed, each RTUIsoBuffer.ErrorCode is set to the frame number (or microframe number for High-Speed and faster endpoints) in which the transfer occurred, or, in case of an error, a negative error code. For IN endpoints, RTUIsoBuffer.Len will contain the actual number of bytes received in each [micro]frame.
|