Linuxカーネルでのgpio-keyドライバーの使用

キーワード

dtsi、gpio、キー、入力サブシステム、イベント分析、長押しキー検出

gpio_keysの説明

キーは組み込み開発で一般的に使用されるものであり、成熟したメカニズムがLinuxカーネルで作成されています。

Linuxカーネルの下のdrivers / input / keyboard / gpio_keys.cは、アーキテクチャに依存しないGPIOキードライバーを実装します。このキードライバーを使用するには、対応するデバイスツリーで関連データを定義するだけです。ドライブの実装は非常に単純ですが、独立したキードライブの実装により適しています。

gpio-keysは、入力アーキテクチャに基づく汎用GPIOキードライバーです。ドライバーは、Linuxデバイスドライバーモデルのアイデアに沿って、ドライバーとデバイスの分離を実現するplatform_driverアーキテクチャに基づいています。プロジェクトのキードライバーは通常、gpio-keysに基づいて記述されているため、gpio_keysを分析する必要があります。

ここでは、長押し検出をサポートするためにアプリケーション層で処理しました(私のプログラムは長押し6S印刷に設定されています)。ドライバー層でデバウンス時間を変更しようとしたところ、効果が非常に悪かったため、あきらめました。

dtsiデバイスツリーの実装

  • デバイスツリーの実装はほとんど同じですが、必要なパラメーターを入力するだけです。

gpio_keys {

    compatible = "gpio-keys";

    label = "gpio-keys";



    pinctrl-names = "default";

    pinctrl-0 = <&key_recovery_default>;



    recovery {

     label = "recovery";

     gpios = <&tlmm 23 GPIO_ACTIVE_HIGH>;

     linux,input-type = <1>;

     linux,code = <115>;

    /*这三项根据需求添加*/

    gpio-key,wakeup;

    debounce-interval = <15>;

    linux,can-disable;

    };

 };

1.ノード名は「gpio-keys」です。

2. gpio-keysノードの互換属性値を「gpio-keys」に設定する必要があります。

3.すべてのKEYはgpio-keysの子ノードであり、各子ノードは次の属性で自身を記述することができます。

gpios:KEYで接続されたGPIO情報。

割り込み:KEYで使用されるGPIO割り込み情報は必要ありません。書き込むことはできません。

ラベル:キー名

Linux、コード:シミュレートするKEYキー できる まっすぐ 受け取り 記入 言葉 \ color {red} {直接数字を入力できます}

gpio-key、wakeup:ウェイクアップできます

debounce-interval:デバウンス時間

  • その他の分野

1.ボタンがダブルクリックをサポートする必要がある場合は、オートリピートを追加します

シンプルなドライバー分析

これは標準のプラットフォームドライバーフレームワークです。デバイスツリーを使用してKEYデバイス情報を記述する場合は、デバイスノードの互換性のある属性値を「gpio-keys」に設定する必要があります。デバイスとドライバーが一致すると、gpio_keys_probe関数が実行されます


static struct platform_driver gpio_keys_device_driver = {

 .probe = gpio_keys_probe,

 .driver = {

  .name = "gpio-keys",

  .pm = &gpio_keys_pm_ops,

  .of_match_table = gpio_keys_of_match,

 }

};

デバイスツリー分析、デバイスツリーからKEYに関連するデバイスノード情報を取得


static int gpio_keys_probe(struct platform_device *pdev)

{

if (!pdata) {

  pdata = gpio_keys_get_devtree_pdata(dev);

  if (IS_ERR(pdata))

   return PTR_ERR(pdata);

 }

}

読み取りイベントを表示

  • イベントを表示

ls -l / dev / input

  • ファイルの内容を表示する

hexdump / dev / input / event0

アプリケーション層の解析キー値


#define RECOVERY_KEY "/dev/input/event2"

#define RECOVERY_KEY_CODE 115

#define RECOVERY_KEY_PRESS 0



void recovery_key_press_timer(int sig)

{

 if(SIGALRM == sig)

 {

  printf("alarm 6s.\n");

 }



 return;

}





static void read_recovery_key_event()

{

 int fd = -1, ret = -1;

 struct input_event ev;



 fd = open(RECOVERY_KEY, O_RDONLY);

 if (fd < 0)

 {

  printf("open RECOVERY_KEY event failed.\n");

  return;

 }



 memset(&ev, 0, sizeof(struct input_event));

 ret = read(fd, &ev, sizeof(struct input_event));

 if (ret != sizeof(struct input_event))

 {

  printf("read RECOVERY_KEY event failed.\n");

  close(fd);

 }



 if( (RECOVERY_KEY_CODE == ev.code) && (RECOVERY_KEY_PRESS == ev.value) )

 {

  printf("recovery-key press.\n");

  alarm(6);

 }

 else

 {

  printf("recovery-key release.\n");

  alarm(0);

 }



 close(fd);

}



int main(int argc, char **argv)

{

    int rc = 0;

 signal(SIGALRM, recovery_key_press_timer);

 while(1)

 {

  read_recovery_key_event();

 }

    return 0;

}

参照リンク

LEDE / OpenWRTはGPIOベースの電源キーを処理します

オリジナルの記事を162件公開 賞賛された183件 表示回数12万回

おすすめ

転載: blog.csdn.net/qq_31339221/article/details/105233924