реклама на сайте
подробности

 
 
> STM32F4 USB CDC, Передаёт не более 32 байт за раз
hd44780
сообщение Mar 7 2013, 08:53
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



Понимаю, что может быть избитая и изъезженная тема тема, но всё же.

Короче, взял пример COM-порта отсюда - http://we.easyelectronics.ru/STM32/primery...4-discovey.html
Порт опознаётся, устанавливается, всё ок. Данные принимает, передаёт.

Но. Не могу передать на комп более 32 байт. Комп просто ничего не принимает. Когда 32 байта и меньше всё в порядке. Это ж отстой полный, хуже чем даже USB HID Generic - 64 байта туда-сюда-обратно. И тот кстати не получается. Примеры - сплошные мыши и джойстики sad.gif ...

Это что, норма? И как этого избежать? Размер буферов в прошивке вроде 2 кила - макрос APP_RX_DATA_SIZE = 2048.

И ещё.
Не хочется, чтобы железка торчала в списке COM-портов. Взял финский пример отсюда - http://forum.easyelectronics.ru/viewtopic....=35&t=10245
Он пошёл без проблем, комп его увидел. Но где взять драйвер? Нашёл libusb, драйвер им сгенерил, но как с ним дальше работать не понял...

Может ли кто-нибудь помочь?

Спасибо.




--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
3 страниц V  < 1 2 3 >  
Start new topic
Ответов (15 - 29)
Golikov A.
сообщение Mar 12 2013, 16:39
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



какой странный подход. По мне последние сообщение не "победил" а "нашел" непонятную вещь. Вот когда вы скажете почему так должно быть, тогда можете считать что победили. Почему по 2 запроса надо? и кучу других почему. Пока что вы нашли куда забить костыль чтобы оно хоть как то зашевелилось...
Go to the top of the page
 
+Quote Post
hd44780
сообщение Mar 13 2013, 09:45
Сообщение #17


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



Согласен полностью.
Но ковыряться в потрохах этого CDC драйвера у меня нет никакого желания. У меня голова гудит от него ... Тем более, что в устройстве и без этого полно других проблем и нерешённых подзадач.
Если у Вас есть вариант получше, работающий без этого костыля, предложите пожалуйста.

Уважаемый Flexz тоже не писал, как именно оно у него работает .... Он писал только, что у него гоняет до 24кБ и про VCP_SendByte.


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Mar 13 2013, 15:04
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



увы...
Go to the top of the page
 
+Quote Post
rudy_b
сообщение Mar 1 2014, 20:05
Сообщение #19


Знающий
****

Группа: Свой
Сообщений: 888
Регистрация: 25-09-08
Из: Питер
Пользователь №: 40 458



И снова та же тема...
Поднял CDC (VirtualComPort) на STM32F207. Использовал либу STM32_USB-Host-Device_Lib_V2.1.0 (stm32_f105-07_f2_f4_usb-host-device_lib_v2.1.0).

И все вроде замечательно пашет с родным виндовым драйвером от ST (на usbser.sys). И контрольные пакеты ходят и скорость передачи данных порядка 700 кбит.

Но вот если размер пакета кратен 64 - то от компа в процессор пакеты ходят прекрасно, а вот обратно не ходит ничего. И вроде ошибка старая и давно известная - если размер пакета кратен 64, то винда посылает дополнительный запрос на пакет длиной 0 байт и на него нужно ответить. А контроллер считает, что все послал и молчит. Я думал ее давно исправили, но вот напоролся.

Пакеты с любыми другими размерами отлично передаются и туда и сюда. Никто не сталкивался с этим? Может кто знает что нужно поправить в либе?

Есть и еще редкие ошибки, примерно одна на 300 транзакций пакетов размером порядка 255 байт. Проявляются только если размер пакета более 64 байт. Но тут все как-то странно, пока не понял в чем дело. Ошибки вроде случайные, но ходят пачками и зависят от загрузки винды.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Mar 2 2014, 05:23
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



последняя ошибка вроде ошибка драйвера винды если я правильно понял о чем идет речь. Там почему то не происходит запрос или происходит но с большим таймаутом, но может не о том...

