STM32F407 + USB + ULPI Interface

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

chradev
Posts: 48
Joined: Sun Apr 28, 2013 6:52 am

Re: STM32F407 + USB + ULPI Interface

Post by chradev »

Thanks Giovanni,

I will update my performance test application, perform new assessment and post new figures as soon as have them.

Best regards
Chris
chradev
Posts: 48
Joined: Sun Apr 28, 2013 6:52 am

Re: STM32F407 + USB + ULPI Interface

Post by chradev »

Hi Giovanni,

I have just run brief tests with almost no changes against chibios-svn-8631-trunk.
The following implementation is used as a test basis (see more in btest-2.zip):

Code: Select all

static uint8_t buf[] = "0123456789abcdef0123456789abcdef..."; // 1024 buffer
count += chSequentialStreamWrite(chp, buf, sizeof buf - 1);

There you are the figures captured with default USB CDC settings using following command from Linux 3.4.79+ on a20-Lime2-SOM:

Code: Select all

root@a20-Lime2-SOM:~# echo -ne '\r\n\r\nwrite\r' > /dev/ttyACM1 | cat /dev/ttyACM1 > /dev/null &

Inside measurement printed to the debug console (USART2):
ChibiOS starting ... OK.
SD1 Throughput [kBps] vs time [sec]:
           cur     max     min     avg
    25    11.5    11.5    11.5    11.5
SDU1 Throughput [kBps] vs time [sec]:
           cur     max     min     avg
    25   959.4   959.5   955.6   958.6
SDU2 Throughput [kBps] vs time [sec]:
           cur     max     min     avg
    25  4027.6  4038.6  4025.2  4031.7

Alternative test from Windows 7 i7 PC using modified Python script (against USB HS only):

Code: Select all

C:\Tools\devs\ChibiStudio\wss\workspace\btest-3\tests>python ser-chibios.py COM73
Port opened: COM73
Time [sec], Cur [MBps], Min [MBps], Max [MBps], Avg [MBps],   Tot [GB]
      44.8,      2.184,      2.153,      2.292,      2.188,      0.091
Test time :     45.3 sec
Throughput:      2.188 MBps
Total xfer:      0.091 GB

Inside measurement printed to the debug console (USART2):
ChibiOS starting ... OK.
SDU2 Throughput [kBps] vs time [sec]:
           cur     max     min     avg
    45  2184.1  2213.2  2175.5  2186.7

As it can be seen now USB FS / HS (SDU1/2) throughput is ~1 / ~4 (~2) MBps respectively (vs ~0.6 with queues).
It is definitely influenced by the new changes but it is far from the results with stm32cube based implementation.
Of course, more changes in main tests logic have to be done to exploit better buffers queue features and options.

Any ideas how to increase transmit performance are welcome.

Thanks again for your prompt and kind support Giovanni.

Best regards
Chris
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F407 + USB + ULPI Interface

Post by Giovanni »

Hi,

Try using the "buffer" mode:

Code: Select all

#if 1
    /* Writing in stream mode.*/
    streamWrite(&SDU1, buf, sizeof buf - 1);
#else
    /* Writing in buffer mode.*/
    (void) obqGetEmptyBufferTimeout(&SDU1.obqueue, TIME_INFINITE);
    memcpy(SDU1.obqueue.ptr, buf, SERIAL_USB_BUFFERS_SIZE);
    obqPostFullBuffer(&SDU1.obqueue, SERIAL_USB_BUFFERS_SIZE);
#endif


There is also the equivalent for receiving: ibqGetFullBufferTimeout() and ibqReleaseEmptyBuffer().

Basically you get an empty buffer, fill it and then send it. I am getting better numbers but not by much. After this there is only the USB direct API which is copy-less.

Giovanni
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F407 + USB + ULPI Interface

Post by Giovanni »

From my tests increasing buffer sizes improves performance, increasing queues depth does not increase performance, kind of expected.

Increasing the OTG thread (usb_lld_pump) priority above the priority of the writer also has a positive impact.

Giovanni
chradev
Posts: 48
Joined: Sun Apr 28, 2013 6:52 am

Re: STM32F407 + USB + ULPI Interface

Post by chradev »

Adding condition to fill the buffers only once did not influence performance at all.

Code: Select all

       (void) obqGetEmptyBufferTimeout(&SDU2.obqueue, TIME_INFINITE);
       if (cn < 2) memcpy(SDU2.obqueue.ptr, buf, SERIAL_USB_BUFFERS_SIZE);
       obqPostFullBuffer(&SDU2.obqueue, SERIAL_USB_BUFFERS_SIZE);
       count += SERIAL_USB_BUFFERS_SIZE;


