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

 
 
 
Reply to this topicStart new topic
> Таймаут ReadFile из USB-устройства на не-INTEL чипсетах
prottoss
сообщение May 13 2011, 15:55
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Привет всем.

Есть устройство выполненное на AT91SAM7S - подробнее на http://prottoss.com/projects/ucGoZilla/ucGoZilla.htm.
Для РС обозначено как СОМ-порт.
Из драйверов только INF-файл, указывающий на штатный для Windows драйвер usbser.sys

Проблема в том что, при работе с внутренним загрузчиком SAM-BA, на некоторых материнских платах, с не-INTEL чипсетами обмен между ПО на РС и устройством может прерываться.
Т.е. первый запрос в устройство через WriteFile проходит (2 байта), далее чтение через ReadFile (2 байта) тоже отлично.
Далее новый запрос. Но функция ReadFile вылетает по таймауту.

Т.е. в микроконтроллере инициализирован штатный внутренний загрузчик и я пытаюсь через самописную утилиту с ним связаться.

Утилита работает с устройством не как с СОМ-портом, а как с USB устройством.
Т.е через "SetupDiEnumDeviceInterfaces" находится устройство с нужным VID/PID затем извлекается хэндл и, далее, уже стандартно, открывается через CreateFile. Далее все как обычно - ReadFile/WriteFile

Ниже функции ввода-вывода

CODE

/*******************************************************************************
Write data to device
*******************************************************************************/
IO_RES WriteData(PVOID Data, ULONG Size)
{
OVERLAPPED sync = {0,};
ULONG xfer, err;
IO_RES res = RES_OK;

/* Create event */
sync.hEvent = CreateEvent(0, FALSE, FALSE, NULL);
if(sync.hEvent == NULL)
return WR_FAIL_CREATE_SYNC;

/* Write data */
if(!WriteFile(g_hWritePipe, Data, Size, &xfer, &sync))
{
/* Check error */
err = GetLastError();
if(ERROR_IO_PENDING == err)
{
/* Pending write operation */
err = WaitForSingleObject(sync.hEvent, CFG_IO_TIMEOUT);
switch(err)
{
case WAIT_OBJECT_0:
if(!GetOverlappedResult(g_hWritePipe, &sync, &xfer, TRUE))
return WR_FAIL_GET_OVERLAPPED_RESULT;
break;
case WAIT_TIMEOUT:
CancelIo(g_hWritePipe); /* Cancelled IO operation */
ResetEvent(sync.hEvent);
res = WRITE_TIMEOUT;
break;
case WAIT_ABANDONED:
default:
res = WR_FAIL_WAIT_FOR_SINGLE_OBJECT;
}
}
else
res = WR_FAIL_WRITE_OPERATION;
}
ResetEvent(sync.hEvent);
CloseHandle(sync.hEvent);
return res;
}

/*******************************************************************************
Read data from device
*******************************************************************************/
IO_RES ReadData(PVOID Data, ULONG Size)
{
OVERLAPPED sync = {0,};
ULONG xfer, err;
IO_RES res = RES_OK;

/* Create event */
sync.hEvent = CreateEvent(0, TRUE, FALSE, NULL);
if(sync.hEvent == NULL)
return RD_FAIL_CREATE_SYNC;

/* Read data */
if(!ReadFile(g_hWritePipe, Data, Size, &xfer, &sync))
{
/* Check error */
err = GetLastError();
if(ERROR_IO_PENDING == err)
{
/* Set pending operation */
err = WaitForSingleObject(sync.hEvent, CFG_IO_TIMEOUT);
switch(err)
{
case WAIT_OBJECT_0: /* Wait read operation complete */
if(!GetOverlappedResult(g_hWritePipe, &sync, &xfer, TRUE))
res = RD_FAIL_GET_OVERLAPPED_RESULT;
break;
case WAIT_TIMEOUT:
CancelIo(g_hWritePipe); /* Cancelled IO operation */
ResetEvent(sync.hEvent);
res = READ_TIMEOUT;
break;
case WAIT_ABANDONED:
default:
res = RD_FAIL_WAIT_FOR_SINGLE_OBJECT;
}
}
else
res = RD_FAIL_WRITE_OPERATION;
}

CloseHandle(sync.hEvent);
return res;
}


--------------------
Go to the top of the page
 
+Quote Post
SysRq
сообщение May 15 2011, 13:02
Сообщение #2


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Проверить, что записано столько сколько и требовалось?
Таймауты как настроены для чтения\записи?

PS: CancelIo() ничего не гарантирует.
PPS: в функции записи утечка хендлов, ибо return WR_FAIL_GET_OVERLAPPED_RESULT.
Go to the top of the page
 
