Linux字符設備驅動開發——簡述按鍵中斷開發流程
博客說明
撰寫日期 | 2019.10.08 |
---|---|
完稿日期 | 2019.10.08 |
最近維護 | 暫無 |
本文作者 | multimicro |
聯繫方式 | [email protected] |
GitHub | https://github.com/wifialan |
本文地址 | https://blog.csdn.net/multimicro/article/details/102365730 |
開發環境
環境說明 | 詳細信息 | 備註信息 |
---|---|---|
與此篇博文開發環境相同 | 從Linux內核LED驅動來理解字符設備驅動開發流程 |
1. 寫在前面
前幾天剛整理完字符驅動的開發流程,詳情請參考從Linux內核LED驅動來理解字符設備驅動開發流程,本篇博文在此篇文章的基礎上開發了AD9833的驅動,是通過GPIO口模擬的SPI時序,此外增加了按鍵中斷控制切換AD9833的波形。本文簡述字符按鍵中斷開發流程。
按鍵中斷所需要的中斷API函數爲:
int gpio_to_irq(unsigned gpio);
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev);
void free_irq(unsigned int irq, void *dev_id);
void gpio_free(unsigned gpio);
還有需自己定義的中斷處理函數
static irqreturn_t ad9833_press_intHandle(int irq, void *dev_id);
2. 中斷開發
2.1 中斷配置——中斷註冊
如下圖所示,爲中斷的配置流程,此流程在驅動初始化時調用
這裏介紹一下request_irq
中斷註冊函數的各參數的意義,首先給出原型:
static inline int __must_check
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
const char *name, void *dev)
{
return request_threaded_irq(irq, handler, NULL, flags, name, dev);
}
- 第一個參數爲調用
gpio_to_irq
函數返回的irq值,即申請的硬件中斷號 - 第二個參數爲向系統登記的中斷處理函數,
- 第三個參數爲中斷處理的屬性,(本文這裏傳遞
IRQ_TYPE_EDGE_FALLING
,表示電平下降沿觸發中斷) - 第四各參數爲定義此中斷的名字,
- 第五個參數在中斷共享時會用到,一般設置爲這個設備的設備結構體或者NULL。
中斷服務函數示例如下,特別注意要加上irqreturn_t
標示
static irqreturn_t ad9833_press_intHandle(int irq, void *dev_id)
{
if( irq == ad9833_irq_desc.irq_sin) {
ad9833->set_wave_type(ad9833, SIN);
printk(DRV_NAME "\tSetting wave type SIN\n");
} else if (irq == ad9833_irq_desc.irq_tri) {
ad9833->set_wave_type(ad9833, TRI);
printk(DRV_NAME "\tSetting wave type TRI\n");
} else if(irq == ad9833_irq_desc.irq_squ) {
ad9833->set_wave_type(ad9833, SQU);
printk(DRV_NAME "\tSetting wave type SQU\n");
}
return IRQ_RETVAL(IRQ_HANDLED);
}
2.2 中斷配置——中斷註銷
如下圖所示,爲中斷註銷流程,此模塊在驅動卸載時調用
- 釋放中斷
void free_irq(unsigned int irq, void *dev_id);
- 第一個參數傳遞硬件中斷號,也就是
gpio_to_irq
函數返回的irq值 - 第二個參數傳遞
request_irq
函數中,最後一個位置的參數
- 釋放 GPIO port 的使用權
void gpio_free(unsigned gpio);
- 傳遞需要釋放的GPIO號