linux裝置驅動的中斷與並發請求事件__linux

來源:互聯網
上載者:User

 

 


   裝置驅動的中斷事件處理如下圖所示,他與普通驅動的不同之處在於多了個資料緩衝區,驅動程式對上層提供的read/write方法並不直接完成硬體的資料操作,中斷處理常式也是相對獨立,他們通過緩衝區交換資料。而資料緩衝區的資料可通過FIFO進行讀和寫的操作,但每次只能進行讀或者寫的操作,兩者不可同時進行,這就又涉及到了並發請求。並發請求類似訊號量中的PV操作,對資料緩衝區的讀寫就相當於之前的生產者和消費者到倉庫的存取。

中斷事件涉及的函數

       標頭檔

#include <asm/irq.h>

申請中斷函數,成功返回0

int request_irq(unsigned int irq,

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

                unsigned long irqflag,

                const char *devname, void *dev_id);

//irq:中斷號

// irqflag:

//    SA_INTERRUPT,快速中斷,執行handler函數時不能被打斷

//    SA_SHIRQ,共用中斷, ,執行handler函數時能被打斷

//    SA_SAMPLE_RANDOM,中斷可能被用來產生隨機數

// dev_id: 在共用中斷時用於區分不同的中斷處理常式

// devname:中斷裝置名稱,在中斷下運行cat /dev/interrupt 可查看到

釋放中斷函數

void free_irq(unsigned int irq, void *dev_id);

       #include <asm/irq.h>

使能中斷函數

void enable_irq(unsigned int irq);

禁止中斷函數

void disable_irq(unsigned int irq);

S3C2410使能GPIO的外部中斷功能

int set_external_irq(int irq, int edge, int pullup);

// edge:

//    EXT_LOWLEVEL,

//    EXT_HIGHLEVEL,

//    EXT_FALLING_EDGE,

//    EXT_RISING_EDGE,

//    EXT_BOTH_EDGES

中斷處理常式樣本

void handler(int irq, void *dev_id, struct pt_regs *regs)

{

    // 中斷處理

}

在初始化時申請並初始化中斷

set_external_irq(IRQ_EINT0, EXT_FALLING_EDGE, 0);

request_irq(IRQ_EINT0,handler,SA_INTERRUPT,"KEY",NULL);

注意:要把使能外部中斷函數set_external_irq放在插斷要求函數request_irq之前,否則,會有小麻煩。

並發請求涉及的函數

使用訊號量控制並發請求

#include <asm/semaphore.h>

定義訊號量變數

struct semaphore bufflock;

初始化訊號量

void sema_init(struct semaphore *sem, int);

擷取(等待)訊號量(不可打斷)(相當於V操作)

void down(struct semaphore *sem);

擷取(等待)訊號量(可被打斷)

int down_interruptible(struct semaphore *sem);

釋放訊號量(相當於P操作)

void up(struct semaphore *sem);

       FIFO隊列

       由於隊列具有先進先出的功能,所以它能符合充當資料緩衝區的功能。我們可以自己寫一個FIFO函數實現讀和寫的功能,也可調用/kernel/kernel/fifo.c 的函數。如果要調用/kernel/kernel/fifo.c,編譯時間要注意,可用命令進行:/usr/local/arm/2.95.3/bin/arm-linux-gcc -c -o kfifo.o kfifo.c -I/home/su/kernel/include -D__KERNEL__ -DMODULE -DEXPORT_SYMTAB –DMODVERSIONS。當我們完成編譯後,要先載入kfifo.o,再載入我們自己寫的驅動,否則會出錯。以下以調用/kernel/kernel/fifo.c為例。

       #include <linux/kfifo.h>

首先需要定義一個自旋鎖,該鎖由kfifo維護,我們只需要定義它即可

static spinlock_t buffer_lock = SPIN_LOCK_UNLOCKED;

然後定義一個kfifo指標, 注意, 這裡定義指標即可,不用分配空間

static struct kfifo *buffer;

使用kfifo_alloc可以建立一個BUFFER_SIZE大小的fifo, 所有空間由kfifo自動分配

#define BUFFER_SIZE         256

buffer = kfifo_alloc(BUFFER_SIZE, GFP_KERNEL, &buffer_lock);

使用kfifo_put可以將資料放入kfifo內

kfifo_put(buffer, &key, sizeof(key));

使用kfifo_len可以檢查fifo內的可用資料

if(kfifo_len(buffer) >= sizeof(key))

使用kfifo_get可以從fifo內取出資料

kfifo_get(buffer, &key, sizeof(key));

最後退出時,釋放buffer的記憶體空間

kfifo_free(buffer);

 

附:基於淩陽SPCE3200實驗箱的4x4鍵盤的驅動(中斷法實現)原始碼

這裡有兩個需要注意的地方:

1、標頭檔的擺放順序:#include <linux/kfifo.h>要放在 #include <asm/irq.h>之後,否則編譯出錯,因為asm/irq.h 裡面定義了一些linux/kfifo.h 要用到的宏,若先寫#include <linux/kfifo.h> ,載入驅動時,編譯器會把裡頭的宏當成函數處理,但又找不到相應的函數,所以出錯。這樣的標頭檔出錯,出錯非常隱蔽,解決的辦法唯有一步一步跟錯尋找。

2、該驅動的等待訊號量函數應使用可打斷類型的int down_interruptible(struct semaphore *sem),否則運行應用程式時,按下ctrl+c程式沒法正常退出,還需按下實驗箱上的任意一個按鍵。因為該中斷是可被打斷類型的,所以能接受響應外部的另外的中斷,即能退出程式。

 

#ifndef __KERNEL__

#define __KERNEL__

#endif

#ifndef MODULE

       #define MODULE

#endif

 

#include <linux/config.h>

#include <linux/module.h>

#include <linux/kernel.h>      /* printk() */

#include <linux/init.h>    /* __init __exit */

#include <linux/types.h>       /* size_t */

#include <linux/fs.h>     /* file_operation */

//#include <linux/errno.h>     /* Error number */

#include <linux/delay.h> /* udelay */

#include <linux/timer.h>

#include <asm/uaccess.h>     /* copy_to_user, copy_from_user */

#include <asm/hardware.h>

#include <asm/semaphore.h>

#include <asm/irq.h>

#include <asm/arch/S3C2410.h>

#include <linux/kfifo.h>

 

#define DRIVER_NAME       "key"

 

#ifdef DEBUG

#define PRINTK(fmt, arg...)        printk(KERN_NOTICE fmt, ##arg)

#else

#define PRINTK(fmt, arg...)

#endif

 

#define BUFFER_SIZE         256

 

static int keyDriver_Major = 0;            /* Driver Major Number */

static int keyNum;

struct semaphore bufflock;

static spinlock_t buffer_lock = SPIN_LOCK_UNLOCKED;

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.