1.編寫乙個外部中斷
1.獲取外部中斷編號
int gpio_to_irq(unsigned int gpio)
功能:通過io口編號轉換成對應的外部中斷編號
引數:gpio 要獲取的io口編號
返回值:成功:中斷編號; 失敗:- einval
2.註冊中斷函式
int request_irq(unsigned int irq,irq_handler_t handler, unsigned long flags, const char *name,void *dev_id);
功能:向核心註冊乙個中斷服務函式,當發生中斷號為 irq 的中斷時候,會執行 handler 指標函式。
引數:
irq:中斷編號(每個中斷源有惟一的編號),這裡的中斷不是看硬體手冊,這一點和裸機程式設計不同。
handler:中斷服務函式指標。 原型 typedef irqreturn_t (*irq_handler_t)(int, void *)。
flags:中斷屬性,如快速中斷,共享中斷,如果是外部分中斷還有:上公升沿,下降沿觸發中斷這類標誌。
flags
16進製制
意義#define irqf_trigger_none
0x00000000
沒有設定觸發邊沿
#define irqf_trigger_rising
0x00000001
設定觸發邊沿為上公升沿
#define irqf_trigger_falling
0x00000002
設定觸發邊沿為下降沿
#define irqf_trigger_high
0x00000004
設定觸發方式 為高電平
#define irqf_trigger_low
0x00000008
設定觸發方式 為低電平
#define irqf_trigger_probe
0x00000010
快速中斷標誌
#define irqf_disabled
0x00000020
指明該中斷是獨佔中斷,只能註冊一次
#define irqf_shared
0x00000080
指明該中斷是共享中斷,可以註冊多次
name:中斷名字, 註冊後會出現/proc/irq/irq號/name資料夾出現。
dev_id: 這個引數是傳遞給中斷服務函式。對共享中斷來說, 這個引數一定有要,當登出共享中斷中的其中乙個時, 用這個來標識要登出哪乙個。 對於有惟一入口的中斷,可以傳遞 null,但是一般來說都會傳遞乙個有意義指標,在中斷程式中使用,以方便程式設計。
返回值:
0 表示成功
-einval (無效引數22)表示中斷號無效。
-ebusy (裝置或者資源忙16)表示中斷已經被占用。
3.登出中斷函式
void free_irq(unsigned int irq,void * dev_id)
功能:從核心中斷鍊錶上刪除乙個中斷結構
引數:irq:中斷編號
dev_id: 要和註冊中斷函式的最後乙個引數 dev_id 相同
4.使能中斷函式
void enable_irq(unsigned int irq);
引數:irq,要使能的中斷對應的編號;
說明:5.禁止中斷函式
void disable_irq_nosync(unsigned int irq);
void disable_irq(unsigned int irq);
引數:
irq,要禁止的中斷對應的編號。
注意:在中斷服務程式中不能使用 disable_irq 這個函式,否則核心崩潰,可以使用 disable_irq_nosync。
disable_irq:函式呼叫後,函式不會馬上返回,而等待中斷程式執行完成才返回,在中斷呼叫會導致死鎖。
disable_irq_nosync:呼叫後,函式馬上返回
#include #include #include #include #include #include #include //按鍵數量
#define btn_size 4鍵緩衝區,'0'表示沒有按鍵,'1'表示按下了
static char keybuf = ;
/*把乙個當成乙個物件來看待,方便程式設計,定義乙個描述按鍵結構*/
struct button_desc ;
/* 定義4個按鍵的資訊 */
static struct button_desc buttons = ,,,
,};//中斷服務函式
irqreturn_t key_isr(int irq, void* dev)
static ssize_t tiny4412_read (struct file *flp, char __user *buff,size_t count, loff_t * off)
//修正引數
if(count > btn_size )
//複製資料到使用者空間
ret = copy_to_user(buff, keybuf, count);
if(ret)
return count;
}static const struct file_operations dev_fops = ;
#define leds_major 255 //255
#define device_name "mybtn"
static struct miscdevice misc = ;
static int __init btn_init(void)
}//如果不是全部成功,則反向登出已經註冊的中斷
if(ret < 0)
return ret;
}//註冊雜項裝置
ret = misc_register(&misc); //註冊混雜裝置
return ret;
}static void __exit btn_exit(void)
//登出雜項裝置
misc_deregister(&misc);
printk(kern_emerg "goodbye,cruel world!, priority = 0\n");
}module_init(btn_init);
module_exit(btn_exit);
module_license("gpl");
module_author("jian");
module_description("button");
裝置驅動 中斷
1 關於裝置驅動中的中斷問題 作業系統為了使得快速裝置和慢速裝置合適工作,需要中斷來提高效率,乙個外設要使用乙個中斷就必須註冊中斷號,獲得跟這個中斷號相關的一些資源,並且在中斷發生的時候核心可以進行一些處理,例如 呼叫中斷處理例程來真正的處理裝置中斷。linux處理中斷的方式很大程度上與它在使用者空...
驅動互斥中斷
互斥機制 1 遮蔽中斷 2 原子操作 定義原子變數 atomic t v 初始化 atomic t v atomic init 0 操作atomic t v atomic init 1 open else release 自旋鎖使用 自旋鎖是忙鎖 系統開銷較大,為了減小系統開銷,需要減少等待時間而減...
UIO 驅動中斷
uio 是怎麼工作的?乙個裝置驅動的主要任務有兩個 1.訪問裝置的記憶體 2.處理裝置產生的中斷 對於第乙個任務,uio 核心實現了mmap 可以處理物理記憶體 physical memory 邏輯記憶體 logical memory 虛擬記憶體 virtual memory uio驅動的編寫是就不...