kopia lustrzana https://github.com/mik3y/usb-serial-for-android
test concurrent access on multi-port devices
rodzic
1f35587739
commit
b853ac773c
|
@ -14,6 +14,7 @@ import android.util.Log;
|
|||
import com.hoho.android.usbserial.driver.UsbSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.UsbSerialPort;
|
||||
import com.hoho.android.usbserial.driver.UsbSerialProber;
|
||||
import com.hoho.android.usbserial.util.TestBuffer;
|
||||
import com.hoho.android.usbserial.util.UsbWrapper;
|
||||
|
||||
import org.junit.Before;
|
||||
|
@ -24,12 +25,14 @@ import org.junit.rules.TestWatcher;
|
|||
import org.junit.runner.Description;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
@ -160,4 +163,53 @@ public class CrossoverTest {
|
|||
usb2.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void concurrent() throws Exception {
|
||||
// 115200 baud ~= 11kB/sec => ~1.5 second test duration with 16kB tbuf
|
||||
// concurrent (+ blocking) write calls as tbuf larger than any buffer size returned by UsbWrapper.getWriteSizes()
|
||||
// concurrent read calls in IoManager threads
|
||||
TestBuffer tbuf1 = new TestBuffer(16*1024);
|
||||
TestBuffer tbuf2 = new TestBuffer(16*1024);
|
||||
|
||||
class WriteRunnable implements Runnable {
|
||||
public WriteRunnable(int port) { this.port = port; }
|
||||
private final int port;
|
||||
Exception exc;
|
||||
@Override
|
||||
public void run() {
|
||||
byte[] buf = new byte[1024];
|
||||
try {
|
||||
for(int i=0; i<tbuf1.buf.length / 1024; i++) {
|
||||
System.arraycopy(tbuf1.buf, i*1024, buf, 0, 1024);
|
||||
if (port == 1)
|
||||
usb1.write(buf);
|
||||
else
|
||||
usb2.write(buf);
|
||||
}
|
||||
} catch (IOException exc) {
|
||||
this.exc = exc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
usb1.open();
|
||||
usb2.open();
|
||||
usb1.setParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||
usb2.setParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||
WriteRunnable wr1 = new WriteRunnable(1), wr2 = new WriteRunnable(2);
|
||||
Thread wt1 = new Thread(wr1), wt2 = new Thread(wr2);
|
||||
boolean done1 = false, done2 = false;
|
||||
wt1.start();
|
||||
Thread.sleep(50);
|
||||
wt2.start();
|
||||
while(!done1 && !done2) {
|
||||
if(!done1)
|
||||
done1 = tbuf1.testRead(usb1.read(-1));
|
||||
if(!done2)
|
||||
done2 = tbuf2.testRead(usb2.read(-1));
|
||||
}
|
||||
wt1.join(); wt2.join();
|
||||
assertNull(wr1.exc);
|
||||
assertNull(wr2.exc);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import com.hoho.android.usbserial.driver.UsbSerialPort;
|
|||
import com.hoho.android.usbserial.driver.UsbSerialProber;
|
||||
import com.hoho.android.usbserial.util.SerialInputOutputManager;
|
||||
import com.hoho.android.usbserial.util.TelnetWrapper;
|
||||
import com.hoho.android.usbserial.util.TestBuffer;
|
||||
import com.hoho.android.usbserial.util.UsbWrapper;
|
||||
|
||||
import org.junit.After;
|
||||
|
@ -145,34 +146,6 @@ public class DeviceTest {
|
|||
telnet.tearDownFixture();
|
||||
}
|
||||
|
||||
private static class TestBuffer {
|
||||
private final byte[] buf;
|
||||
private int len;
|
||||
|
||||
private TestBuffer(int length) {
|
||||
len = 0;
|
||||
buf = new byte[length];
|
||||
int i=0;
|
||||
int j=0;
|
||||
for(j=0; j<length/16; j++)
|
||||
for(int k=0; k<16; k++)
|
||||
buf[i++]=(byte)j;
|
||||
while(i<length)
|
||||
buf[i++]=(byte)j;
|
||||
}
|
||||
|
||||
private boolean testRead(byte[] data) {
|
||||
assertNotEquals(0, data.length);
|
||||
assertTrue("got " + (len+data.length) +" bytes", (len+data.length) <= buf.length);
|
||||
for(int j=0; j<data.length; j++)
|
||||
assertEquals("at pos "+(len+j), (byte)((len+j)/16), data[j]);
|
||||
len += data.length;
|
||||
//Log.d(TAG, "read " + len);
|
||||
return len == buf.length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// clone of org.apache.commons.lang3.StringUtils.indexOfDifference + optional startpos
|
||||
private static int indexOfDifference(final CharSequence cs1, final CharSequence cs2) {
|
||||
return indexOfDifference(cs1, cs2, 0, 0);
|
||||
|
@ -816,30 +789,6 @@ public class DeviceTest {
|
|||
assertEquals(availableDrivers.get(0).getClass(), usb.serialDriver.getClass());
|
||||
}
|
||||
|
||||
// return [write packet size, write buffer size(s)]
|
||||
private int[] getWriteSizes() {
|
||||
if (usb.serialDriver instanceof Cp21xxSerialDriver) {
|
||||
if (usb.serialDriver.getPorts().size() == 1) return new int[]{64, 576};
|
||||
else if (usb.serialPort.getPortNumber() == 0) return new int[]{64, 320};
|
||||
else return new int[]{32, 128, 160}; // write buffer size detection is unreliable
|
||||
} else if (usb.serialDriver instanceof Ch34xSerialDriver) {
|
||||
return new int[]{32, 64};
|
||||
} else if (usb.serialDriver instanceof ProlificSerialDriver) {
|
||||
return new int[]{64, 256};
|
||||
} else if (usb.serialDriver instanceof FtdiSerialDriver) {
|
||||
switch (usb.serialDriver.getPorts().size()) {
|
||||
case 1: return new int[]{64, 128};
|
||||
case 2: return new int[]{512, 4096};
|
||||
case 4: return new int[]{512, 2048};
|
||||
default: return null;
|
||||
}
|
||||
} else if (usb.serialDriver instanceof CdcAcmSerialDriver) {
|
||||
return new int[]{64, 128};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeTimeout() throws Exception {
|
||||
usb.open();
|
||||
|
@ -866,7 +815,7 @@ public class DeviceTest {
|
|||
|
||||
int writeBufferSize = writePacketSize * writePackets;
|
||||
Log.d(TAG, "write packet size = " + writePacketSize + ", write buffer size = " + writeBufferSize);
|
||||
int[] writeSizes = getWriteSizes();
|
||||
int[] writeSizes = usb.getWriteSizes();
|
||||
assertNotNull(writeSizes);
|
||||
assertEquals("write packet size", writeSizes[0], writePacketSize);
|
||||
assertTrue("write buffer size", Arrays.binarySearch(writeSizes, writeBufferSize) > 0);
|
||||
|
@ -967,7 +916,7 @@ public class DeviceTest {
|
|||
if(usb.serialDriver instanceof Cp21xxSerialDriver && usb.serialDriver.getPorts().size() == 1)
|
||||
purge = false; // purge is blocking
|
||||
|
||||
int[] writeSizes = getWriteSizes();
|
||||
int[] writeSizes = usb.getWriteSizes();
|
||||
int writePacketSize = writeSizes[0];
|
||||
int writeBufferSize = writeSizes[1];
|
||||
int purgeTimeout = 250;
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package com.hoho.android.usbserial.util;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class TestBuffer {
|
||||
public final byte[] buf;
|
||||
public int len;
|
||||
|
||||
public TestBuffer(int length) {
|
||||
len = 0;
|
||||
buf = new byte[length];
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
for (j = 0; j < length / 16; j++)
|
||||
for (int k = 0; k < 16; k++)
|
||||
buf[i++] = (byte) j;
|
||||
while (i < length)
|
||||
buf[i++] = (byte) j;
|
||||
}
|
||||
|
||||
public boolean testRead(byte[] data) {
|
||||
assertNotEquals(0, data.length);
|
||||
assertTrue("got " + (len + data.length) + " bytes", (len + data.length) <= buf.length);
|
||||
for (int j = 0; j < data.length; j++)
|
||||
assertEquals("at pos " + (len + j), (byte) ((len + j) / 16), data[j]);
|
||||
len += data.length;
|
||||
//Log.d(TAG, "read " + len);
|
||||
return len == buf.length;
|
||||
}
|
||||
}
|
|
@ -12,7 +12,11 @@ import android.net.Uri;
|
|||
import android.util.Log;
|
||||
|
||||
import com.hoho.android.usbserial.driver.CdcAcmSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.Ch34xSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.CommonUsbSerialPort;
|
||||
import com.hoho.android.usbserial.driver.Cp21xxSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.FtdiSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.ProlificSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.UsbSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.UsbSerialPort;
|
||||
|
||||
|
@ -246,15 +250,40 @@ public class UsbWrapper implements SerialInputOutputManager.Listener {
|
|||
}
|
||||
}
|
||||
|
||||
// return [write packet size, write buffer size(s)]
|
||||
public int[] getWriteSizes() {
|
||||
if (serialDriver instanceof Cp21xxSerialDriver) {
|
||||
if (serialDriver.getPorts().size() == 1) return new int[]{64, 576};
|
||||
else if (serialPort.getPortNumber() == 0) return new int[]{64, 320};
|
||||
else return new int[]{32, 128, 160}; // write buffer size detection is unreliable
|
||||
} else if (serialDriver instanceof Ch34xSerialDriver) {
|
||||
return new int[]{32, 64};
|
||||
} else if (serialDriver instanceof ProlificSerialDriver) {
|
||||
return new int[]{64, 256};
|
||||
} else if (serialDriver instanceof FtdiSerialDriver) {
|
||||
switch (serialDriver.getPorts().size()) {
|
||||
case 1: return new int[]{64, 128};
|
||||
case 2: return new int[]{512, 4096};
|
||||
case 4: return new int[]{512, 2048};
|
||||
default: return null;
|
||||
}
|
||||
} else if (serialDriver instanceof CdcAcmSerialDriver) {
|
||||
return new int[]{64, 128};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onNewData(byte[] data) {
|
||||
long now = System.currentTimeMillis();
|
||||
if(readTime == 0)
|
||||
readTime = now;
|
||||
if(data.length > 64) {
|
||||
Log.d(TAG, "usb read: time+=" + String.format("%-3d",now- readTime) + " len=" + String.format("%-4d",data.length) + " data=" + new String(data, 0, 32) + "..." + new String(data, data.length-32, 32));
|
||||
Log.d(TAG, "usb " + devicePort + " read: time+=" + String.format("%-3d",now- readTime) + " len=" + String.format("%-4d",data.length) + " data=" + new String(data, 0, 32) + "..." + new String(data, data.length-32, 32));
|
||||
} else {
|
||||
Log.d(TAG, "usb read: time+=" + String.format("%-3d",now- readTime) + " len=" + String.format("%-4d",data.length) + " data=" + new String(data));
|
||||
Log.d(TAG, "usb " + devicePort + " read: time+=" + String.format("%-3d",now- readTime) + " len=" + String.format("%-4d",data.length) + " data=" + new String(data));
|
||||
}
|
||||
readTime = now;
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue