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

 
 
 
Reply to this topicStart new topic
> FTDI 232, Уменьшить время отклика
Danis
сообщение Jul 5 2011, 09:08
Сообщение #1


Twilight Zone
***

Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990



Приветствую коллеги по цеху!

Такая задача у меня: Имеется некий софт для ПК, который принимает данные от «железки», последняя отправляет данные в ПК через FTDI(FT232). Между ПК и железкой есть свой простой протокол обмена. Вопрос в том, что после посылки сообщения железка ждет подтверждения от ПК, которое приходит с задержкой 5-25 ms, что сильно напрягает и делает пропускную способность канала 25% при скорости 115200 (сообщения короткие 24-50 байт). Предполагаю что это связанно с задержками самого драйвера FTDI. Для работы с FTDI со стороны ПК пользовался D2XX Programmer's Guide.

клик

Данные с FTDI вычитываю каждую 1 ms с использованием мультимедийного таймера (разрешение - 1ms точно). Передаю также с разрешением 1ms, но увы, идут задержки. Прошу совета как выйти из положения. Писать свой драйвер под Windows могу но нет желания. Отказаться от FTDI нет возможности.

Прилагаю листинг инициализации FTDI.

Заголовок для класса FTDI

Код
#ifndef __FTDI_H
#define __FTDI_H

  #include "ftd2xx.h"
  #include <Mmsystem.h>

  class My_FTDI
  {
  public:  My_FTDI(void);
  public: ~My_FTDI(void);

  int Multimedia_Timer_Init(void);
  static int Get_number_D2XX_devices(void);
  static int Write_FTDI(BYTE *sours, WORD len);
  static int Read_FTDI(BYTE *RxBuffer);
  static int Find_FTDI_Connect(void);
  void static __stdcall TimeProc(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);

  FT_HANDLE ftHandle;
  DWORD NumDevs;
  DWORD Monitor_Timer;
  int Timer_Resolution;  

  };

  extern My_FTDI My_FTDI_Dev;

#endif


Вырезка из метода поиска/инициализации/подключения к FTDI

Код
Метод  инициализации FTDI
int My_FTDI::Find_FTDI_Connect(void)    // Пробую подлючиться к железке
{
    FT_STATUS ftStatus;
    BYTE sours[2]      = {0x01, 0x03};    // START, STOP
    static BYTE Rx_Buff[1024] = {0};
    WORD BytesWritten =  0;


   cout << " Connect to FTDI " << endl;

  for ( int i = 0; i < (int)My_FTDI_Dev.NumDevs; i++ )
  {

   ftStatus = FT_Open (i, &My_FTDI_Dev.ftHandle );
   if (ftStatus != FT_OK)
   FT_Close(My_FTDI_Dev.ftHandle); // Закрыть в случае ошибки;

   ftStatus = FT_SetTimeouts( My_FTDI_Dev.ftHandle, 1, 1 );  //  Timeout
   if (ftStatus != FT_OK)
   {
    cout << " Fail timeout " << i << endl;
    FT_Close(My_FTDI_Dev.ftHandle); // Закрыть в случае ошибки
   }


   ftStatus = FT_SetBaudRate(My_FTDI_Dev.ftHandle, 115200); // Set baud rate to 115200
   if (ftStatus != FT_OK)
   FT_Close(My_FTDI_Dev.ftHandle); // Закрыть в случае ошибки

   // Set 8 data bits, 1 stop bit and no parity
   ftStatus = FT_SetDataCharacteristics(My_FTDI_Dev.ftHandle, FT_BITS_8, FT_STOP_BITS_1, FT_PARITY_NONE);
   if (ftStatus != FT_OK)
   FT_Close(My_FTDI_Dev.ftHandle); // Закрыть в случае ошибки

  } //  for ( int i = 0; i < (int)My_FTDI_Dev.NumDevs; i++ )


   return 0;

}



Спасибо!


--------------------
Magic Friend
Go to the top of the page
 
+Quote Post
V_G
сообщение Jul 5 2011, 11:12
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Возможно, не по делу.
Но под винду писать приложения, для которых критичны задержки 5-25 мс, не есть правильно.
Оттестируйте свой софт на другой машине, где памяти побольше, а софта - поменьше (лучше всего на чистой винде). Сохранятся ли там задержки?
Ваш софт не проверял, сам пользуюсь для FT232 виртуальными компортами. Даже на 460800 особых проблем не видел. Мой софт, правда, особо комовским трафиком машину не грузит.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jul 5 2011, 11:47
Сообщение #3


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Danis @ Jul 5 2011, 12:08) *
сообщения короткие 24-50 байт
Т.е. меньше размера пакета обмена для FTDI. И не отправлются из микросхемы в комп до тех пор, пока не отработает Latency Timer, по умолчанию 16 мс (собственно, для длинных пакетов та же беда с остатком в конце пакета). Надо или крутить в свойствах данного ком-порта, или (на мой взгляд, лучше) устанавливать через FT_SetLatencyTimer().
Ещё лучше в пакетах иметь флаговый байт конца пакета (типа того, как в SLIP сделно) и назначить его для ком-порта как EventChar (вероятно, через FT_SetChars(), я этим делом пользовался и с обычным ком-портом через поле в DCB). Это для любого ком-порта полезно, чтобы в Win через WaitObject не за каждым символом из ком-порта дёргаться, а только по приходу всего пакета.
А в случае FTDI это ещё и приводит к немедленной отправке неполного буфера по приходу данного символа. Даже минимальный LatencyTimer не отсчитывается, его настройка не влияет вообще.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 5 2011, 12:53
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Danis @ Jul 5 2011, 12:08) *
есть свой простой протокол обмена.

В данном случае правильный выход только один - протокол должен стать сложнее и не требовать немедленного подтверждения каждого фрейма. Посмотрите как подобное делается в классических протоколах, например, LAPB. TCP тоже годится для ознакомления с принципами.
QUOTE (Danis @ Jul 5 2011, 12:08) *
Данные с FTDI вычитываю каждую 1 ms с использованием мультимедийного таймера...

Сканирование это моветон sad.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Danis
сообщение Jul 5 2011, 13:12
Сообщение #5


Twilight Zone
***

Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990



Цитата(ReAl @ Jul 5 2011, 15:47) *
(на мой взгляд, лучше) устанавливать через FT_SetLatencyTimer().


Да, помогло. Установил минимальное значение LatencyTimer – 2 ms, повесил на RX и TX осциллограф, замерил, действительно 2-2,5 ms. Работает! Этого мне достаточно.
Большое спасибо cool.gif .



Цитата(zltigo @ Jul 5 2011, 16:53) *
В данном случае правильный выход только один - протокол должен стать сложнее и не требовать немедленного подтверждения каждого фрейма. Посмотрите как подобное делается в классических протоколах, например, LAPB. TCP тоже годится для ознакомления с принципами.


Согласен, дело в том, что это не мой софт, он написан давно и «устаканен», человек который его написал не «железячник», менять кардинально ничего нельзя, вот перед ним встала проблема, я ее помог решить. На счет сканирования, я завел его в отдельный паток Windows в котором идет обработка мультимедийного таймера, загрузка процессора от него не более 0,7% при max трафике, сам проверял, так что для ПК это сойдет. Вот подготовил класс С++ пусть вставляет и живет счастливо. Отозвавшимся спасибо, тему можно закрывать.

Цитата(zltigo @ Jul 5 2011, 16:53) *
Сканирование это моветон sad.gif

Программирование микроконтроллеров меня конечно воспитало но не на столько.


--------------------
Magic Friend
Go to the top of the page
 
+Quote Post

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

 


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


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