Jump to content

    

Принять данные через COM порт и сохранить в файл

1 hour ago, jcxz said:

Приём вели в отдельном потоке или в GUI-потоке?

Не совсем понял вопрос, но потоков никаких не организовывал.

Пишу на Delphy.

Простой таймер вызывается раз в 1 мс.

В обработчике просто вычитываю все что накопилось в буфере и складываю в массив.

Share this post


Link to post
Share on other sites
1 час назад, aaarrr сказал:

У FT232RL объем приемного буфера составляет 256 байт, на скорости 2M он заполнится за 1.28мс при периоде обслуживания 1мс в наихудшем случае (USB FS).

ИМХО, не стоит рассчитывать на прием скоростного потока без потерь в отсутствие протокола и управления потоком.

Почему? Если ОС не пропускает циклов обслуживания USB хоста, то времени выкачать данные вполне достаточно. Главное чтобы на этом USB больше не сидело ничего, требующего обмена.

Да и почему Вы думаете, что за один цикл шины может быть только одна bulk-транзакция?

Да - и про "ОС не пропускает циклов обслуживания USB хоста" я не зря написал: в некоторых случаях некоторые USB-драйвера на WinXP пропускают эти циклы. :( 

Но думаю у автора не XP.

Share this post


Link to post
Share on other sites

а "mode COM7 baud=2000000 data=8 parity=n to=off" и "type COM7 > data.txt" в виндах уже поломали и всё ещё работает?

 

Share this post


Link to post
Share on other sites
56 минут назад, zombi сказал:

4096 байт в настройках USB-COM если речь об этом.

никак. пишу в массив в озу. После окончания приёма сохраняю на диск.

Причём тут настройки USB если речь о Вашем приложении? само собой разумеется я говорю о размерах буферов для SetupComm(). Эта буферизация идёт в виндовом Comm-драйвере.

51 минуту назад, zombi сказал:

Не менял.

Не менял. А какие надо поставить?

Ну а чего же вы хотели от винды, если сами ничего не сделали для нормальной работы? у Вас вроде скорость не 1 б/сек - кое-как, не разбираясь сделать тут не получится.

Изучайте WinAPI, overlapped IO, многопоточную работу приложений и как работать в стиле event-driven (а не по каким-то таймерам). И тогда сможете написать нормально.

А терминалки, которые теряют байты, вот примерно в таком стиле как у Вас и написаны. Поэтому и теряют.

В thread-е, работающем с COM-портом не должно быть никаких GUI-операций, никаких файловых операций. Он не должен ни чем тормозиться. Он должен писать в кольцевой буфер в ОЗУ размером в несколько МБ, и выдавать нотификации (об изменении положения точки записи в кольце) другому thread-у, который уже будет писать в файл.

 

46 минут назад, zombi сказал:

Не совсем понял вопрос, но потоков никаких не организовывал.

Пишу на Delphy.

Простой таймер вызывается раз в 1 мс.

В обработчике просто вычитываю все что накопилось в буфере и складываю в массив.

С потоком 2 Мб/с так работать нельзя. Ничего не получится.

В винде нет таймеров, вызывающихся один раз в 1мс. И винда это не система реального времени. Работать с устройствами реального времени под ней надо учиться, а сделать абы как - не получится.

Но принять такой поток (и даже больший) через COM-порт - вполне реально.

Share this post


Link to post
Share on other sites
1 hour ago, jcxz said:

Да и почему Вы думаете, что за один цикл шины может быть только одна bulk-транзакция?

А почему Вы решили, что я так думаю, интересно?

Вопрос только в том, когда хост попытается выполнить очередную IN-транзакцию после NAK'а. Никто не гарантирует, что это случится в том же фрейме (да и в следующем

тоже не гарантирует, но то такое).

Share this post


Link to post
Share on other sites
2 hours ago, jcxz said:

С потоком 2 Мб/с так работать нельзя. Ничего не получится. И винда это не система реального времени

А разве я сомневался?

Или может спрашивал кого почему байты теряются?

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

 

 

Share this post


Link to post
Share on other sites
3 hours ago, _pv said:

а "mode COM7 baud=2000000 data=8 parity=n to=off" и "type COM7 > data.txt" в виндах уже поломали и всё ещё работает?

 

