Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: RS232 RxBufferSize (CE_RXOVER flag) WinCE  (Прочитано 15990 раз)
0 Пользователей и 1 Гость смотрят эту тему.
aba
Гость
« : 05-02-2004 10:06 » 

Столкнулся с проблемой с портом RS-232 (COM1) - на PocketPC (ARM) функция GetCommProperties(..) возвращает максимальный размер приемного буфера (dwMaxRxQueue) равным 1! Текущий размер буфера (dwCurrentRxQueue) составляет 0 байт, причем установить другой размер этого буфера функцией SetupComm(..) не могу - ошибки нет, но размер остается нулевым.
Соответственно (я подозреваю), прием данных не возможен. Даже функция ClearCommError(..) возвращает установленный флаг ошибки CE_RXOVER (1) в любом случае - когда данные физически идут (кабель подсоединен, cbInQue = 1) и не идут (кабель не подсоединен, cbInQue = 0).
Под Desktop PocketPC Emulation (x86) с подсоединенным устройством на COM1 все работает на ура. Размер приемного буфера по умолчанию 1000 байт, могу установить требуемый (ограничений на максимальный размер нет), в общем все как под "нормальной" виндой (Win2000).

Машина - PocketPC iPAQ 3760.
Кабель на COM - МакЦентр'овский (распайку проверил - все в соответствии с информацией на кабель на COM с сайта hp.com).
Не стандартное использование линий RTS (всегда 0) и DTR (всегда 1).
Чтение данных осуществляется в отдельном потоке с использованием WaitCommEvent(..).

Что посоветуете?
Следует ли использовать WaitCommEvent для ожидания байт?
Может пример кода на C++?


"Попутные" вопросы:
1. В чем разница между флагами ошибки CE_OVERRUN и CE_RXOVER (функция ClearCommError)?
2. Как работает ActiveSync (экспериментировали - использует все линии), спокойно принимает и отправляет данные на той же машине?
3. Не глючный ли драйвер на этой машине - хотя в свойствах (GetCommProperties) указано, что возможно установить любую скорость передачи данных, однако реально устанавливает только стандартные!? И опять - функция SetCommState не возвращает ошибки, а нестандартная скорость не устанавливается (остается прежде установленная или 9600).
4. Как узнать какой номер порта использовать - COM1, COM2 или какой-то другой. Пока на этой машине могут "одинаково" открыться COM1 и COM2, и одинаково плохо работать. Жаль
5. Есть подозрение, что это может быть связано и с USB. Как работать с USB (особенно интересно, когда на машинке PocketPC есть USB-Host), вкратце?


Приведу свой код. Вероятно, где там закралась ошибка.
Инициализация порта. Далее выполняемая функция потока чтения с COM-порта (точнее их две, запрятаны в класс).

