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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Передача большого массива данных от МК к PC (STMicroelectronics Virtual COM Port)
js_slider
сообщение May 19 2014, 08:33
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 29
Регистрация: 22-12-05
Пользователь №: 12 577



Камень STM32F405
Задача требуется передавать большой массив данных по виртуальному COM порту.
За основу взял пример от ST, COM порт определился, попробывал передавать данные вот так:

Код
    for( i = 0; i < Len; i++ )
    {
        //push data into transfer buffer
        APP_Rx_Buffer[APP_Rx_ptr_in] = 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;
        }
    }

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

Сообщение отредактировал IgorKossak - May 19 2014, 10:02
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
js_slider
сообщение May 19 2014, 09:41
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 29
Регистрация: 22-12-05
Пользователь №: 12 577



Заметил еще проблему...
Если массив данных более 64 байт, то переодически происходят сбои в передаче данных...
Кто сталкивался? Подскажите что не так делаю?
Go to the top of the page
 
+Quote Post
Vladimir_T
сообщение May 19 2014, 11:02
Сообщение #3


Знающий
****

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



Размер буфера данных между конечными точками не должен превышать 64Б, по стандарту USB. Таким образом вы и передавайте блоками, кратными 64Б, если последний блок будет 64Б, то потребуется передать дополнительный пустой блок. Пользуюсь примером от ST, правда процессор STR912, удается передавать до 62 кБ.
Go to the top of the page
 
+Quote Post
js_slider
сообщение May 19 2014, 11:15
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 29
Регистрация: 22-12-05
Пользователь №: 12 577



Цитата(Vladimir_T @ May 19 2014, 19:12) *
Размер буфера данных между конечными точками не должен превышать 64Б, по стандарту USB. Таким образом вы и передавайте блоками, кратными 64Б, если последний блок будет 64Б, то потребуется передать дополнительный пустой блок. Пользуюсь примером от ST, правда процессор STR912, удается передавать до 62 кБ.

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

Сообщение отредактировал js_slider - May 19 2014, 11:17
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 19 2014, 11:20
Сообщение #5


Гуру
******

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



не совсем верно, это при передачи через контрольную точку 64 байта пакеты. Но вроде виртуальный ком порт еще 2 интерапт точки делает, а там размер буфера 1024 бита вроде как...

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

Как работает USB лучше почитать стандарт. Смысл в том что USB с вашей стороны это слейв, его опрашивает мастер, если грубо и коротко, то каждую милисекунду проверяют наличие данных, и если они есть они уходят в компьютер. При этом есть 2 вида пакетов DATA1, DATA2 и они уходят по очереди, это как раз чтобы пока отгружают первый буфер, второй уже набивался.

По уму ваша задача решается через ДМА, которая из огромного буфера отгружает данные, но можно и проще. Полингом проверять ушел прошлый пакет, и если ушел, то добавлять новый...
Go to the top of the page
 
+Quote Post
js_slider
сообщение May 19 2014, 13:05
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 29
Регистрация: 22-12-05
Пользователь №: 12 577



Цитата(Golikov A. @ May 19 2014, 19:30) *
сбои которые вы видите, видят многие, пока есть мнение что какие то ошибки в драйверах винды, но может вы видите какие то другие сбои.

Сбои заключаются в том что посланный массив данных от МК к PC, не доходит весь, а частично где то теряется.
Как решается данная задача потери? неужели это не лечится на VCP?

По поводу DMA.. USB у меня работает в режиме FullSpeed, как я понял в этом режиме нет поддержки DMA у ST32F4, поправте если ошибаюсь.

Цитата(Golikov A. @ May 19 2014, 19:30) *
но можно и проще. Полингом проверять ушел прошлый пакет, и если ушел, то добавлять новый...

Люди добрые покажите примером как это можно сделать... как понять что буфер APP_Rx_Buffer[] освободился на N-ое кол-во байт...
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 19 2014, 14:53
Сообщение #7


Гуру
******

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



Вот, потеря данных...
http://electronix.ru/forum/index.php?showtopic=118917
вот ваши коллеги...

а вот еще
http://electronix.ru/forum/index.php?showtopic=118369

Go to the top of the page
 
+Quote Post
js_slider
сообщение May 19 2014, 16:46
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 29
Регистрация: 22-12-05
Пользователь №: 12 577



У коллег ветка заглохла.. и без результатно в отношении потери данных... Неужели Virtual COM Port не способен стабильно работать... работают же как то FTDI и им подобные...
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 20 2014, 00:50
Сообщение #9


Гуру
******

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



у коллег по первой ссылке ближе к концу был пример как сделать передачу. А мой знакомый разработчик который боролся с этой проблемой сказал что увеличение таймаута ожидания данных ему помогло. Ну и конечно стандартное решение, при долгом отсутствии данных - переконект. В общем пока что я видел в качестве решения - заплатки. А FTDI еще имеет свой драйвер, и все обычно в конце на него переходят, неспроста....
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 20 2014, 02:20
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Я уже конечно давно не работал с CDC, но по-моему скорей всего ТС просто не разобрался со своим стеком.
Когда я работал с CDC (на стеке LPC и его CPU), никаких таких потерь не было. Вообще.
API для юзера там позволяло отправлять и большие блоки (они разбивались внутри стека).
Уведомление о завершении передачи от стека (и подкачка новых данных) там было сделано через callback-вызовы.

