python - usb bulk transfer(Loopback) speed test

python - usb bulk transfer speed test

1. install libusb on PC

2. pip install pyusb

3. libusb for usb device

3.1 windows:

run 'libusb-win32-bin-1.2.6.0\bin\inf-wizard.exe' with admin to setup libusb port for slave device.

4. Enable Loopback port on your device.

4.1 Add loopback function for SDM630 :

diff --git a/arch/arm64/configs/sdm660_defconfig b/arch/arm64/configs/sdm660_defconfig
index 041e661..0884e6c 100644
--- a/arch/arm64/configs/sdm660_defconfig
+++ b/arch/arm64/configs/sdm660_defconfig
@@ -486,6 +486,8 @@ CONFIG_USB_CONFIGFS_F_HID=y
 CONFIG_USB_CONFIGFS_F_DIAG=y
 CONFIG_USB_CONFIGFS_F_CDEV=y
 CONFIG_USB_CONFIGFS_F_QDSS=y
+CONFIG_USB_CONFIGFS_F_LB_SS=y
+CONFIG_USB_TEST=y
 CONFIG_MMC=y
 CONFIG_MMC_PERF_PROFILING=y
 CONFIG_MMC_RING_BUFFER=y
4.2 Add loopback config on sdm630:
diff --git a/rootdir/etc/init.msm.usb.configfs.rc b/rootdir/etc/init.msm.usb.configfs.rc
index 35d243e..3ffc6ab 100644
--- a/rootdir/etc/init.msm.usb.configfs.rc
+++ b/rootdir/etc/init.msm.usb.configfs.rc
@@ -63,6 +63,27 @@ on property:sys.usb.ffs.ready=1 && property:sys.usb.config=mass_storage,adb && p
     write /config/usb_gadget/g1/UDC ${sys.usb.controller}
     setprop sys.usb.state ${sys.usb.config}

+on property:sys.usb.config=lbss,adb && property:sys.usb.configfs=1
+    start adbd
+
+on property:sys.usb.ffs.ready=1 && property:sys.usb.config=lbss,adb && property:sys.usb.configfs=1
+    write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "usbtest"
+    rm /config/usb_gadget/g1/configs/b.1/f1
+    rm /config/usb_gadget/g1/configs/b.1/f2
+    rm /config/usb_gadget/g1/configs/b.1/f3
+    rm /config/usb_gadget/g1/configs/b.1/f4
+    rm /config/usb_gadget/g1/configs/b.1/f5
+    rm /config/usb_gadget/g1/configs/b.1/f6
+    rm /config/usb_gadget/g1/configs/b.1/f7
+    rm /config/usb_gadget/g1/configs/b.1/f8
+    write /config/usb_gadget/g1/idVendor 0x05C6
+    write /config/usb_gadget/g1/idProduct 0x8015
+    symlink /config/usb_gadget/g1/functions/Loopback.0 /config/usb_gadget/g1/configs/b.1/f1
+    symlink /config/usb_gadget/g1/functions/SourceSink.0 /config/usb_gadget/g1/configs/b.1/f2
+    symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f3
+    write /config/usb_gadget/g1/UDC ${sys.usb.controller}
+    setprop sys.usb.state ${sys.usb.config}
+
 on property:sys.usb.config=diag,adb && property:sys.usb.configfs=1
     start adbd

diff --git a/rootdir/etc/init.qcom.usb.rc b/rootdir/etc/init.qcom.usb.rc
index b6cd138..10920b5 100644
--- a/rootdir/etc/init.qcom.usb.rc
+++ b/rootdir/etc/init.qcom.usb.rc
@@ -82,6 +82,8 @@ on boot
     mkdir /config/usb_gadget/g1/functions/rmnet_bam.dpl
     mkdir /config/usb_gadget/g1/functions/ncm.0
     mkdir /config/usb_gadget/g1/functions/ccid.ccid
+    mkdir /config/usb_gadget/g1/functions/Loopback.0
+    mkdir /config/usb_gadget/g1/functions/SourceSink.0
     mkdir /config/usb_gadget/g1/configs/b.1 0770 shell shell
     mkdir /config/usb_gadget/g1/configs/b.1/strings/0x409 0770 shell shell
     write /config/usb_gadget/g1/os_desc/b_vendor_code 0x1