Код:
DWORD CISerial::PortInitialize(LPCTSTR lpPort, DWORD dwBaudRate, HWND hWndOnMsg)
{

COMMPROP commProp;
CString str;

COMSTAT Stat;
DWORD   dwErrors;
// Attempt to open the serial port (COM1)

PortClose();
m_bPortOpened = FALSE;
m_hSerialPort = CreateFile (_T("COM1:"), // Pointer to the name of the port
  GENERIC_READ | GENERIC_WRITE,  // Access (read-write) mode
  0,            // Share mode
  NULL,         // Pointer to the security attribute
  OPEN_EXISTING,// How to open the serial port
  0,            // Port attributes
  NULL);        // Handle to port with attribute
// to copy
if (m_hSerialPort == INVALID_HANDLE_VALUE){
#ifdef DEBUG_MSGS_ON
MessageBox(_T("Unable to open serial port"), _T("Error"), MB_OK);
#endif
return GetLastError();
}

// Set the size of the input and output buffer
if (!SetupComm(m_hSerialPort, 1024, 0)) {
#ifdef DEBUG_MSGS_ON
MessageBox (_T("Unable to set the buffer-size parameters"), _T("Error"), MB_OK);
#endif
return GetLastError()?GetLastError():-1;
}

    // Terminates all outstanding read and write operations and clear the buffers
    VERIFY(PurgeComm(m_hSerialPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR));

// Initialize the DCBlength member.
DCB PortDCB;
FillMemory(&PortDCB, sizeof(PortDCB), 0);
PortDCB.DCBlength = sizeof (DCB);

// Get the default port setting information.
GetCommState (m_hSerialPort, &PortDCB);

// Change the DCB structure settings.
PortDCB.BaudRate = dwBaudRate; //16384;              // Current baud
PortDCB.fBinary = TRUE;               // Binary mode; no EOF check
PortDCB.fParity = TRUE;               // Enable parity checking
PortDCB.fOutxCtsFlow = FALSE;         // No CTS output flow control
PortDCB.fOutxDsrFlow = FALSE;         // No DSR output flow control
PortDCB.fDtrControl = DTR_CONTROL_ENABLE; //DTR_CONTROL_DISABLE;
  // DTR flow control type
PortDCB.fDsrSensitivity = FALSE;      // DSR sensitivity
PortDCB.fTXContinueOnXoff = FALSE;     // XOFF continues Tx
PortDCB.fOutX = FALSE;                // No XON/XOFF out flow control
PortDCB.fInX = FALSE;                 // No XON/XOFF in flow control
PortDCB.fErrorChar = FALSE;           // Disable error replacement
PortDCB.fNull = FALSE;                // Disable null stripping
PortDCB.fRtsControl = RTS_CONTROL_DISABLE;
  // RTS flow control
PortDCB.fAbortOnError = FALSE;        // Do not abort reads/writes on
  // error
PortDCB.ByteSize = 8;                 // Number of bits/byte, 4-8
PortDCB.Parity = NOPARITY;            // 0-4=no,odd,even,mark,space
PortDCB.StopBits = ONESTOPBIT;        // 0,1,2 = 1, 1.5, 2

// Configure the port according to the specifications of the DCB
// structure.
if (!SetCommState (m_hSerialPort, &PortDCB))
{
  // Could not create the read thread.
#ifdef DEBUG_MSGS_ON
MessageBox(_T("Unable to configure the serial port"), _T("Error"), MB_OK);
#endif
return GetLastError();
}

// Retrieve the time-out parameters for all read and write operations
// on the port.
COMMTIMEOUTS CommTimeouts;
GetCommTimeouts (m_hSerialPort, &CommTimeouts);

// Change the COMMTIMEOUTS structure settings.
CommTimeouts.ReadIntervalTimeout = MAXDWORD; 
CommTimeouts.ReadTotalTimeoutMultiplier = 0; 
CommTimeouts.ReadTotalTimeoutConstant = 0;    //5
CommTimeouts.WriteTotalTimeoutMultiplier = 0; 
CommTimeouts.WriteTotalTimeoutConstant = 10;

// Set the time-out parameters for all read and write operations
// on the port.
if (!SetCommTimeouts (m_hSerialPort, &CommTimeouts))
{
  // Could not create the read thread.
#ifdef DEBUG_MSGS_ON
MessageBox (_T("Unable to set the time-out parameters"), _T("Error"), MB_OK);
#endif
return GetLastError();
}

if (!ClearCommBreak(m_hSerialPort)) {
#ifdef DEBUG_MSGS_ON
MessageBox (_T("Unable to restore character transmission (unBREAK)"), _T("Error"), MB_OK);
#endif
return GetLastError();
}

/* if (!SetCommMask (m_hSerialPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RING)) {
#ifdef DEBUG_MSGS_ON
MessageBox (_T("Unable to specify a set of events to be monitored for a communications device"), _T("Error"), MB_OK);
#endif
return GetLastError();
}
*/
if (!EscapeCommFunction(m_hSerialPort, SETDTR)){
#ifdef DEBUG_MSGS_ON
MessageBox (_T("Unable to set DTR line"), _T("Error"), MB_OK);
#endif
return GetLastError();
}
if (!EscapeCommFunction(m_hSerialPort, CLRRTS)){
#ifdef DEBUG_MSGS_ON
MessageBox (_T("Unable to clear RTS line"), _T("Error"), MB_OK);
#endif
return GetLastError();
}

// ::Sleep(10);

#ifdef DEBUG_MSGS_ON
if (GetCommProperties(m_hSerialPort, &commProp)) {
str.Format(_T("Comm properties: %X(dwMaxTxQueue), %X(dwMaxRxQueue), %X(dwMaxBaud), %X(dwProvSubType), %X(dwProvCapabilities), %X(dwSettableParams), %X(dwSettableBaud), %X(wSettableData), %X(wSettableStopParity), %X(dwCurrentTxQueue), %X(dwCurrentRxQueue)"), commProp.dwMaxTxQueue, commProp.dwMaxRxQueue, commProp.dwMaxBaud, commProp.dwProvSubType, commProp.dwProvCapabilities, commProp.dwSettableParams, commProp.dwSettableBaud, commProp.wSettableData, commProp.wSettableStopParity, commProp.dwCurrentTxQueue, commProp.dwCurrentRxQueue);
MessageBox (str, _T("SerialPort"), MB_OK);
}
#endif

dwErrors = 0;
if (ClearCommError (m_hSerialPort, &dwErrors, &Stat)) {
#ifdef DEBUG_MSGS_ON
str.Format(_T("Possible errors: CE_BREAK(%d), CE_FRAME(%d), CE_IOE(%d), CE_MODE(%d), CE_OVERRUN(%d), CE_RXOVER(%d), CE_RXPARITY(%d), CE_TXFULL(%d)\nCOMM Status information: fCtsHold(%d), fDsrHold(%d), fRlsdHold(%d), fXoffHold(%d), fXoffSent(%d), fEof(%d), fTxim(%d), cbInQue(%d), cbOutQue(%d)"), dwErrors&CE_BREAK, dwErrors&CE_FRAME, dwErrors&CE_IOE, dwErrors&CE_MODE, dwErrors&CE_OVERRUN, dwErrors&CE_RXOVER, dwErrors&CE_RXPARITY, dwErrors&CE_TXFULL, Stat.fCtsHold, Stat.fDsrHold, Stat.fRlsdHold, Stat.fXoffHold, Stat.fXoffSent, Stat.fEof, Stat.fTxim, Stat.cbInQue, Stat.cbOutQue);
MessageBox (str, _T("SerialPort"), MB_OK);
#endif
}


//GetCommState (m_hSerialPort, &PortDCB);
//str.Format(_T("Actual BaudRate is %d"), PortDCB.BaudRate);
//MessageBox (str, _T("OpeningPort"), MB_OK);
m_BaudRate = dwBaudRate;
m_lpPortName = lpPort;


m_bPortOpened = TRUE;


//Starting working thread for reading & processing inData
THREADPARMS* ptp = new THREADPARMS;
ptp->pClass = this;
ptp->hWndOnMsg = hWndOnMsg;

//pReadThread = AfxBeginThread(PortReadThreadProcT, ptp, THREAD_PRIORITY_HIGHEST); //LPVOID(this));


pReadThread = ::CreateThread(NULL, 0, PortReadThreadProcT, ptp, 0, NULL); //LPVOID(this));
if (pReadThread == NULL) {
#ifdef DEBUG_MSGS_ON
MessageBox (_T("Unable to run ReadThread"), _T("Error"), MB_OK);
#endif
return GetLastError();
}

VERIFY(SetThreadPriority(pReadThread, THREAD_PRIORITY_HIGHEST));


return 0;
}

