[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Proposal: button and power control



週末になると活動する Takmeuraです。

すこし power management に関連することを考えているのですが、
GPIO の先*など*につながっている電源を on/off するあたりを
整理したいと思います。

そこで提案が2つあります。
まだ実装していないので、ちゃんと動くか(見落としがないか)わかりませんが、
ぼちぼち書こうと思いますので、コメントください。

提案1:
現在 gpio のポートは以下のように gpbus で設定されていますが、

gpbus0 at vrgiu? button1 9 button2 10 button3 11 ...

このへんを少し変えて、

button* at vrgiu? id BUTTON1 port 9
button* at vrgiu? id BUTTON2 port 10
button* at vrgiu? id BUTTON3 port 11
pwctl* at vrgiu? id PW_COM port 14
pwctl* at vrgiu? id PW_BACKRIGHT port 15

などとしてはどうでしょうか。

提案2:
カーネル内でつかえるイベントハンドラのようなものを
以下のようなインターフェースで作成します。
これは、整数で識別されるカーネル内にグローバルなイベント配信
機構です。(整数で識別されるので、config ファイルで config できる)
(以下では関数名やシンボル名はいいかげんです。よい名前を募集中)

establish_receiver(int type, long id,
        int (*recv_handler)(void* ctx, long id, void* msg),
        void* ctx);
send(long id, int type, void* msg);

type: イベントのカテゴリを示します。とりあえずボタンとパワーマネージメント
    実装的にはこれで msg の型を分けます。
id: イベントを識別する識別子です。ボタンの区別とか。config ファイルで書きま
す。
    type 内で一意。
recv_handler: イベントを受け取るルーチン
ctx: イベントを受け取りたい側のコンテキスト
msg: イベントの詳細を示すデータ。どんな型でもかまわない。
    type が同じイベントは同じ型の msg を使う。

イベント発生側で send(id, type, &msg) を実行すると、どこかで
recv_handler(ctx, id, msg) が呼ばれるというかんたんな仕組みです。

たとえば、pwctl* at vrgiu? id PW_COM port 14 では、

establish_receiver(POWER_MANAGEMENT, PW_COM, pw_handler, sc, SHARE);

とし、com 側で

send(POWER_MANAGEMENT, PW_COM, (void*)1);

とかやると、pw_handler(sc, PW_COM, 1) が呼ばれて gpio の 14 を on にする。
button デバイスでは、割り込みがかかったら単に

send(BUTTON, BUTTON1, (void*)1)

を呼ぶだけ。
効率を考えなければ実装は簡単で、カーネルの容量もほとんど増えないと
思います。

Takemura