**
先說明一下按鍵與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...