Сейчас на форуме: hgdagon (+5 невидимых) |
![]() |
eXeL@B —› Программирование —› Проблема с прерыванием АЦП НВЛ-45 |
Посл.ответ | Сообщение |
|
Создано: 21 августа 2007 16:50 · Личное сообщение · #1 Есть АЦП НВЛ-45, приобретённый через www.signal.ru. Пишу для него WDM драйвер, т.к. родной не выполняет нужные задачи. Имеется: WinXP, VC++2005, DriverStudio 3.2 Возникла проблема. При срабатывании прерывания (чтение данных завершено) запрос на него должен автоматически сниматься при первом чтении из памяти устройства (по документации), а он не снимается - происходит постоянно вызов ISR-процедуры, даже когда в ней провожу конфигурирование платы с запретом прерываний. Что можно предпринять в этом случае? Кто-нибудь имел дело с такой платой? ![]() |
|
Создано: 22 августа 2007 13:50 · Личное сообщение · #2 |
|
Создано: 22 августа 2007 21:53 · Личное сообщение · #3 |
|
Создано: 23 августа 2007 01:17 · Личное сообщение · #4 |
|
Создано: 23 августа 2007 20:22 · Личное сообщение · #5 |
|
Создано: 23 августа 2007 23:53 · Личное сообщение · #6 "native"'ом я назвал тот, который вроде как работает, но не так, как б хотелось. Да, в отладчике, но так как драйвер (sys) работает в нулевом кольце (вроде), то перехват (bpio) в софтайсе скорее всего ничего не даст. К тому же из-за лагов (пока выписываешь что читается-пишется) может быть искаженная картинка. Тут нужен либо логгер использующий отладочные регистры (DRx) - может, есть такие (я для себя писал в 98), либо возможно что драйвер не сам пишет в порты а через переходники NTKERN. Драйвер может сам работать с портами, например: mov dx,PORT_BASE mov al,SOME_VALUE out dx,al Но может работать через заглушки (HAL) в NTKERN, это функи (имя примерно) ~WRITE_PORT_USHORT и т.п. Возможно, есть логгера как раз под это или более общие логгера где можно указать перехват именно этих функций. Также возможен анализ самого кода драйвера в дизассемблере (IDA, etc). ----- The one derivative you manage is the one I abhore (c) Slipknot ![]() |
|
Создано: 24 августа 2007 01:45 · Поправил: Ratinsh · Личное сообщение · #7 |
|
Создано: 24 августа 2007 03:54 · Личное сообщение · #8 Обнуляю 13-й бит 5-го порта при входе в функцию обработки прерывания и считываю произвольный элемент из памяти платы, но прерывание не снимается - эта функция опять вызывается постоянно, комп начинает тормозить, приходится перезагружаться. Специалисты signal.ru после каждого вопроса по плате присылают мне своё руководство и драйвер платы от "Scan Engineering Telecom" с руководством к нему. В руководстве платы написано: После заполнения требуемого количества памяти устройство NVL45 формирует прерывание на линии INTA# и бит готовности, который расположен в нулевом разряде слова, которое читается по адресу порта 6H. Лог. 0 в этом разряде означает, что буфер заполнен полностью. Запрос на прерывание сбрасывается при первом чтении из памяти устройства. Логично предположить, что раз 0 - буфер заполнен, то во время заполнения буфера там единица. Я пытался ловить эту единицу, чтобы потом, дождавшись там нуля, определить момент окончания записи (для избежания работы с прерыванием). Но при постоянном опросе бита во-первых все остальные программы "засыпают", а во-вторых и это не всегда срабатывает - редко, но возникают ситуации, когда единица там так и не появляется. Конечно, можно было бы работать по таймеру, но у меня внешняя синхронизация, да и период синхроимпульсов - 700мкс всего, за которые надо всё успеть - и считать и обработать. В руководстве драйвера от "Scan Engineering Telecom" описана функция: BOOL SETPCI_SetIntrParam( SETPCI_HANDLE hSETPCI,DWORD dwAddr,DWORD dwMask); Задает параметры обработчика прерываний драйвера: адрес (!)регистра статуса прерываний(!) и маску определяющую в каком бите проверяется флаг прерывания. Регистр статуса должен быть расположен в нулевом баре устройства, параметр dwAddr должен содержать смещение внутри нулевого бара в 32х разрядных словах. Параметр dwMask должен содержать единицу в том бите в котором выставляется флаг прерывания, остальные биты должны быть равны нулю. Что за регистр, как с ним работать, где он находится - в руководстве платы ни слова и разработчики молчат. Может его как-то вычислить можно? ![]() |
|
Создано: 24 августа 2007 11:00 · Личное сообщение · #9 |
|
Создано: 25 августа 2007 14:31 · Личное сообщение · #10 |
|
Создано: 25 августа 2007 15:24 · Личное сообщение · #11 |
|
Создано: 25 августа 2007 20:39 · Личное сообщение · #12 |
|
Создано: 25 августа 2007 20:41 · Личное сообщение · #13 Хех, посмотрел немнога. Сам драйвер, походу дела что-то с портами делает, и работает именно через WRITE_PORT_USHORT и т.п. т.е. через заглушки. Т.е. лог снять вполне можно, например дописать в сам драйвер логгирующие переходники. Основная работа с портами ведется в процедуре DriverUnload (DriverObject->DriverUnload), при этом возможно чтение какой-то группы данных. Тем не менее хочу заметить что вроде как обработка прерывания делается совсем не в драйвере (точнее, оттуда вызывается пользовательский (!!) обработчик). Косвенным доказательством служит то, что большинство аргументов для записи в порт передаются по ссылке или довольно сложно вычисляются: и именно это демонстрирует пример "intr_test" из архива, в котором в main.cpp: // пользовательская функция обработки прерываний void MyIntHandler(SETPCI_HANDLE hSETPCI, LPVOID param) { ... Просьба все же уточнить что именно ты пишешь: свой драйвер? (sys) - где твой код для него? (чтобы было с чем сравнивать). ----- The one derivative you manage is the one I abhore (c) Slipknot ![]() |
|
Создано: 25 августа 2007 21:04 · Личное сообщение · #14 |
|
Создано: 26 августа 2007 02:29 · Поправил: Chingachguk · Личное сообщение · #15 ++ Посмотрел я этот sys более-менее внимательно. Итого там практически ничего нет ![]() .text:000105D8 ; Also handles: .text:000105D8 ; IRP_MJ_READ .text:000105D8 ; IRP_MJ_INTERNAL_DEVICE_CONTROL .text:000105D8 ; Attributes: bp-based frame .text:000105D8 .text:000105D8 ; int __stdcall sub105D8_CREATE_NAMED_PIPE(DEVICE_OBJECT *DeviceObject,PIRP Irp) .text:000105D8 sub105D8_CREATE_NAMED_PIPE proc near ; DATA XREF: start+4o Вот эта процедурина предоставляет что-то вроде интерфейса для обычных (прикладных) прог: чтение порта (READ_PORT_UCHAR/USHORT/ULONG) и то же самое для записи. А какие порты читать или писать - это уж пользователю надо знать ![]() Некоторый интерес представляет, уже упоминал, обработчег события UnloadDriver - он может читать какие-то блоки данных с устройства, какие он порты использует - пока не определил. Т.е. перехват и логгирование портов вроде бы смысла не имеет - просто там ничего нет ![]() Есть в этом архиве реально рабочий код? Может, это в intr_test? т.е. все в этой самой демо? (DLL) +++ Небольшие вычисления адреса порта, конечно, есть: loc_10AFA: mov ecx, [esi+eax*4+50h] cmp byte ptr [eax+esi+80h], 0 lea ecx, [ecx+edx*2] jz short loc_10B10 movzx eax, word ptr [ecx] jmp short loc_10B40 loc_10B10: push ecx ; Port call ds:READ_PORT_USHORT movzx eax, ax jmp short loc_10B40 loc_10B1C: Или как в вот этом интересном примере с глюком: mov ecx, [esi+eax*4+50h] add ecx, edx movzx edx, byte ptr [ecx] mov [edi], edx cmp byte ptr [eax+esi+80h], 0 jz short loc_10B36 movzx eax, byte ptr [ecx] jmp short loc_10B40 loc_10B36: push ecx ; Port call ds:READ_PORT_UCHAR movzx eax, al ----- The one derivative you manage is the one I abhore (c) Slipknot ![]() |
![]() |
eXeL@B —› Программирование —› Проблема с прерыванием АЦП НВЛ-45 |