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

 
 
> STM32F4 USB CDC-класс, Вопросы по работе с USB (CDC-класс) на STM32F4
Haamu
сообщение Feb 14 2014, 06:33
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 90
Регистрация: 12-12-13
Пользователь №: 79 587



Разбираюсь с работой USB (CDC-класс) на STM32F4.
У меня на плате имеется возможность связи с копмьютером как через USB (виртуальный COM-порт), так и через USART (RS-485). Для приема данных, не столь важно откуда они пришли. А вот при отправке нужно знать, куда отправлять, то есть нужно знать, подключено ли устройство по USB или нет. Как более правильно это сделать, используя драйвер USB (использую драйвер с сайта st.com)? Можно отслеживать, откуда пришли данные, можно проверить, есть ли питание от USB, наверняка можно еще кучу способов придумать, но хотелось бы через драйвер.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Axel
сообщение Feb 14 2014, 07:12
Сообщение #2


Местный
***

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



Цитата(Haamu @ Feb 14 2014, 09:33) *
...но хотелось бы через драйвер.


Если я правильно понял вопрос, то: можно в функции USBD_OTG_ISR_Handler() в обработке прерывания SOF фиксировать подключение, а в обработке SUSPEND - отключение (я так делаю). Работает вполне устойчиво.
Go to the top of the page
 
+Quote Post
Haamu
сообщение Feb 17 2014, 13:55
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 90
Регистрация: 12-12-13
Пользователь №: 79 587



Цитата(Axel @ Feb 14 2014, 11:12) *
Если я правильно понял вопрос, то: можно в функции USBD_OTG_ISR_Handler() в обработке прерывания SOF фиксировать подключение, а в обработке SUSPEND - отключение (я так делаю). Работает вполне устойчиво.

Спасибо. Попробую такой способ.

Появился еще один вопрос. Отправляю большой объем данных (порядка 30кБайт). В файле usbd_conf.h вот такие строки:
Код
#define CDC_IN_FRAME_INTERVAL          5    /* Number of frames between IN transfers */
#define APP_RX_DATA_SIZE               2048 /* Total size of IN buffer: APP_RX_DATA_SIZE*8/MAX_BAUDARATE*1000 should be > CDC_IN_FRAME_INTERVAL */

Поясните пожалуйста, почему тут заданны именно такие значения и в каких пределах можно их изменять? Можно ли сделать размер буфера равным 30кБ? На что это повлияет?
Я не трогал размер буфера, а пробую передавать данные частями, не превышающими размер буфера (передаю по 1000 байт). Как в таком случае определить, что данные из буфера переданны и можно подсовывать следующую порцию данных?
Go to the top of the page
 
+Quote Post
Axel
сообщение Feb 18 2014, 04:36
Сообщение #4


Местный
***

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



Значение CDC_IN_FRAME_INTERVAL определяет частоту попыток драйвера передать блок данных хосту и (соответственно) размер этого блока.
Значение APP_RX_DATA_SIZE определяется махимальным количеством байт, поступающих в драйвер (изнутри) за один usb-шный квант (1ms). Для 256кБод это 320 байт = CDC_IN_FRAME_INTERVAL * 64. Естественно, для исключения потерь при передаче, размер передаваемого пакета должен быть кратен величине (CDC_IN_FRAME_INTERVAL * 64). Это уже под Вашу ответственность. Я использовал этот код для своего, более простого bulk драйвера, передаю пакеты с размером, кратным 512 байт и, соответственно, использую значение CDC_IN_FRAME_INTERVAL, равное 8.
Go to the top of the page
 
+Quote Post
Haamu
сообщение Feb 18 2014, 05:40
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 90
Регистрация: 12-12-13
Пользователь №: 79 587



Цитата(Axel @ Feb 18 2014, 08:36) *
Для 256кБод это 320 байт = CDC_IN_FRAME_INTERVAL * 64.

А откуда эти 256кБод берутся?
Цитата(Axel @ Feb 18 2014, 08:36) *
размер передаваемого пакета должен быть кратен величине (CDC_IN_FRAME_INTERVAL * 64).

Значит в моем случае для кратности либо CDC_IN_FRAME_INTERVAL нужно с делать равным 8, либо изменить APP_RX_DATA_SIZE на 1920 или 2240. Я правильно понял?
Подскажите пожалуйста, как лучше сделать для моего конкретного случая, когда нужно передать до 30000 Байт, какие должны быть значения?
На данный момент, когда я передаю 2000 байт, всё передается нормально. Когда передаю больше 2000, на комп приходит только (N - 2048) последних байт.
Go to the top of the page
 
+Quote Post
Axel
сообщение Feb 18 2014, 06:11
Сообщение #6


Местный
***

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



Цитата(Haamu @ Feb 18 2014, 08:40) *
А откуда эти 256кБод берутся?

Да, вобщем, ниоткуда... Просто это близко (с некоторым запасом) к одной из высоких (для COM порта) стандартных скорстей - 250кБод. Вы, естсственно, можете использовать другую. Касательно размера буфера - трудно сказать. Он во многом определяется тем, как прерывание IN endpoint забирает из него данные. Я использую FIFO в виде кольцевого буфера. По поводу потерь данных - попробуйте просмотреть обмен каким-нибудь сниффером (напр. Bus Hound). Многое может прясниться...
Go to the top of the page
 
+Quote Post
Haamu
сообщение Feb 19 2014, 08:15
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 90
Регистрация: 12-12-13
Пользователь №: 79 587



Понял свою ошибку. Я накидываю кучу данных в буфер раньше, чем успевает что-то отправиться, соответственно данные затерают друг-друга и остаются только хвост, который приходит последним, он же и отправляется на комп.
Соответственно возникает вопрос. По какому признаку можно определить, что данные из буфера успешно отправленны и буфер готов к приему очередной порции данных?
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 19:27
Рейтинг@Mail.ru


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