насчет пакета нулевой длинны - это правила стандарта, если последний пакет имеет длину равную буферу, то он требует после себя посылки пакета 0 длинны, как подтверждение окончания пакета. Ответом на этот пакет 0 длинны - должен быть АКК, то есть так же пакет 0 длинны.
Go to the top of the page
 
+Quote Post
rudy_b
сообщение Mar 2 2014, 10:46
Сообщение #21


Знающий
****

Группа: Свой
Сообщений: 888
Регистрация: 25-09-08
Из: Питер
Пользователь №: 40 458



Вторая ошибка действительно похожа на придурь виндов. Несмотря на то что выставлены немалые таймауты и я пытаюсь докачать пакет 10 раз - этого не хватает, а в ответ на следующий запрос я получаю предыдущие данные. Но у 7-ки блокировка всех секунд на 10 - норма поведения.

А вот то, что не ходят пакеты с кратным 64 размером - это явно ошибка ST-шной либы. В эхо-режиме моя прога просто перекладывает данные из приемного буфера в передающий, остальное делает либа. В том числе и докладку пакета нулевой длины - с пользовательского уровня мне это недоступно.

Мне просто важно понять - это что-то не то у меня или это действительно ошибка либы. Никто не гонял пакеты с такой длиной?
Go to the top of the page
 
+Quote Post
Axel
сообщение Mar 2 2014, 11:58
Сообщение #22


Местный
***

Группа: Свой
Сообщений: 480
Регистрация: 21-11-04
Пользователь №: 1 188



Цитата(rudy_b @ Mar 2 2014, 14:46) *
Мне просто важно понять - это что-то не то у меня или это действительно ошибка либы. Никто не гонял пакеты с такой длиной?


Я слепил свой bulk-девайс на основе ST-шной либы. Обмен только пакетами, кратными 64 байтам. Никаких проблем не отмечал. В предыдущих проектах с LPC17 - та же ситуация (в смысле все нормально).
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Mar 2 2014, 13:11
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



балк обменивается не по контрольной конечной точке, и у него размер буфера больше 64 байт.
CDC работает через контрольную конечную точку, у которой буфер как раз 64 байта (про slow speed не говорим), потому при посылке пакета кратного 64 байтам, последняя передача идет с полным буфером, и требует по стандарту USB досылки еще одного пакета 0 длинны, как признак окончания.

думаю в этом подвох, странно что либа сама не добавляет 0 посылку, а исходники либы есть? может просто посмотреть глазьями есть там проверка на кратность длинны и досылка 0 пакета?
Go to the top of the page
 
+Quote Post
rudy_b
сообщение Mar 2 2014, 13:41
Сообщение #24


Знающий
****

Группа: Свой
Сообщений: 888
Регистрация: 25-09-08
Из: Питер
Пользователь №: 40 458



А какой именно либы? Я использовал stm32_f105-07_f2_f4_usb-host-device_lib_v2.1.0 (файлы V1.1.0 19-March-2012) и сравнивал с верией от 2011 (нет существенных различий).

Программа в контроллере (режим эхо) ничего не знает о размерах пакетов. К ней на вход валятся блоки по 64 байта или менее. Разбивку пакетов на блоки делает драйвер виндюков (пакеты заданного размера отправляются по WriteFile прогой в компе), а контроллер только перекладывает принятые блоки из буфера приемника в буфер передатчика. И я вижу, что все пакеты нормально приходят в контроллер (стоит счетчик принятых байт) и, скорее всего, нормально отправляются в комп. А вот прога в компе (ReadFile с заданным размером) не получает ничего, даже при нескольких перезапросах если длина отправленного пакета кратна 64.

Поскольку это VirtualCom, то драйвер в контроллере должен передавать любое количество байт. Но если в буфер передатчика положено сразу 64 байта, то, после их передачи, он, похоже, не отправляет пакета нулевой длины несмотря на то, что буфер пуст. И вот тут-то ReadFile (usdser.sys) похоже считает передачу незавершенной и сбрасывает весь пакет - не приходит ни одного байта при любом количестве перезапросов. Ну или что-то в этом роде, хотя и непонятно как такого можно добиться.




Цитата(Golikov A. @ Mar 2 2014, 17:11) *
балк обменивается не по контрольной конечной точке, и у него размер буфера больше 64 байт.
CDC работает через контрольную конечную точку, у которой буфер как раз 64 байта (про slow speed не говорим), потому при посылке пакета кратного 64 байтам, последняя передача идет с полным буфером, и требует по стандарту USB досылки еще одного пакета 0 длинны, как признак окончания.

