今回は、moduleを使わずに、ユーザープログラムからパラレルポートへ出力させます.
ソースコードは正味たったの9行です.アホかってくらい簡単.
-----
その前に長い経緯を書かねばなるまいて...
こちらの記事に書きましたとおり、わたしのLinuxマシンにはCH382という謎のchipの載った中華基板が刺さっています.CH382がパラレルポートのchipなのですが、これのdetasheetがネットに無くて、レジスタ仕様が判らんのです.
もしもそれが判ったなら、ioperm(),outb()を使ったユーザープログラムでパラレルポート制御なんか簡単にできてしまうはずです.
ちくしょうな事にch382が仕様不明なのでmodule programmingしたのがひとつ前の記事だったのです.
moduleで動かせたので、今一度ch382の仕様を調べてみようとしたけれどムダでした.でも、いろんなことをして次第に手掛かりはつかめました.
【dmesg】
dmesgに次の文字が見えます.
parport0: PC-style at 0xe100, irq 16 [PCSPP(,...)]
parport0のIOアドレスは0xe100であるらしい.【/proc】
cat /proc/ioports | grep parport
e100-e102 : parport0
ここにもe100が登場する.しかもたったの3バイトと表示される.
【lspci】
lspciの表示の抜粋です.ここにもe100が見られます.
01:00.0 Serial controller: Device 1c00:3050 (rev 10) (prog-if 05 [16850])
Interrupt: pin A routed to IRQ 16
Region 0: I/O ports at e000 [size=256]
Region 1: Memory at f0000000 (32-bit, prefetchable) [size=32K]
Region 2: I/O ports at e100 [size=4]
これらより、e100から3バイトがパラレルポートIOであるらしい.
【wiki】
wikiパラレルポートを見ると、IBM PCのIO仕様は、SPPモードで3バイトだと書かれている.SPPモードとは、セントロニクスとしても知られる最も素朴なモードです.
レジスタbitとコネクタの相関関係は、この図がわかりやすい.
D0~D7のIN/OUTを指定するレジスタは無いのだろうかと勘繰りたくなるが、SPPモードでは出力オンリーなので、directionレジスタは存在しない.(SPP,ECP,EPPの選択レジスタは何処に在るのかという問題は依然として不明)
以上の情報から、わたしのLinuxマシンでは、e100番地を書き換えてやれば、パラレルポートの先端につけたLEDをON/OFFできると推測されました.
------
やってみたソースコードはたったのこれだけ.IOを直接触っているので劇薬です.またマシンによってはe100番地じゃないケースもあり得るので注意してください.しくじってもわたしはしらんよー.
#include <sys/io.h>
#include <linux/unistd.h>
#define PARADRS 0xe100
int main(int argc, char *argv[]){
if(argc!=2) return -1;
if(ioperm(PARADRS, 8, 1)!=0) return -1;
outb( argv[1][0], PARADRS );
return 0;
}
ioperm()はe100番地の8bitをアクセスする許可を得ています.
outb()はe100番地をargvで上書きしてます.
ビルド方法
gcc -I/lib/modules/4.16.7-rt1-kona-rt/build/include leddirect.c
linux versionの部分は各位の環境によりけりで書き換えて下さい.
使い方
a.out 1
これで、パラレルポートのLEDが'1'のascii code=$31=00110001で発光します.
でも、これはroot権限者じゃないと動かないと思いますので注意、注意.
温故知新
ハード直叩きのソフトは気持ちいいですね。
返信削除モジュールの記事は読んでいてモヤモヤしました~。あースッキリ。
しかもさ、IBM-PCのパラレルポートの剥き出し感といったら相当なもんですよね.
削除ドアを開けたらいきなり外部(笑)
おぞー
むき出し最高です。
返信削除ラピュタじゃないですけどハード(地面)から切り離されては生きていけない的な感情が癒されます~。
ドアを開けたらいきなり宇宙空間w
削除