|
STM32F2xx USB FS CDC, Достижение максимальной пропускной способности |
|
|
|
Apr 28 2013, 08:01
|
Частый гость
 
Группа: Участник
Сообщений: 144
Регистрация: 28-08-07
Пользователь №: 30 111

|
Пытаюсь разобраться с работой USB full-speed в STM32 на примере USB CDC от ST из STM32_USB-Host-Device_Lib_V2.1.0. Хочу добиться скорости 800кБ/с передачи в одну сторону от устройства до ПК. Использую драйвер VCP_V1.3.1 от ST. Работаю с STM32F205RBT6. Прием/передача нормально работают, но хочется выжать максимальную пропускную способность в одном направлении (от устройства к ПК). И здесь возникли трудности, не удается получить более 740кБ/с (чуть меньше половины от максимальной пропускной способности USB FS). В пример внес изменения: Код #define CDC_IN_FRAME_INTERVAL 0 /* Number of frames between IN transfers */ #define APP_RX_DATA_SIZE 32768 /* Total size of IN buffer: */ В основном цикле отправляю данные со скоростью 1МБ/с: Код uint32_t cnt = 0; uint32_t value = 4; while (1) { // Запуск отсчета задержки value мс TIM2->PSC = (2*30000000/1000)/((value == 1) ? 2 : 1)-1; //настроить делитель для формирования милисекунд TIM2->ARR = (value == 1) ? 1 : (value-1); //загрузить значение задержки TIM2->CNT = 0; TIM2->EGR = TIM_EGR_UG; TIM2->SR &= ~TIM_SR_UIF; TIM2->CR1 = TIM_CR1_OPM | TIM_CR1_CEN; //запустить таймер
for (uint32_t j = 0; j < 1024; j++) { APP_Rx_Buffer[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[3]; APP_Rx_Buffer[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[2]; APP_Rx_Buffer[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[1]; APP_Rx_Buffer[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[0]; cnt++; } if(APP_Rx_ptr_in == APP_RX_DATA_SIZE) { APP_Rx_ptr_in = 0; }
while((TIM2->SR & TIM_SR_UIF)==0){} //дождаться конца задержки TIM2->SR &= ~TIM_SR_UIF; //сбросить флаг } Здесь идет запись в буфер раз в 4мс по 4096б, при этом достигается скорость 740кБ/с. Если записывать в буфер раз в 2мс по 2048б, при этом достигается скорость 660кБ/с. При записи в буфер меньшими объемами, но чаще, например каждую 1мс по 1024б (0,5мс/512б, 0,25мс/256б), уже скорость падает до 500кБ/с. Я так понимаю, что это из-за NACK. Но что ограничивает максимальную пропускную способность при передаче в одну сторону до половины от максимально возможной? Дело в драйвере VCP от ST на ПК или я что-то не учитываю на стороне устройства?
|
|
|
|
|
 |
Ответов
|
May 2 2013, 13:35
|
Частый гость
 
Группа: Участник
Сообщений: 144
Регистрация: 28-08-07
Пользователь №: 30 111

|
Опять у меня проблемы с обменом. Нужно передавать непрерывный поток данных 750кБ/с. При отправке данных в цикле: Код while (1) { if ( (USB_OTG_dev.dev.device_status == USB_OTG_CONFIGURED) && (USB_Tx_State == 0 )) { USB_Tx_State = 1; DCD_EP_Tx (&USB_OTG_dev, CDC_IN_EP, (uint8_t*)&APP_Rx_Buffer[0], APP_RX_DATA_SIZE); } } Достигается скорость 950кБ/с. Сделал проверочную отправку непрерывного потока данных 750кБ/с: CODE #define APP_RX_DATA_SIZE (7*4096) ... uint8_t APP_Rx_Buffer [APP_RX_DATA_SIZE]; uint8_t APP_Rx_Buffer_2 [APP_RX_DATA_SIZE]; ... SysTick_Config(SystemCoreClock /48000); while (1) { if (new_data_ready == 1) { static uint32_t cnt = 0; uint8_t *buf_ptr;
new_data_ready = 0; if (USB_Tx_Buf_State == 0) { buf_ptr = APP_Rx_Buffer; } else { buf_ptr = APP_Rx_Buffer_2; }
if(APP_Rx_ptr_in == APP_RX_DATA_SIZE) { if (APP_Rx_ptr_in_OVERFLOW <= (APP_RX_DATA_SIZE-8)) { buf_ptr[APP_Rx_ptr_in_OVERFLOW++] = 'O'; buf_ptr[APP_Rx_ptr_in_OVERFLOW++] = 'V'; buf_ptr[APP_Rx_ptr_in_OVERFLOW++] = 'E'; buf_ptr[APP_Rx_ptr_in_OVERFLOW++] = 'R'; buf_ptr[APP_Rx_ptr_in_OVERFLOW++] = 'F'; buf_ptr[APP_Rx_ptr_in_OVERFLOW++] = 'L'; buf_ptr[APP_Rx_ptr_in_OVERFLOW++] = 'O'; buf_ptr[APP_Rx_ptr_in_OVERFLOW++] = 'W'; } } else { // Записываем 16 байт данных с частотой 48кГц buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[3]; buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[2]; buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[1]; buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[0]; cnt++; buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[3]; buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[2]; buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[1]; buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[0]; cnt++; buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[3]; buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[2]; buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[1]; buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[0]; cnt++; buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[3]; buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[2]; buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[1]; buf_ptr[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[0]; cnt++; } } if ( (USB_OTG_dev.dev.device_status == USB_OTG_CONFIGURED) && (USB_Tx_State == 0 ) && (APP_Rx_ptr_in > (4096-1))) { uint8_t *buf_ptr; uint8_t *fill_ptr; uint32_t buf_leftovers; uint32_t len;
if (USB_Tx_Buf_State == 0) { buf_ptr = APP_Rx_Buffer; fill_ptr = APP_Rx_Buffer_2; USB_Tx_Buf_State = 1; } else { buf_ptr = APP_Rx_Buffer_2; fill_ptr = APP_Rx_Buffer; USB_Tx_Buf_State = 0; } len = APP_Rx_ptr_in; APP_Rx_ptr_in = 0; APP_Rx_ptr_in_OVERFLOW = 0; // Копируем данные из бефера, которые не кратны 4096 // т.к. приемный буфер драйвера VCP от ST размером 4096 buf_leftovers = len & 0x00000FFF; len -= buf_leftovers; while (APP_Rx_ptr_in < buf_leftovers) { fill_ptr[APP_Rx_ptr_in] = buf_ptr[(len+APP_Rx_ptr_in)]; APP_Rx_ptr_in++; } USB_Tx_State = 1; DCD_EP_Tx (&USB_OTG_dev, CDC_IN_EP, buf_ptr, len); } } ... void SysTick_Handler(void) { new_data_ready = 1; } При проверке подключаю устройство напрямую к корневому хабу, все остальные устройства отключаю от шины USB. Настраиваю USBlyzer на логгирование всех устройств на шине (моего устройства, всех хабов, всех хостов). И в итоге всё нормально передается, но почему-то возникает нечастая (может подряд через несколько сотен мс, может через несколько десятков секунд) непериодическая задержка между передачами разной длительностью в среднем 40мс, но до 100мс, из-за которой у меня забиваются буферы и данные теряются. При этом, судя по логу, никакого трафика на шине в этот момент не идет. Что это вообще может быть?
Эскизы прикрепленных изображений
|
|
|
|
|
May 3 2013, 09:56
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(BaN @ May 2 2013, 19:35)  Опять у меня проблемы с обменом. Нужно передавать непрерывный поток данных 750кБ/с. Если у вас требование по ТЗ - передача потока с фиксированной скоростью и при этом использование bulk - это явное противоречие. bulk - не предназначен для передач с гарантированной скоростью. bulk - это фоновая передача с низшим приоритетом. Для гарантированной полосы вам нужна изохронная передача и только она. Правьте ТЗ. Если так уж нужно чтоб ваше устройство выглядело на стороне PC как COM-порт, создайте виртуальный COM сторонними драйверами и передавайте потоки (RX/TX) через две изохронные точки.
|
|
|
|
|
May 3 2013, 10:03
|
Частый гость
 
Группа: Участник
Сообщений: 144
Регистрация: 28-08-07
Пользователь №: 30 111

|
Цитата(jcxz @ May 3 2013, 16:56)  Если у вас требование по ТЗ - передача потока с фиксированной скоростью и при этом использование bulk - это явное противоречие. bulk - не предназначен для передач с гарантированной скоростью. bulk - это фоновая передача с низшим приоритетом. Для гарантированной полосы вам нужна изохронная передача и только она. Правьте ТЗ. Если так уж нужно чтоб ваше устройство выглядело на стороне PC как COM-порт, создайте виртуальный COM сторонними драйверами и передавайте потоки (RX/TX) через две изохронные точки.  Попробую пока сделать тестовую передачу через изохронную точку и посмотреть, будет ли возникать эта же задержка.
|
|
|
|
Сообщений в этой теме
BaN STM32F2xx USB FS CDC Apr 28 2013, 08:01 vptr Цитата(BaN @ Apr 28 2013, 11:01) Пытаюсь ... Apr 28 2013, 09:28 BaN Цитата(vptr @ Apr 28 2013, 16:28) А разве... Apr 28 2013, 09:34  vptr Цитата(BaN @ Apr 28 2013, 12:34) Если я н... Apr 28 2013, 11:10   BaN Цитата(vptr @ Apr 28 2013, 18:10) Транзак... Apr 28 2013, 11:23    vptr Цитата(BaN @ Apr 28 2013, 14:23) Судя по ... Apr 28 2013, 11:28     BaN Цитата(vptr @ Apr 28 2013, 18:28) Скорост... Apr 28 2013, 11:43 BaN Проверил как идет передача. После каждого SOF пере... Apr 28 2013, 15:24 vptr Цитата(BaN @ Apr 28 2013, 18:24) Проверил... Apr 28 2013, 16:42  BaN Цитата(vptr @ Apr 28 2013, 23:42) вот вет... Apr 28 2013, 19:52 toweroff Я пробовал, правда на lpc2478, раскочегарить FS
Бо... Apr 28 2013, 22:33 BaN Возможно, проблема в организации буфера в примере:... Apr 29 2013, 08:01 vptr ... Apr 29 2013, 11:28 BaN Проверил еще раз, с тактовой частотой всё нормальн... Apr 30 2013, 06:48 BaN Подкорректировал буфер USB:
Код#define RX_FIFO_FS_... May 1 2013, 22:13 jcxz Если CDC - не обязательное условие, то создавайте ... May 2 2013, 02:39  BaN Цитата(jcxz @ May 2 2013, 09:39) Если CDC... May 2 2013, 04:24    BaN Цитата(jcxz @ May 3 2013, 22:02) Да с чег... May 3 2013, 15:19     aaarrr Цитата(BaN @ May 3 2013, 19:19) А с чего ... May 3 2013, 15:53      BaN Цитата(aaarrr @ May 3 2013, 22:53) Шина н... May 3 2013, 18:07 Golikov A. Среда? Фоновые процессы? Например C# так может мус... May 3 2013, 05:04 BaN Цитата(Golikov A. @ May 3 2013, 12:04) Ср... May 3 2013, 07:52 BaN Еще нашел баг в библиотеке, из-за которого у меня ... May 4 2013, 03:17 ander0 BaN, можете выложить исходники своего последнего в... Nov 19 2014, 23:51
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|