Skip to main content
Ehill.16
Senior
August 3, 2020
Solved

Trying to measure how long it takes to send 140kB array through the FS USB CDC

I am checking for end of transmission like this, while(hcdc->TxState == 1). But it seems to blow right past this although the transmission hasn't ended. I am checking the speed with the core cycle counter and am getting ridiculously fast speeds. But if I measure a 500000 for loop, I get what I suspect to be about the time. Any one have any clues?

This topic has been closed for replies.
Ehill.16
Ehill.16Best answer
Senior
August 4, 2020

i got it working by using the following line;

while(((USBD_CDC_HandleTypeDef*)(hUsbDeviceFS.pClassData))->TxState!= 0);	// wait for end of transfer

So I calculated the time with both the core cycle counter and the HAL_GetTicks(). Both counters gave the same time, 8ms to transfer 140kB array. That turns out to be about 17MB/s. This can't be correct can it?

9 replies

Jack Peacock_2
Associate II
August 3, 2020

Measuring instruction loops won't tell you much since it doesn't account for latency in transmission through the USB buffer, framing, and available slots for messages on the bus. First off, the theoretical maximum transfer rate for FS CDC packets is 64 bytes (max bulk message size) / 1ms (the SOF frame rate). In practice you won't see anywhere near 64KBytes/sec since you have to allow for USB bus turnaround (it is a half duplex bus) as well as other traffic such as host data requests and interrupt messages to maintain the CDC emulated line status.

There's also a loss from time to pass through the USB driver. If the USB FIFO is properly used this is not significant since the next packet can be loaded in parallel with the current outgoing packet on the bus. And there's whatever overhead your application adds and how well it takes advantage of the USB hardware FIFO.

So you may see about 30KBytes/sec for a full speed connection, again assuming the far end host doesn't impose additional latency (this can be significant if the host app doesn't buffer incoming data). 140/30 yields about 4.7 seconds for your transfer from device to host.

Jack Peacock

Ehill.16
Ehill.16Author
Senior
August 3, 2020

Thanks for the response. I just want a rough idea. How can I detect the end of transmission. Realterm is showing 79kB/s.

TDK
August 3, 2020

TxState should accurately reflect the status of the USB. Works for me.

> I just want a rough idea.

> Realterm is showing 79kB/s.

Isn't that good enough?

"If you feel a post has answered your question, please click ""Accept as Solution""."
Ehill.16
Ehill.16Author
Senior
August 4, 2020

I am testing TxState this way;

status = CDC_Transmit_FS(ramArray, sizeof(ramArray)); // send the 140KB array over the USB to PC
while(hcdc->TxState == 1);

Someone else wanted me to verify Realterms results this way.

Ehill.16
Ehill.16AuthorBest answer
Senior
August 4, 2020

i got it working by using the following line;

while(((USBD_CDC_HandleTypeDef*)(hUsbDeviceFS.pClassData))->TxState!= 0);	// wait for end of transfer

So I calculated the time with both the core cycle counter and the HAL_GetTicks(). Both counters gave the same time, 8ms to transfer 140kB array. That turns out to be about 17MB/s. This can't be correct can it?

TDK
August 4, 2020

> That turns out to be about 17MB/s. This can't be correct can it?

No it cannot.

Not sure what the problem is. TxState works for me on the F4 series using mostly stock HAL USB drivers. You don't specify your chip family.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Ehill.16
Ehill.16Author
Senior
August 4, 2020

It's working now. I don't know what I did. But I did I increase the array size to 180KB, Now I am reading 1.5MB/s. Thanks for your help TDK.

EDeme.1
Associate
October 23, 2021

It seems a bit suspicious.,, On common MCUs length of the buffer in CDC_Transmit_FS is 16bit (64k max) so, i would guess you actually send 12kB when sending 140 and 52kB sending 180.

for reference, the actual tx speed that I achieve on F4 is about 1200kB/s transferring 256kB of data (sending 4kB at a time, win 10).