Перейти к содержанию
    

какой странный подход. По мне последние сообщение не "победил" а "нашел" непонятную вещь. Вот когда вы скажете почему так должно быть, тогда можете считать что победили. Почему по 2 запроса надо? и кучу других почему. Пока что вы нашли куда забить костыль чтобы оно хоть как то зашевелилось...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Согласен полностью.

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И снова та же тема...

Поднял 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 байт. Но тут все как-то странно, пока не понял в чем дело. Ошибки вроде случайные, но ходят пачками и зависят от загрузки винды.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Я слепил свой bulk-девайс на основе ST-шной либы. Обмен только пакетами, кратными 64 байтам. Никаких проблем не отмечал. В предыдущих проектах с LPC17 - та же ситуация (в смысле все нормально).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А какой именно либы? Я использовал 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) похоже считает передачу незавершенной и сбрасывает весь пакет - не приходит ни одного байта при любом количестве перезапросов. Ну или что-то в этом роде, хотя и непонятно как такого можно добиться.

 

 

 

 

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

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

 

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

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

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

 

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

 

Но исходники есть, могу послать если нужно, размер-порядка 4 метров (с примерами).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

не надо мешать все в одну кашу.

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

 

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

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

 

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

 

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

 

Да, это не контрольная точка - это реальный балк.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Они, почему-то, используют 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 кбит, но, надеюсь, мне этого хватит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

Обмен отчетам происходит по 2 конечным точкам интерапт типа, входной и выходной, или через контрольную, в контрольной будут теже сложности с делением пакета на 8-64 байта, но по интерапт точкам данные ходят одним куском. И проблем с драйверами HID сильно меньше, судя по отзывам...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...