PCI. Методы работы с тюнером 
raxp@mail.zp.ua
Статья предназначена прежде всего использованию возможностей шины PCI в промышленной автоматизации и энтузиастам телеуправления, желающих расширить сферу применения своих домашних ПК.
В автоматизации...
Узким местом при цифровой обработке сигналов как правило является передача в реальном времени уже преобразованного потока данных (АЦП) непосредственно в “ПК” по интерфейсам COM/LPT/USB. Первые отличаются простотой и дешевизной, а последний имеет высокие скорости до 480 Мбит/с при поддержке USB2.0, что не всегда имеется в наличии. Альтернативой является PCI интерфейс. При относительной дешевизне, простейшее PCI ядро без конфигурационного пространства возможно реализовать на обычной ПЛИС или использовать готовое решение к примеру: на базе микросхемы MACH215, производимой фирмой AMD. При этом, обеспечивается скорость передачи данных от 60 мегабайт в секунду и выше.
В быту...
С расширением номенклатуры выпускаемых моделей тюнеров у пользователей все чаще появляется желание расширить возможности стандартных программ управления, которые зачастую имеют убогий набор функций. Особо продвинутые “лезут внутрь” и перехватывают команды пульта... НО этот метод сугубо индивидуальный и к сожалению не универсальный...
Второй подход заключается в использовании интерфейса производителя, т.е. работа с тюнером осуществляется через готовую dll, к примеру avertv32/avertv2k/averapi/becholder32
...
function LinkProc(ProcName: string):Pointer;
begin
try
result:= GetProcAddress(FAverLib,PChar(ProcName));
Win32Check(Assigned(Result))
except end
end;
FAverLib:= LoadLibrary(pchar(plib + namelib + '.dll'));
Win32Check(FAverLib<>0);
if (namelib <> 'avertv32') then //98-
HWInit:= LinkProc('AVER_HWInit');
HWFree:= LinkProc('AVER_Free');
IsRemoteDataReady:= LinkProc('AVER_IsRemoteDataReady');
GetRemoteData:= LinkProc('AVER_GetRemoteData');
SetRemoteFlag:= LinkProc('AVER_SetRemoteFlag');
GetRemoteFlag:= LinkProc('AVER_GetRemoteFlag');
//
CoInitialize(nil);
if (namelib <> 'avertv32') then begin //98-
if (namelib = 'averapi')or(namelib = 'aver307')
then HWInit2(nil,PChar(@dummy),0)
else Win32Check(HWInit<>0)
...
определенного chipset-а... и опять мы ограниченны, а ведь поддержка не всегда такая “добрая” и выкладывает свои api.
Все устройства на шине PCI имеют уникальные (в пределах условной стандартизации производителей*) идентификаторы и номера: VendorID и DeviceID
* на самом деле, чтобы BIOS распознал находящееся в PCI- устройство, необходимо, чтобы при инициализации оно вернуло VendorID/DeviceID не равным 0xFFFF [6]
что вы можете сами увидеть при каждой загрузке bios... Непосредственный доступ к PCI (в nt- подобных системах) возможен при входе в нулевое кольцо, то бишь без драйвера не обойтись. Как правило разрабатывается WDM – драйвер, через который и идет обмен с областью памяти.
Подобный подход используют по крайней мере 5- из известных мне приложений:
- Dscaler
- bTTool / bTTest
- RC4WA
- SlyControl
Разработка
Все имеющиеся в сети “комплекты разработчика драйверов”, к примеру WinDriver, имеют общий недостаток – demo режим с ограничением по времени, либо с навязчивым сообщением о “денежках” (оно и понятно, кушать всем хочется).
Исследование dll обслуживания wdm- драйвера дало только название точек входа*** [3],
readPort / readPortW / readPortL / writePort / writePortW / writePortL / memoryMap / memoryUnmap / memoryRead
memoryWrite / pciGetHardwareResources / isDriverOpened / memoryMapEx / memoryAlloc / memoryFree
*** входная точка любого драйвера - функция, которая фактически играет ту же самую роль для драйвера, что и main для приложения на C. Эта функция вызывается при загрузке драйвера (неважно, загружается ли он
динамически или при запуске системы). Данная функция регистрирует в специальном массиве адреса всех
остальных функций драйвера, чтобы диспетчер ввода - вывода мог вызывать их по этим адресам). Если это не WDM
драйвер, то в этой функции происходит поиск оборудования, выделение и подтверждение используемых
аппаратных ресурсов, выдача видимых для системы имён всем устройствам и т.д. WDM драйвера эту работу
перекладывают на функцию AddDevice…
но решение было найдено в Dscaler. Всем известно, что эта замечательная программа работает с железом напрямую.
... что показательно, последние из сервисных приложений воспользовались решением от Dscaler-а [см. ссылки], перекомпилировав исходники под новым названием.
Для отладки драйвера нам понадобится утилита DebugView [4]. Полные тексты драйверов приводить тут не вижу необходимости, т.к. зачем тогда [ссылки]?
DLL обслуживания драйвера компилируем в VisualC, а сам драйвер WinAsm- ом + тут понадобятся хэдеры из WinDDK [5].
Т.о.: наша задача облегчается, функции и точки входа нам известны, остается обеспечить лишь динамический их вызов в своем компоненте и универсальность для любых VendorID/DeviceID. Добавляем тайминги и скорость опроса PCI регистра.

|
Цель создания данного компонента – отладка простейшего ядра PCI slave контроллера на ПЛИС Xilinx в среде Win32. |

|
Тестовый монитор <pci.exe> осуществляет ввод-вывод значения регистра устройства по заданному VendorID и DeviceID.
|
Полные исходные текста компонента доступны по согласованию с автором.
Ссылки:
http://www.koders.com/cpp/fidADFA3760B21797F8DD0A30670C7C6D747B334132.aspx
Контактная информация:
raxp@mail.zp.ua
26.03.2007
[Переход к списку статей]
|