DWORD WINAPI CISerial::PortReadThreadProcT(LPVOID pParam)
{
// Route the method to the actual object
THREADPARMS* ptp = (THREADPARMS*) pParam;
CISerial* pThis = reinterpret_cast<CISerial*>(ptp->pClass);
    HWND hWnd = ptp->hWndOnMsg;
    delete ptp;

return pThis->PortReadThreadProc(hWnd);
}

UINT CISerial::PortReadThreadProc(HWND hWnd)
{
DWORD inDataCount = sizeof(m_InDataPacketCur)/sizeof(m_InDataPacketCur[0]);
DWORD dwBytesTransferred, dwTotalBytesTransferred = 0;
BOOL bErr;
DWORD dwCommModemStatus;
int dCheckErrCount = NUM_CHECKSUM_TRY;
COMSTAT Stat;
DWORD   dwErrors;
BYTE readBuf[RxBufferSize];
// int pReadBuf = 0; //pointer to current position in readBuf

CString str;

::PostMessage (hWnd, WM_USER_SERIAL_PORT_READING_THREAD_WAITING, (WPARAM) 0, 0);
VERIFY(PurgeComm(m_hSerialPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR));
VERIFY(SetCommMask (m_hSerialPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RING | EV_BREAK | EV_ERR));

dwErrors = 0;
if (ClearCommError (m_hSerialPort, &dwErrors, &Stat)) {
#ifdef DEBUG_MSGS_ON
str.Format(_T("Possible errors: CE_BREAK(%d), CE_FRAME(%d), CE_IOE(%d), CE_MODE(%d), CE_OVERRUN(%d), CE_RXOVER(%d), CE_RXPARITY(%d), CE_TXFULL(%d)\nCOMM Status information: fCtsHold(%d), fDsrHold(%d), fRlsdHold(%d), fXoffHold(%d), fXoffSent(%d), fEof(%d), fTxim(%d), cbInQue(%d), cbOutQue(%d)"), dwErrors&CE_BREAK, dwErrors&CE_FRAME, dwErrors&CE_IOE, dwErrors&CE_MODE, dwErrors&CE_OVERRUN, dwErrors&CE_RXOVER, dwErrors&CE_RXPARITY, dwErrors&CE_TXFULL, Stat.fCtsHold, Stat.fDsrHold, Stat.fRlsdHold, Stat.fXoffHold, Stat.fXoffSent, Stat.fEof, Stat.fTxim, Stat.cbInQue, Stat.cbOutQue);
MessageBox (str, _T("SerialPort"), MB_OK);
#endif
}

while (m_hSerialPort != INVALID_HANDLE_VALUE) |//
// Wait for an event to occur for the port.
WaitCommEvent (m_hSerialPort, &dwCommModemStatus, NULL);
// Re-specify the set of events to be monitored for the port.
SetCommMask (m_hSerialPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RING | EV_BREAK | EV_ERR);

//check the event for errors
if (dwCommModemStatus & EV_ERR)
{
dwErrors = 0;
if (ClearCommError(m_hSerialPort, &dwErrors, &Stat)) {
#ifdef DEBUG_MSGS_ON
str.Format(_T("Possible errors: CE_BREAK(%d), CE_FRAME(%d), CE_IOE(%d), CE_MODE(%d), CE_OVERRUN(%d), CE_RXOVER(%d), CE_RXPARITY(%d), CE_TXFULL(%d)\nCOMM Status information: fCtsHold(%d), fDsrHold(%d), fRlsdHold(%d), fXoffHold(%d), fXoffSent(%d), fEof(%d), fTxim(%d), cbInQue(%d), cbOutQue(%d)"), dwErrors&CE_BREAK, dwErrors&CE_FRAME, dwErrors&CE_IOE, dwErrors&CE_MODE, dwErrors&CE_OVERRUN, dwErrors&CE_RXOVER, dwErrors&CE_RXPARITY, dwErrors&CE_TXFULL, Stat.fCtsHold, Stat.fDsrHold, Stat.fRlsdHold, Stat.fXoffHold, Stat.fXoffSent, Stat.fEof, Stat.fTxim, Stat.cbInQue, Stat.cbOutQue);
MessageBox (str, _T("SerialPort"), MB_OK);
#endif
}
} //if (dwCommModemStatus & EV_ERR)

//check for RXCHAR
if (dwCommModemStatus & EV_RXCHAR)
{

// Loop for waiting for the data.
do
{
bErr = ReadFile(m_hSerialPort, &readBuf[0], (inDataCount>dwTotalBytesTransferred)?(inDataCount-dwTotalBytesTransferred):0, &dwBytesTransferred, NULL);
if (!bErr) {
return GetLastError();
}

if (dwBytesTransferred > 0){
m_mutexSerPortRxBufferBusy.Lock();
//copying inData from readBuf to m_InDataPacketCur
memcpy(&m_InDataPacketCur[dwTotalBytesTransferred], &readBuf[0], dwBytesTransferred);
m_mutexSerPortRxBufferBusy.Unlock();

dwTotalBytesTransferred += dwBytesTransferred;

if (dwTotalBytesTransferred < inDataCount)
::PostMessage (hWnd, WM_USER_SERIAL_PORT_READING_THREAD_WAITING, (WPARAM) 0, 0);
//return 2 ;
else {
// if (dwTotalBytesTransferred >= inDataCount) {
if (!CISerial::ProcessInData()) {
//Error in checksum => try to receive extra data
::PostMessage (hWnd, WM_USER_SERIAL_PORT_READING_THREAD_SUMCHECK_ERR, (WPARAM) (NUM_CHECKSUM_TRY-dCheckErrCount), 0);
if (dCheckErrCount--) {
m_mutexSerPortRxBufferBusy.Lock();
memmove(&m_InDataPacketCur[0], &m_InDataPacketCur[1], inDataCount-1);
m_mutexSerPortRxBufferBusy.Unlock();
dwTotalBytesTransferred--;
}
else {
dwTotalBytesTransferred = 0;
::PostMessage (hWnd, WM_USER_SERIAL_PORT_READING_THREAD_CANCELED, (WPARAM) 0, 0);
return 1;
}
}
else {
dwTotalBytesTransferred = 0;
dCheckErrCount = NUM_CHECKSUM_TRY;
::PostMessage (hWnd, WM_USER_SERIAL_PORT_READING_THREAD_FINISHED, (WPARAM) 0, 0);
}
} //if (dwTotalBytesTransferred >= inDataCount)
} //if (dwBytesTransferred > 0)

} while ((dwBytesTransferred > 0));//&&(dwTotalBytesTransferred < inDataCount));
}


if (WaitForSingleObject(m_eventSerPortReadKill, 0) == WAIT_OBJECT_0){
break;
}


} //while (m_hSerialPort != INVALID_HANDLE_VALUE)

