|
STM32F4 USB CDC, Передаёт не более 32 байт за раз |
|
|
|
Mar 7 2013, 08:53
|

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

|
Понимаю, что может быть избитая и изъезженная тема тема, но всё же. Короче, взял пример COM-порта отсюда - http://we.easyelectronics.ru/STM32/primery...4-discovey.htmlПорт опознаётся, устанавливается, всё ок. Данные принимает, передаёт. Но. Не могу передать на комп более 32 байт. Комп просто ничего не принимает. Когда 32 байта и меньше всё в порядке. Это ж отстой полный, хуже чем даже USB HID Generic - 64 байта туда-сюда-обратно. И тот кстати не получается. Примеры - сплошные мыши и джойстики  ... Это что, норма? И как этого избежать? Размер буферов в прошивке вроде 2 кила - макрос APP_RX_DATA_SIZE = 2048. И ещё. Не хочется, чтобы железка торчала в списке COM-портов. Взял финский пример отсюда - http://forum.easyelectronics.ru/viewtopic....=35&t=10245Он пошёл без проблем, комп его увидел. Но где взять драйвер? Нашёл libusb, драйвер им сгенерил, но как с ним дальше работать не понял... Может ли кто-нибудь помочь? Спасибо.
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 31)
|
Mar 7 2013, 17:20
|

Участник

Группа: Участник
Сообщений: 30
Регистрация: 1-08-05
Из: Украина Винница
Пользователь №: 7 258

|
Цитата(hd44780 @ Mar 7 2013, 15:07)  Ну пусть COM-порт уже, фиг с ним ...
А чего только 32 байта гоняет? Кривизна ST-шных библиотек? Или моих рук? КакбЕ #ifdef USB_OTG_FS_CORE #define RX_FIFO_FS_SIZE 128 #define TX0_FIFO_FS_SIZE 32 #define TX1_FIFO_FS_SIZE 128 #define TX2_FIFO_FS_SIZE 32 #define TX3_FIFO_FS_SIZE 0 в файле usb_conf.h строка 144 Глубоко не копал - может отсюда ноги ростут??? У меня HID - проблем нет
|
|
|
|
|
Mar 8 2013, 14:54
|

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

|
Нашёл в интернете вот такое: Код #define RX_FIFO_FS_SIZE 128 #define TX0_FIFO_FS_SIZE 64 #define TX1_FIFO_FS_SIZE 128 #define TX2_FIFO_FS_SIZE 0 #define TX3_FIFO_FS_SIZE 0 Поставил себе - ничего не изменилось. Кстати размер конечных точек - по 64 байта ...
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
Mar 8 2013, 18:05
|

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

|
FlexZ, это из архива STM32_USB-Host-Device_Lib_V2.1.0? Попробовал - то же самое  . А у Вас сколько байт за раз передаёт? Можно конечно самому дробилку-сшивалку пакетов написать, но, может, готовое есть? Может ещё какой-то пример есть? Или Вы поделитесь, если можете .... Спасибо.
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
Mar 8 2013, 19:39
|
Местный
  
Группа: Свой
Сообщений: 252
Регистрация: 9-10-08
Из: Московская обл.
Пользователь №: 40 797

|
Да, пример из этого архива. Пачки уходят вплоть до 24кб за раз. Правда на каком-то этапе они разбиваются на блоки размером не более 4кб (видно в USBTrace). Подробно не вникал где именно, но это явно больше чем 32 байта. Один из проектов есть в открытом доступе https://code.google.com/p/logicdiscovery/so...FLogicDiscoveryPS а вы случайно не в HS режиме его запускаете? У меня в HS режиме с внешней физикой этот код тоже тупил.
|
|
|
|
|
Mar 9 2013, 05:20
|

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

|
Спасибо. Цитата(Flexz @ Mar 8 2013, 21:39)  Пачки уходят вплоть до 24кб за раз. Правда на каком-то этапе они разбиваются на блоки размером не более 4кб (видно в USBTrace). Подробно не вникал где именно, но это явно больше чем 32 байта. Круто  . Цитата(Flexz @ Mar 8 2013, 21:39)  Да, натыкался на него, только с головы вылетел, посмотрю. Вот, кстати, статья от этого кода - http://habrahabr.ru/post/165853/Цитата(Flexz @ Mar 8 2013, 21:39)  PS а вы случайно не в HS режиме его запускаете? У меня в HS режиме с внешней физикой этот код тоже тупил. Нет, FS. HS физика в виде маленькой платки с USB3300 ко мне пока едет ... С ней буду потом разбираться. Когда доедет.
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
Mar 11 2013, 07:11
|

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

