Linux裝置中斷程式編寫

2021-05-23 09:17:02 字數 3351 閱讀 2318

一. 幾個要點知識:

1. 睡眠

安全睡眠的要點:

<1> 當你執行在原子上下文時不能睡眠;

<2> 醒後必須通過檢查來確你在等待的條件;

<3> 睡眠必須對應乙個喚醒。

《注》: **針對於2.6的核心

等待佇列:   declare_wait_queue_head(name);

睡眠函式:   wait_event_interruptible

(queue, condition)

(它可能被訊號中斷. 這個版本返回乙個你應當檢查的整數值; 乙個非零值意味著你的睡眠被某些訊號打斷, 並且你的驅動可能當

返回 -erestartsys.)

喚醒函式:  void wake_up_interruptible(wait_queue_head_t *queue);

2. poll, select

獲取裝置驅動的支援:  unsigned int (*poll) (struct file *filp, poll_table *wait);

<1>  在乙個或多個可指示查詢狀態變化的等待佇列上呼叫poll_wait

void poll_wait (struct file *, wait_queue_head_t *, poll_table *)

<2>  返回乙個位掩碼, 描述可能不必阻塞就立刻進行的操作.標誌參見

3. 中斷

中斷註冊函式: int request_irq(unsigned int irq,

irqreturn_t (*handler)(int, void *, struct pt_regs *),

unsigned long flags,

const char *dev_name,

void *dev_id);

中斷釋放函式: void free_irq(unsigned int irq, void *dev_id);

request_irq 返回給請求函式的返回值或者是 0 指示成功, 或者是乙個負的錯誤碼, 如同平常. 函式返回 -ebusy 來指示另乙個驅

動已經使用請求的中斷線是不尋常的. 函式的引數如下:

unsigned int irq            請求的中斷號

irqreturn_t (*handler)  安裝的處理函式指標

unsigned long flags      如你會希望的, 乙個與中斷管理相關的選項的位掩碼(後面描述).

const char *dev_name 這個傳遞給 request_irq 的字串用在 /proc/interrupts 來顯示中斷的擁有者

void *dev_id                 用作共享中斷線的指標. 它是乙個獨特的標識, 用在當釋放中斷線時以及可能還被驅動用來指向它自己的私有

資料區(來標識哪個裝置在中斷).如果中斷沒有被共享, dev_id 可以設定為 null。

呼叫 request_irq 的正確位置是當裝置第一次開啟時, 在硬體被指示來產生中斷前.

呼叫 free_irq 的位置是裝置最後一次被關閉時, 在硬體被告知不要再中斷處理器之後.

中斷處理函式: irqreturn_t short_interrupt(int irq, void *dev_id, struct pt_regs *regs)

struct pt_regs *regs, 很少用到

二. tq2440 irq **分析

1.驅動**(不完整)

天嵌提供的例項**並不複雜,但作為乙個例程是非常合適的,**具體的給出了如何註冊,處理,釋放中斷。

/*必要的標頭檔案,我只列出中斷相關的*/

....

#include

#include

#include

#include

....

#define  device_name   "embedsky_buttons"

#define  button_major  232                                  //裝置號用自動獲取方式更好!

/*等待佇列*/

static declare_wait_queue_head(button_waitq);

/*中斷flag, 中斷處理函式置1,read函式清0 */

static volatile int ev_press = 0;

/* 按鈕被按下的回數(準確地說,是發生中斷的回數) */

static volatile int press_cnt = ;

static struct class *button_class;

/*中斷資訊結構,這個結構的設計很不錯*/

struct button_irqs_desc ;

static struct button_irqs_desc button_irqs = ,

, ,,

};/*中斷處理函式*/ 

static irqreturn_t buttons_interrupt(int irq,void *dev_id)

static int tq2440_buttons_open(struct inode *inode,structfile *file)

if(err)

return 0;}

static int tq2440_buttons_close(struct inode *inode,structfile *file)

return 0;

}static int tq2440_buttons_read(struct file *filp,char__user *buff,size_t count,loff_t *offp)

ev_press = 0;

err = copy_to_user(buff,(const void*)press_cnt,min(sizeof(press_cnt),count));

memset((void *)press_cnt,0,sizeof(press_cnt));

return err? -efault:0;}

static unsigned int embedsky_buttons_poll(struct file *filp, poll_table *wait)

static struct file_operations tq2440_buttons_fops = ;

static int __init tq2440_buttons_init(void)

static void __exit tq2440_buttons_exit(void)

module_init(tq2440_buttons_init);

module_exit(tq2440_buttons_exit)

LINUX 基於裝置樹編寫按鍵中斷驅動程式

linux核心版本 4.14.2 1.在原理圖中確定home按鍵的引腳 2.在裝置樹檔案中新增節點描述home引腳 3.重新編譯燒寫裝置樹 4.編寫驅動程式,呼叫裝置樹介面函式獲取home引腳的中斷號,使用中斷號註冊按鍵中斷處理程式 在原理圖中確定home按鍵的引腳 在原理圖中找到home按鍵對應的...

linux驅動學習 linux中斷程式編寫流程

linux中斷 1 確定中斷號 2 申請中斷號 request irq 不用一定要釋放free irq 3 編寫中斷服務函式 request irq unsigned int irq,irq handler t handler,unsigned long flags,const char name,...

編寫Linux裝置驅動程式教程

序言 linux是unix作業系統的一種變種,在linux下編寫驅動程式的原理和思想完全類似於其他的unix系統,但它dos或window環境下的驅動程式有很大的區別。在linux環境下設計驅動程式,思想簡潔,操作方便,功能也很強大,但是支援函式少,只能依賴kernel中的函式,有些常用的操作要自己...