さえきさんの ホームページ  -  Armadillo のページ -


その7 - PIOボードの増設 と デバイスドライバ整備 -


さて 新たに高機能なI/Oボードの採用で より本格的な組み込みLinuxの応用装置を と 進展させます

PC/104規格対応拡張ボードのなかに PLA搭載のすごいものもあって入手し 検討をすすめています
それには ドライバソフトの開発が伴いますし また PLAを加工して.. と 次なる目標も固まりつつあります


A. HT3070 プログラマブルI/Oモジュール

出荷時はシンプルなDIO ボードとして機能しますが、CPLD の書き込み内容を変更してアプリケーションに適した
処理を組み込むことができます。CPU バスインターフェースに必要な最低限の信号以外、全てのI/Oピンは40 極
ボックスピンヘッダ2つで取り出すことができます。また64 極のコネクタにもほとんど全ての信号が接続されて
いますので、同寸のプロトタイプ用ボード(HT9030-U00) をスタックしI/O 入出力に付加回路を接続することが
できます。 −と カタログで紹介しているように 組み込み応用では大変に興味をそそるモジュールです




ここでは まず 出荷時にPLAに設定されている 60を超えるポートを持つ デジタルI/Oボードとしての機能を
Armadilloとの組み合わせで実現すべく ドライバソフトを検討する ことになった (各自 勉強しなさい!!
という大変に扱いづらい商品の購入条件でしたので 躊躇はしましたが 夢を買う気持ちで手に入れました)

8:07 2006/03/10 やっと ht3070(CPLD出荷時設定のDIOのもの)でドライバが動作を始めた 
 
ht2020.cを参考にしながら手を加えていった  まずは init部分 ht3070の起動時の様子を掴むのに
手間取った 起動時はすべてのポートが入力モードで だが その入力データ読み出しは 不定の様だ
外部的にはプルアップもプルダウンもしていない結果 レジスタ内は00hにリセットされていると言うが
ポートリードは実際のポートの状態をreadすることになっているので そのようなことになるようだ