|
Кабель длиной где-то 30 см от телефона Nokia X2-02. Точнее куплен был отдельно для этого телефона. Плюс USB удлинитель 1.8м, т.к. эти 30 см короткие... Может я отсылку данных неправильно осуществляю. В библиотеках драйвера есть метод uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len), который вроде и предназначен для отсылки данных в комп: CODE uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len) { uint32_t i; // loop through buffer for( i = 0; i < Len; i++ ) { // буфер APP_Rx_Buffer используется драйвером USB APP_Rx_Buffer[APP_Rx_ptr_in] = (uint8_t) Buf[i]; //increase pointer value APP_Rx_ptr_in++; // To avoid buffer overflow if(APP_Rx_ptr_in == APP_RX_DATA_SIZE) { APP_Rx_ptr_in = 0; } } // for return USBD_OK; } // VCP_DataTx
Т.е. он просто копирует мои данные во внутренний буфер драйвера. Константа APP_RX_DATA_SIZE равна 2048, т.е. 2 кила он должен вроде отсылать. Этот метод я и вызываю для отсылки своих данных в комп. Единственное, что я изменил - убрал с него модификатор static, чтобы его можно было извне вызывать ... Может из-за этого косяки и его надо через какую-то функцию-обёртку вызывать (я такое где-то видел)?
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
Mar 11 2013, 09:45
|
Местный
  
Группа: Свой
Сообщений: 252
Регистрация: 9-10-08
Из: Московская обл.
Пользователь №: 40 797

|
Вот в этом месте у меня во всех проектах немного по-другому - тело цикла вынесено в функцию, которая кладет в буфер один единственный байт (изначально делалось для putchar). Код uint16_t VCP_ByteTx (uint8_t dataByte) { APP_Rx_Buffer[APP_Rx_ptr_in] = dataByte; APP_Rx_ptr_in++;
/* To avoid buffer overflow */ if(APP_Rx_ptr_in == APP_RX_DATA_SIZE) { APP_Rx_ptr_in = 0; }
return USBD_OK; } В том проекте, на который я выше ссылку давал, перемещение массива в буфер дополнительно обернуто в запрет прерываний, и там тоже по байту кладется. Возможно, это имеет значение, по-другому я даже не пробовал.
|
|
|
|
|
Mar 11 2013, 13:50
|

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

|
Сделал, но заметил следующую странность: У меня сейчас работа организована в формате "запрос-ответ", т.е. комп шлёт команду (символ 'S'), железяка в ответ должна выплюнуть некий объём информации. Сейчас для отладки выплёвывает синусоиду, которая рассчитывается в коде и ни от чего не зависит. Так вот, когда я выплёвываю до 32 байт, все работает как и задумано, а если больше (например килобайт), то на первую команду ответа нет вообще (ждал до 10 сек), но как только я пуляю в него ещё один 'S', то я мгновенно получаю 2 кила синусоиды (причём там явно видно, что это именно 2 разных независимых ответа, т.к. синусоида на конце килобайта "оторванная", не дошедшя до конца периода). Такое ощущение, что данные где-то "залипают". Буфер приёма на компе задан 10 кил, т.е. он с гарантией ничего не потеряет. Также, если после первой 'S' закрыть порт, и потом открыть его, то я мгновенно получаю ответ на 'S', поданный до закрытия порта. Если ставлю больше килобайта, то ответов нет вообще. Может это вообще косяки ST-шного драйвера порта, а не прошивки? Драйвер версии 1.3.1 от 23 июля 2010, найден где-то на форумных развалах. Понимаю, что старьё, но на ST- шном сайте сам чёрт ногу сломит, ещё и глючит, зараза  винда - 2003 сервер. С COM-портами работать умею, т.к. по профессии программист. Недавно 3 кассоовых аппарата завёл через COM-порт. Работают нормально. Из 2-х из них данные вообще льются как из ведра непрерывным потоком, успевай ловить....
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
Mar 11 2013, 19:15
|

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

|
Победил я кажись эту хреновину  . Западло (по крайней мере в моём случае) заключалось в том, что объём передаваемых данных должен быть как минимум на килобайт меньше размера буфера APP_RX_DATA_SIZE. Последнее, чего я достиг - APP_RX_DATA_SIZE = 11 кил, передаёт по 10 кил стабильно, без глюков и подвисаний. Работает и с ST-шными дровами и общими, виндозными.
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
Mar 2 2014, 11:58
|
Местный
  
Группа: Свой
Сообщений: 480
Регистрация: 21-11-04
Пользователь №: 1 188

|
Цитата(rudy_b @ Mar 2 2014, 14:46)  Мне просто важно понять - это что-то не то у меня или это действительно ошибка либы. Никто не гонял пакеты с такой длиной? Я слепил свой bulk-девайс на основе ST-шной либы. Обмен только пакетами, кратными 64 байтам. Никаких проблем не отмечал. В предыдущих проектах с LPC17 - та же ситуация (в смысле все нормально).
|
|
|
|
|
Mar 2 2014, 13:41
|
Знающий
   
Группа: Свой
Сообщений: 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 метров (с примерами).
|
|
|
|
|
Mar 2 2014, 14:27
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
не надо мешать все в одну кашу. балк, изохронный, прерывания, и контрольные обмены. Что какой то из них тоже использует буфер 64 байта это ничего не значит.
Правда заключается в том что контрольная точка может послать максимум 64 байта. Когда на компьютер приходит пакет длинной меньше 64 байт - это конец послания. И вам становится доступно сообщение по ReadFile в винде. Если же приходит пакет длинной 64 байта, то не понятно это все сообщение, или нет, так как ограничение длинны может быть из-за максимального размера конечной точки. Поэтому драйвер винды кладет себе это сообщение и ждет следующего пакета, если придет пакет длинной меньше, он поймет что это конец и все вам отдаст, потому по стандарту пакеты длинной в макс буфер конечной точки обязательно должны быть дополнены пакетом 0 длины.
Если вы монитором USB порта после прихода пакета длинной 64 байта, не видите закрывающего пакета 0 длинны (его иногда могут как АКК воспринимать мониторы порта), то это явная ошибка процедуры посылки данных, и эти данные вы не получите, в винде. Проверяйте либу
|
|
|
|
|
Mar 2 2014, 16:36
|
Знающий
   
Группа: Свой
Сообщений: 888
Регистрация: 25-09-08
Из: Питер
Пользователь №: 40 458

|
Угу, еще раз посмотрел внимательно. При приеме из компа в контроллер все аккуратно. А вот при передаче из контроллера в комп - все криво. До конца еще не разобрался, но, похоже, понял в чем дело.
Эта зараза рассчитана на то, что приходящие снаружи (на СОМ) данные никогда не достигнут 64 за один фрейм, т.е. за 1 мсек. И, поэтому, она вообще не заботится о полном размере посылки, а тупо посылает все, рассчитывая, что число посланных байт всегда меньше 64 и проблем с завершением пакета не возникнет.
Это в чем-то обосновано, 64 байта за 1 мсек - это примерно 640кбит - намного выше стандартных скоростей СОМ порта.
Похоже, что для обмена пакетами нельзя использовать CDC, нужно брать что-то другое или не допускать размера пакетов кратного 64.
Конечно можно и драйвер поправить, но для этого прийдется полностью разбираться в структуре драйвера и, фактически, переписать его. Как-то лениво, но, может, прийдется.
Да, это не контрольная точка - это реальный балк.
|
|
|
|
|
Mar 2 2014, 18:16
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
очень странно что это балк, мне казалась что стандартный виндовый драйвер через контрольную работает, ну да ладно...
На самом деле вам не надо разбирать всю библиотеку, можно сделать внешний модуль обертку который будет следить за данными, в нем сделать фифо, и пусть он все выдавливает наружу, и если вдруг случиться что данных больше 64 байт, то пусть давит их наружу, и проверяет последний пакет.
Собственно когда я сам писал USB у меня так и была организованна посылка, получала данные, и слала, проверяя длину последнего пакета, дополняя нулем если что.
И еще одна вещь которую вам надо знать про USB, это то что в винде реально боле менее поддержаны только CDC и HID, все остальное потребует от вас в реальности написания собственного драйвера.
|
|
|
|
|
Mar 2 2014, 18:46
|
Знающий
   
Группа: Свой
Сообщений: 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 кбит, но, надеюсь, мне этого хватит.
|
|
|
|
|
Mar 2 2014, 19:35
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Да нет никакой проблемы, все равно для уравнивания скоростей надо делать ФИФО, и никто не мешает выдавать данные из этого фифо не более чем по 63 байта, и скорость будет 63 КБайта. Неудобство в сборе пакета потом, сom port - это потоковый протокол, а не пакетный, пакеты все равно придется собирать.
А вот что касается HID, то там как раз прям пакетно ориентированная идея. Основная единица обмена информацией у HID - это отчет. Отчет это фиксированная структура данных, определяемой вами длинны. Причем отчетов может быть несколько типов, так что можно определить несколько видов структур.
Обмен отчетам происходит по 2 конечным точкам интерапт типа, входной и выходной, или через контрольную, в контрольной будут теже сложности с делением пакета на 8-64 байта, но по интерапт точкам данные ходят одним куском. И проблем с драйверами HID сильно меньше, судя по отзывам...
|
|
|
|
|
Mar 3 2014, 05:02
|
Местный
  
Группа: Свой
Сообщений: 480
Регистрация: 21-11-04
Пользователь №: 1 188

|
Цитата(rudy_b @ Mar 2 2014, 22:46)  Они, почему-то, используют EP1 для приема и передачи данных в режиме балк, а EP2 - для команд... При балк обмене драйвер хоста должен знать размер принимаемого пакета, иначе он выйдет из приема по таймауту с потерей информации. Именно для передачи этого знания используется ЕР2, а через ЕР1 идут собственно данные. Если Вам просто нужно организовать обмен и не строго использовать Virtual Com или HID, то (ИМХО) самый простой путь - выдрать из либы минимум для балк обмена и определить фиксированную длину пакета. Со стороны хоста - libusb или winusb. Они достаточно хорошо описаны и несложны в использовании, правда (как и все остальные) не снимают геморроя при удаленной инсталляции, особенно под Windows8.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|