+Quote Post
prottoss
сообщение May 15 2011, 13:15
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(SysRq @ May 15 2011, 20:02) *
Проверить, что записано столько сколько и требовалось?
Таймауты как настроены для чтения\записи?
Таймауты не настраиваются. Они определяются динамически через WaitForSingleObject(sync.hEvent, CFG_IO_TIMEOUT).

CFG_IO_TIMEOUT = 10 секунд.

Цитата(SysRq @ May 15 2011, 20:02) *
PS: CancelIo() ничего не гарантирует.
Она ничего гарантирует, она отменяет операцию ввода-вывода.

Цитата(SysRq @ May 15 2011, 20:02) *
PPS: в функции записи утечка хендлов, ибо return WR_FAIL_GET_OVERLAPPED_RESULT.
Здесь не понял о чем речь.


--------------------
Go to the top of the page
 
+Quote Post
SysRq
сообщение May 15 2011, 13:55
Сообщение #4


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Цитата(prottoss @ May 15 2011, 17:15) *
Таймауты не настраиваются.
Это таймауты ожидания результата от операций записи\чтения. А таймауты на сами операции есть?

Цитата(prottoss @ May 15 2011, 17:15) *
она отменяет операцию ввода-вывода.
В том и дело, что нет гарантии, отменится или нет (где-то в MSDN описано).

Цитата(prottoss @ May 15 2011, 17:15) *
Здесь не понял о чем речь.
CloseHandle() не выполняется, ибо вызов её в конце, а выйдем из середины по ошибке.
Go to the top of the page
 
+Quote Post
prottoss
сообщение May 15 2011, 14:38
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(SysRq @ May 15 2011, 20:55) *
Это таймауты ожидания результата от операций записи\чтения. А таймауты на сами операции есть?
Нет. Эти таймауты я не устанавливаю. Попробую сейчас.

Цитата(SysRq @ May 15 2011, 20:55) *
В том и дело, что нет гарантии, отменится или нет (где-то в MSDN описано).

Пробовал и на INTEL, и на AMD и на nForce - отменяют. Без CancelIO, если функция вылетела по таймауту, при следующем обращении может вылетать аншлаг Windows о недопустимой операции. С CancelIO аншлагов нет.

Цитата(SysRq @ May 15 2011, 20:55) *
CloseHandle() не выполняется, ибо вызов её в конце, а выйдем из середины по ошибке.
Да, вместо
return WR_FAIL_GET_OVERLAPPED_RESULT
нужно
res = WR_FAIL_GET_OVERLAPPED_RESULT

Сейчас проверю.

return WR_FAIL_GET_OVERLAPPED_RESULT - это не принципиально, потому как эта ошибка не возникает. Функция вылетает по таймауту.

Код
case WAIT_TIMEOUT:
                    CancelIo(g_hWritePipe);     /* Cancelled IO operation */
                    ResetEvent(sync.hEvent);
                    res = READ_TIMEOUT;
                    break;


--------------------
Go to the top of the page
 
+Quote Post
SysRq
сообщение May 15 2011, 15:35
Сообщение #6


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Цитата(prottoss @ May 15 2011, 18:38) *
...при следующем обращении может вылетать аншлаг Windows о недопустимой операции. С CancelIO аншлагов нет.
В этом аспекте, да, всё отлично работает (ошибка же, вероятно, возникала вследствие того, что система всё же просигналит событие от предыдущего вызова, но событие было расположено в локальном стеке, и уже не действительно к этому моменту).
А вот с данными сложнее, ибо есть некоторая не контролируемая из верхних уровней (чаще всего в драйвере не реализовано управление) буферизация на низком уровне, оттуда все равно данные будут переданы.
Go to the top of the page
 
+Quote Post
prottoss
сообщение May 16 2011, 00:58
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Поигрался с SetCommTimeouts(...). Толку ноль sad.gif


--------------------
Go to the top of the page
 
+Quote Post
SysRq
сообщение May 16 2011, 21:53
Сообщение #8


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Запись\чтение и их повторения идут из одного и того же потока?
Перейти на работу с автоматически (не вручную) сбрасываемым событием не пробовали?

Покажите чуть больше кода, как используются функции...
Go to the top of the page
 
+Quote Post
prottoss
сообщение May 19 2011, 14:13
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(SysRq @ May 17 2011, 04:53) *
Запись\чтение и их повторения идут из одного и того же потока?
Перейти на работу с автоматически (не вручную) сбрасываемым событием не пробовали?

Покажите чуть больше кода, как используются функции...

Выкладываю исходники. Протокол SAM-BA для работы с внутренним загрузчиком AT91SAM (samba.cpp) + собственно ввод-вывод (inout.cpp). Эта неделя вся загружена, так что до домашнего компьютера еле доползаю.
Прикрепленные файлы
Прикрепленный файл  Sources.rar ( 3.52 килобайт ) Кол-во скачиваний: 25
 


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

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

 


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


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