return 0;
}



Надеюсь на скорый ответ,
Андрей.
« Последнее редактирование: 23-11-2007 21:39 от Алексей1153++ » Записан
Lex
Специалист

ru
Offline Offline

WWW
« Ответ #1 : 05-02-2004 11:10 » 

aba, попробуй определять пустоту буфера приема по тому, что вернуля тебе функция ReadFile(). В свое всермя у нас с Громом была большая дискуссия на эту тему, в ходе которой выяснилось, что это наиболее корректный метод.
Записан

Megabyte be with you!
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #2 : 05-02-2004 11:36 » 

Работа с COM портом на WinCE это один большой трабл. Тут действительно скорее эмпирический метод подойдет. Причина этого одна- очень плохо написанные драйвера, порой они недоделаны. Также одной из причин может быть неправильные параметры для порта в реестре- те что дает Майкрософт по умолчанию, обычно не верны, а не все сборщики систем проверяют это.
Записан
aba
Гость
« Ответ #3 : 09-02-2004 06:38 » 

Так я определяю пустоту буфера по тому, что возвращает функция ReadFile - из параметра "сколько байт записано в буфер/прочитано":
if (dwBytesTransferred > 0){...}

Я вот теперь думаю, может отказаться от ожидания события приема первого байта с помощью WaitCommEvent и установить "бесконечные" таймауты и пусть себе ReadFile висит и ждет?
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #4 : 09-02-2004 09:12 » 

aba, я никогда не делал SetupComm() - МХО лишнее.
Порт работает при этом вполне нормально.
На том же iPaq у меня не было проблем с приемом данных.

Алгортм как тебе сказал LEX построен на возврате значений.

Но WaitCommEvent работает не так как ты говоришь.

Да тайм аут надо ставить бесконечный иначе будешь вылетать, но тут будет тебе интаресная трабла.

Так как завис WaitCommEvent блокирует поток в котором сидит прием порта и может повиснуть при требовании на выход и него и окончании работы.

Вот тебе совет.

1. Алгоритм приема данных - двойной цикл.

while(!EXIT)
{

     WaitCommEvent()
     while (ReadFile())
     {
         // Обработка данных
      }

}

Т.е. суть в том, что ожидание идет только на Wait, а читаем пока есть данные, как только прочли 0 неблокируемым ридом - выходим и опять в ожидание.

Выбить из состояния ожидания можно, если при необходимости вызвать функцию SetCommState - это работает только в WinCE.

Она выбъет WaitCommEvent из состояния ожидания...
Записан

А птичку нашу прошу не обижать!!!
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #5 : 09-02-2004 11:44 » 

Цитата

while(!EXIT)
{

WaitCommEvent()
while (ReadFile())
{
// Обработка данных
}

}


именно так, потому что биты для WaitCommEvent ставятся даже, если уже поставлены- то есть можно не дочитать данные, надо при помощи ReadFile опустошать  буфер до конца.
Записан
aba
Гость
« Ответ #6 : 11-02-2004 09:50 » 

Гром, вызов функции SetupComm я изначально тоже не делал, сейчас использую для _принудительной_ установки размера входного буфера.

Пробовал на iPAQ 37xx? Просто я уже подумываю :/, что HP не просто так не продает для этой серии COM-кабели... А ActiveSync может работает совсем с другими функциями. Никто не знает, как работает ActiveSync?

А как работает WaitCommEvent? Я думал, что следующим образом: физически приходит байт, этот байт записывается во внутренний (аппаратный?) буфер, срабатывает WaitCommEvent на EV_RXCHAR (точнее драйвер посылает это сообщение), далее я читаю из этого внутреннего буфера (а не напрямую)!

Разве закрытие порта (а также, PurgeComm) не выбрасывает из WaitCommEvent?

Теперь с алгоритмом. Я тоже делаю двойной (внутренний цикл):

    while (m_hSerialPort != INVALID_HANDLE_VALUE) {
        // Wait for an event to occur for the port.
        WaitCommEvent (m_hSerialPort, &dwCommModemStatus, NULL);

        //check for RXCHAR
        if (dwCommModemStatus & EV_RXCHAR)
        {

            // Loop for waiting for the data.
            do
            {
                bErr = ReadFile(m_hSerialPort, &readBuf[0], inDataCount, &dwBytesTransferred, NULL);

                if (dwBytesTransferred > 0){
                    // обработка данных
                }
            } while ((dwBytesTransferred > 0));
        }
    } //while (m_hSerialPort != INVALID_HANDLE_VALUE)

Фактически, тот же алгоритм что и у тебя. Отличие - вложенный цикл прекращает работу по другому условию. У меня - когда принято 0 байт. У тебя - когда ReadFile вернет ошибку (сразу вопрос - на какую ошибку ты рассчитываешь?, или у тебя пока порт открыт работает только вложенный цикл?). В то же время, дальше ты говоришь "читаем пока есть данные, как только прочли 0 неблокируемым ридом - выходим и опять в ожидание". Неблокируемым ридом - это как? Когда                   CommTimeouts.ReadIntervalTimeout = MAXDWORD;  
   CommTimeouts.ReadTotalTimeoutMultiplier = 0;  
   CommTimeouts.ReadTotalTimeoutConstant = 0;?
 Чего-то я не допонял. Жаль                      
 
 Спасибо за вниммание и помощь,
 Андрей.
Записан
aba
Гость
« Ответ #7 : 12-02-2004 06:34 » 

Цитата: SlavaI
Цитата

while(!EXIT)
{

WaitCommEvent()
while (ReadFile())
{
// Обработка данных
}

}


именно так, потому что биты для WaitCommEvent ставятся даже, если уже поставлены- то есть можно не дочитать данные, надо при помощи ReadFile опустошать  буфер до конца.


Так я опустошаю буфер до конца (см. пред. сообщения) перед тем как ждать прихода следующего байта WaitCommEvent'ом.
Записан
aba
Гость
« Ответ #8 : 01-03-2004 06:58 » new

Благодарю всех за помощь, проблема та была не в софте, а в RTS/DTR сигналах.
Однако, есть другой вопрос по теме.
Оказалось, что время переключения между тредами на этой машинке (StrongARM 1100, PPC2002) достаточно большое - ~50 мс! А у меня данные чаще идут. :/ А некоторые пакеты надо еще обработать и отобразить. в общем, не чудно это. Жаль
Посему вопрос - на новых машинах (xScale, WM2003) это пошустрее?
Да, и еще один вопрос Улыбаюсь - никто не работал с RS-232C в формфакторе CompactFlash? Доступ через виртуальный COM-порт?

С уважением,
Андрей.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines