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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: SetFilePointer для устройства PCIe  (Прочитано 12583 раз)
0 Пользователей и 4 Гостей смотрят эту тему.
chaika_sv
Участник

ru
Offline Offline
Пол: Мужской

« : 01-06-2010 09:08 » 

Добрый день.

У меня есть kmdf-драйвер для PCIe-устройства. Сейчас стоит задача разработать cpp-приложение верхнего уровня для работы с этим драйвером.
Драйвер принимает от cpp-приложения IRP-запросы и обрабатывает их в режиме PIO (взаимодействие через окно BAR0). В частности, запрос на запись обрабатывается так:
Код:
  ...
  WdfMemoryCopyToBuffer(
                  regMemory,
                  0,
                  (INT *)devExt->RegsBase,    //   Указатель на начало окна BAR0
                  Length);
               
  WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, Length);
  ...


Запрос на запись посылается из cpp-приложения командой:
Код:
  WriteFile(
                 hDevice,
                 WriteBuffer,
                 WriteBufferSize,
                 &bytes,
                 NULL);


После выполнения этой команды содержимое буфера WriteBuffer действительно помещается в начало окна BAR0, а bytes становится равным значению WriteBufferSize.
ВОПРОС. Как сделать произвольный доступ к окну BAR0?

Попробовал перед WriteFile выполнить функцию SetFilePointer:
Код:
  SetFilePointer(
                 hDevice,
                 offset,     //  Младший адрес смещения относительно начала файла (пробовал разные значения)
                 NULL,       //  Окно BAR0 всего 2КБ, так что длинный указатель тут не нужен (делаем старший адрес - NULL)
                 FILE_BEGIN);
но содержимое буфера всё равно пишется в начало окна BAR0.

Более того, если я два раза подряд выполняю функцию WriteFile, то второй вызов функции приводит к тому, что перезаписываются данные, записанные первым вызовом. Т.е. указатель после WriteFile почему-то не перемещается  Быть такого не может
Записан
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 01-06-2010 09:56 » 

А как вы обрабатываете IRP_MJ_SET_INFORMATION ? Ведь именно этот IRP, если не ошибаюсь, приходит при вызове SetFilePointer.

Попробую даже сам же и ответить на свой вопрос  Улыбаюсь Вы его не обрабатываете вообще никак. А надо.
Записан
chaika_sv
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 01-06-2010 10:18 » 

Вы его не обрабатываете вообще никак.
Действительно не обрабатываю.

А надо.
А надо ли? Опыта написания драйверов у меня много нет, но я всегда думал, что в WDF на этот случай должен быть дефолтный обработчик (мне ж там ничего особенного реализовывать не надо).

Тем более, что для команд чтения SetFilePointer работает!
Записан
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 01-06-2010 11:37 » 

Нда. Про Wdf я не вкурсе, поэтому врать не буду.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 01-06-2010 20:31 » 

попробуйте в драйвере сразу при записи смещение задать - будет работать?
железка поддерживает? выравнивание?
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
chaika_sv
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 02-06-2010 05:05 » 

попробуйте в драйвере сразу при записи смещение задать - будет работать?
Пробовал. Работает.

железка поддерживает? выравнивание?
Да.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 02-06-2010 06:29 » 

а где в этом коде  :
Код:
  WdfMemoryCopyToBuffer(
                  regMemory,
                  0,
                  (INT *)devExt->RegsBase,    //   Указатель на начало окна BAR0
                  Length);
вообще задаваемое пользователем смещение? у вас destination = devExt->RegsBase всегда один и тот же?
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
chaika_sv
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 02-06-2010 07:40 » 

Ochkarik, да, теперь я понял, что мне нужно как-то из IRP-запроса получить смещение. Что-то вроде такого:
Код:
 WdfMemoryCopyToBuffer(
                  regMemory,
                  0,
                  (INT *)devExt->RegsBase + offset,    //   Указатель на начало окна BAR0 + смещение
                  Length);

На RSDN подсказывают, что мне нужно это:
WdfRequestGetParameters — WDF_REQUEST_PARAMETERS::Write::DeviceOffset

Буду пробовать. Что получится - отпишусь.
Записан
chaika_sv
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 02-06-2010 12:12 » 

Проблема решена. Сделал так:

Код:
	
    INT offset;
    WDF_REQUEST_PARAMETERS  params;

    ...

    WDF_REQUEST_PARAMETERS_INIT(&params);

    WdfRequestGetParameters(
                            Request,
                            &params
                            );

    switch (params.Type) {
        case WdfRequestTypeWrite:
            offset = params.Parameters.Write.DeviceOffset;
            break;
        default:
            return;
    }

WdfMemoryCopyToBuffer(
regMemory,
0,
(INT *)devExt->RegsBase + offset,
Length);

Всё верно Ochkarik сказал: про смещение я сначала совсем забыл Скромно так...
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 02-06-2010 15:40 » new

 Ага
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
sys_dev
Гость
« Ответ #10 : 11-06-2010 09:16 » 

не совсем по теме, но не понимаю таких строк:
Код:
    switch (params.Type) {
        case WdfRequestTypeWrite:
            offset = params.Parameters.Write.DeviceOffset;
            break;
        default:
            return;
    }
Не думаю, что надо надеяться на то что компиллер догадается вместо таблички развернуть в обыкновенные проверки cmp reg,num. По крайней мере GCC для ARM один раз оператор из двух switch у меня изготовил табличку! Ага

Думаю код вида:
Код:
    if (params.Type == WdfRequestTypeWrite)
            offset = params.Parameters.Write.DeviceOffset;

будет куда лучше, конечно, мои слова не касаются ситуации когда в будущем предполагается задавать идентификаторы типа больше 3-4
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 11-06-2010 15:38 » 

оно конечно да... но...
такое оформление все таки немного читабельность кода повышает(ИМХО). сразу понятно что параметр может принимать не одно и не два значения. а что до компилятора... если не ошибаюсь майкрософтовский еще лет пять-десять назад вполне адекватно оценивал что ему делать) по крайней мере на x86)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines