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

 
 
> STM4 USB CDC. Интересное поведение
drozel
сообщение Oct 19 2015, 10:35
Сообщение #1


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

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Использую libopencm3. За основу взят вот этот пример CDC.
Размер фрейма для нашего ендпойнта настроен 64.
Написал простеньку логику: МК принимает фрейм, смотрит первый элемент и высылает назад статик массив размером, указанным в принятом байте.
Таким образом, я в терминале посылаю число и в ответ получаю заказанное кол-во байт.
Код:
Код
static void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep)
{
    (void)ep;

    int len = usbd_ep_read_packet(usbd_dev, 0x01, USBio.buffer, 64);
    сdcacm_data_tx((uint8_t *)textBuf, USBio.buffer[0]);
}


Посылаю число 0х20 - получаю 32 байта данных.
Посылаю число 0х3F - gjkexf. 63 байта в ответ.
Посылаю 0x40 - тишина. Еще раз - тишина. Теперь внимание! Посылаю 0х01 - получаю 129 байт.
Т.е. пришли все запрошенные за прошлые 3 раза данные.
Выходит, что если МК посылает кол-во байт, совпадающее с размером фрейма - данные где-то зависают.

Начал копать: посылает ли МК? Поставил коллбек по окончанию передачи, виду, что передача проходит.
Принимает ли ПК? К сообщению прикреплен скриншот USB сниффера.
Данные действительно где-то зависают. Буфер драйвера? Буфер USB контроллера?

Кто сталкивался?

Прикрепленное изображение


UPD: нащел аналогичный вопрос на форуме СТ. Он там остался без ответа)
UPD2: Вот тут пояснили, что передача длиной равной размеру кадра должна дополняться передачей нулевой длины. Однако, такая логика не согласуется с логикой разрабов libopencm3, которые используют следующую логику для проверки занятости ендпойнта в функции отправки:
Код
while(usbd_ep_write_packet(usbd_dev, 0x82, buf, len) == 0);

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

Сообщение отредактировал drozel - Oct 19 2015, 10:46
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
drozel
сообщение Oct 22 2015, 10:29
Сообщение #2


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

Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650



Еще вопрос: в случае передачи послыки с ПК через CDC кто организует ZLP, когда кол-во байт кратно 64?
Terminal шлет строку по одному символу в кадре, а NI VISA просто отправляет 64 без всяких ZLP.

Не могу составить нормальное представление работы CDC. Я полагал, что пользователь системы работает с портом, как с простым UART, засылая теда что хочет и когда хочет. А драйвер передает это в МК пакетами по 64 байта, трансферами по 1024. Т.е. если я пошлю 256 байт, уйдет 4 пакета и ZLP. Если отправлю 1025, уйдет 16 пакетов, потом МК поставит NACK и ПК будет ждать разрешения для досылки еще одного байта. И пытаюсь создать соответствующую логику на МК, которая будет формировать трансфер (ожидая ZLP или пакета меньше чем 64 байта), после чего выставлять force NAK и вызывать обработчик для данных.

Поправьте, в чем я не прав.

Сообщение отредактировал drozel - Oct 22 2015, 10:59
Go to the top of the page
 
+Quote Post



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

 


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


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