驅動中斷程式設計

2021-09-01 00:18:42 字數 3461 閱讀 3060

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驅動的編寫是就不...