думаю в этом подвох, странно что либа сама не добавляет 0 посылку, а исходники либы есть? может просто посмотреть глазьями есть там проверка на кратность длинны и досылка 0 пакета?

Балк в FS все равно работает пакетами с максимальным размером 64 байта. Я это смотрел. Происходит прмерно так, если правильно понял исходники.
По фрейму происходит проверка на наличие данных в пользовательском буфере. Если данные есть то из них выкусывается блок размером до 64 байт и устанавливается размер для передачи и указатель данных. После этого в более глубоких потрохах драйвера происходит его загрузка в фифо и передача в данном фрейме.

А вот однократной передачи пустого блока при переходе буфера из полностью заполненного состояния в пустое я не увидел. Но может плохо смотрел, да и разбираться в ST-шных либах и их изумительном харде при отсутствии внятных описаний - проблема еще та.

Но исходники есть, могу послать если нужно, размер-порядка 4 метров (с примерами).
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Mar 2 2014, 14:27
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



не надо мешать все в одну кашу.
балк, изохронный, прерывания, и контрольные обмены. Что какой то из них тоже использует буфер 64 байта это ничего не значит.

Правда заключается в том что контрольная точка может послать максимум 64 байта. Когда на компьютер приходит пакет длинной меньше 64 байт - это конец послания. И вам становится доступно сообщение по ReadFile в винде.
Если же приходит пакет длинной 64 байта, то не понятно это все сообщение, или нет, так как ограничение длинны может быть из-за максимального размера конечной точки. Поэтому драйвер винды кладет себе это сообщение и ждет следующего пакета, если придет пакет длинной меньше, он поймет что это конец и все вам отдаст, потому по стандарту пакеты длинной в макс буфер конечной точки обязательно должны быть дополнены пакетом 0 длины.

Если вы монитором USB порта после прихода пакета длинной 64 байта, не видите закрывающего пакета 0 длинны (его иногда могут как АКК воспринимать мониторы порта), то это явная ошибка процедуры посылки данных, и эти данные вы не получите, в винде. Проверяйте либу
Go to the top of the page
 
+Quote Post
rudy_b
сообщение Mar 2 2014, 16:36
Сообщение #26


Знающий
****

Группа: Свой
Сообщений: 888
Регистрация: 25-09-08
Из: Питер
Пользователь №: 40 458



Угу, еще раз посмотрел внимательно. При приеме из компа в контроллер все аккуратно. А вот при передаче из контроллера в комп - все криво. До конца еще не разобрался, но, похоже, понял в чем дело.

Эта зараза рассчитана на то, что приходящие снаружи (на СОМ) данные никогда не достигнут 64 за один фрейм, т.е. за 1 мсек. И, поэтому, она вообще не заботится о полном размере посылки, а тупо посылает все, рассчитывая, что число посланных байт всегда меньше 64 и проблем с завершением пакета не возникнет.

Это в чем-то обосновано, 64 байта за 1 мсек - это примерно 640кбит - намного выше стандартных скоростей СОМ порта.

Похоже, что для обмена пакетами нельзя использовать CDC, нужно брать что-то другое или не допускать размера пакетов кратного 64.

Конечно можно и драйвер поправить, но для этого прийдется полностью разбираться в структуре драйвера и, фактически, переписать его. Как-то лениво, но, может, прийдется.

Да, это не контрольная точка - это реальный балк.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Mar 2 2014, 18:16
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



очень странно что это балк, мне казалась что стандартный виндовый драйвер через контрольную работает, ну да ладно...

На самом деле вам не надо разбирать всю библиотеку, можно сделать внешний модуль обертку который будет следить за данными, в нем сделать фифо, и пусть он все выдавливает наружу, и если вдруг случиться что данных больше 64 байт, то пусть давит их наружу, и проверяет последний пакет.

Собственно когда я сам писал USB у меня так и была организованна посылка, получала данные, и слала, проверяя длину последнего пакета, дополняя нулем если что.