нет, не поломали. Работает, но тоже байты теряет (

Share this post


Link to post
Share on other sites

Написал небольшое приложение для COM-порта. Очередное из, так сказать. Хотел все-таки тоже поковыряться на высоких скоростях UART-а.

Скорость 2 мегабита/с (2000000 бит/с). Железка отправляет 100 мегабайт непрерывным потоком. ПК через переходник FT232RL без проблем принимает ровно 100 мегабайт (104857600 байт). Расчетное время передачи данных ~9 минут. Оно так и вышло в действительности. Пришлось немного переписать пару чисел в драйвере FTDI, чтобы полноценную скорость 2 мегабит/с проверить. FTDI обещают в этом преобразователе скорость до 3 мегабит/с. Надо будет проверить...

Пока что приложуха выглядит как-то так:

image.png.17b016847019e0f375c7cd793eb9fbb6.png

Edited by Arlleex

Share this post


Link to post
Share on other sites
3 minutes ago, Arlleex said:

Железка отправляет 100 мегабайт непрерывным потоком. ПК через переходник FT232RL без проблем принимает ровно 100 мегабайт (104857600 байт).

Любопытно. А если попробовать передавать кусками по 2048 байт со случайной паузой между фрагментами?

Share this post


Link to post
Share on other sites
Just now, aaarrr said:

Любопытно. А если попробовать передавать кусками по 2048 байт со случайной паузой между фрагментами?

Случайное время сделал на скорую руку (думаю, для данной ситуации - годится):

// рабочий буфер данных
char StringUart[2048];

// таблица "случайных" задержек =)
unsigned int DelayTable[16] = {1, 3, 15, 7, 50, 2, 3, 0, 1, 48, 54, 1, 55, 37, 100, 6};

// функция отправки пачки из Size байт
void UsartSendData(char *Buffer, unsigned int Size)
{
  for(unsigned int i = 0; i < Size; ++i)
  {
    while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET){}
    USART_SendData(USART2, Buffer[i]);
  }
	
  return;
}

// задача тестирования - одна в системе ОСРВ
void MonitorTask(void *Parameters)
{
  // заполнение массива адекватными числами
  for(unsigned int i = 0; i < 2048; ++i)
    StringUart[i] = '1';
	
  // ждем после включения питания 10с
  vTaskDelay(10000);
	
  // 100МБ - поехали
  for(int i = 0; i < 51200; ++i)
  {
    taskENTER_CRITICAL();
    UsartSendData(StringUart, 2048);
    taskEXIT_CRITICAL();
		
    // "случайная" задержка
    vTaskDelay(DelayTable[i&0xF]);
  }
  
  while(1)
  {
    vTaskDelay(1000);
  }
}

Задача теста имеет максимальный приоритет (да и она одна в системе). Отправку пачки из 2048 байт защитил критической секцией для обеспечения одинаковых временнЫх межбайтовых разрывов. Может, имело смысл сделать на DMA, но не думаю - сейчас процессор только тем и занимается, что молотит в UART.

 

Результаты: буфер в 100 мегабайт принялся с потерями. Потери составили 31 байт. Интересно, откуда такое явление.

Share this post


Link to post
Share on other sites
3 minutes ago, Arlleex said:

Результаты: буфер в 100 мегабайт принялся с потерями. Потери составили 31 байт. Интересно, откуда такое явление.

Возможный механизм описал выше. Возникновение потерь при добавлении пауз гипотезу подтверждает.

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

Share this post


Link to post
Share on other sites
Just now, aaarrr said:

Возможный механизм описал выше. Возникновение потерь при добавлении пауз гипотезу подтверждает.

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

Лучше завтра отпишусь о результатах, под вечер понял, что немного запорол тест (не в коде выше).

P.S. Запорол - это не поставил высокий приоритет потоку чтения в процессе клиентского приложения на персоналке. Сейчас выставил - уже 50 мегабайт скачалось - нет ни одного пропущенного байта. Но мне пора домой - завтра поставлю скачку на мегабайт 500 и отпишусь о результатах.

Edited by Arlleex

Share this post


Link to post
Share on other sites
32 minutes ago, Arlleex said:

P.S. Запорол - это не поставил высокий приоритет потоку чтения

"Что только не придумают люди Геббельса, чтобы не поехать копать мою картошку !!!" :)

 

http://anekdotov.me/kino-i-tv/93262-kak-to-ves-rejstag-uexal-na-sbor-kartoshki.html

 

"Большая наука" на ровном месте. И все это вместо того, чтобы подпаять два провода и реализовать RTS/CTS ...

Share this post


Link to post
Share on other sites
Just now, kovigor said:

"Большая наука" на ровном месте. И все это вместо того, чтобы подпаять два провода и реализовать RTS/CTS ...

А если ног свободных нет больше на плате? =) И это уже спортивный интерес - временные параметры еще пока позволяют организовать передачу без контроля потока, ИМХО...

Share this post


Link to post
Share on other sites
10 minutes ago, Arlleex said:

А если ног свободных нет больше на плате? =) И это уже спортивный интерес - временные параметры еще пока позволяют организовать передачу без контроля потока, ИМХО...

Тогда Xon/Xoff. Но для передачи произвольных данных он, насколько я помню, не годится. Только для текстов.

Управлению потоком не один десяток лет. И не я его придумал. И придумали его не от нечего делать. Так что ...

P.S. Не хотите - не делайте. Но лучше один раз сделать нормально, чем постоянно ловить и исправлять проблемы. И еще, не забудьте проинформировать вашего заказчика/потребителя/работодателя, что работа сделана "на авось" и надежность обмена данными не гарантируется ...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now