一. 幾個要點知識:
1. 睡眠
安全睡眠的要點:
<1> 當你執行在原子上下文時不能睡眠;
<2> 醒後必須通過檢查來確你在等待的條件;
<3> 睡眠必須對應乙個喚醒。
《注》: **針對於2.6的核心
等待佇列: declare_wait_queue_head(name);
睡眠函式: wait_event_interruptible
(queue, condition)
(它可能被訊號中斷. 這個版本返回乙個你應當檢查的整數值; 乙個非零值意味著你的睡眠被某些訊號打斷, 並且你的驅動可能當
返回 -erestartsys.)
喚醒函式: void wake_up_interruptible(wait_queue_head_t *queue);
2. poll, select
獲取裝置驅動的支援: unsigned int (*poll) (struct file *filp, poll_table *wait);
<1> 在乙個或多個可指示查詢狀態變化的等待佇列上呼叫poll_wait
void poll_wait (struct file *, wait_queue_head_t *, poll_table *)
<2> 返回乙個位掩碼, 描述可能不必阻塞就立刻進行的操作.標誌參見
3. 中斷
中斷註冊函式: int request_irq(unsigned int irq,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags,
const char *dev_name,
void *dev_id);
中斷釋放函式: void free_irq(unsigned int irq, void *dev_id);
request_irq 返回給請求函式的返回值或者是 0 指示成功, 或者是乙個負的錯誤碼, 如同平常. 函式返回 -ebusy 來指示另乙個驅
動已經使用請求的中斷線是不尋常的. 函式的引數如下:
unsigned int irq 請求的中斷號
irqreturn_t (*handler) 安裝的處理函式指標
unsigned long flags 如你會希望的, 乙個與中斷管理相關的選項的位掩碼(後面描述).
const char *dev_name 這個傳遞給 request_irq 的字串用在 /proc/interrupts 來顯示中斷的擁有者
void *dev_id 用作共享中斷線的指標. 它是乙個獨特的標識, 用在當釋放中斷線時以及可能還被驅動用來指向它自己的私有
資料區(來標識哪個裝置在中斷).如果中斷沒有被共享, dev_id 可以設定為 null。
呼叫 request_irq 的正確位置是當裝置第一次開啟時, 在硬體被指示來產生中斷前.
呼叫 free_irq 的位置是裝置最後一次被關閉時, 在硬體被告知不要再中斷處理器之後.
中斷處理函式: irqreturn_t short_interrupt(int irq, void *dev_id, struct pt_regs *regs)
struct pt_regs *regs, 很少用到
二. tq2440 irq **分析
1.驅動**(不完整)
天嵌提供的例項**並不複雜,但作為乙個例程是非常合適的,**具體的給出了如何註冊,處理,釋放中斷。
/*必要的標頭檔案,我只列出中斷相關的*/
....
#include
#include
#include
#include
....
#define device_name "embedsky_buttons"
#define button_major 232 //裝置號用自動獲取方式更好!
/*等待佇列*/
static declare_wait_queue_head(button_waitq);
/*中斷flag, 中斷處理函式置1,read函式清0 */
static volatile int ev_press = 0;
/* 按鈕被按下的回數(準確地說,是發生中斷的回數) */
static volatile int press_cnt = ;
static struct class *button_class;
/*中斷資訊結構,這個結構的設計很不錯*/
struct button_irqs_desc ;
static struct button_irqs_desc button_irqs = ,
, ,,
};/*中斷處理函式*/
static irqreturn_t buttons_interrupt(int irq,void *dev_id)
static int tq2440_buttons_open(struct inode *inode,structfile *file)
if(err)
return 0;}
static int tq2440_buttons_close(struct inode *inode,structfile *file)
return 0;
}static int tq2440_buttons_read(struct file *filp,char__user *buff,size_t count,loff_t *offp)
ev_press = 0;
err = copy_to_user(buff,(const void*)press_cnt,min(sizeof(press_cnt),count));
memset((void *)press_cnt,0,sizeof(press_cnt));
return err? -efault:0;}
static unsigned int embedsky_buttons_poll(struct file *filp, poll_table *wait)
static struct file_operations tq2440_buttons_fops = ;
static int __init tq2440_buttons_init(void)
static void __exit tq2440_buttons_exit(void)
module_init(tq2440_buttons_init);
module_exit(tq2440_buttons_exit)
LINUX 基於裝置樹編寫按鍵中斷驅動程式
linux核心版本 4.14.2 1.在原理圖中確定home按鍵的引腳 2.在裝置樹檔案中新增節點描述home引腳 3.重新編譯燒寫裝置樹 4.編寫驅動程式,呼叫裝置樹介面函式獲取home引腳的中斷號,使用中斷號註冊按鍵中斷處理程式 在原理圖中確定home按鍵的引腳 在原理圖中找到home按鍵對應的...
linux驅動學習 linux中斷程式編寫流程
linux中斷 1 確定中斷號 2 申請中斷號 request irq 不用一定要釋放free irq 3 編寫中斷服務函式 request irq unsigned int irq,irq handler t handler,unsigned long flags,const char name,...
編寫Linux裝置驅動程式教程
序言 linux是unix作業系統的一種變種,在linux下編寫驅動程式的原理和思想完全類似於其他的unix系統,但它dos或window環境下的驅動程式有很大的區別。在linux環境下設計驅動程式,思想簡潔,操作方便,功能也很強大,但是支援函式少,只能依賴kernel中的函式,有些常用的操作要自己...