Цитата(Golikov A. @ May 19 2014, 21:30) *
не совсем верно, это при передачи через контрольную точку 64 байта пакеты. Но вроде виртуальный ком порт еще 2 интерапт точки делает, а там размер буфера 1024 бита вроде как...

У меня сейчас в комп воткнуты два разных (с разными дровами) USB-COM. В обоих имеется только по два bulk-эндпоинта. Никаких интеррапт.
Не уверен, но возможно FS позволяет несколько транзакций с одной bulk-точкой за один 1мс-фрейм. Надо читать описание USB.

PS: Нет, сорри - в одном из CDC-устройств имеется одна интеррапт-точка. Но размер её == 2байта с интервалом 1мс. А значит - в ней только какие-то статусы передаются.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение May 20 2014, 03:16
Сообщение #11


Гуру
******

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



Я давно не ковырял USB, так что вполне могу ошибаться. Помниться что 90% идет через контрольную конечную точку, и помниться что вроде в стандарте было еще 2 какие то конечные точки, почему то казалось что interrupt. Но bulk тоже подходит.


на interrupt наверное RTS, CTS повесилиsm.gif

HS - устройства точно имеют микрофреймы внутри милисекундного кадра, вроде как 8 микрофреймов, FS и LS не должны иметь. Хотя в стандарте было как-то путано написано, но вроде как решили что речь идет о передаче через несколько конечных точек одновременно...

Вот почитал стандарт. Bulk обмен для FS устройств может делать до 19 передач в один фрайм, буфера размером 64 байта.
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 20 2014, 03:44
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Golikov A. @ May 20 2014, 13:26) *
Вот почитал стандарт. Bulk обмен для FS устройств может делать до 19 передач в один фрайм, буфера размером 64 байта.

Вот! я же слышал где-то звон, но не помнил где он wink.gif
Как я помню стратегию bulk - она самая низкоприоритетная, но одна точка может занимать весь канал и обеспечивать 100% скорости всей USB-FS
при отсутствии передач по другим точкам. 19*64=1216 - как раз полные 100% скорости USB.
А фрагментацию должен стек осуществлять. Стек от LPC умеет её делать, и для Control-кадров тоже.
Go to the top of the page
 
+Quote Post
Axel
сообщение May 21 2014, 00:51
Сообщение #13


Местный
***

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



Виртуальный COM, как отмечалось, использует bulk трансфер. PC-шные bulk-драйверы умеют принимать только заранее известный объем данных. Для передачи этой информации используются дополнительные interrupt ендпоинты. Оба типа обменов, естественно, должны быть жестко засинхронизированы. Именно потерями на синхронизацию объясняется невозможность достижения максимальнх скоростей при использовании FTDI. И именно проблемами этой синхронизации (IMXO) объясняются обсуждавшиеся потери информации в направлении девайс - РС.
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 21 2014, 02:55
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Да ну, правда что-ль? wink.gif
Интересно - как тогда пашет тот мой USB-COM, в котором только две bulk-точки? А ведь как-то умудряется на 230400, а местами и на 460800 работать!
CP210x
А что мешает драйверу периодически (раз в неск. мс) опрашивать эти самые bulk-точки, а в CP210x иметь буфер на несколько размеров bulk-точки?
Конечно - если есть интеррапт, то оно вроде как само. Но не надо забывать, что любые транзакции, с любыми типами точек (и даже interrupt и isochronous),
инициирует хост-драйвер. Точно также и драйвер конкретного устройства может периодически инициировать транзакции со своими bulk-точками.
Ну конечно когда ему выдадут ресурс времени в соответствии с приоритетом.
Go to the top of the page
 
+Quote Post
Axel
сообщение May 21 2014, 03:35
Сообщение #15


Местный
***

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



Цитата
...А ведь как-то умудряется на 230400, а местами и на 460800 работать!...

Даже Ваши 460800 это как-то не совсем USB-шные теоретические 12Мb...

Цитата
А что мешает драйверу периодически (раз в неск. мс) опрашивать эти самые bulk-точки, а в CP210x иметь буфер на несколько размеров bulk-точки?

Что мешает - не знаю. Знаю, как работают функции bulk_read из известных мне драйверов. Знаю (из собственного опыта), что "обычный" bulk-обмен
(с фиксированным размером пакета) достаточно легко пoзволяет скорости до 750kB/s и работает часами без потерь информации, а моя единственная
(может быть не очень умелая) попытка организовать обмен пакетами пермеменной длины с приемлемой (более 300 kB/s) скоростью закончилась такими
же результатами, как и те, что имеет сообщество с виртуальным (не FTDI) COM
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 03:51
Рейтинг@Mail.ru


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