中斷方式獲取按鍵值

2021-07-26 13:45:22 字數 1994 閱讀 2006

先總結一下中斷的處理過程:

/首先要著重強調一點,irq_desc這個結構體很重要/

在trap_init()中,完成對異常向量的複製,linux中是複製到0xffff0000。當發生異常時,cpu會自動跳轉到這裡,再跳轉到執行更複雜的**,比如呼叫異常處理函式。

當執行中斷處理函式時,會首先呼叫asm_do_irq(),同時會傳入中斷號irq,然後根據中斷號呼叫irq_desc[irq],這是乙個結構體陣列,在handle.c中定義。其中有乙個handler_irq的函式指標,指向中斷處理函式的入口。即會呼叫irq_desc[irq].handler_irq,然後入口函式會先清除中斷,在呼叫在action鍊錶中註冊的中斷處理函式action.handler。

需要特別注意的是,handler_irq只是入口函式,對於電平觸發的中斷是handler_level_irq,邊緣觸發的中斷是handler_edge_irq,真正的中斷處理函式在action鍊錶中的action.handler。

所以,如果我們想要增加乙個中斷處理函式,就需要在action鍊錶中註冊,所需要借助對的函式是request_irq(irq,handler,irqflags, *devname, *dev_id)。在request_irq中會首先構造乙個irqaciton結構,然後通過setup_irq將這個結構放到action鍊錶中。

具體來說,setup_irq實現了三個功能,第一,將irqaction結構放入action鍊錶;第二,把對應的引腳設定為中斷模式;第三,使能中斷。同樣的,想要解除安裝乙個中斷處理函式,需要用到的是free_irq(irq, *dev_id),dev_id的作用就在於此。free_irq使用中斷號定位irq_desc裡的action鍊錶,再使用dev_id定位action鍊錶中要解除安裝的表項(因為共用中斷時必須要用不同的dev_id來區分不同的中斷處理函式)。

接下來總結一下具體的實現過程:

首先是配置中斷,自然是要在third_drv_open函式中加入request_irq(irq,handler,irqflags, *devname, *dev_id),查閱原理圖可以得到,需要用到的irq_eint13、irq_eint14、irq_eint15,handler即為中斷處理函式,暫且寫為buttons_irq(),具體實現稍後再寫,標誌設為irqt_bothedge雙邊沿觸發,名字起為「k1」,dev_id的設定則需要考慮一下。

然後是再考慮釋放中斷的問題,因此需要在file_operation結構裡新增:.release= third_drv_close,在這個函式裡要使用free_irq(irq,dev_id)。

接下來考慮dev_id的問題。我們目前只是知道中斷號,而不知道具體是哪個中斷。所以我們可以把引腳和值封裝起來,定義乙個引腳描述的結構體:

struct pin_desc;

再定義乙個陣列:

struct pin_desc pins_desc[3]=,

, ,

}; 這樣,我們可以把這個陣列的一項作為dev_id,當產生中斷時,request_irq把這個dev_id傳到中斷處理函式中,再解析出來引腳和值。

這樣,我們就解決「找到中斷產生位置」的目的。由於按下和鬆開都會產生中斷,所以我們還需要得到這個按鍵究竟是被按下還是鬆開,於是我們需要用到s3c2410_gpio_getpin(),如果被按下,則輸出0,鬆開則輸出1。通過解析出來的引腳:假如是s3c2410_gpg5被按下,則會輸出0x01,否則輸出0x81;假如是s3c2410_gpg6被按下,則會輸出0x02,否則輸出0x82;假如是s3c2410_gpg7被按下,則會輸出0x03,否則輸出0x83。

完成這些之後,將中斷事件標誌置1,喚醒休眠的程序(在應用程式執行read時,在沒有中斷產生之前一直處於休眠狀態)。然後返回third_drv_read()中使用copy_to_user把鍵值拷貝給應用程式。

程序的休眠與喚醒需要用到wait_event_interruptible和wake_up_interruptible,使用之前需要定義乙個佇列static declare_wait_queue_head(button_waitq);

3 按鍵輸入驅動(中斷方式)

1 配置中斷優先順序分組 2 根據硬體初始化gpio為上 下拉輸入 3 外部中斷初始化 4 編寫中斷服務函式 我是分割線 一 中斷優先順序分組一般選擇為2 nvic prioritygroupconfig nvic prioritygroup 2 設定nvic中斷分組2 2位搶占優先順序,2位響應優...

map 按鍵 值排序

思路 把entry的集合放入list中,利用其sort函式完成排序。public static void main string args private static void sort mapmap 擴充套件 求int陣列中重複次數最多的值。思路 首先構造乙個key為陣列中int值,value為...

中斷掃瞄按鍵

之前都是使用軟掃瞄,參考 int button scan else 缺點是必須放到主函式的while 1 迴圈,如果while 1 中其他功能占用大量時間,就無法實現按鍵的連續掃瞄。但是如果採用中斷方式,當按鈕連線的pin來乙個上公升沿或下降沿,就會中斷主程序去執行中斷函式,從而實現連續掃瞄。1.f...