Will try to increase buffer size.

Chris
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F407 + USB + ULPI Interface

Post by Giovanni »

How much would you estimate the advantage of the new system compared to normal queues?

If it is worth keeping then something else can be gained by removing the queues support from the USB driver, some more by optimizing the driver itself, I suspect that the data moving is not done in the fastest possible way in usb_lld_pump.

The optimal would be using the DMA but that is only available for OTG_HS, having one OTG use DMA and other using the current system in the SAME driver would be difficult.

Giovanni
chradev
Posts: 48
Joined: Sun Apr 28, 2013 6:52 am

Re: STM32F407 + USB + ULPI Interface

Post by chradev »

Increasing buffers size to 1k performs slightly better:

Code: Select all

SDU2 Throughput [kBps] vs time [sec] @ 1024 buffer size:
           cur     max     min     avg
    75  4659.2  6927.3  4622.8  4683.5

Unfortunately, my tests with stm32cube show the best results at 36kB transmit buffer size.
At 1k buffer size USB HS the performance is ~10 MBps which is only 2 times better.
STM32Cube implementation exploits callbacks so maybe this can help to increase performance additionally.

Chris
Attachments
USB FS/HS performance at stm32cube based implementation
USB FS/HS performance at stm32cube based implementation
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F407 + USB + ULPI Interface

Post by Giovanni »

That would be equivalent to the direct USB API, that uses callbacks as well.

Tomorrow I will give a try to driver-side optimizations.

Giovanni
chradev
Posts: 48
Joined: Sun Apr 28, 2013 6:52 am

Re: STM32F407 + USB + ULPI Interface

Post by chradev »

Hi Giovanni,

Giovanni wrote:How much would you estimate the advantage of the new system compared to normal queues?

As I can see in preliminary tests performance is increased at:
* USB FS from ~585 to ~958 kBps or with more than 60% (close to one measured with stm32cube implementation - ~1048 kBps),
* USB HS from ~585 to ~4680 kBps or 8 times (~2 times less than one measured with stm32cube implementation - ~10 MBps).
My expectation is to reach much better performance at 10-40kB buffer sizes and exploiting callbacks.

Giovanni wrote:If it is worth keeping then something else can be gained by removing the queues support from the USB driver, some more by optimizing the driver itself, I suspect that the data moving is not done in the fastest possible way in usb_lld_pump.

In my opinion usage of queues is definitely harmful and optimization of whole data chain will be of great worth.

Giovanni wrote:The optimal would be using the DMA but that is only available for OTG_HS, having one OTG use DMA and other using the current system in the SAME driver would be difficult.

For the best results DMA for USB HS is a must like in stm32cube implementation even with separate driver.
To make buffer copy faster it can be used DMA in memory to memory mode as well.

One possible way is to use whole ST USB stack as alternative.
It will make use of USB Host and all Device/Host classes implemented there.
It is definitely possible thanks to CMSIS wrapper but most of ChibiOS goodies will be lost.
We discuss it is behind your interests but it will gain a big advantage especially if ChibiOS is used in a native way.

Note that above figures are preliminary so I will post wider tests result as soon as have them

Best regards
Chris
chradev
Posts: 48
Joined: Sun Apr 28, 2013 6:52 am

Re: STM32F407 + USB + ULPI Interface

Post by chradev »

Hi to All,

I have made some more tests with different buffer sizes and would like to update preliminary figures.
Unfortunately, when buffer size was set to 16 kB or more the following linker error is observed:

Code: Select all

Linking build/ch.elf
rules.ld:359 cannot move location counter backwards (from 20021f50 to 20020000)

which most probably is memory problem.

The results for the throughput of USB FS/HS with ULPI are shown on the attached chart together with results from old queue implementation.
While USB FS behaves as expected USB HS with ULPI performance become limited on a very low level ~5 MBps at buffer sizes 4 kB and more.
Limitation of the throughput value most likely is because of DMA lack on the contrary of my preliminary expectations for higher figures.

Best regards
Chris
Attachments
STM32F4 USB FS/HS with ULPI throughput measured with a test based on ChibiOS (svn-8636-trunk)
STM32F4 USB FS/HS with ULPI throughput measured with a test based on ChibiOS (svn-8636-trunk)
Post Reply