また 実際のポートデータのread、writeには これもかなり手こずりました  複数枚のボードの装着を考えて
作成されたht2020ドライバをベースにしたので その動作の詳細を把握するまでいろいろ探りを入れる試しの
あちこちにprintkを加えたドライバをコンパイルしてはチェックの繰り返しで解析した  結論としては:
例えば ボードのI/Oアドレス設定を0x110にして armadilloと結合したあと insmod /... /ht3070.o io=0x110
というように組み込む  そのあと mknod /dev/ht3070_PA c 223 0 などと スペシャルファイルを用意する際
最後の マイナ番号で 注意が必要だ − ドライバで 0x100,0x110,…というように 複数枚対応にしているので
0x110にセットしたボードへのアクセスは +16した値を指定することだ  ファイル名の方は後で使い易いように
このマイナ番号を入れておくのもいいかもしれない(ht2020の例ではそうなっていたですね ht2020_100とか ..
(初めのうちはこの仕掛けが判らず ht2020とht3070を両方接続しているため重ならないように 3070の方を0x110で
装着していて この様子を把握するまでは 苦労しました  判ってみれば どうと言うことは無いんですが..)

これらに対処するまでは insmodすると そんなデバイスはありません I/Oポートエラーといって 組み込まれません
そして いろいろ 着けたり外したりを繰り返しているときに バスに金属部が触れたのでしょうか armadilloが起動
せず も一度インストールし直すなど かなり苦労しました  デバイスを壊してしまったかと ヒヤヒヤものでした
これ以降 armadillo potatoではコンパイルまでとし 動作チェックはオンボードフラッシュ起動のlinuxで行い
何をやっても後遺症が残らないよう心掛けた  その代わり ドライバの.cソースの編集 コンパイルのあとhalt
し 切り替えてオンボードフラッシュ起動 コンソール入力で 一時的に /dev/hda2のマウント ファイルコピー
insmodなどのコマンド入力 動作確認の一連の操作入力 と 根気の要る単純作業を伴う考察・仮説の検討でした
こんな経緯はありましたが これでドライバなるものの ちょっとしたコツなど掴めたかな と ホッとしてます


B. HT3070 デバイスドライバの作成

さて ht3070では 入出力定義制御のレジスタはffhになっていて 各ポートを入力モードにしている状態が 
初期状態。つまり 起動時はすべてのポートが入力モードで だが その入力データ読み出しでは 外部的には
プルアップもプルダウンもしていない結果 実際のポートの状態をreadすることになっているので 不定である
一方 入出力定義制御のレジスタ(I/Oアドレス、Base+8から+15)は確かに ffh に落ち着いている  そこで

Base+0〜+7は確認すること無しに しっかりとffhにセットされているこの部分だけをチェックし  そのあと
Base+0〜+7、+8〜+15のすべてに対し00hを書き込んで (つまり 各ポートのレジスタにall LOW を記入して
定義制御を出力に切り替えています 結果 全ポートがLOW出力とし) その内の一部を改めてリードし ちゃんと
00hにセットされていることを確認し ht3070ボードが 指定のI/Oアドレス に配備されていると看做しました
その後 領域確保しデバイスの登録を完了させます  このinit部によって insmodでカーネルに込みこまれます

動作確認用には ポートコネクタ部に装着できる330Ω抵抗+オレンジLEDの32組配列の表示出力器を用意した
ということで まずは 全ポート 出力モードで動作するデバイスドライバにするようにしました  そして
最後の マイナ番号で 注意が必要だ − ということに留意しながら スペシャルファイルを用意しました

例えば echo -en "\\252">/dev/ht3070_PA というように そのようにしたスペシャルファイルに書き込んだときに
デバイスドライバのread、write部分で マイナ番号を分析し 指定のデバイスの 指定のポートに書き込んでくれ
\252 (8進数): 10 101 010 つまり PAポートの8個のLEDを 一つ置きに点灯する動作が 確認できました
\125 (8進数): 01 010 101 で その反転の点灯状態、 \0 (8進数): 00 000 000 で全消灯状態 です 

  ここに 完成したHT3070デバイスドライバのCソースを示します:

以上のように この度のドライバは all OUTという形でまとめましたが 実際の応用において
上記の手順を繰り返すことで 如何様にもアレンジできますので まずは Happyです  どうも

何れ PLAの編集もやってみるつもり  割り込みの機能もドライバに持たせるのも ..ですね

−−−−

以下 記録として 作業手順やメモを記しておきます:
mount /dev/hda2 /mnt ここにはpotatoで作業した結果の 以下の開発用のファイルや資料などがある:
[guest@armadillo (ttyp0) ~]$ ls -l /mnt/
drwxr-xr-x 2 root root 1024 Mar 5 20:01 _CF_ash_save/
drwxr-xr-x 2 root root 1024 Mar 5 20:00 _CF_save/
drwxr-xr-x 2 root root 1024 Mar 5 20:01 boot/
drwxrwxrwx 2 root root 1024 Feb 26 09:05 dev_ht2020/
drwxrwxrwx 2 root root 1024 Mar 8 23:09 dev_ht3070/
drwxr-xr-x 33 root root 2048 Mar 5 16:21 etc_save/
drwxr-xr-x 5 root root 1024 Mar 5 16:39 home_save/
drwxrwxrwx 11 root root 1024 Feb 20 11:55 initrd_image_220/
drwxr-xr-x 3 root root 1024 Feb 26 08:35 kernel_source/
drwx------ 2 root root 12288 Feb 18 18:58 lost+found/
drwxrwxrwx 4 root root 1024 Feb 24 23:09 www/
[guest@armadillo (ttyp0) ~]$
.cの編集 ftp転送  dev_ht3070/下へ
[guest@armadillo (ttyp0) ~]$ ls -l /mnt/dev_ht3070/
-rw-r--rwx 1 1001 www-data 489785 Mar 3 09:40 CTLG3070.PDF*
-rw-r--rwx 1 1001 www-data 5507 Mar 8 23:09 ht3070.c*  <- ここへ
-rw-r--rwx 1 1001 www-data 79 Mar 2 08:59 ht3070.h*
-rw-r--r-- 1 root root 4260 Mar 8 23:09 ht3070.o
-rw-r--rwx 1 1001 www-data 212355 Mar 3 09:39 ht3070man.pdf*
-rw-r--rwx 1 1001 www-data 1344 Mar 2 08:37 ht3070ボード用デバイスドライバモジ ュール作成.txt*
-rw-r--rwx 1 1001 www-data 503 Mar 3 09:48 makedev_3070.sh*
-rw-r--rwx 1 1001 www-data 467 Mar 4 12:00 makefile*
-rw-r--rwx 1 1001 www-data 6372 Mar 2 08:28 moji_ht2020_test5.c*
[guest@armadillo (ttyp0) ~]$
cd/mnt/ht3070/して ここで make    ここにあるmakefileでコンパイル実行され ht3070.oが出来る
makefileの内容
#INCLUDEDIR = /ext/linux-2.4.21-rmk1-armadillo-2/include
INCLUDEDIR = ../kernel_source/linux-2.4.21-rmk1-armadillo-2/include   <-これも hda2下のを使っています
CC = gcc                                <- 実質 セルフコンパイルです
#CC = arm-linux-gcc
CFLAGS = -D__KERNEL__ -I$(INCLUDEDIR) \
-Wall -Wstrict-prototypes -Wno-trigraphs \
-O2 -fno-strict-aliasing -fno-common -pipe \
-mapcs-32 -march=armv4 -mtune=arm7tdmi -mshort-load-bytes \
-DMODULE
OBJS = ht3070.o
all: $(OBJS)
ht3070: ht3070.c ht3070.h
$(CC) $< -o $@
clean:
rm -f *.o *~ core *.bak
[guest@armadillo (ttyp0) ~]$

ここで halt  umountすべてやって壊さないようにして  パワーオフ  そして JP1をオフ
オンボードフラッシュで起動   root rootでログイン  すぐに mount /dev/hda2 /mntし
出来ている.oなどを使う   
insmod /mnt/dev_3070/ht3070.o io=0x100や /mnt/dev_3070/makedev_3070.sh実行 など
makedev_3070.sh の内容
[guest@armadillo (ttyp0) ~]$ [guest@armadillo (ttyp0) ~]$ cat /mnt/dev_ht3070/makedev_3070.sh
mknod /dev/ht3070_PA c 223 0
mknod /dev/ht3070_PB c 223 1
mknod /dev/ht3070_PC c 223 2
mknod /dev/ht3070_PD c 223 3
mknod /dev/ht3070_PE c 223 4
mknod /dev/ht3070_PF c 223 5
mknod /dev/ht3070_PG c 223 6
mknod /dev/ht3070_PH c 223 7
mknod /dev/ht3070_PAC c 223 8
mknod /dev/ht3070_PBC c 223 9
mknod /dev/ht3070_PCC c 223 10
mknod /dev/ht3070_PDC c 223 11
mknod /dev/ht3070_PEC c 223 12
mknod /dev/ht3070_PFC c 223 13
mknod /dev/ht3070_PGC c 223 14
mknod /dev/ht3070_PHC c 223 15
chmod 666 /dev/ht3070_*
[guest@armadillo (ttyp0) ~]$
デバイスの組み込みの様子
[guest@armadillo (ttyp0) ~]$ [guest@armadillo (ttyp0) ~]$ cat /proc/devices
Character devices:
1 mem
2 pty
3 ttyp
5 console
10 misc
90 mtd
162 raw
204 ttyAM
205 cuaam
210 cs89712port
211 ssi-max149
222 ht2020     <- ここにいますね
223 ht3070     <- これも組み込んでいます
Block devices:
1 ramdisk
3 ide0
7 loop
31 mtdblock
[guest@armadillo (ttyp0) ~]$
[guest@armadillo (ttyp0) ~]$ lsmod          <- lsmodで見ると
Module Size Used by Tainted: P
ht3070 2208 0
ht2020 1928 0
[guest@armadillo (ttyp0) ~]$
/dev/下の ht2020やht3070関係のスペシャルファイルは:
[guest@armadillo (ttyp0) ~]$ [guest@armadillo (ttyp0) ~]$ ls -l /dev/ht*
crw-rw-rwx 1 root root 222, 0 Mar 21 2004 /dev/ht2020_100  <-0x100に設定し insmod ..0x100にした時
crw-rw-rwx 1 root root 222, 1 Mar 21 2004 /dev/ht2020_101  <-これらをcallしていた
crw-rw-rwx 1 root root 222, 2 Mar 21 2004 /dev/ht2020_102
crw-rw-rwx 1 root root 222, 3 Mar 21 2004 /dev/ht2020_103     0x110に設定したとき
crw-r--r-- 1 root root 222, 16 Mar 10 05:00 /dev/ht2020_110  <-このように マイナ番号をずらせたのも
crw-r--r-- 1 root root 222, 17 Mar 10 05:01 /dev/ht2020_111  <-用意  これを 呼んでいます
crw-r--r-- 1 root root 222, 18 Mar 10 05:01 /dev/ht2020_112  <- echo -en "\\252">/dev/ht2020_112
crw-rw-rw- 1 root root 223, 0 Mar 10 02:14 /dev/ht3070_PA  <- 3070が 0x100〜0x10fのI/Oアドレスを
crw-rw-rw- 1 root root 223, 8 Mar 10 02:14 /dev/ht3070_PAC  <- 占有使用  
crw-rw-rw- 1 root root 223, 1 Mar 10 02:14 /dev/ht3070_PB    このため 2020をずらすことにした訳 
crw-rw-rw- 1 root root 223, 9 Mar 10 02:14 /dev/ht3070_PBC
crw-rw-rw- 1 root root 223, 2 Mar 10 02:14 /dev/ht3070_PC
crw-rw-rw- 1 root root 223, 10 Mar 10 02:14 /dev/ht3070_PCC
crw-rw-rw- 1 root root 223, 3 Mar 10 02:14 /dev/ht3070_PD
crw-rw-rw- 1 root root 223, 11 Mar 10 02:14 /dev/ht3070_PDC
crw-rw-rw- 1 root root 223, 4 Mar 10 02:14 /dev/ht3070_PE
crw-rw-rw- 1 root root 223, 12 Mar 10 02:14 /dev/ht3070_PEC
crw-rw-rw- 1 root root 223, 5 Mar 10 02:14 /dev/ht3070_PF
crw-rw-rw- 1 root root 223, 13 Mar 10 02:14 /dev/ht3070_PFC
crw-rw-rw- 1 root root 223, 6 Mar 10 02:14 /dev/ht3070_PG
crw-rw-rw- 1 root root 223, 14 Mar 10 02:14 /dev/ht3070_PGC
crw-rw-rw- 1 root root 223, 7 Mar 10 02:14 /dev/ht3070_PH
crw-rw-rw- 1 root root 223, 15 Mar 10 02:14 /dev/ht3070_PHC
[guest@armadillo (ttyp0) ~]$
このドライバでは 書き込みに echo -en "\\252">/dev/ht2020_112 という形で キーボードからデバイスに書き込めます \\252:"10 101 010" \\125:"01 010 101" \\0:"00 000 000" \\は8進数指定です
ということです  以上

−−−−  

17:02 2006/03/06  いろいろ 3070.cを書き換えながらコンパイル そして フラッシュだけの
立ち上げにしてテスト まだです  potatoでコンパイルし フラッシュ立ち上げでチェックは安全のためです
mount /dev/hda2 /extの.oを 作り そして insmodしながら  
14:12 2006/03/04 HT3070ドライバ コンパイルした  ところが
どうも armadilloでチェック始めると insmodでInput/outout Errorとのことで 困った  
いろいろ取り外しや取り付けやっているうちに hda1のCFの中味可笑しくしたらしく 動作変に..
JP1:0FFでの自動立ち上がりでは問題ない  ここで hda1マウントし 書き換えて直すことになった
ArmadilloPotatoにてfdiskパーティション1だけnewで そして mke2fsでリフレシュ MebiusPCにて
potato1〜3を展開install  apt-get updateから telnetd ftpd などインストール thttpdは
etc/httpd.confと供にcp-a
ともかく 前の動作が出来るところまで

2006/03/01 HT3070のドライバ作成準備へ
40Pinコネクタ-ケーブルに8x4片側1列分のLED表示部作成 オレンジ 330Ω抵抗

−−−−−−−
大いに参考にさせて頂いたHPから引用の資料です
http://web.kyoto-inet.or.jp/people/bunchan/Linux/DeviceDriver/DeviceDriverBackUp.html
◆ 使用できるメジャー番号
 メジャー番号は割り当てが決まっているものなので、勝手に使ってはいけないものです。
メジャー番号の定義はカーネルソースに付属している /usr/src/linux/Documentation/devices.txt
に記述してあります。
この中にユーザが使用して良いメジャー番号の指示もあります。

 このdevices.txtには以下のような記述があります。このことから、60〜63番、120〜127番、
そして240〜254番はユーザが使用できることがわかります。

<参考>ハードウェアの情報を見る方法

 今回の実習でも何度か用いていますが、ハードウェアの情報を見る方法を紹介しておきます。それは、
「/proc」にあるファイルを「cat」することです。
 試しに「cat /proc/interrupt」や「cat /proc/ioports」などをやってみてください。システムの情報が現れます。
なお、これらのファイルには直接「less」や「more」はできません。出てくる内容が多くて画面上を流れていって
しまう場合はパイプを利用してください。

ex.)$cat /proc/ksyms | less

