Linux gpio 按鍵中斷學習

2021-07-11 22:43:50 字數 4367 閱讀 7417

**

先說明一下按鍵與s3c2440晶元的連線方式:

key1 <----> eint8<---->

gpg0

key2 <---->

eint11

<---->

gpg3

key3 <---->

eint13

<---->

gpg5

key4 <---->

eint14

<---->

gpg6

key5 <---->

eint15

<---->

gpg7

key6 <---->

eint19

<---->

gpg11

驅動程式原始碼如下:

(drivers/char/mini2440_buttons.c)

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define device_name "buttons"

//裝置名稱

/*定義中斷所用的結構體*

/struct button_irq_desc;/

*結構體實體定義*

/static struct button_irq_desc button_irqs =

,,,,

,,};

/*開發板上按鍵的狀態變數,注意這裡是』0』,對應的ascii 碼為30*

/static volatile char key_values =

;/*因為本驅動是基於中斷方式的,在此建立乙個等待佇列,以配合中斷函式使用;當有按鍵按下並讀》取到鍵值時,將會喚醒此佇列,並設定中斷標誌,以便能通過 read 函式判斷和讀取鍵值傳遞到使用者》態;當沒有按鍵按下時,系統並不*//

*會輪詢按鍵狀態,以節省時鐘資源*

/static declare_wait_queue_head(button_waitq);/

*中斷標識變數,配合上面的佇列使用,中斷服務程式會把它設定為1,read 函式會把它清零*

/static volatile int ev_press = 0;

/*本按鍵驅動的中斷服務程式*

/static irqreturn_t buttons_interrupt(

int irq, void *dev_id)

return irq_retval(irq_handled);}

/**在應用程式執行open(「/dev/buttons」,…)時會呼叫到此函式,在這裡,它的作用主要是註冊6 個按

鍵的中斷。

*所用的中斷型別是irq_type_edge_both,也就是雙沿觸發,在上公升沿和下降沿均會產生中斷,這樣》做

**是為了更加有效地判斷按鍵狀態*/

static int s3c24xx_buttons_open(struct inode *inode, struct file *file)

/*註冊中斷函式*

/err

= request_irq(button_irqs[i]

.irq, buttons_interrupt, irq_type_edge_both,

button_irqs[i]

.name,

(void *

)&button_irqs[i]);

if(err)

break;}if

(err

)disable_irq(button_irqs[i]

.irq)

;free_irq(button_irqs[i]

.irq,

(void *

)&button_irqs[i]);

}return -ebusy;}/

*註冊成功,則中斷佇列標記為1,表示可以通過read 讀取*

/ev_press = 1;

/*正常返回*

/return 0;}/

**此函式對應應用程式的系統呼叫close(fd)函式,在此,它的主要作用是當關閉裝置時釋放6 個按鍵

的中斷*處理函式*/

static int s3c24xx_buttons_close(struct inode *inode, struct file *file)

/*釋放中斷號,並登出中斷處理函式*

/free_irq(button_irqs[i]

.irq,

(void *

)&button_irqs[i]);

}return 0;}/

**對應應用程式的read(fd,…)函式,主要用來向使用者空間傳遞鍵值*/

static int s3c24xx_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)

/*把中斷標識清零*

/ev_press = 0;

/*一組鍵值被傳遞到使用者空間*

/err

= copy_to_user(buff,

(const void *

)key_values, min(sizeof(key_values)

, count));

return err

?-efault : min(sizeof(key_values)

, count);}

static unsigned int s3c24xx_buttons_poll( struct file *file, struct poll_table_struct *wait)

/*裝置操作集*

/static struct file_operations dev_fops =

;static struct miscdevice misc =;/

*裝置初始化,主要是註冊裝置*

/static int __init dev_init(void)

/*登出裝置*

/static void __exit dev_exit(void)

module_init(dev_init);/

/模組初始化,僅當使用insmod/podprobe 命令載入時有用,如果裝置不是

通過模組方式載入,此處將不會被呼叫

module_exit(dev_exit);/

/解除安裝模組,當該裝置通過模組方式載入後,可以通過rmmod 命令解除安裝,將

呼叫此函式

module_license(

"gpl");

//版權資訊

module_author(

"friendlyarm inc.");

//作者名字

測試程式:

#include

#include

#include

#include

#include

#include

#include

#include select

.h>

#include time

.h>

#include

intmain(void)

;buttons_fd = open(

"/dev/buttons"

, 0);if

(buttons_fd < 0)

for(;;

)for

(i = 0, count_of_changed_key = 0; i < sizeof buttons / sizeof buttons[0]

; i++)

}if(count_of_changed_key)

}close(buttons_fd)

;return 0;

} 在開發板上執行測試程式,按不同的按鍵,串列埠輸出如下:

key 1 is down

key 1 is up

key 2 is down

key 2 is up

key 2 is down

key 2 is up

key 3 is down

key 3 is up

key 6 is down

key 6 is up

key 4 is down

key 4 is up

key 5 is down

key 5 is up

Linux GPIO中斷非同步通知

fasync機制是非同步通知機制,當驅動程式向應用程式傳送訊號量,觸發應用程式的訊號處理函式,以達到類似中斷的效果 驅動程式中 1 在檔案專屬的fasync函式中,呼叫了fasync helper,將屬主資訊通知給核心 2 當發生按鍵中斷,進入按鍵中斷服務程式,讀取鍵值,呼叫kill fasync,...

linux GPIO讀取以及中斷註冊

home uart ring gpx1 1 back sim det gpx1 2 switch3 ap sleep gpc0 3 switch4 xeint6 gpx0 6 步驟 申請gpio gpio request exynos4 gpx1 1 home 設定模式,輸入模式 s3c gpio ...

linux gpio子系統級聯中斷解析

linux 4.9 drivers pinctrl 中的gpio子系統中斷級聯解析 dts相關 中斷相關的device tree知識回顧 想要進行對映,首先要了解interrupt controller的拓撲結構。系統中的interrupt controller的拓撲結構以及其interrupt r...