4.3 Connect sdm630 to PC, and switch to loopback:

>adb root
>adb shell setprop sys.usb.config lbss,adb
5. Test script


import time
import sys

import usb.core
import usb.util

from mythread import myThread
from mythread import setlogger
from mythread import myThreadParam as myParam
from mythread import T
import threading

from mylog import mylog
from mylog import debug
from mylog import info
from mylog import error
from mylog import initlog
from mylog import destory

from struct_param import Sparam

PYUSB_DEBUG = 10 #critical, error, warning, info or debug
MAX_BULK_BUFFER_SIZE = 1024 * 1024
bulk_case = (524288,
			262144,
			131072,
			65536, 
			16384)

def setparam(p, a, b, c, d, e):
	p = a,b,c,d,e
	
def getparam(p):
	return p
	
def alloc_buf(size = 16384):
	buf = ''
	for x in range(size/32):
		buf = buf + 'abcdefghijklmnopqrstuvwxyz012345'
	length = len(buf)
	debug('alloc_buf: ' + str(len(buf)))
	return buf, length

def write(dev, msg):
	start = time.time()
	try:
		real = dev.write(0x1, msg, 200)
	except usb.core.USBError:
		debug(sys.exc_info()[1])
		return 0
	passed = time.time() - start
	#debug('write ' + str(real) + ' take ' + str(passed) + ' s')
	return real

def read(dev, msgl):
	start = time.time()
	try:
		real = len(dev.read(0x81, msgl, 200))
	except usb.core.USBError:
		debug(sys.exc_info()[1])
		return 0
	passed = time.time() - start
	#debug('read ' + str(real) + ' take ' + str(passed) + ' s')
	return real

def bulk_out(mp):
	param = mp.param
	dev = param.a0
	msg = param.a1
	#debug(T(mp) + param.name)
	param.a3 = param.a3 + write(dev, msg)

def bulk_in(mp):
	param = mp.param
	dev = param.a0
	msgl = param.a2
	#debug(T(mp) + param.name)
	param.a3 = param.a3 + read(dev, msgl)

def condfunc(mp):
	return not mp.condparam 
	
def sptest(sp, passed, spo, wr = 'write : '):
	#error('Current speed: ' + str(passed) + 's ' + wr + str(sp - spo) + ' bytes per second')
	info(wr + str((sp - spo)/ 1024/1024/passed) + ' MBps')
	return sp
	
def realtime_sp(start, paramo, parami, timeout = 60):
	spo = paramo.a3
	spi = parami.a3
	while True:
		instart = time.time()
		time.sleep(1)
		cur = time.time()
		spo = sptest(paramo.a3, cur - instart, spo)
		spi = sptest(parami.a3, cur - instart, spi, ' read : ')
		if cur - start > timeout :
			break	

def dynamic_sp(dev, size, timeout = 60, isdebug = False):
	msg,msgl = alloc_buf(size)	
	
	paramo = Sparam('bulk_out')
	paramo.set(dev, msg, msgl, 0)
	mpout = myParam(paramo, False, condfunc)
	try:
		to = myThread('bulk_out', bulk_out, mpout)
		to.start()
	except:
		print sys.exc_info()
	
	
	parami = Sparam('bulk_in')
	parami.set(dev, msg, msgl, 0)
	mpin = myParam(parami, False, condfunc)
	try:
		ti = myThread('bulk_in', bulk_in, mpin)
		ti.start()
	except:
		print sys.exc_info()
	
	start = time.time()
	if isdebug:
		realtime_sp(start, paramo, parami, timeout = timeout)
	else :
		time.sleep(timeout)
	cur  = time.time()
	sptest(paramo.a3, cur - start, 0, ' total write : ')
	sptest(parami.a3, cur - start, 0, ' total  read : ')
	sp = (paramo.a3 + parami.a3)/ 1024/1024/(cur - start)
	mpout.condparam = True
	mpin.condparam = True
	to.stop()
	time.sleep(0.1)
	ti.stop()
	time.sleep(0.5)
	return sp

def clear_bulk_in(dev, size):
	while read(dev, size) > 0 : time.sleep(0.1) # clear bulk in buffer
	
def loopback_test(vid=0xfffe, pid=0x0001) :
	# find our device
	dev = usb.core.find(idVendor=vid, idProduct=pid)

	# was it found?
	if dev is None:
		raise ValueError('Device not found')

	# set the active configuration. With no arguments, the first
	# configuration will be the active one
	dev.set_configuration()
	global MAX_BULK_BUFFER_SIZE
	bulk_size = MAX_BULK_BUFFER_SIZE
	result = []
	'''
	while bulk_size > 1024:
		clear_bulk_in(dev, bulk_size)
		info('Loopback test -- ' + str(bulk_size))
		sp = dynamic_sp(dev, bulk_size, timeout = 30)
		result.append((bulk_size, sp))
		#info(str(bulk_size) + ' ' + str(sp) +'MBps')
		bulk_size = bulk_size / 2
		'''
		
	for size in bulk_case:
		clear_bulk_in(dev, size)
		info('Loopback test -- ' + str(size))
		sp = dynamic_sp(dev, size, timeout = 30)
		result.append((size, sp))
	
	for i in result:
		info(i)
	
	return result	

def main():
	logger = initlog('Loopback', 'loopback_test')
	setlogger(logger)
	loopback_test(vid=0x05c6, pid=0x8015)
	destory()
	
main()

6. Test result:

D:\workspace\libusb>python lb.py
2018-05-10 17:31:45,848 INFO Loopback: Loopback test -- 524288
2018-05-10 17:32:15,848 INFO Loopback:  total write : 63.0 MBps
2018-05-10 17:32:15,848 INFO Loopback:  total  read : 63.0 MBps
2018-05-10 17:32:16,661 INFO Loopback: Loopback test -- 262144
2018-05-10 17:32:46,661 INFO Loopback:  total write : 64.4 MBps
2018-05-10 17:32:46,661 INFO Loopback:  total  read : 64.4 MBps
2018-05-10 17:32:47,473 INFO Loopback: Loopback test -- 131072
2018-05-10 17:33:17,473 INFO Loopback:  total write : 56.7314424223 MBps
2018-05-10 17:33:17,473 INFO Loopback:  total  read : 56.7314424223 MBps
2018-05-10 17:33:18,380 INFO Loopback: Loopback test -- 65536
2018-05-10 17:33:48,380 INFO Loopback:  total write : 55.2333333333 MBps
2018-05-10 17:33:48,380 INFO Loopback:  total  read : 55.2333333333 MBps
2018-05-10 17:33:49,427 INFO Loopback: Loopback test -- 16384
2018-05-10 17:34:19,427 INFO Loopback:  total write : 53.1982268543 MBps
2018-05-10 17:34:19,427 INFO Loopback:  total  read : 53.1982268543 MBps
2018-05-10 17:34:20,052 INFO Loopback: (524288, 126.03333333333333)
2018-05-10 17:34:20,052 INFO Loopback: (262144, 128.8)
2018-05-10 17:34:20,052 INFO Loopback: (131072, 113.46288484462866)
2018-05-10 17:34:20,052 INFO Loopback: (65536, 110.46666666666667)
2018-05-10 17:34:20,052 INFO Loopback: (16384, 106.39645370859421)

7. tuning performance

Check Performance - tuning BIMC turbo mode and cpu

8. Tuning Loopback function

8.1 Tuning bulk endpoint

From usb 3.1 spec:

Chapter: 9.6.7 SuperSpeed Endpoint Companion
bMaxBurst:
The maximum number of packets the endpoint can send or receive as part of a burst.  
Valid values are from 0 to 15.  
A value of 0 indicates that the endpoint can only burst one packet at a time and a value of 15 
indicates that the endpoint can burst up to 16 packets at a time. 
For endpoints of type control this shall be set to 0. 
bmAttributes:
If this is a Bulk Endpoint: 
Bits Description 4:0 MaxStreams.  
The maximum number of streams this endpoint supports.  
Valid values are from 0 to 16, where a value of 0 indicates that the endpoint does not define streams.  
For the values 1 to 16, the number of streams supported equals 2MaxStream. 