И еще одна вещь которую вам надо знать про USB, это то что в винде реально боле менее поддержаны только CDC и HID, все остальное потребует от вас в реальности написания собственного драйвера.
Go to the top of the page
 
+Quote Post
rudy_b
сообщение Mar 2 2014, 18:46
Сообщение #28


Знающий
****

Группа: Свой
Сообщений: 888
Регистрация: 25-09-08
Из: Питер
Пользователь №: 40 458



Они, почему-то, используют EP1 для приема и передачи данных в режиме балк, а EP2 - для команд (BaudRate и т.п.) в режиме interrupt. А EP0 не используют совсем. Она используется только в режиме HS и странным образом.

#define CDC_IN_EP 0x81 /* EP1 for data IN */ //USB_OTG_EP_BULK
#define CDC_OUT_EP 0x01 /* EP1 for data OUT */ //USB_OTG_EP_BULK
#define CDC_CMD_EP 0x82 /* EP2 for CDC commands */ //USB_OTG_EP_INT

Цитата
На самом деле вам не надо разбирать всю библиотеку, можно сделать внешний модуль обертку который будет следить за данными, в нем сделать фифо, и пусть он все выдавливает наружу, и если вдруг случиться что данных больше 64 байт, то пусть давит их наружу, и проверяет последний пакет.

Тут, похоже, и это может не помочь. Возможно возникнут еще и проблемы с виндюковым usbser.sys - он ведь тоже VirtualComPort и не должен реагировать на отсутствие общего размера посылки, только на длину конкретного блока данных. И проблемы у него есть - редкие ошибки при трансляции пакетов с размером более 64 байт связаны именно с его глюками, я специально поигрался. А если пакет меньше 64 байт - ошибок нет вообще.

Цитата
И еще одна вещь которую вам надо знать про USB, это то что в винде реально боле менее поддержаны только CDC и HID, все остальное потребует от вас в реальности написания собственного драйвера.

Вот этого я и боюсь. HID тоже не рассчитан на передачу блоков данных и фиг знает, что нам накручено. А в аудио и вообще лезть не хочется. Ну а писать свой драйвер под виндюки жутко не хочется, мои мозги не в состоянии воспринять их идеологию, хотя под нормальную ОС раньше писал без проблем.

Похоже прийдется обойтись пакетами 63 байта. Правда скорость при этом получается порядка 200 кбит, но, надеюсь, мне этого хватит.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Mar 2 2014, 19:35
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Да нет никакой проблемы, все равно для уравнивания скоростей надо делать ФИФО, и никто не мешает выдавать данные из этого фифо не более чем по 63 байта, и скорость будет 63 КБайта. Неудобство в сборе пакета потом, сom port - это потоковый протокол, а не пакетный, пакеты все равно придется собирать.

А вот что касается HID, то там как раз прям пакетно ориентированная идея. Основная единица обмена информацией у HID - это отчет. Отчет это фиксированная структура данных, определяемой вами длинны. Причем отчетов может быть несколько типов, так что можно определить несколько видов структур.

Обмен отчетам происходит по 2 конечным точкам интерапт типа, входной и выходной, или через контрольную, в контрольной будут теже сложности с делением пакета на 8-64 байта, но по интерапт точкам данные ходят одним куском. И проблем с драйверами HID сильно меньше, судя по отзывам...
Go to the top of the page
 
+Quote Post
rudy_b
сообщение Mar 2 2014, 23:43
Сообщение #30


Знающий
****

Группа: Свой
Сообщений: 888
Регистрация: 25-09-08
Из: Питер
Пользователь №: 40 458



Так тогда мне проще сразу работать блоками по 63 байта. Сборщик/делитель более длинных пакетов на блоки по 63 - все одно писать, либо в проге либо в драйвере. Все одинаково получается.

Правда драйвер все равно хочется переделать, уж больно там все криво написано. Но сейчас времени нет, может при следующем заходе.

Тут только один вопрос возникает, может ли одна ЕР передать или принять более 64 байт за один фрейм в случае если пакет занимает несколько блоков? При блоках по 256 байт скорость передачи была не менее 400кбит, а при передаче пакетов по 63 байта - порядка 200 кбит. Такое ощущение, что может. Вот тогда причесывание передающей части драйвера становится осмысленным.
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 11:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.01528 секунд с 7
ELECTRONIX ©2004-2016