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

Потоковая передача данных АЦП

Доброго времени суток, коллеги!

Есть задача максимально близко к 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);
	  	  	  }
  	  }
}

Буду благодарен за любую подсказку)

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


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

1 hour ago, RedHeadIvan said:

Возможно, кто-нибудь может подсказать, как грамотно построить процесс передачи?

1. Задействовать DMA для приема данных с АЦП (прерывание с частотой 100кГц - очень плохая идея)

2. Не использовать очереди ОС для данных

3. Не передавать данные текстом

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


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

17 hours ago, aaarrr said:

1. Задействовать DMA для приема данных с АЦП (прерывание с частотой 100кГц - очень плохая идея)

2. Не использовать очереди ОС для данных

3. Не передавать данные текстом

В силу другой направленности специальности DMA раньше не использовал, поэтому путаюсь. Получается, надо циклически заполнять через DMA и отправлять по USB некоторый массив? На FS же нет своего DMA

Но ведь в этом случае все равно USB будет в роли догоняющего: DMA кладет данные, пока USB их отправляет. Возможны коллизии?

Не совсем в голове складывается полная картина, буду очень признателен за небольшие разъяснения

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


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

59 minutes ago, RedHeadIvan said:

Получается, надо циклически заполнять через DMA и отправлять по USB некоторый массив?

Да, только не один массив, а несколько (в простейшем случае два): пока один заполняется из АЦП, данные из другого передаются через USB.

Если скорость передачи через USB достаточна, то коллизий не будет.

 

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


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

22 часа назад, RedHeadIvan сказал:

Но ведь в этом случае все равно USB будет в роли догоняющего: DMA кладет данные, пока USB их отправляет. Возможны коллизии?

Не совсем в голове складывается полная картина, буду очень признателен за небольшие разъяснения

На USB коллизии будут всегда, поэтому на время коллизии надо иметь буфер.

Чем больше время коллизии - тем больше буфер.

Данные из буфера должны выбираться быстрее чем они туда поступают.

А дальше считаем/оцениваем.

USB host запрашивает у USB в микроконтроллере данные 1 раз в миллисекунду, т.е. получается буфер должен быть не меньше 100 16-битных слов.

Удваиваем на пропуск одного запроса, получаем первый буфер 400 байт.

Дальше смотрим как у вас реализован USB - имеет FIFO? Умеет по DMA забирать данные? Т.е. минимизировать время занятости контроллера.

Еще не понятна загрузка вашей ОС. И еще много всяких.

Во второй такой же буфер(400 байт) будет писать АЦП. Как только АЦП заполнил его, по прерыванию - переключаем на его на первый, а USB переключаем на второй и ждем запрос от USB host.

Стоит вообще почитать как работает USB. Потому как чем больше устройств висит на одном USB host - тем больше вероятность что вашему устройство кто-то помешает.

 

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


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

22 часа назад, HardEgor сказал:

На USB коллизии будут всегда, поэтому на время коллизии надо иметь буфер.

Что за "коллизии" на USB? О чём речь?

Такую передачу неоднократно делал на FS USB через изохронную точку, со скоростью до 1023 байт за 1 мс. И никаких коллизий.

Но глядя на творение ТС, сомневаюсь что такая задача ему по плечу.

Цитата

Удваиваем на пропуск одного запроса, получаем первый буфер 400 байт.

Что за "пропуск"? Из-за кривого USB-драйвера?

Цитата

Стоит вообще почитать как работает USB. Потому как чем больше устройств висит на одном USB host - тем больше вероятность что вашему устройство кто-то помешает.

Чтобы никто не помешал следует использовать изохронную точку. А с балком (как ни крутись с буферами) - всё-рано никаких гарантий нет.

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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