現在組み込まれているモジュールを見るだけなら、「cat /proc/modules」で見ることができます。

 デバイスドライバプログラム内で使える関数は一般のユーザプログラムで使える関数とは異なります。
ゆえに、使える関数は普通のライブラリ関数ではなく、モジュールのためにカーネルがエクスポートした関数、
またはヘッダに含まれているマクロとなります。 使用可能な関数の一覧は以下のコマンドでわかります
cat /proc/ksyms
これら使用可能な関数には通常のライブラリ関数と全く同じコマンドのものもあるので誤解の無いようにしてください。
(sprintfやstrlenなど)

−−−−−−−
10:08 2006/02/25 potatoパワーオンから  まだオートではないのでマニュアルで
rootログインで thttpd -C /etc/httpd.conf
        insmod /dev/ht2020.o io=0x100  これで Webブラウザから働く

ここまでを 自動起動に追加する必要あり   ところで だめなときの 解析は
cgi-bin/下で  ./moji_ht2020_test5 ../moji_data/sae2006224  
4x4では     ./PIO_test2 ../moji_data_PIO/sae333

6:26 2006/02/25 昨日全日 I/Oドライバソフト整備
以前コンパイル済みのht2020.oを拾ってきて動かしたら カーネルが合わないとのエラー
(linux-2.4.21-rmk1-armadillo-2にした 以前のは16でした  カーネル依存のようだ)
potatoにて /dev/hda2を/ext/とマウントdev/にht2020.cやmakefileなど置いている
また nasもnfsマウントして カーネルソース展開済みを置いておき makefileの
INCLUDEDIR=/EXT_NAS/...と書き換え セルフでコンパイルし 新たにht2020.oを得た
(colinuxのクロスではどうも途中でエラーを出してくる エラー表示内容の部分は
確かに 前のカーネルのその部分とは若干書き換えてあって それが問題なのか?
セルフではすんなりノーエラーで作業終わって.oが出来ていました
ところで  カーネルソースは
http://armadillo.atmark-techno.com/download/armadillo/kernel/linux-2.4.21/source/
に linux-2.4.21-rmk1-armadillo-2.tgz 01-Jun-2004 18:46 34.9M がある 
これ展開すると170MBほどのどでかいファイルです このままではCF上にはセーブ無理
ドライバの開発はたまにしか行なわないでしょう そのときはnfsマウント でも やってみよう
--中味調べて 本当に必要なものだけ .../include下だけですと 24Mちょっとですね 

これだけ 拾っておけばいいということで /ext/dev/下に置きました 8:52 2006/02/26
それで 以下のようにソースのDIR指定を書き換え やってみた  うまく行きました
コンパイルに結構時間が掛かりますが-1分? これで potatoのみで本当のセルフが可能に)
−−−−
INCLUDEDIR = ../kernel_source/linux-2.4.21-rmk1-armadillo-2/include <-ここ 作った
#INCLUDEDIR = /ext_nas/linux-2.4.21-rmk1-armadillo-2/include <-カーネルソース全体なら
#CC = arm-linux-gcc <-ここは
CC = gcc <-このようにセルフに
CFLAGS = -D__KERNEL__ -I$(INCLUDEDIR) \
-Wall -Wstrict-prototypes -Wno-trigraphs \
-O2 -fno-strict-aliasing -fno-common -pipe \
-mapcs-32 -march=armv4 -mtune=arm7tdmi -mshort-load-bytes \
-DMODULE
OBJS = ht2020.o
all: $(OBJS)
ht2020: ht2020.c ht2020.h
$(CC) $< -o $@
clean:
rm -f *.o *~ core *.bak


−−−−−−−−−−−−−−−−−

以上
−−−−−−−−−−−−−−−−−−−−

  

  作成:2006-3-12 最終更新日:2006-3-13