ふにゃるんv2

もとは、http://d.hatena.ne.jp/Wacky/

ハードウェア制御が出来る PCIDEBUG.DLL を、Pythonから呼べるようにする

ご存知とは思いますが、Windowsは基本的にハードウェア資源に直接アクセス出来ません。
ところが、世の中には便利なものを物を作る方も居られまして、ガジマルの森さんの所で提供されているPCIDEBUG.DLLでは、以下のハードウェア資源にアクセスできます。

組み込み制御を行いたい時に、非常に便利ですよね?


ってな訳で、先の ctypesのネタを使って、PCIDEBUG.DLLをPythonから呼び出せるようにしてみましょう。

準備

ダウンロードページから、以下のファイルをダウンロードします。

展開後、Pythonコードの作成と実行に必要なのは、以下のファイルです。

  • Pcidebug.sys
  • PCIDEBUG.DLL
  • Pcidef.h
  • Pcifunc.h

ヘッダファイルから ctypes コードを生成する

まずは、pcifunc.hから、XMLを生成しましょう。
…の前に、pcifunc.hに以下の行を追加してください。
(実は、この行が必要だと言う事を知らず、何度も挑戦して敗れ去ってしまいました。あはは)

/*
	PCIDEBUG.DLL export 関数
*/

#include    <windef.h>   # <- この行が重要

#ifndef _NTDDK_ 

では早速。

F:\Wacky\Test\python\test>python C:\tool2\Python24\Lib\site-packages\ctypes\wrap
\h2xml.py F:\Wacky\Test\python\test\Pcifunc.h -I "C:\Program Files\Microsoft Vis
ual Studio\VC98\Include" -o pcifunc.xml -q -c

これで、pcifunc.xmlが出来ました。
では、XMLファイルからPythonコードを生成します。

F:\Wacky\Test\python\test>python C:\tool2\Python24\Lib\site-packages\ctypes\wrap
\xml2py.py pcifunc.xml -o pcifunc.py -l pcidebug.dll
# unresolved alias: iscsymf = __iscsymf
# unresolved alias: MB_CUR_MAX = __mb_cur_max
# unresolved alias: toascii = __toascii
# unresolved alias: wcswcs = wcsstr
# unresolved alias: NTSYSAPI = DECLSPEC_IMPORT
# unresolved alias: iscsym = __iscsym

これで完了です。pcifunc.pyが出来ています。
信じられない程の、簡単さです。

動かしてみる

では早速動かしてみましょう。
動かす際、pcifunc.pyと同じフォルダに、pcidebug.dllとpcidebug.sysがある事を確認してください。

F:\Wacky\Test\python\test>ipython

F:\Wacky\Test\python\test>python C:\tool2\Python24\Scripts\ipython
WARNING: Could not import user config!
 ('C:\Documents and Settings\user\_ipython/ipy_user_conf.py' does not exist?
Please run '%upgrade')

Python 2.4.2 (#67, Sep 28 2005, 12:41:11) [MSC v.1310 32 bit (Intel)]
Type "copyright", "credits" or "license" for more information.

IPython 0.7.2 -- An enhanced Interactive Python.
?       -> Introduction to IPython's features.
%magic  -> Information about IPython's 'magic' % functions.
help    -> Python's own help system.
object? -> Details about 'object'. ?object also works, ?? prints more.

In [1]: import pcifunc

In [2]: pcifunc.getdllstatus()
Out[2]: 0
#   ↑PCIDEBUG.DLLが呼び出し可能である事を確認。

In [3]: pcifunc._pciBusNumber()
Out[3]: 3
#   ↑このパソコンでは、PCIバスの最大数は3。

In [4]: hex(pcifunc._pciConfigReadLong(0, 0))
Out[4]: '0x25788086L'
#   ↑バス番号:0,デバイス番号:0,ファンクション番号:0のレジスタ番号:0の、PCIレジスタ値。

In [5]: hex(pcifunc._pciConfigReadLong(1 << 3, 0))
Out[5]: '0x25798086L'
#   ↑バス番号:0,デバイス番号:1,ファンクション番号:0のレジスタ番号:0の、PCIレジスタ値。

In [6]: hex(pcifunc._pciConfigReadLong(2 << 3, 0))
Out[6]: '0xFFFFFFFFL'
#   ↑バス番号:0,デバイス番号:2,ファンクション番号:0のレジスタ番号:0の、PCIレジスタ値。

どうやらアクセスできたっぽいです。


試しに、pdbg10.lzhに付属している。PCIバイスの列挙ツール(pciwatch.exe)で確認してみましょう。
2
PCIDEBUG.DLL posted from フォト蔵

バイス(Device)一覧に出てくる、'0 0 0 : 8086 2578'は、バス番号、デバイス番号、ファンクション番号、レジスタ0のワード値(ベンダID)、レジスタ2のワード値(デバイスID)という意味です。
上の結果と合わせてみると、確かに合ってます。
どうやら、呼び出し出来たようです。

結論

最後に結論。

  • PCIDEBUG.DLLを使うと、Windows上で簡単にハードウェアへの直接制御が出来ます。
  • h2xml.pyとxml2py.pyと組み合わせて使う事で、Pythonから簡単にPCIDEBUG.DLLの機能を呼び出せるようになります。
  • ハードウェアの直接制御は、自己責任の上でバンバンやってください。;-)