This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Tool/software: TI-RTOS
Working with PDK 1.0.5 on an OMAP L138, using the USB bulk example, we found the driver would some times lock up, waiting for readSem to be signalled.
The patch below fixed this for us. We're hoping someone at TI can verify that this is a problem, and that our fix is correct.
diff -uprN pdk_omapl138_1_0_5-original/packages/ti/drv/usb/src/usb_func/device/usbdbulk.c pdk_omapl138_1_0_5/packages/ti/drv/usb/src/usb_func/device/usbdbulk.c --- pdk_omapl138_1_0_5-original/packages/ti/drv/usb/src/usb_func/device/usbdbulk.c 2018-07-26 19:35:01.000000000 -0700 +++ pdk_omapl138_1_0_5/packages/ti/drv/usb/src/usb_func/device/usbdbulk.c 2018-10-15 13:50:10.643378800 -0700 @@ -918,6 +918,7 @@ int32_t USBD_bulkWrite(USB_Handle handle { if ((dataSize <= DATA_IN_EP_MAX_SIZE) && (dataSize > 0)) { + psInst->eBulkTxState = BULK_STATE_WAIT_DATA; usbSetupEpReq(pGadgetObj, psInst->ucINEndpoint, /* IN EP # */ (uint32_t*)buffer, @@ -925,7 +926,6 @@ int32_t USBD_bulkWrite(USB_Handle handle dataSize, USB_TRANSFER_TYPE_BULK); - psInst->eBulkTxState = BULK_STATE_WAIT_DATA; usb_osalPendLock(psInst->writeSem, SemaphoreP_WAIT_FOREVER); retSize = psInst->usLastTxSize; @@ -972,6 +972,9 @@ int32_t USBD_bulkRead(USB_Handle handle, /* prepare for incoming bulk connection from host */ *dataSize = psInst->usLastRxSize = 0; + /* set state to waiting */ + psInst->eBulkRxState = BULK_STATE_WAIT_DATA; + /* Setup request for the lower layer to be ready for OUT transfer */ usbSetupEpReq(pGadgetObj, psInst->ucOUTEndpoint, @@ -980,9 +983,6 @@ int32_t USBD_bulkRead(USB_Handle handle, DATA_OUT_EP_MAX_SIZE, USB_TRANSFER_TYPE_BULK); - /* set state to waiting */ - psInst->eBulkRxState = BULK_STATE_WAIT_DATA; - usb_osalPendLock(psInst->readSem, SemaphoreP_WAIT_FOREVER); *dataSize = psInst->usLastRxSize;
Hello Adam,
I'm working on getting this setup on my end. If there are any specific steps needed to reproduce the race condition please let me know.
Apologies, it took me a while to set things up.
Here's my setup:
Brand new fresh out of the box lcdk
pdk 1.0.6 (unmodified)
CCSv7
usb bulk example built as described in processors.wiki.ti.com/index.php/Rebuilding_The_PDK#PDK_Example_and_Test_Project_Creation
I'm on windows, so I run Linux (ubuntu 18.04, freshly installed VM) in order to "python usb_dev_bulk_host_application.py"
Here's what it does for me:
USB generic bulk host application
Send string to usb bulk device and wait for reverse case string echo back
and check to make sure the returned data is matched with what we expect
usb_dev_bulk_host_application.py [single] to send 1 packet
Found device with following usb info:
('Bus: ', 1)
('Address: ', 4)
('Vendor Id: ', '0x1cbe')
('Product Id: ', '0x0003')
Sending test string of length 5200 bytes... in chunk of 512 bytes
Traceback (most recent call last):
File "usb_dev_bulk_host_application.py", line 160, in <module>
for letter in ep2.read(len(substring)):
File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 402, in read
return self.device.read(self, size_or_buffer, timeout)
File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 988, in read
self.__get_timeout(timeout))
File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", line 833, in bulk_read
timeout)
File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", line 936, in __read
_check(retval)
File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", line 595, in _check
raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 110] Operation timed out
I also have a hardware USB protocol analyzer between the LCDK and the PC (Beagle USB 480 by Total Phase) so I could watch packets fly by.
I've included (below) a CSV of what it caught during this test. (Index 0 through 1407 is all the initial string descriptor stuff with the Windows OS. Index 1432 is where I "connected" it to the Linux VM. Index 7225 is where I ran the python script you suggested)
Note this may NOT be the deadlock I was seeing; this may be a different problem another developer here is seeing: Once the LCDK starts, any subsequent Control transfers will cause it to lock up.
# Total Phase Data Center(tm) v6.73
# (c) 2005-2017 Total Phase, Inc.
# www.totalphase.com
#
#
#
# Level,Sp,Index,m:s.ms.us,Dur,Len,Err,Dev,Ep,Record,Summary
0,,0,0:00.000.000,,,,,,Capture started (Aggregate),[11/28/18 15:15:13]
0,,1,0:00.000.000,,,,,,<Host connected>,
0,FS,2,0:30.257.569,,,,,,<Full-speed>,
0,FS,3,0:30.260.569,97.726.666 ms,,,,,<Suspend>,
0,FS,4,0:30.358.296,5.650 us,,,,,<Reset> / <Chirp J> / <Tiny J>,
0,FS,5,0:30.358.301,1.097.500 ms,,,,,<Chirp K>,
0,FS,6,0:30.359.399,26.033 us,,,,,<Reset> / <Chirp J> / <Tiny J>,
0,FS,7,0:30.359.425,53.723.600 ms,,,,,[548 Chirp K-J pairs] ,
0,FS,1105,0:30.413.149,297.883 us,,,,,<Reset>,
0,HS,1106,0:30.413.446,,,,,,<High-speed>,
0,HS,1107,0:30.413.446,32.129.850 ms,,,,,[258 SOF],[Frames: 231.x - 263.3]
0,HS,1108,0:30.445.595,28.250 us,18 B,,00,00,Get Device Descriptor,Index=0 Length=64
0,HS,1122,0:30.445.701,83 ns,,,,,[1 SOF],[Frame: 263.4]
0,HS,1123,0:30.445.690,23.200 us,0 B,,00,00,Set Address,Address=56
0,HS,1133,0:30.445.826,10.251.600 ms,,,,,[83 SOF],[Frames: 263.5 - 273.7]
0,HS,1134,0:30.456.163,34.033 us,18 B,,56,00,Get Device Descriptor,Index=0 Length=18
0,HS,1148,0:30.456.203,1.000.216 ms,,,,,[9 SOF],[Frames: 274.0 - 275.0]
0,HS,1149,0:30.457.240,28.650 us,32 B,,56,00,Get Configuration Descriptor,Index=0 Length=255
0,HS,1163,0:30.457.293,28.450 us,18 B,,56,00,Get String Descriptor,Index=3 Length=255
0,HS,1177,0:30.457.328,66 ns,,,,,[1 SOF],[Frame: 275.1]
0,HS,1178,0:30.457.336,30.516 us,4 B,,56,00,Get String Descriptor,Index=0 Length=255
0,HS,1192,0:30.457.382,28.333 us,40 B,,56,00,Get String Descriptor,Index=2 Length=255
0,HS,1206,0:30.457.453,16.877.583 ms,,,,,[136 SOF],[Frames: 275.2 - 292.1]
0,HS,1207,0:30.474.404,34.416 us,18 B,,56,00,Get Device Descriptor,Index=0 Length=18
0,HS,1221,0:30.474.455,83 ns,,,,,[1 SOF],[Frame: 292.2]
0,HS,1222,0:30.474.508,16.633 us,4 B,,56,00,Get String Descriptor,Index=0 Length=255
0,HS,1235,0:30.474.580,83 ns,,,,,[1 SOF],[Frame: 292.3]
0,HS,1236,0:30.474.598,30.300 us,18 B,,56,00,Get String Descriptor,Index=3 Length=255
0,HS,1250,0:30.474.705,83 ns,,,,,[1 SOF],[Frame: 292.4]
0,HS,1251,0:30.474.698,12.766 us,36 B,,56,00,Get String Descriptor,Index=1 Length=255
0,HS,1264,0:30.474.793,29.600 us,40 B,,56,00,Get String Descriptor,Index=2 Length=255
0,HS,1278,0:30.474.831,2.250.400 ms,,,,,[19 SOF],[Frames: 292.5 - 294.7]
0,HS,1279,0:30.477.135,28.183 us,18 B,,56,00,Get Device Descriptor,Index=0 Length=18
0,HS,1293,0:30.477.206,66 ns,,,,,[1 SOF],[Frame: 295.0]
0,HS,1294,0:30.477.187,28.183 us,9 B,,56,00,Get Configuration Descriptor,Index=0 Length=9
0,HS,1308,0:30.477.241,34.416 us,32 B,,56,00,Get Configuration Descriptor,Index=0 Length=32
0,HS,1322,0:30.477.290,28.283 us,2 B,,56,00,Get Device Status,
0,HS,1336,0:30.477.331,66 ns,,,,,[1 SOF],[Frame: 295.1]
0,HS,1337,0:30.477.362,26.216 us,0 B,,56,00,Set Configuration,Configuration=1
0,HS,1347,0:30.477.456,605.339.850 ms,,,,,[4843 SOF],[Frames: 295.2 - 900.4]
0,HS,1348,0:31.082.839,41.433 us,4 B,,56,00,Get String Descriptor,Index=0 Length=255
0,HS,1362,0:31.082.921,66 ns,,,,,[1 SOF],[Frame: 900.5]
0,HS,1363,0:31.082.911,29.533 us,36 B,,56,00,Get String Descriptor,Index=1 Length=255
0,HS,1377,0:31.082.958,33.850 us,40 B,,56,00,Get String Descriptor,Index=2 Length=255
0,HS,1391,0:31.083.046,66 ns,,,,,[1 SOF],[Frame: 900.6]
0,HS,1392,0:31.083.052,47.900 us,48 B,,56,00,Get String Descriptor,Index=5 Length=255
0,HS,1406,0:31.083.171,66 ns,,,,,[1 SOF],[Frame: 900.7]
0,HS,1407,0:31.083.162,43.200 us,40 B,,56,00,Get String Descriptor,Index=4 Length=255
0,HS,1421,0:31.083.296,1.999.921.683 s,,,,,[15998 SOF],[Frames: 901.0 - 852.5] [Periodic Timeout]
0,HS,1422,0:33.083.342,1.999.921.700 s,,,,,[15998 SOF],[Frames: 852.6 - 804.3] [Periodic Timeout]
0,HS,1423,0:35.083.389,1.999.921.700 s,,,,,[15998 SOF],[Frames: 804.4 - 756.1] [Periodic Timeout]
0,HS,1424,0:37.083.436,1.999.921.700 s,,,,,[15998 SOF],[Frames: 756.2 - 707.7] [Periodic Timeout]
0,HS,1425,0:39.083.482,1.999.921.700 s,,,,,[15998 SOF],[Frames: 708.0 - 659.5] [Periodic Timeout]
0,HS,1426,0:41.083.529,1.999.921.683 s,,,,,[15998 SOF],[Frames: 659.6 - 611.3] [Periodic Timeout]
0,HS,1427,0:43.083.576,1.999.921.683 s,,,,,[15998 SOF],[Frames: 611.4 - 563.1] [Periodic Timeout]
0,HS,1428,0:45.083.622,1.999.921.666 s,,,,,[15998 SOF],[Frames: 563.2 - 514.7] [Periodic Timeout]
0,HS,1429,0:47.083.669,1.999.921.666 s,,,,,[15998 SOF],[Frames: 515.0 - 466.5] [Periodic Timeout]
0,HS,1430,0:49.083.715,1.999.921.666 s,,,,,[15998 SOF],[Frames: 466.6 - 418.3] [Periodic Timeout]
0,HS,1431,0:51.083.762,144.521.500 ms,,,,,[1157 SOF],[Frames: 418.4 - 563.0]
0,HS,1432,0:51.231.285,5.510.383 ms,,,,,<Suspend>,
0,HS,1433,0:51.236.795,5.933 us,,,,,<Reset> / <Chirp J> / <Tiny J>,
0,HS,1434,0:51.236.801,1.097.166 ms,,,,,<Chirp K>,
0,HS,1435,0:51.237.898,25.750 us,,,,,<Reset> / <Chirp J> / <Tiny J>,
0,HS,1436,0:51.237.924,53.704.800 ms,,,,,[548 Chirp K-J pairs] ,
0,HS,2534,0:51.291.629,289.333 us,,,,,<Reset>,
0,HS,2535,0:51.291.918,,,,,,<High-speed>,
0,HS,2536,0:51.291.918,32.754.933 ms,,,,,[263 SOF],[Frames: 626.x - 659.3]
0,HS,2537,0:51.324.697,28.266 us,18 B,,00,00,Get Device Descriptor,Index=0 Length=64
0,HS,2551,0:51.324.798,66 ns,,,,,[1 SOF],[Frame: 659.4]
0,HS,2552,0:51.324.839,22.783 us,0 B,,00,00,Set Address,Address=57
0,HS,2562,0:51.324.923,10.001.550 ms,,,,,[81 SOF],[Frames: 659.5 - 669.5]
0,HS,2563,0:51.334.928,28.150 us,18 B,,57,00,Get Device Descriptor,Index=0 Length=18
0,HS,2577,0:51.335.049,500.150 us,,,,,[5 SOF],[Frames: 669.6 - 670.2]
0,HS,2578,0:51.335.523,32.216 us,32 B,,57,00,Get Configuration Descriptor,Index=0 Length=255
0,HS,2592,0:51.335.620,28.650 us,18 B,,57,00,Get String Descriptor,Index=3 Length=255
0,HS,2606,0:51.335.674,83 ns,,,,,[1 SOF],[Frame: 670.3]
0,HS,2607,0:51.335.720,28.366 us,4 B,,57,00,Get String Descriptor,Index=0 Length=255
0,HS,2621,0:51.335.799,83 ns,,,,,[1 SOF],[Frame: 670.4]
0,HS,2622,0:51.335.808,28.216 us,40 B,,57,00,Get String Descriptor,Index=2 Length=255
0,HS,2636,0:51.335.924,7.251.150 ms,,,,,[59 SOF],[Frames: 670.5 - 677.7]
0,HS,2637,0:51.343.143,38.466 us,18 B,,57,00,Get Device Descriptor,Index=0 Length=18
0,HS,2651,0:51.343.258,16.483 us,4 B,,57,00,Get String Descriptor,Index=0 Length=255
0,HS,2664,0:51.343.301,83 ns,,,,,[1 SOF],[Frame: 678.0]
0,HS,2665,0:51.343.361,15.666 us,18 B,,57,00,Get String Descriptor,Index=3 Length=255
0,HS,2678,0:51.343.426,83 ns,,,,,[1 SOF],[Frame: 678.1]
0,HS,2679,0:51.343.506,28.766 us,36 B,,57,00,Get String Descriptor,Index=1 Length=255
0,HS,2693,0:51.343.551,83 ns,,,,,[1 SOF],[Frame: 678.2]
0,HS,2694,0:51.343.586,29.650 us,40 B,,57,00,Get String Descriptor,Index=2 Length=255
0,HS,2708,0:51.343.676,582.586.466 ms,,,,,[4661 SOF],[Frames: 678.3 - 1260.7]
0,HS,2709,0:51.926.317,29.316 us,4 B,,57,00,Get String Descriptor,Index=0 Length=255
0,HS,2723,0:51.926.387,66 ns,,,,,[1 SOF],[Frame: 1261.0]
0,HS,2724,0:51.926.404,28.250 us,36 B,,57,00,Get String Descriptor,Index=1 Length=255
0,HS,2738,0:51.926.512,66 ns,,,,,[1 SOF],[Frame: 1261.1]
0,HS,2739,0:51.926.524,29.933 us,40 B,,57,00,Get String Descriptor,Index=2 Length=255
0,HS,2753,0:51.926.592,28.483 us,48 B,,57,00,Get String Descriptor,Index=5 Length=255
0,HS,2767,0:51.926.637,66 ns,,,,,[1 SOF],[Frame: 1261.2]
0,HS,2768,0:51.926.705,28.416 us,40 B,,57,00,Get String Descriptor,Index=4 Length=255
0,HS,2782,0:51.926.762,1.250.266 ms,,,,,[11 SOF],[Frames: 1261.3 - 1262.5]
0,HS,2783,0:51.927.985,33.433 us,18 B,,57,00,Get Device Descriptor,Index=0 Length=18
0,HS,2797,0:51.928.086,27.416 us,9 B,,57,00,Get Configuration Descriptor,Index=0 Length=9
0,HS,2811,0:51.928.137,83 ns,,,,,[1 SOF],[Frame: 1262.6]
0,HS,2812,0:51.928.174,27.783 us,32 B,,57,00,Get Configuration Descriptor,Index=0 Length=32
0,HS,2826,0:51.928.262,83 ns,,,,,[1 SOF],[Frame: 1262.7]
0,HS,2827,0:51.928.243,29.383 us,18 B,,57,00,Get Device Descriptor,Index=0 Length=18
0,HS,2841,0:51.928.387,66 ns,,,,,[1 SOF],[Frame: 1263.0]
0,HS,2842,0:51.928.356,35.433 us,9 B,,57,00,Get Configuration Descriptor,Index=0 Length=9
0,HS,2856,0:51.928.512,100.514.983 ms,,,,,[805 SOF],[Frames: 1263.1 - 1363.5]
0,HS,2857,0:52.029.060,29.733 us,32 B,,57,00,Get Configuration Descriptor,Index=0 Length=32
0,HS,2871,0:52.029.152,186.402.716 ms,,,,,[1492 SOF],[Frames: 1363.6 - 1550.1]
0,HS,2872,0:52.215.555,3.000.666 ms,,,,,<Reset> / <Target disconnected>,
0,HS,2873,0:52.218.556,103.166 us,,,,,<Reset> / <Chirp J> / <Tiny J>,
0,HS,2874,0:52.218.659,1.097.166 ms,,,,,<Chirp K>,
0,HS,2875,0:52.219.756,25.250 us,,,,,<Reset> / <Chirp J> / <Tiny J>,
0,HS,2876,0:52.219.781,50.666.383 ms,,,,,[517 Chirp K-J pairs] ,
0,HS,3912,0:52.270.448,240.483 us,,,,,<Reset>,
0,HS,3913,0:52.270.688,,,,,,<High-speed>,
0,HS,3914,0:52.270.688,32.379.866 ms,,,,,[260 SOF],[Frames: 1605.x - 1637.5]
0,HS,3915,0:52.303.058,37.333 us,18 B,,00,00,Get Device Descriptor,Index=0 Length=64
0,HS,3929,0:52.303.193,66 ns,,,,,[1 SOF],[Frame: 1637.6]
0,HS,3930,0:52.303.193,3.000.583 ms,,,,,<Reset> / <Target disconnected>,
0,HS,3931,0:52.306.194,102.850 us,,,,,<Reset> / <Chirp J> / <Tiny J>,
0,HS,3932,0:52.306.296,1.097.500 ms,,,,,<Chirp K>,
0,HS,3933,0:52.307.394,25.383 us,,,,,<Reset> / <Chirp J> / <Tiny J>,
0,HS,3934,0:52.307.419,50.571.066 ms,,,,,[516 Chirp K-J pairs] ,
0,HS,4968,0:52.357.990,335.716 us,,,,,<Reset>,
0,HS,4969,0:52.358.326,,,,,,<High-speed>,
0,HS,4970,0:52.358.326,32.379.883 ms,,,,,[260 SOF],[Frames: 1692.x - 1725.2]
0,HS,4971,0:52.390.706,23.016 us,0 B,,00,00,Set Address,Address=57
0,HS,4981,0:52.390.831,10.251.583 ms,,,,,[83 SOF],[Frames: 1725.3 - 1735.5]
0,HS,4982,0:52.401.162,28.050 us,18 B,,57,00,Get Device Descriptor,Index=0 Length=18
0,HS,4996,0:52.401.207,303.795.133 ms,,,,,[2431 SOF],[Frames: 1735.6 - 2039.4]
0,HS,4997,0:52.705.003,3.000.633 ms,,,,,<Reset> / <Target disconnected>,
0,HS,4998,0:52.708.003,103.316 us,,,,,<Reset> / <Chirp J> / <Tiny J>,
0,HS,4999,0:52.708.107,1.097.033 ms,,,,,<Chirp K>,
0,HS,5000,0:52.709.204,25.916 us,,,,,<Reset> / <Chirp J> / <Tiny J>,
0,HS,5001,0:52.709.229,50.557.533 ms,,,,,[516 Chirp K-J pairs] ,
0,HS,6035,0:52.759.787,348.666 us,,,,,<Reset>,
0,HS,6036,0:52.760.136,,,,,,<High-speed>,
0,HS,6037,0:52.760.136,32.629.916 ms,,,,,[262 SOF],[Frames: 46.x - 79.2]
0,HS,6038,0:52.792.790,27.766 us,18 B,,00,00,Get Device Descriptor,Index=0 Length=64
0,HS,6052,0:52.792.818,3.000.550 ms,,,,,<Reset> / <Target disconnected>,
0,HS,6053,0:52.795.819,103.116 us,,,,,<Reset> / <Chirp J> / <Tiny J>,
0,HS,6054,0:52.795.922,1.097.233 ms,,,,,<Chirp K>,
0,HS,6055,0:52.797.019,26.150 us,,,,,<Reset> / <Chirp J> / <Tiny J>,
0,HS,6056,0:52.797.045,50.571.050 ms,,,,,[516 Chirp K-J pairs] ,
0,HS,7090,0:52.847.616,282.516 us,,,,,<Reset>,
0,HS,7091,0:52.847.899,,,,,,<High-speed>,
0,HS,7092,0:52.847.899,32.379.866 ms,,,,,[260 SOF],[Frames: 134.x - 166.6]
0,HS,7093,0:52.880.326,22.850 us,0 B,,00,00,Set Address,Address=57
0,HS,7103,0:52.880.403,10.126.583 ms,,,,,[82 SOF],[Frames: 166.7 - 177.0]
0,HS,7104,0:52.890.557,28.300 us,18 B,,57,00,Get Device Descriptor,Index=0 Length=18
0,HS,7118,0:52.890.655,469.069.650 ms,,,,,[3753 SOF],[Frames: 177.1 - 646.1]
0,HS,7119,0:53.359.794,28.366 us,4 B,,57,00,Get String Descriptor,Index=0 Length=255
0,HS,7133,0:53.359.850,5.750.933 ms,,,,,[47 SOF],[Frames: 646.2 - 652.0]
0,HS,7134,0:53.365.686,27.983 us,40 B,,57,00,Get String Descriptor,Index=2 Length=255
0,HS,7148,0:53.365.725,6.876.083 ms,,,,,[56 SOF],[Frames: 652.1 - 659.0]
0,HS,7149,0:53.372.638,30.083 us,36 B,,57,00,Get String Descriptor,Index=1 Length=255
0,HS,7163,0:53.372.727,5.875.950 ms,,,,,[48 SOF],[Frames: 659.1 - 665.0]
0,HS,7164,0:53.378.655,28.583 us,18 B,,57,00,Get String Descriptor,Index=3 Length=255
0,HS,7178,0:53.378.727,8.126.283 ms,,,,,[66 SOF],[Frames: 665.1 - 673.2]
0,HS,7179,0:53.386.890,24.666 us,0 B,,57,00,Set Configuration,Configuration=1
0,HS,7189,0:53.386.979,3.625.616 ms,,,,,[30 SOF],[Frames: 673.3 - 677.0]
0,HS,7190,0:53.390.674,28.716 us,48 B,,57,00,Get String Descriptor,Index=5 Length=255
0,HS,7204,0:53.390.729,6.626.066 ms,,,,,[54 SOF],[Frames: 677.1 - 683.6]
0,HS,7205,0:53.397.437,36.900 us,40 B,,57,00,Get String Descriptor,Index=4 Length=255
0,HS,7219,0:53.397.480,1.999.921.683 s,,,,,[15998 SOF],[Frames: 683.7 - 635.4] [Periodic Timeout]
0,HS,7220,0:55.397.527,1.999.921.683 s,,,,,[15998 SOF],[Frames: 635.5 - 587.2] [Periodic Timeout]
0,HS,7221,0:57.397.573,1.999.921.683 s,,,,,[15998 SOF],[Frames: 587.3 - 539.0] [Periodic Timeout]
0,HS,7222,0:59.397.620,1.999.921.683 s,,,,,[15998 SOF],[Frames: 539.1 - 490.6] [Periodic Timeout]
0,HS,7223,1:01.397.667,1.999.921.683 s,,,,,[15998 SOF],[Frames: 490.7 - 442.4] [Periodic Timeout]
0,HS,7224,1:03.397.713,956.892.000 ms,,,,,[7655 SOF],[Frames: 442.5 - 1399.3]
0,HS,7225,1:04.354.632,9.300 us,512 B,,57,02,OUT txn (NYET),61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78…
0,HS,7229,1:04.354.730,10.626.650 ms,,,,,[86 SOF],[Frames: 1399.4 - 1410.1]
0,HS,7230,1:04.365.451,9.433 us,512 B,,57,01,IN txn,41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58…
0,HS,7234,1:04.365.482,2.875.500 ms,,,,,[24 SOF],[Frames: 1410.2 - 1413.1]
0,HS,7235,1:04.368.443,11.650 us,512 B,,57,02,OUT txn (NYET),53 54 55 56 57 58 59 5A 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70…
0,HS,7242,1:04.368.482,1.999.921.683 s,,,,,[15998 SOF],[Frames: 1413.2 - 1364.7] [Periodic Timeout]
0,HS,7243,1:04.372.080,1.001.367.983 s,,,57,01,[40086 IN-NAK],[Periodic Timeout]
0,HS,7244,1:06.368.529,1.999.921.700 s,,,,,[15998 SOF],[Frames: 1365.0 - 1316.5] [Periodic Timeout]
0,HS,7245,1:08.368.576,1.999.921.716 s,,,,,[15998 SOF],[Frames: 1316.6 - 1268.3] [Periodic Timeout]
0,HS,7246,1:10.368.622,1.999.921.716 s,,,,,[15998 SOF],[Frames: 1268.4 - 1220.1] [Periodic Timeout]
0,HS,7247,1:12.368.669,1.999.921.716 s,,,,,[15998 SOF],[Frames: 1220.2 - 1171.7] [Periodic Timeout]
0,HS,7248,1:14.368.716,1.999.921.700 s,,,,,[15998 SOF],[Frames: 1172.0 - 1123.5] [Periodic Timeout]
0,HS,7249,1:16.368.762,1.999.921.716 s,,,,,[15998 SOF],[Frames: 1123.6 - 1075.3] [Periodic Timeout]
0,HS,7250,1:18.368.809,1.999.921.700 s,,,,,[15998 SOF],[Frames: 1075.4 - 1027.1] [Periodic Timeout]
0,HS,7251,1:20.368.855,1.999.921.700 s,,,,,[15998 SOF],[Frames: 1027.2 - 978.7] [Periodic Timeout]
0,HS,7252,1:22.368.902,1.999.921.700 s,,,,,[15998 SOF],[Frames: 979.0 - 930.5] [Periodic Timeout]
0,HS,7253,1:24.368.949,1.999.921.700 s,,,,,[15998 SOF],[Frames: 930.6 - 882.3] [Periodic Timeout]
0,HS,7254,1:26.368.995,1.999.921.700 s,,,,,[15998 SOF],[Frames: 882.4 - 834.1] [Periodic Timeout]
0,HS,7255,1:28.369.042,1.296.317.350 s,,,,,[10370 SOF],[Frames: 834.2 - 82.3]
0,,7256,1:29.665.359,,,,,,Capture stopped,[11/28/18 15:16:43]
More information: If I add
usb_osalDelayMs(9000);
in dev_bulk_main.c line 234, that gives me enough time to connect the device to the VM before the while loop starts.
Under those conditions, the usb_dev_bulk_host_application.py runs to completion and prints "Test passes!"
Hi Adam
Thank you for contacting us and showing us the patch.
We will need to investigate as of why we see such kind of race condition. If there is a race condition somewhere, moving the line code that setups the eBulkTxState or eBulkRxState to before the function usbSetupEpReq() would make difference since the function usbSetupEpReq() is a non-blocking function. I'm not certain how it helps with your tests.
As for the second problem that you mentioned that you were writing 14 OUT packets without any reads, could you please clarify if the read is from the OMAP or from the host PC? If the host PC doesn't do USB read, the USB_write from the OMAP will get stalled (USB device cannot send unsolicited data to USB host without USB host asking for it) and then result in the stalled USB write from host PC. The bulk example anticipates the both USB device and host working together.
We need to start the bulk transfer only after the controlled transfer on EP 0 has completed. The USB bulk example relies on the "Set Configuration" command to figure out when the EP0 has done its setup. It sets up a 500ms delay after the Set Configuration arrives to deal with this. In your logic analyzer capture with Linux running under VM, there are 2 "Set Configuration" commands. This could be the reason why you see it works after you increase the delay to 9 second. Do you see "Host disconnect" event showing up in the UART console of the OMAP when you mount the USB bulk device to the VM machine?
As for the NYET, we also see that with OMAP and AM3. We will address it in the future release.
Bottom line, your usb bulk driver, as written, is too fragile. Activity should be able to occur on any endpoint regardless of what is happening on the other endpoints.
This should be easy to do with just a little buffering.
Host sends a read request and you have no data for them? Tell them you have no data.
Host sends a read request and there is data in the buffer? Give it to them.
Host sends a write request? accept it, buffer the data, and hold it until a Task asks for it.
Task wants to read and there's no data? Tell the task there's no data.
Task wants to read and there is data? Give the Task the data.
Task wants to write? Take the data, put it in a buffer, and keep it until the HOST sends an IN.
OUT is, by definition a transfer FROM the HOST (i.e. a write). See sdphca.ucsd.edu/Lab_Equip_Manuals/usb_20.pdf page 33, "Endpoint Direction"
Your arbitrary 500ms delay is insufficient for all use cases, and would not be necessary at all if you treated the endpoints independently. It is completely possible you may receive any number of CONTROL packets before receiving an IN or an OUT. The test case I gave you is a perfect example of this.
Hi Adam
What you've suggested about what to do with host send read / write requests or if task want to read / write data are really application level functions, IMHO. You're free to implement your application that way. The driver is just providing the read/write functions on top of the hardware. The bulk example that comes with the USB driver is just a simple example and definitely won't fit all use cases.
Take a look at USB Mass Storage Class implementation for example:
Set configuration comes and done
Host sends a class request for get LUN on EP0. The device application then starts preparing for the MSC application.
The device then starts preparing for the bulk transfer anticipating the first bulk OUT from the host.
Host then sends a SCSI command to tell the device what to do (to read or to write from or to storage or reading capacity, etc.)
The device then does what host wants it to do
Then device then waits for another SCSI command (Bulk out) from host.
As for the delay, the bulk endpoint transfer can only happen after the bulk endpoints have been configured. This configuration is done when the "Set Configuration" command comes from the host. Ideally the host application should send out a class request for the bulk application (similar to the get LUN with the MSC implementation) so that the bulk application knows when it's ready to do bulk read. The bulk example application doesn't have this command as a mark so it relies on the delay. We will look at how to get rid of this delay in future release.
The delay doesn't work with the VM like in your setup where it should have. I see multiple reset / disconnects coming to the OMAP in your logic analyzer capture. The demo application should have changed its state and restarted the timer accordingly. Do you see the log on the UART console of the OMAP reporting multiple disconnect/connect as well?
Regards
Hi Adam
The incoming buffer that is associated with the call back are the g_bulkRxBuffer in file example/usb_dev/bulk/usb_bulk_structs.c
const tUSBDBulkDevice g_sBulkDevice =
{
USB_VID_STELLARIS,
USB_PID_BULK,
500,
USB_CONF_ATTR_SELF_PWR,
usbdbulkEventCallback, /* pfnRxCallback */
(void *)g_bulkRxBuffer, /* pvRxCBData */
usbdbulkEventCallback, /* pfnTxCallback */
(void *)g_bulkTxBuffer, /* pvTxCBData */
g_pStringDescriptors, /* ppStringDescriptors */
NUM_STRING_DESCRIPTORS, /* ulNumStringDescriptors */
&g_sBulkInstance /* psPrivateBulkData */
};
You can replace the buffer in this structure with any buffer of your choice. Keep in mind that data will be written to it by DMA engine, so the buffer needs to be cache size aligned.
To send data from USB device (BULK IN) without blocking, you need to create a new function. It's basically a copy of the function
int32_t USBD_bulkWrite(USB_Handle handle, uint8_t* buffer, uint32_t dataSize)
But you would need to remove the function
usb_osalPendLock(psInst->writeSem, SemaphoreP_WAIT_FOREVER);
Then you will have to wait for the call back to tell you that it's finished sending.
Please let us know if this works for you or not.
Best regards
Thanh
Thanks Thanh. I'd reached most of the same conclusions about the same time you sent this message.
This resolves my issue, although i do still think your example code should be more robust.
Hi Adam
It's great to hear that you made some great progress.
As for the NAK question, I'm still waiting for response from an expert on the hardware.
My understanding of the USB hardware in OMAP138 is that it does not give the software any visibility of whenever it sends a NAK to an OUT request.
For IN request, the USB block would retry on its own without letting the CPU involved when it sees a NAK.
If I receive any information that says it is possible to do so, I'll update you here.
Regards
Thanh
Hi Adam
The USB core sends out NAK for OUT or PING when it cannot accept any more data. This could be because the USB's FIFO is full. Either the ARM or DMA has not read and emptied the USB's FIFO in this case. Could you read the endpoint status by calling the function USBEndpointStatus or by reading the register associated with OUT endpoint or IN endpoint and see what their value is.