基於linux-2.6.22.6核心,arm9 s3c2440開發板
原始碼分析:
drivers/input/input.c:
input_init > err = register_chrdev(input_major, "input", &input_fops);
static const struct file_operations input_fops = ;
問:怎麼讀按鍵?
input_open_file
struct input_handler *handler = input_table[iminor(inode) >> 5];
new_fops = fops_get(handler->fops) // =>&evdev_fops
file->f_op = new_fops;
err = new_fops->open(inode, file);
input_table陣列由誰構造?
input_register_handler
註冊input_handler:
input_register_handler
// 放入陣列
input_table[handler->minor >> 5] = handler;
// 放入鍊錶
list_add_tail(&handler->node, &input_handler_list);
// 對於每個input_dev,呼叫input_attach_handler
list_for_each_entry(dev, &input_dev_list, node)
input_attach_handler(dev, handler); // 根據input_handler的id_table判斷能否支援這個input_dev
註冊輸入裝置:
input_register_device
// 放入鍊錶
list_add_tail(&dev->node, &input_dev_list);
// 對於每乙個input_handler,都呼叫input_attach_handler
list_for_each_entry(handler, &input_handler_list, node)
input_attach_handler(dev, handler); // 根據input_handler的id_table判斷能否支援這個input_dev
input_attach_handler
id = input_match_device(handler->id_table, dev);
error = handler->connect(handler, dev, id);
註冊input_dev或input_handler時,會兩兩比較左邊的input_dev和右邊的input_handler,
根據input_handler的id_table判斷這個input_handler能否支援這個input_dev,
如果能支援,則呼叫input_handler的connect函式建立"連線"
怎麼建立連線?
1. 分配乙個input_handle結構體
2. input_handle.dev = input_dev; // 指向左邊的input_dev
input_handle.handler = input_handler; // 指向右邊的input_handler
3. 註冊:
input_handler->h_list = &input_handle;
inpu_dev->h_list = &input_handle;
誰來喚醒?
evdev_event
wake_up_interruptible(&evdev->wait);
evdev_event被誰呼叫?
猜:應該是硬體相關的**,input_dev那層呼叫的
在裝置的中斷服務程式裡,確定事件是什麼,然後呼叫相應的input_handler的event處理函式
gpio_keys_isr
// 上報事件
input_event(input, type, button->code, !!state);
input_sync(input);
input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
struct input_handle *handle;
list_for_each_entry(handle, &dev->h_list, d_node)
if (handle->open)
handle->handler->event(handle, type, code, value);
怎麼寫符合輸入子系統框架的驅動程式?
1. 分配乙個input_dev結構體
2. 設定
3. 註冊
4. 硬體相關的**,比如在中斷服務程式裡上報事件
struct input_dev {
void *private;
const char *name;
const char *phys;
const char *uniq;
struct input_id id;
unsigned long evbit[nbits(ev_max)]; // 表示能產生哪類事件
unsigned long keybit[nbits(key_max)]; // 表示能產生哪些按鍵
unsigned long relbit[nbits(rel_max)]; // 表示能產生哪些相對位移事件, x,y,滾輪
unsigned long absbit[nbits(abs_max)]; // 表示能產生哪些絕對位移事件, x,y
unsigned long mscbit[nbits(msc_max)];
unsigned long ledbit[nbits(led_max)];
unsigned long sndbit[nbits(snd_max)];
unsigned long ffbit[nbits(ff_max)];
unsigned long swbit[nbits(sw_max)];
分析圖:
測試:1.
hexdump /dev/event1 (open(/dev/event1), read(), )
秒 微秒 類 code value
0000000 0bb2 0000 0e48 000c 0001 0026 0001 0000
0000010 0bb2 0000 0e54 000c 0000 0000 0000 0000
0000020 0bb2 0000 5815 000e 0001 0026 0000 0000
0000030 0bb2 0000 581f 000e 0000 0000 0000 0000
2. 如果沒有啟動qt:
cat /dev/tty1
按:s2,s3,s4
就可以得到ls
或者:exec 0
3. 如果已經啟動了qt:
可以點開記事本
然後按:s2,s3,s4
驅動 linux裝置驅動 字元裝置驅動開發
preface 前面對linux裝置驅動的相應知識點進行了總結,現在進入實踐階段!linux 裝置驅動入門篇 linux 裝置驅動掃盲篇 fedora下的字元裝置驅動開發 開發乙個基本的字元裝置驅動 在linux核心驅動中,字元裝置是最基本的裝置驅動。字元裝置包括了裝置最基本的操作,如開啟裝置 關閉...
Linux裝置驅動開發
1.操作硬體 讓硬體能夠正常工作 2.要給使用者提供訪問操作硬體的介面 1.字元裝置 特點 操作時,資料都是按照位元組流形式進行 訪問 例子 串列埠,led,按鍵,觸控螢幕,lcd顯示屏,藍芽 gps,gprs,各種感測器,攝像頭,音效卡,震子,電源管理ic等 2.塊裝置 特點 操作時,資料按照一定...
Linux裝置驅動 核心開發
linux裝置驅動需要使用核心api來實現,一般被包含在linux核心原始碼樹中。驅動可以編譯到核心,隨著核心一起在系統啟動的時候被載入。也可以編譯成核心模組,在系統執行起來之後動態地載入到核心中,使得除錯的時候無需重新編譯核心,也無需重啟系統,很大程度上方便了驅動 的除錯。但並不是只有裝置驅動才能...