Increase default read/write buffer sizes; allow tuning.

pull/36/head
mike wakerly 2012-10-11 19:40:54 -07:00
rodzic c5e9955b01
commit b328f3cbc9
3 zmienionych plików z 123 dodań i 64 usunięć

Wyświetl plik

@ -1,7 +1,6 @@
package com.hoho.android.usbserial.driver;
import java.io.IOException;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
@ -21,8 +20,6 @@ public class CdcAcmSerialDriver extends UsbSerialDriver {
private final String TAG = CdcAcmSerialDriver.class.getSimpleName();
private final byte[] mReadBuffer = new byte[4096];
private UsbInterface mControlInterface;
private UsbInterface mDataInterface;
@ -96,47 +93,55 @@ public class CdcAcmSerialDriver extends UsbSerialDriver {
@Override
public int read(byte[] dest, int timeoutMillis) throws IOException {
int readAmt = Math.min(dest.length, mReadBuffer.length);
readAmt = Math.min(readAmt, mReadEndpoint.getMaxPacketSize());
final int transferred = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer, readAmt,
timeoutMillis);
if (transferred < 0) {
// This sucks: we get -1 on timeout, not 0 as preferred.
// We *should* use UsbRequest, except it has a bug/api oversight
// where there is no way to determine the number of bytes read
// in response :\ -- http://b.android.com/28023
return 0;
final int numBytesRead;
synchronized (mReadBufferLock) {
int readAmt = Math.min(dest.length, mReadBuffer.length);
readAmt = Math.min(readAmt, mReadEndpoint.getMaxPacketSize());
numBytesRead = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer, readAmt,
timeoutMillis);
if (numBytesRead < 0) {
// This sucks: we get -1 on timeout, not 0 as preferred.
// We *should* use UsbRequest, except it has a bug/api oversight
// where there is no way to determine the number of bytes read
// in response :\ -- http://b.android.com/28023
return 0;
}
System.arraycopy(mReadBuffer, 0, dest, 0, numBytesRead);
}
System.arraycopy(mReadBuffer, 0, dest, 0, transferred);
return transferred;
return numBytesRead;
}
@Override
public int write(byte[] src, int timeoutMillis) throws IOException {
// TODO(mikey): Nearly identical to FtdiSerial write. Refactor.
int offset = 0;
final int chunksize = mWriteEndpoint.getMaxPacketSize();
while (offset < src.length) {
final byte[] writeBuffer;
final int writeLength;
final int amtWritten;
// bulkTransfer does not support offsets; make a copy if necessary.
writeLength = Math.min(src.length - offset, chunksize);
if (offset == 0) {
writeBuffer = src;
} else {
writeBuffer = Arrays.copyOfRange(src, offset, offset + writeLength);
synchronized (mWriteBufferLock) {
final byte[] writeBuffer;
writeLength = Math.min(src.length - offset, mWriteBuffer.length);
if (offset == 0) {
writeBuffer = src;
} else {
// bulkTransfer does not support offsets, make a copy.
System.arraycopy(src, offset, mWriteBuffer, 0, writeLength);
writeBuffer = mWriteBuffer;
}
amtWritten = mConnection.bulkTransfer(mWriteEndpoint, writeBuffer, writeLength,
timeoutMillis);
}
final int amt = mConnection.bulkTransfer(mWriteEndpoint, writeBuffer, writeLength,
timeoutMillis);
if (amt <= 0) {
if (amtWritten <= 0) {
throw new IOException("Error writing " + writeLength
+ " bytes at offset " + offset + " length=" + src.length);
}
Log.d(TAG, "Wrote amt=" + amt + " attempted=" + writeBuffer.length);
offset += amt;
Log.d(TAG, "Wrote amt=" + amtWritten + " attempted=" + writeLength);
offset += amtWritten;
}
return offset;
}

Wyświetl plik

@ -22,7 +22,6 @@ package com.hoho.android.usbserial.driver;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
@ -38,8 +37,8 @@ import com.hoho.android.usbserial.util.HexDump;
/**
* A {@link UsbSerialDriver} implementation for a variety of FTDI devices
* <p>
* This driver is based on <a
* href="http://www.intra2net.com/en/developer/libftdi">libftdi</a>, and is
* This driver is based on
* <a href="http://www.intra2net.com/en/developer/libftdi">libftdi</a>, and is
* copyright and subject to the following terms:
*
* <pre>
@ -142,11 +141,6 @@ public class FtdiSerialDriver extends UsbSerialDriver {
public static final int FTDI_DEVICE_IN_REQTYPE =
UsbConstants.USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN;
/**
* Size of chunks, used in {@link #write(byte[], int)}.
*/
private static final int WRITE_CHUNKSIZE = 4096;
/**
* Length of the modem status header, transmitted with every read.
*/
@ -156,8 +150,6 @@ public class FtdiSerialDriver extends UsbSerialDriver {
private DeviceType mType;
private final byte[] mReadBuffer = new byte[4096];
/**
* FTDI chip types.
*/
@ -228,10 +220,15 @@ public class FtdiSerialDriver extends UsbSerialDriver {
@Override
public int read(byte[] dest, int timeoutMillis) throws IOException {
final int readAmt = Math.min(dest.length, mReadBuffer.length);
final UsbEndpoint endpoint = mDevice.getInterface(0).getEndpoint(0);
if (ENABLE_ASYNC_READS) {
final int readAmt;
synchronized (mReadBufferLock) {
// mReadBuffer is only used for maximum read size.
readAmt = Math.min(dest.length, mReadBuffer.length);
}
final UsbRequest request = new UsbRequest();
request.initialize(mConnection, endpoint);
@ -245,27 +242,32 @@ public class FtdiSerialDriver extends UsbSerialDriver {
throw new IOException("Null response");
}
final int nread = buf.position() - MODEM_STATUS_HEADER_LENGTH;
if (nread > 0) {
final int payloadBytesRead = buf.position() - MODEM_STATUS_HEADER_LENGTH;
if (payloadBytesRead > 0) {
Log.d(TAG, HexDump.dumpHexString(dest, 0, Math.min(32, dest.length)));
return nread;
return payloadBytesRead;
} else {
return 0;
}
} else {
final int transferred = mConnection.bulkTransfer(endpoint, mReadBuffer, readAmt,
timeoutMillis);
if (transferred < MODEM_STATUS_HEADER_LENGTH) {
final int totalBytesRead;
synchronized (mReadBufferLock) {
final int readAmt = Math.min(dest.length, mReadBuffer.length);
totalBytesRead = mConnection.bulkTransfer(endpoint, mReadBuffer,
readAmt, timeoutMillis);
}
if (totalBytesRead < MODEM_STATUS_HEADER_LENGTH) {
throw new IOException("Expected at least " + MODEM_STATUS_HEADER_LENGTH + " bytes");
}
final int nread = transferred - MODEM_STATUS_HEADER_LENGTH;
if (nread > 0) {
System.arraycopy(mReadBuffer, MODEM_STATUS_HEADER_LENGTH, dest, 0, nread);
final int payloadBytesRead = totalBytesRead - MODEM_STATUS_HEADER_LENGTH;
if (payloadBytesRead > 0) {
System.arraycopy(mReadBuffer, MODEM_STATUS_HEADER_LENGTH, dest, 0, payloadBytesRead);
}
return nread;
return payloadBytesRead;
}
}
@Override
@ -274,25 +276,32 @@ public class FtdiSerialDriver extends UsbSerialDriver {
int offset = 0;
while (offset < src.length) {
final byte[] writeBuffer;
final int writeLength;
final int amtWritten;
// bulkTransfer does not support offsets; make a copy if necessary.
writeLength = Math.min(src.length - offset, WRITE_CHUNKSIZE);
if (offset == 0) {
writeBuffer = src;
} else {
writeBuffer = Arrays.copyOfRange(src, offset, offset + writeLength);
synchronized (mWriteBufferLock) {
final byte[] writeBuffer;
writeLength = Math.min(src.length - offset, mWriteBuffer.length);
if (offset == 0) {
writeBuffer = src;
} else {
// bulkTransfer does not support offsets, make a copy.
System.arraycopy(src, offset, mWriteBuffer, 0, writeLength);
writeBuffer = mWriteBuffer;
}
amtWritten = mConnection.bulkTransfer(endpoint, writeBuffer, writeLength,
timeoutMillis);
}
final int amt = mConnection.bulkTransfer(endpoint, writeBuffer, writeLength,
timeoutMillis);
if (amt <= 0) {
if (amtWritten <= 0) {
throw new IOException("Error writing " + writeLength
+ " bytes at offset " + offset + " length=" + src.length);
}
Log.d(TAG, "Wrote amt=" + amt + " attempted=" + writeBuffer.length);
offset += amt;
Log.d(TAG, "Wrote amtWritten=" + amtWritten + " attempted=" + writeLength);
offset += amtWritten;
}
return offset;
}

Wyświetl plik

@ -32,12 +32,27 @@ import android.hardware.usb.UsbDeviceConnection;
*/
public abstract class UsbSerialDriver {
public static final int DEFAULT_READ_BUFFER_SIZE = 16 * 1024;
public static final int DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024;
protected final UsbDevice mDevice;
protected final UsbDeviceConnection mConnection;
protected final Object mReadBufferLock = new Object();
protected final Object mWriteBufferLock = new Object();
/** Internal read buffer. Guarded by {@link #mReadBufferLock}. */
protected byte[] mReadBuffer;
/** Internal write buffer. Guarded by {@link #mWriteBufferLock}. */
protected byte[] mWriteBuffer;
public UsbSerialDriver(UsbDevice device, UsbDeviceConnection connection) {
mDevice = device;
mConnection = connection;
mReadBuffer = new byte[DEFAULT_READ_BUFFER_SIZE];
mWriteBuffer = new byte[DEFAULT_WRITE_BUFFER_SIZE];
}
/**
@ -93,4 +108,34 @@ public abstract class UsbSerialDriver {
return mDevice;
}
/**
* Sets the size of the internal buffer used to exchange data with the USB
* stack for read operations. Most users should not need to change this.
*
* @param bufferSize the size in bytes
*/
public final void setReadBufferSize(int bufferSize) {
synchronized (mReadBufferLock) {
if (bufferSize == mReadBuffer.length) {
return;
}
mReadBuffer = new byte[bufferSize];
}
}
/**
* Sets the size of the internal buffer used to exchange data with the USB
* stack for write operations. Most users should not need to change this.
*
* @param bufferSize the size in bytes
*/
public final void setWriteBufferSize(int bufferSize) {
synchronized (mWriteBufferLock) {
if (bufferSize == mWriteBuffer.length) {
return;
}
mWriteBuffer = new byte[bufferSize];
}
}
}