RedHeadIvan 0 11 февраля, 2019 Опубликовано 11 февраля, 2019 · Жалоба Доброго времени суток, коллеги! Есть задача максимально близко к RealTime передавать данные, получаемые с АЦП с частотой до 100 кГц, в обработчик в компьютере. Взял FreeRTOS, сделал в прерывании АЦП по EOC передачу значения в очередь, которую разбирает FS USB Пока работал на малых выборках косяк не заметил, но когда увеличил время оцифровки увидел, что USB не успевает разобрать очередь и как только количество точек выходит за пределы очереди - все, начинается дичь Возможно, кто-нибудь может подсказать, как грамотно построить процесс передачи? Собственно, реализация треда передачи, где SendString, по сути, CDC_Transmit_FS void StartCommandHandler(void const * argument) { osEvent event; for(;;) { event = osMessageGet(DataQueueHandle, 0); if (event.status == osEventMessage) { uint16_t data = event.value.v; p = itoa(data,buffer,radix); SendString(p); } } } Буду благодарен за любую подсказку) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 11 февраля, 2019 Опубликовано 11 февраля, 2019 · Жалоба 1 hour ago, RedHeadIvan said: Возможно, кто-нибудь может подсказать, как грамотно построить процесс передачи? 1. Задействовать DMA для приема данных с АЦП (прерывание с частотой 100кГц - очень плохая идея) 2. Не использовать очереди ОС для данных 3. Не передавать данные текстом Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RedHeadIvan 0 12 февраля, 2019 Опубликовано 12 февраля, 2019 · Жалоба 17 hours ago, aaarrr said: 1. Задействовать DMA для приема данных с АЦП (прерывание с частотой 100кГц - очень плохая идея) 2. Не использовать очереди ОС для данных 3. Не передавать данные текстом В силу другой направленности специальности DMA раньше не использовал, поэтому путаюсь. Получается, надо циклически заполнять через DMA и отправлять по USB некоторый массив? На FS же нет своего DMA Но ведь в этом случае все равно USB будет в роли догоняющего: DMA кладет данные, пока USB их отправляет. Возможны коллизии? Не совсем в голове складывается полная картина, буду очень признателен за небольшие разъяснения Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 12 февраля, 2019 Опубликовано 12 февраля, 2019 · Жалоба 59 minutes ago, RedHeadIvan said: Получается, надо циклически заполнять через DMA и отправлять по USB некоторый массив? Да, только не один массив, а несколько (в простейшем случае два): пока один заполняется из АЦП, данные из другого передаются через USB. Если скорость передачи через USB достаточна, то коллизий не будет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 76 13 февраля, 2019 Опубликовано 13 февраля, 2019 · Жалоба 22 часа назад, RedHeadIvan сказал: Но ведь в этом случае все равно USB будет в роли догоняющего: DMA кладет данные, пока USB их отправляет. Возможны коллизии? Не совсем в голове складывается полная картина, буду очень признателен за небольшие разъяснения На USB коллизии будут всегда, поэтому на время коллизии надо иметь буфер. Чем больше время коллизии - тем больше буфер. Данные из буфера должны выбираться быстрее чем они туда поступают. А дальше считаем/оцениваем. USB host запрашивает у USB в микроконтроллере данные 1 раз в миллисекунду, т.е. получается буфер должен быть не меньше 100 16-битных слов. Удваиваем на пропуск одного запроса, получаем первый буфер 400 байт. Дальше смотрим как у вас реализован USB - имеет FIFO? Умеет по DMA забирать данные? Т.е. минимизировать время занятости контроллера. Еще не понятна загрузка вашей ОС. И еще много всяких. Во второй такой же буфер(400 байт) будет писать АЦП. Как только АЦП заполнил его, по прерыванию - переключаем на его на первый, а USB переключаем на второй и ждем запрос от USB host. Стоит вообще почитать как работает USB. Потому как чем больше устройств висит на одном USB host - тем больше вероятность что вашему устройство кто-то помешает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 235 14 февраля, 2019 Опубликовано 14 февраля, 2019 · Жалоба 22 часа назад, HardEgor сказал: На USB коллизии будут всегда, поэтому на время коллизии надо иметь буфер. Что за "коллизии" на USB? О чём речь? Такую передачу неоднократно делал на FS USB через изохронную точку, со скоростью до 1023 байт за 1 мс. И никаких коллизий. Но глядя на творение ТС, сомневаюсь что такая задача ему по плечу. Цитата Удваиваем на пропуск одного запроса, получаем первый буфер 400 байт. Что за "пропуск"? Из-за кривого USB-драйвера? Цитата Стоит вообще почитать как работает USB. Потому как чем больше устройств висит на одном USB host - тем больше вероятность что вашему устройство кто-то помешает. Чтобы никто не помешал следует использовать изохронную точку. А с балком (как ни крутись с буферами) - всё-рано никаких гарантий нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться