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

    

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

1 hour ago, jcxz said:

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

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

Пишу на Delphy.

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

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

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


Ссылка на сообщение
Поделиться на другие сайты
1 час назад, aaarrr сказал:

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

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

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

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

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

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

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


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

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

 

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


Ссылка на сообщение
Поделиться на другие сайты
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-порт - вполне реально.

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


Ссылка на сообщение
Поделиться на другие сайты
1 hour ago, jcxz said:

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

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

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

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

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


Ссылка на сообщение
Поделиться на другие сайты
2 hours ago, jcxz said:

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

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

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

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

 

 

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


Ссылка на сообщение
Поделиться на другие сайты
3 hours ago, _pv said:

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

 

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

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


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

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

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

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

image.png.17b016847019e0f375c7cd793eb9fbb6.png

Изменено пользователем Arlleex

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


Ссылка на сообщение
Поделиться на другие сайты
3 minutes ago, Arlleex said:

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

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

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


Ссылка на сообщение
Поделиться на другие сайты
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 байт. Интересно, откуда такое явление.

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


Ссылка на сообщение
Поделиться на другие сайты
3 minutes ago, Arlleex said:

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

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

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

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


Ссылка на сообщение
Поделиться на другие сайты
Just now, aaarrr said:

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

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

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

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

Изменено пользователем Arlleex

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


Ссылка на сообщение
Поделиться на другие сайты
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 ...

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


Ссылка на сообщение
Поделиться на другие сайты
Just now, kovigor said:

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

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

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


Ссылка на сообщение
Поделиться на другие сайты
10 minutes ago, Arlleex said:

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

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

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

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

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


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

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти