3.23 割り込みに基づきのボタンドライバ
3.23.1ハードウェア回路図
Mini2440 には6つのユーザーテストボタンがあり、すべて CPUの割り込みピンに接続する:
6 つのユーザーテストボタンとCPUの割り込みピンの対応関係:
先ず、割り込み機能があり、直接割り込みを実験できる。中に GPG3、5、6、7の組み合わせはSPIインターフェースを構成できる。そして便利にするようにCON12を増やし、これらのボタンをパネルと繋がり、または拡張・フル機能キ―ボードインタフェースとして使用する。これもmini2440の特性の一つである。
3.23.2 ドライバプログラム分析とコンパイル
/linux-2.6.32.2/drivers/char/ディレクトリで新しいドライバプログラム mini2440_buttons.cを作成する:
3.23.3 ボタンドライバをカーネルに追加
ボタンドライバをカーネルに加えます、 linux-2.6.32.2_fa/drivers/char/Kconfigをオープンし、赤字のコードを追加する:
次に、ドライバ構成定義に基づき、ドライブのターゲットファイルをカーネルに追加する、linux-2.6.32.2/drivers/char/Makefile をオープンし、赤字のコードを追加する:
ここまで、カーネルにLEDドライバは追加した
3.23.4 カーネル再構成・コンフィグ
上記の手順で、カーネルのソースコードのディレクトリで実行:make menuconfigカーネルを再構成、サブメニュに入る:
ボタンドライバの設定メニューに入る:
スペースボタンで゛<*> Buttons driver for FriendlyARM Mini2440 development boards(NEW) ゛ オプションを選択、上記のカーネル設定を保存し、終了する。
カーネルのソースコードのディレクトリで次のコマンドを実行:make zImage、生成された新カーネルを開発ボードにプログラミングする。
3.23.5 ボタンテスト
前章のボタンをテストするため、テストプログラムを作成する:btn-test.c:
注:付属DVDにテストプログラムのソースコードがある。位置は:\linux\examples\buttons 、ファイル名:buttons_test.c、ここでは名前をbtn-test.c に変更する。
ソースコードのコマンドラインに:#arm-linux-gcc –o btn-test btn-test.cを実行し、btn-testという実行可能のバイナリファイルを生成する。USBメモリードライブやFTPツールなどでファイルを開発ボードにコピーし、属性を実行権限に変更する。最後に実行し、ボタンテストを行う。下図を参照する:
3.24 ブザードライバを制御するPWMを追加
3.24.1ハードウェア解析
Mini2440 ボードにプザーがあり、PWMで制御される。接続回路図は下図を参照する:
ブザーの GPB0 ポートの多重化機能は TOUT0、即ち PWM 出力。
S3C2440データシートで下記記述がある:
ドライバにGPB0ポートを PWM 機能出力に設定し、該当のタイマーを設定し、PWMの出力周波数を制御できる。
3.24.2ドライバ追加
linux-2.6.32.2/drivers/char/ディレクトリ下にドライバファイル mini2440_pwm.cを追加する:
上記ドライバプログラムに関する説明:
1 CPUカウンタ制御レジスタ
1)タイマ入力クロックを設定
TCFG0-クロック・コンフィギュレーション・レジスタ0、プリスケーラ値(1~255)を取得する機能
TCFG1-クロック・コンフィギュレーション・レジスタ 1、分割值(2、4、8、16、32)を取得する機能
タイマ入力クロック周波数=PLCK/{プリスケーラ+1}/{分割值}
2)PWMのデューティサイクルを設定
TCNTB0-タイマー 0カウント・バッファレジスタ、タイマ入力クロック周波数から得るパルス幅変調の周波数。TCMTB0-タイマー 0比較バッファレジスタ、PWMのデューティサイクルを設定する機能、レジスタの値はハイー、例えTCNTB0の周波数は160、IF TCMTB0 は 110、 PWM は 110 目のサイクルはハイ、50 目サイクルはロー、したがって、デューティ•サイクルは11:5
3)タイマコントロールレジスタTCON
TCON[0~4]はタイマー 0を制御する
2. レジスタ読み取り/書き込み関数:__raw_readl と__raw_writel
ポート・レジスタ読み取り関数 :__raw_readl(a )、当関数はポート aから一つの32ビット値を返する。関連定義はinclude/asm-arm/io.hにある。#define __raw_readl(a) (*(volatile unsigned int*)(a))、ポート・レジスタ書き込み関数 : __raw_writel(v、a)、当関数は一つの32ビット値をポート aに書き込み。関連定義は include/asm-arm/io.hにある。#define __raw_writel(v、a) (*(volatile unsigned int*)(a) = (v))。ここにファンクション•コントロール•レジスタを設定し、該当ピンを出力に設定する。
3. カーネルのGPIO操作
gpio_cfgpin で対応 GPIO ポートコンフィグ
gpio_setpin IOポート出力機能な場合、ピン書き込み
4. カーネルのセマフォに基づきのLinuxの同時制御
ドライバでは、複数のスレッドが同時に同一のリソースにアクセスする時に、"レース"状態となり、共有リソースへの同時実行制御を行う必要がある。セマフォ(多くの場合はミューテックスとして使用される)は同時実行制御の手段として使用する(他にスピンロック、それは非常に短い期間を維持する場合に適している)。セマフォは、プロセスのコンテキストだけで使用されます。void init_MUTEX(&lock) mutexロックを初期化する、すなわちセマフォを1に設定する
void up (&lock) セマフォリリース、待ち関数をウェイクアップ
int down_trylock(&lock) セマフォロック取得を試みる、セマフォ取得すると、0を返する、or 非0を返する。そしてスリープを引き起こさず、割り込みコンテキストで使用できる。 PWMでは、カウント値がオーバーフローすると、カウント割り込みが発生するため、この関数でセマフォ取得する。
3.24.3ドライバをカーネルに追加
次に、linux-2.6.32.2/drivers/char/Kconfig ファイルをオープンし、赤字部分を追加する:
linux-2.6.32.2/drivers/char/Makefileオープン、ドライバのターゲットファイルを構成定義に追加する、赤字コード:
ここまで、カーネルにブザー制御のPWMドライバを追加した。
3.24.4 新しいカーネルをコンフィグとコンパイル
上記の手順で、カーネルのソースコード・ディレクトリで下記のコマンドを実行する:make menuconfig カーネル再コンパイル、次のサブメニュに入る:
PWM制御ブザーのメニューに入る:
スペースキ―で゛<*> Buzzer driver for FriendlyARM Mini2440 development boards(NEW)゛オプションを選択、上記のカーネル設定を保存し、終了する。
カーネルのソースコードのディレクトリで次のコードを実行:make zImage、生成された新カーネルを開発ボードにプログラミングする。
3.24.5 PWM制御ブザーテスト
前章のボタンをテストするため、テストプログラムを作成する:pwm.c:
注:付属DVDにテストプログラムのソースコードがある。位置は:\linux\examples\pwm、ファイル名:pwm_test.c、ここでは名をpwm.c に変更する。
pwm.c があるディレクトリからコマンドライン:#arm-linux-gcc –o pwm pwm.cを実行し、PWM可実行バイナリ•ファイルを生成する。USBメモリードライブやFTPツールなどでファイルを開発ボードにコピーして、属性を実行権限に変更する。最後に実行し、ボタンテストを行う。下図を参照する:
説明:テスト中ボタンボードの゛+゛/゛-゛でPWMの出力周波数を調整できる。
第四章ファイルシステムについて
4.1 mini2440 root_qtopiaファイルシステムのスタートアッププロセスの分析
mini2440 最新の root_qtopia ファイルシステムのスタートアッププロセスについて、root_qtopiaファイルシステムのGUIはQtopiaに基づき、その初期化のスタートプロセスはほどんと busybox で完成する。Qtopia(qpe)はスタート最終段階だけで起動する。デフォルトカーネルコマンドにinit=/linuxrcがあるため、ファイルシステムがロードされた後、最初実行するプログラムはルートディレクトリ下のlinuxrcである。 これは/bin/busyboxへのポインタ・リンクで、即ち最初起動されたプログラムは busybox 自身である。
先ず、busybox は/etc/inittab を解析し、更なる初期設定情報を取得する。(busyboxソースコード init/init.c の parse_inittab()関数を参考ください)。次、root_qtopia に/etc/inittab というプロフィールが存在しないため、busybox のロジックにより、デフォルトのコンフィギュレーションを生成する:
一番大切なのは new_init_action(SYSINIT、 INIT_SCRIPT、 ")、それは次の初期化スクリプトはINIT_SCRIPTが定義値で決める。マクロのデフォルト値は"/etc/init.d/rcS"。下記のはファイルシステム中
/etc/init.d/rcS の内容は分析の重点でもある:
順次分析する:
ブート環境に必要な環境変数を設定:
マシン名を設定:
バーチャルファイルシステムをマウントし、゛/proc゛と゛/sys゛、そして/devディレクトリで ramfsをマウント、これは NAND Flash 上の読み取り専用の/devディレクトリ上に書き込み可能のSDRAMを上書きする。
次、/sys とramfs をマウントした/devは正確にデバイスノードを作成するキ―ポイントである。2.6.29カーネルに対して、 devfsのサポートはないため、デバイスノードを作成する方法は2つある:
1) ファイルシステム・ミラーリングを作成する前に、mknodを使って手動でシステム内全てのデバイスノードを作成する、そしてデバイスノードをファイルシステムのミラーリングに加えます;
2)ファイルシステムの初期化処理中、/sys ディレクトリの出力情報により、/dev ディレクトリ下ダイナミックで目录システムの実際のデバイスノードを作成する。
方法 1)にはデバイスが動的に増減する場合に適して、多くのホットスワップデバイスがある場合には適用しない、例えばフラッシュドライブ、SDカードなど。
方法 2)は現在PC Linuxのやり方で( udevに基づき)。2つの前提が必要である:/ sysディレクトリマウントと書き込み可能な/ devディレクトリ。
そして、システムファイル初期化する前に、/dev ディレクトリ下にはデバイスノート:/dev/consoleが必要である。
1) mdev -s で/devディレクトリ内に必要なデバイスノードを作成する;
2)カーネルの hotplug handler を mdevに設定し、デバイスがホット•スワップすると、 mdevがカーネルからのメッセージを受信し該当の動作を行われる。例えば:USBメモリードライブ・マウント。
mdevについて、ファイルシステムには/etc/mdev.conf ファイルが存在し、そしてmdevの設定情報を含まれる。このファイルを介して、特定のニーズ用のデバイスノード名またはリンクをカスタムできる。下記はroot qtopia の mdev.conf の内容:
元シリアルドライバのデバイス登録名は s3c2410_serial0、 s3c2410_serial1 とs3c2410_serial2で、 mdev は/dev ディレクトリ下にttySAC0、ttySAC1とttySAC2を生成される。同じく、/dev/sdcard と/dev/udisk はSDカードおよびUSBメモリードライブのファーストパーティションを指する
他の良く使われるファイルシステムをマウントする、そして/ varディレクトリに(同じRAMFS、書き込み可能)必要なディレクトリを作成する。
システム時刻を設定する機能、ハードウェアRTCから取得し、正しい時刻に設定する必要がある(RTCを設定する方法は、ユーザーマニュアルの説明を参照する)。現在開発ボードの時間はデフォルト時間である。次はシステムサービス起動で、log•レコード、サービスネットワーク、HTTP Serverとカスタマイズされた"繰り返し点灯•サービス"を含む...
mdev.conf について:
上記の機能はSDカードやUSBメモリードライブの取り付け/取り外しの場合、情報をカスタマイズされたホットスワップ handler、 /bin/hotplugに伝送する。流れは、ファースト・パーティションをFAT/FAT32としてSDカードまたはUSBメモリードライブにマウントする。
そして、フィールドテーブルが無いまたはファースト・パーティションがFAT/FAT32ではない場合は適用しない。
/bin/hotplugのバイナリデータの一部は下記通り:
----------続く