?? keyboard.c
字號:
/*鍵盤驅動范例 keybd.c*/
/* Copyright (C) 1998 by Ori Pomerantz */
/*必要頭文件*/
/*標準頭文件*/
#include <linux/kernel.h> /*內核工作*/
#include <linux/module.h> /*明確指定是模塊*/
/*處理 CONFIG_MODVERSIONS */
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include <linux/modversions.h>
#endif
#include <linux/sched.h>
#include <linux/tqueue.h>
/* 在程序中將用到中斷 */
#include <linux/interrupt.h>
#include <asm/io.h>
/*在2.2.3 版/usr/include/linux/version.h 中包含這個宏
* 但 2.0.35 版不包含-因此在這加入以被需要*/
#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))
#endif
/*Bottom Half - 一旦內核模塊認為它做任何事都是安全的時候這將被內核調用*/
static void got_char(void *scancode)
{
printk("Scan Code %x %s.\n",
(int) *((char *) scancode) & 0x7F,
*((char *) scancode) & 0x80 ? "Released" : "Pressed");
}
/*這個函數為鍵盤中斷服務。它讀取來自鍵盤的相關信息,然后安排到當內核認為bottom half安全的時候讓它運行*/
void irq_handler(int irq,
void *dev_id,
struct pt_regs *regs)
{
/*這些變量是靜態的,因為它們需要對 bottom half 可見(通過指針)*/
static unsigned char scancode;
static struct tq_struct task =
{NULL, 0, got_char, &scancode};
unsigned char status;
/*讀取鍵盤狀態*/
status = inb(0x64);
/*讀取掃描碼*/
scancode = inb(0x60);
/*安排 bottom half 運行*/
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)
queue_task(&task, &tq_immediate);
#else
queue_task_irq(&task, &tq_immediate);
#endif
mark_bh(IMMEDIATE_BH);
}
/*在這里假設驅動的加載還是采用模塊化方式*/
/*初始化模塊--登記 IRQ 句柄*/
int init_module()
{
/*由于原來鍵盤的句柄不能和本驅動程序共存,所以在啟動本程序前(請不要用人稱代詞,如"我們","他們"等)不得不關閉它(釋放它的 IRQ)。
*同時因為不知道它在哪兒,所以搶占以后沒有辦法恢復它,因此當本程序運行完后計算機將被重新啟動
*/
free_irq(1, NULL);
/*請求IRQ 1,鍵盤的IRQ,指向我們的 irq_handler*/
return request_irq(
1, /* PC上的鍵盤的 IRQ 號*/
irq_handler, /* 我們的句柄*/
SA_SHIRQ,
/* SA_SHIRQ 意味著將這個 IRQ指定為可以共享
*
* SA_INTERRUPT 能使句柄為一個快速中斷
*/
"test_keyboard_irq_handler", NULL);
}
/*清除*/
void cleanup_module()
{
/*它(指代不明,指代是明確的,就是這段代碼)在這兒只是為了使驅動程序結構完整。它是完全不相關的,因為沒有辦法恢復被屏蔽的系統自帶鍵盤中斷,因此計算機完全沒用了,需要被重新啟動*/
free_irq(1, NULL);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -