2010年11月18日
PARTNER-Jetで直接I/Oポートを読み書きする
KZM-A9-DualボードのLinuxのデバイスドライバのデバッグをしてます。
SDカードを読むときにエラーになってしまいます。eMMCは問題がないのになんで?
と悩んでいたらボード屋さんからSDの電源がONになっていないのでは?という情報が。
GPIOのP024をON(1)にしてみてということなので、PARTNER-JetのI/Oポートの読み書きする機能を使って試してみました。
SDカードの挿入検出はちゃんとできているので、SDカードを差すと自動的にカーネルのSDドライバがSDのファイルシステムの種別をチェックしようとするのですが、そこでのコマンドがエラーになってしまっています。カーネルのログには以下のエラーメッセージがでます。
mmc1: error -110 whilst initialising SD card
「GPIOのP024をONにする」ためには以下の手順をふむ必要があります。
- GPIOのP024が割り当てられているピンをGPIOモードにセットする。
- GPIOのP024のPull Up/Pull Downの設定をする。
- GPIOのP024の入出力の方向をoutputに設定する
- GPIOのP024に1を書き込む。
(1)と(2)は初期化時の設定がすでにそうなっていることを確認しました。
(3)は 0xe0050000 のbit24を立てればよいということがわかりました。
(4)は 0xe005000c の上位16bitで書き込みマスク、下位16bitで書き込む値を入れればよいということがわかりました。つまり、0xe005000cに0x01000100 を書けばよい。
(3)と(4)を行うために普通はデバイスドライバのソースを修正して最コンパイルして試すことになるのですが、PARTNER-Jetでブレークさせてコマンドラインから直接これらのI/Oポートを読み書きすることができます。
podコマンドを使います。 (Port Output by Double word)
>pod 0xe0050000,0x01000000 >pod 0xe005000c,0x01000100
GPIO P024に書き込んだ値は 0xe005000cの下位16bitを読めば確認できます。ここではGPIO[16:31]が読めます。pidコマンドを使います。(Port Input by Double word)
>pid 0xe005000c address : data : bit data E005000C 00002100 0000 0000 0000 0000 0010 0001 0000 0000 >
16進数と2進数の両方で表示されます。普通のメモリを読むコマンドだと目的のアドレス以外にもその周辺のメモリを読んでしまいますが、このpidコマンドでは指定したアドレスだけをピンポイントで読み込みます。
GPIO P024は確かに1になったようです。
これがONになるとボード上のLED5が点灯するそうですが、それも確認できました。
PARTNER-JetのGoコマンドでCPUの実行を再開させます。
>g
この状態でSDカードをスロットに差してみると
mmc1: new SD card at address 0300 mmcblk1: mmc1:0300 SD512 488 MiB mmcblk1: p1 p2 p3
うまくいきました!!
/dev/mmcblk1p3をマウントしてファイルシステムを読み書きすることもできました。
つまりSDの電源がONになっていなかったというのが大正解。
この事実さえ確認できれば、LinuxのSDのデバイスドライバにGPIO P24を1にするコードを追加すればよいということです。
これはすぐにできて問題解決しました。
このあと、LCDボード上にある十字キーとメニューキー、バックキーが使えるようにキーボードデバイスドライバを修正したのですが、これらのキーはやはりGPIOでつながっているので、同じようにPARTNER-Jetのpod, pidコマンドで先に動作を確認することができました。
(2010.12.2追記)
物理アドレスを直接指定する方法
Linuxが動いているときは基本的にMMUはONになっているのでCPUの扱うアドレスは全て仮想アドレスとして扱われます。一方、ハードウェアの仕様書に書いてあるI/Oポートのアドレスは物理アドレスです。
そのためI/Oポートは直接物理アドレスで指定したい場面も多いと思います。PARTNER-Jetのpid, podコマンドでは ,/p というオプションをつけると指定されたアドレスを強制的に物理アドレスとして扱うことができます。
>pid 0xe005000c,/p address : data : bit data E005000C 00002100 0000 0000 0000 0000 0010 0001 0000 0000