1. 程式人生 > >【驅動】第2課、輸入子系統驅動之學習筆記

【驅動】第2課、輸入子系統驅動之學習筆記


一、筆記
1、問題:原本的字元驅動框架被拆分為兩部分,
在本例的 buttons.c 驅動中,沒有用 open, read, write 等操作,只是在按鍵中斷及其觸發的系統定時器中斷中得到按鍵值並上報,

問題:原本一套驅動程式呼叫的步驟被拆分為幾部分了?都在哪裡?如今一套按鍵 操作的驅動呼叫流程是怎樣的?
答:

原按鍵字元驅動 和 現輸入子系統驅動的區別:
答:(1) 之前的字元驅動中,fops 結構有很多操作函式,其中的open函式用來 配置硬體相關的引腳/註冊中斷,
input.c中的 struct file_operations fops{.open}; 只一個open函式,且只起到中轉的作用:在某個陣列(input_table[])
裡面找到 input_handler 結構,呼叫裡面的 fops{.open, .read, .write}結構裡面的操作。
(2) 原本的驅動操作在一個檔案buttons_drv.c,現在被拆分為好幾個檔案: input.c, evdev.c, 驅動開發者自己的裝置原始碼檔案buttons.c。
(3) 工作內容:原來的需要構建整個驅動,現在只需做硬體相關,即 input_dev 相關的一部分即可。

3、buttons.c 驅動
目的:用輸入子系統註冊一個新字元裝置--按鍵裝置,並把按鍵值關聯一個字元,進行按鍵操作並列印鍵值到終端 或 用鍵值作為輸入命令;
方法步驟:
(1)分配一個 input_dev 結構體;
(2)設定該 input_dev 結構體內的元素;
(3)註冊該 input_dev 結構體;
(4)硬體相關的操作:有資料產生時(即按鍵按下),在中斷服務程式裡呼叫 input_event() 上報事件


---------------------------------------------------------------------------------------------


二、測試
1、input_keys1.c驅動測試
nfs掛接命令:
未成功:mount -t nfs -o nolock.vers=2 192.168.1.105:/work/nfs_root/fs_second /mnt
成功: mount -t nfs -o nolock 192.168.1.105:/work/nfs_root/fs_second /mnt
實驗:當未執行上面的nfs掛載到/mnt命令,直接載入驅動模組 xx.ko,然後執行 #cat /dev/tty1 命令並進行按鍵操作時,程式崩潰!!

檔案 /etc/init.d/rcS 修改:
修改前:
#mount -t proc none /proc
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
修改後:
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
if [ ! -e /etc/pointercal ]
then
/bin/ts_cal.sh
fi
#/bin/qpe.sh & #遮蔽Qt;
<結束>
實驗現象:執行# cat /dev/tty1 命令時,按鍵輸入字元‘l’‘s’時沒有列印,當執行 “Enter” 鍵之後,才打印,為什麼?

2、input_keys2.c驅動測試
和input_keys1.c基本一樣的程式,但是載入之後,無論是執行 #cat /dev/tty1 命令還是 #exec 0</dev/tty1 命令,都沒有列印資訊!
為什麼?相同裝置名字而只能註冊一個嗎?
答:不是,程式碼編寫有問題:
static int keys_init(void)
{
/* 1.分配一個input_dev結構體 */ 。。。
/* 2.配置該結構體 */ 。。。
/* 3.註冊該結構體 */
err = input_register_device(keys_dev2);
...
/* 4.硬體相關的操作 */
/* 4.1初始化並註冊定時器 */
init_timer(&keys_timer2);
keys_timer2.function = keys_timer2_function;
add_timer(&keys_timer2);
/* 註冊按鍵外部中斷 */
...
//return 0; //程式不列印時未新增該語句!!!

err_fail:
if(err)
{
for(i--; i >= 0; i--)
free_irq(pinsdesc[i].irq, (void *)&pinsdesc[i]);
}
del_timer(&keys_timer2);
input_unregister_device(keys_dev2);
input_free_device(keys_dev2);
return err;
}
由於//return 0 語句缺失,初始化和註冊成功完成之後未退出 keys_init() 函式,造成程式又繼續執行了 err_fail 識別符號的語句,
之前初始化和註冊的程式全部回滾,等於完全沒註冊,驅動載入之後當然沒有任何資訊了!!!細心啊細心!!

------------------------------------------------------------------------------------------------
三、複習