7:5 Reserved.  
These bits are reserved and shall be set to zero.
So , try:
diff --git a/drivers/usb/gadget/function/f_loopback.c b/drivers/usb/gadget/function/f_loopback.c
index ddc3aad..56de514 100644
--- a/drivers/usb/gadget/function/f_loopback.c
+++ b/drivers/usb/gadget/function/f_loopback.c
@@ -118,8 +118,8 @@ static struct usb_endpoint_descriptor ss_loop_source_desc = {
 static struct usb_ss_ep_comp_descriptor ss_loop_source_comp_desc = {
        .bLength =              USB_DT_SS_EP_COMP_SIZE,
        .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
-       .bMaxBurst =            0,
-       .bmAttributes =         0,
+       .bMaxBurst =            cpu_to_le16(15),
+       .bmAttributes =         cpu_to_le16(16),
        .wBytesPerInterval =    0,
 };

@@ -134,8 +134,8 @@ static struct usb_endpoint_descriptor ss_loop_sink_desc = {
 static struct usb_ss_ep_comp_descriptor ss_loop_sink_comp_desc = {
        .bLength =              USB_DT_SS_EP_COMP_SIZE,
        .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
-       .bMaxBurst =            0,
-       .bmAttributes =         0,
+       .bMaxBurst =            cpu_to_le16(15),
+       .bmAttributes =         cpu_to_le16(16),
        .wBytesPerInterval =    0,
 };
8.2 Tuning request buffer size
diff --git a/drivers/usb/gadget/function/g_zero.h b/drivers/usb/gadget/function/g_zero.h
index 15f1809..3f4889a 100644
--- a/drivers/usb/gadget/function/g_zero.h
+++ b/drivers/usb/gadget/function/g_zero.h
@@ -6,8 +6,10 @@
 #ifndef __G_ZERO_H
 #define __G_ZERO_H

-#define GZERO_BULK_BUFLEN      4096
-#define GZERO_QLEN             32
+//#define GZERO_BULK_BUFLEN    4096
+//#define GZERO_QLEN           32
+#define GZERO_BULK_BUFLEN      16384
+#define GZERO_QLEN             64
 #define GZERO_ISOC_INTERVAL    4
 #define GZERO_ISOC_MAXPACKET   1024

9. Test result after 8

(host side bulk out buffer size, loopback speed -  MBps)
test 1:

2018-05-14 16:01:38,165 INFO Loopback: (524288, 415.297279473308)
2018-05-14 16:01:38,165 INFO Loopback: (262144, 483.55197771014156)
2018-05-14 16:01:38,165 INFO Loopback: (131072, 468.73986737719)
2018-05-14 16:01:38,165 INFO Loopback: (65536, 440.2718004107036)
2018-05-14 16:01:38,165 INFO Loopback: (16384, 299.7403602573539)

test 2:
2018-05-14 16:12:29,123 INFO Loopback: (524288, 440.8758285449145)
2018-05-14 16:12:29,124 INFO Loopback: (262144, 455.7102578630732)
2018-05-14 16:12:29,124 INFO Loopback: (131072, 472.793685560666)
2018-05-14 16:12:29,124 INFO Loopback: (65536, 462.0707672585888)
2018-05-14 16:12:29,124 INFO Loopback: (32768, 390.2901733203179)

test 3:
2018-05-14 16:46:12,831 INFO Loopback: (524288, 454.51135385303076)
2018-05-14 16:46:12,831 INFO Loopback: (262144, 505.1883079841852)
2018-05-14 16:46:12,831 INFO Loopback: (131072, 381.9174333965175)
2018-05-14 16:46:12,831 INFO Loopback: (65536, 378.4891975291734)
2018-05-14 16:46:12,831 INFO Loopback: (32768, 344.5215950598288)




你可能感兴趣的:(python,performance,usb,speed,python,usb,speed,performance)