Re[10]: чтение из FTDI-устройства
От: cr lf  
Дата: 12.07.07 13:53
Оценка:
G>>>Ведь для функции чтения есть TimeOut.
CL>>Кстати, я не совсем понимаю что это такое ;(
G>Это время, в течение которого функция будет ждать прихода данных в порт.
CL>>И чем Time Out отличается от Latency.
G>Я тоже не знаю что такое Latency(лучше не пользуй). Нужно читать справку по API для FTDI.

In the FT8U232AM and FT8U245AM devices, the receive buffer timeout that is used to flush
remaining data from the receive buffer was fixed at 16 ms. In all other FTDI devices, this timeout
is programmable and can be set at 1 ms intervals between 2ms and 255 ms. This allows the
device to be better optimized for protocols requiring faster response times from short data packets.

Насколько я понял, latency — это интервал, в течение которого сохраняются непрочитанные данные в буфере устройства, прежде чем они потеряются.
Поправь, если я не прав.

G>>>Прочитав все, могу спросить: Что будет, если машины совсем не поедут?

CL>>Да ничего не будет — загорится зеленый и устройство будет ждать получения сигнала от фотоэлемента стоящего на старте.
G>Да. И их проги выйти поможет только диспетчер задач.
Почему ?
Во-первых, можно предусмотреть аварийный выход из цикла чтения даже в том варианте, который я постил, хотя это и нехорошо.
А во-вторых, это ведь только самый первый вариант, лишь бы заработало.
В окончательном варианте это, конечно, будет выполняться в отдельном потоке.

CL>>>>WaitForSingleObject в данном случае вешает программу навечно:

CL>>>>
CL>>>>hEvent := CreateEvent(0,false,false,'');
CL>>>>FT_SetEventNotification(h,FT_EVENT_RXCHAR,@hEvent);
CL>>>>WaitForSingleObject(hEvent,Infinite);
CL>>>>FT_GetStatus(h,@RxBytes,@TxBytes,@EventDWord);
CL>>>>if RxBytes > 0 then begin
CL>>>>  FT_Read(h,@Buf,1,@Count);
CL>>>>  WriteLn('buf = ',IntToBin(buf));
CL>>>>end;
CL>>>>

G>>>Навечно она останавливается из-за вызова WaitForSingleObject с параметром Infinite.
CL>>Если я указываю определенный интервал, WaitForSingleObject заканчивается с результатом WAIT_TIMEOUT, хотя сигнал был и, стало быть,
CL>> hEvent должен быть Signalled
G>Значит так и есть. Поставь интервал 1000мс или 10000мс. Или проверь второй параметр, может не того ждешь. Нет доков по FTDI... протерял
G> где-то... не нахожу..
Все проверил, все сделал как надо, сигнал есть, а выход по TimeOut ;(
Документацию могу прислать, если интересно.

Здесь отрывок:

FT_STATUS FT_SetEventNotification (FT_HANDLE ftHandle, DWORD dwEventMask, PVOID pvArg)
Sets conditions for event notification.

Parameters
ftHandle — Handle of the device.
dwEventMask — Conditions that cause the event to be set.
pvArg — Interpreted as the handle of an event.

Return Value
FT_OK if successful, otherwise the return value is an FT error code.

Remarks
An application can use this function to setup conditions which allow a thread to block until one of
the conditions is met. Typically, an application will create an event, call this function, then block on
the event. When the conditions are met, the event is set, and the application thread unblocked.
dwEventMask is a bit-map that describes the events the application is interested in. pvArg is
interpreted as the handle of an event which has been created by the application. If one of the
event conditions is met, the event is set.
If FT_EVENT_RXCHAR is set in dwEventMask, the event will be set when a character has been
received by the device. If FT_EVENT_MODEM_STATUS is set in dwEventMask, the event will be
set when a change in the modem signals has been detected by the device.

This example shows how to wait for a character to be received or a change in modem status.
First, create the event and call FT_SetEventNotification.

FT_HANDLE ftHandle; // handle of an open device
FT_STATUS ftStatus;
HANDLE hEvent;
DWORD EventMask;
hEvent = CreateEvent(NULL,false,false,"");
EventMask = FT_EVENT_RXCHAR | FT_EVENT_MODEM_STATUS;
ftStatus = FT_SetEventNotification(ftHandle,EventMask,hEvent);



Sometime later, block the application thread by waiting on the event, then when the event has
occurred, determine the condition that caused the event, and process it accordingly.

WaitForSingleObject(hEvent,INFINITE);

DWORD EventDWord;
DWORD RxBytes;
DWORD TxBytes;

FT_GetStatus(ftHandle,&RxBytes,&TxBytes,&EventDWord);
if (EventDWord & FT_EVENT_MODEM_STATUS) {
  // modem status event detected, so get current modem status
  FT_GetModemStatus(ftHandle,&Status);
  if (Status & 0x00000010) {
    // CTS is high
  }
  else {
    // CTS is low
  }
  if (Status & 0x00000020) {
    // DSR is high
  }
  else {
    // DSR is low
  }
}
if (RxBytes > 0) {
// call FT_Read() to get received data from device
}

... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.