記事ディレクトリ
入力サブシステムの役割とフレームワーク
- 入力デバイスとは
- キー/キーボード
- マウス
- タッチスクリーン(タッチスクリーン):gt811、ft56xx
- ジョイスティックジョイスティック
- 駆動する必要のある入力デバイスが複数ある場合、入力サブシステムが考慮されていない場合
- gt811
デバイス番号、ファイル作成、ハードウェア初期化、fopの実現、ブロッキング、ハードウェア初期化(I2Cなど) - ft56xx
デバイス番号、ファイル作成、ハードウェア初期化、fopの実現、ブロッキング、ハードウェア初期化(I2Cなど)。
- 複数の入力デバイスの共通点:
データの取得(ハードウェア操作)-------差別化と
ユーザーへのレポート(xxx_read、copy_to_user、ブロッキング)------複数の入力デバイスが一般的
です。いくつかの違いがあります。
考慮し、一般的なコードを記述し、差別化されたコードをドライバーエンジニアに任せる汎用カーネルもいくつかあります。 - 入力サブシステムとして設計:アプリケーションプログラマーとドライバープログラマーがプログラミングを簡単かつ統合できるようにします
- すべての入力デバイスと互換性があります
- 統一されたプログラミングドライブ方式(差別化されたハードウェア操作を実現するため)
- 統合アプリケーション操作インターフェイス:/ dev / input / event0、event1、open( "/ dev / input / event0、event1")、read(fd、struct input_event):structinput_eventバフは統合データパケットと見なすことができます
フレーム
- フレームワーク:ドライバーは、
入力コアレイヤーと入力ハンドラーレイヤーの3つのレイヤーに分かれています。カーネルに付属するコード。ドライバーエンジニアは、入力デバイスレイヤー(入力デバイスレイヤー)でプログラミングするだけで済みます。
入力サブシステムをプログラムする方法
- 入力サブシステムのプログラミング方法—入力サブシステムを開発する簡単な方法を学びます
- 前提条件:入力コアレイヤーコードと入力ハンドラーレイヤーコードには、カーネルに/drivers/input/input.cが含まれている必要があります
//コアレイヤーコード
/drivers/input/evdev.c//イベントハンドラー - 家makemenuconfig中
デバイスドライバー
— >入力デバイスサポート—>
汎用入力レイヤー
イベントインターフェイス//入力ハンドラー層evdev.c
プログラミング手順:
(1)入力デバイスオブジェクトの割り当て
(2)入力デバイスオブジェクトの初期化
(3)入力デバイスオブジェクトの登録
- レポートデータ
void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
パラメータ1:現在の入力デバイス
によって報告されたデータパラメータ2:報告されたデータのタイプはEV_KEY、EV_ABSです
パラメータ3:特定のデータは何ですか:KEY_POWER
パラメータ4:値は何ですか
- ユーザースペースで読み取られたデータ:統合データパケット
struct input_event
{
struct timeval time; //时间戳
__u16 type; //数据类型
__u16 code; //具体数据是什么
__s32 value; //值是什么
}
- コード例
#include<linux/init.h>
#include<linux/module.h>
#include<linux/input.h>
struct input_dev *inputdev;
static int __init simple_input_init(void)
{
//编写输入子系统代码
/*
*(1)分配一个 input device 对象
*(2)初始化 input device 对象
*(3)注册 input device 对象
* */
int ret;
inputdev = input_allocate_device();
if(inputdev == NULL)
{
printk(KERN_ERR "input allocate device error\n");
return -ENOMEM;
}
//当前设备能够产生按键数据
__set_bit(EV_KEY,inputdev->evbit);
//表示当前设备能够产生power按键
__set_bit(KEY_POWER,inputdev->keybit);
ret = input_register_device(inputdev);
if(ret != 0)
{
printk(KERN_ERR "input register device error\n");
goto err_0;
return ret;
}
return 0;
err_0:
input_free_device(inputdev);
return ret;
}
static void __exit simple_input_exit()
{
input_unregister_device(inputdev);
input_free_device(inputdev);
}
module_init(simple_input_init);
module_exit(simple_input_exit);
MODULE_LICENSE("GPL");
ユーザースペースアプリケーション:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
int main(void)
{
int fd;
int ret;
struct input_event event;
fd = open("/dev/event0",O_RDWR);
if(fd < 0)
{
perror("open");
exit(1);
}
while(1)
{
ret = read(fd,&event,sizeof(struct input_event));
if(ret < 0)
{
perror("read");
exit(1);
}
if(event.type == EV_KEY)
{
if(event.code == KEY_POWER)
{
if(event.value) //按键按下
{
printf("__APP_USER__:power pressed\n");
}
else //按键抬起
{
printf("__APP_USER__:power up\n");
}
}
}
}
close(fd);
return 0;
}