国产一级一区二区_segui88久久综合9999_97久久夜色精品国产_欧美色网一区二区

掃一掃
關注微信公眾號

深入淺出 Linux設備驅動中斷處理介紹
2007-07-28   網絡

與Linux設備驅動中中斷處理相關的首先是申請與釋放IRQ的API: request_irq()和free_irq()。

request_irq()的原型為:

int request_irq(unsigned int irq,
void (*handler)(int irq, void *dev_id, struct pt_regs *regs),
unsigned long irqflags,
const char * devname,
                        void *dev_id);

irq是要申請的硬件中斷號;

handler是向系統登記的中斷處理函數,是一個回調函數,中斷發生時,系統調用這個函數,dev_id參數將被傳遞;

irqflags是中斷處理的屬性,若設置SA_INTERRUPT,標明中斷處理程序是快速處理程序,快速處理程序被調用時屏蔽所有中斷,慢速處理程序不屏蔽;若設置SA_SHIRQ,則多個設備共享中斷,dev_id在中斷共享時會用到,一般設置為這個設備的device結構本身或者NULL。

free_irq()的原型為:

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

另外,與Linux中斷息息相關的一個重要概念是Linux中斷分為兩個半部:上半部(tophalf)和下半部(bottom half)。上半部的功能是"登記中斷",當一個中斷發生時,它進行相應地硬件讀寫后就把中斷例程的下半部掛到該設備的下半部執行隊列中去。因此,上半部執行的速度就會很快,可以服務更多的中斷請求。但是,僅有"登記中斷"是遠遠不夠的,因為中斷的事件可能很復雜。因此,Linux引入了一個下半部,來完成中斷事件的絕大多數使命。下半部和上半部最大的不同是下半部是可中斷的,而上半部是不可中斷的,下半部幾乎做了中斷處理程序所有的事情,而且可以被新的中斷打斷!下半部則相對來說并不是非常緊急的,通常還是比較耗時的,因此由系統自行安排運行時機,不在中斷服務上下文中執行。

Linux實現下半部的機制主要有tasklet和工作隊列。

tasklet基于Linux softirq,其使用相當簡單,我們只需要定義tasklet及其處理函數并將二者關聯:

void my_tasklet_func(unsigned long); //定義一個處理函數:

DECLARE_TASKLET(my_tasklet,my_tasklet_func,data); //定義一個tasklet結構my_tasklet,與my_tasklet_func(data)函數相關聯

然后,在需要調度tasklet的時候引用一個簡單的API就能使系統在適當的時候進行調度運行:

tasklet_schedule(&my_tasklet);

此外,Linux還提供了另外一些其它的控制tasklet調度與運行的API:

DECLARE_TASKLET_DISABLED(name,function,data); //與DECLARE_TASKLET類似,但等待tasklet被使能 tasklet_enable(struct tasklet_struct *); //使能tasklet tasklet_disble(struct tasklet_struct *); //禁用tasklet tasklet_init(struct tasklet_struct *,void (*func)(unsigned long),unsigned long); //類似DECLARE_TASKLET() tasklet_kill(struct tasklet_struct *); // 清除指定tasklet的可調度位,即不允許調度該tasklet

我們先來看一個tasklet的運行實例,這個實例沒有任何實際意義,僅僅為了演示。它的功能是:在globalvar被寫入一次后,就調度一個tasklet,函數中輸出"tasklet is executing":

#include <linux/interrupt.h> … //定義與綁定tasklet函數 void test_tasklet_action(unsigned long t); DECLARE_TASKLET(test_tasklet, test_tasklet_action, 0); void test_tasklet_action(unsigned long t) {  printk("tasklet is executing\n"); } … ssize_t globalvar_write(struct file *filp, const char *buf, size_t len, loff_t *off) {  …  if (copy_from_user(&global_var, buf, sizeof(int)))  {   return - EFAULT;  }  //調度tasklet執行 tasklet_schedule(&test_tasklet);  return sizeof(int); }

由于中斷與真實的硬件息息相關,脫離硬件而空談中斷是毫無意義的,我們還是來舉一個簡單的例子。這個例子來源于SAMSUNG S3C2410嵌入式系統實例,看看其中實時鐘的驅動中與中斷相關的部分:

static struct fasync_struct *rtc_async_queue;
static int __init rtc_init(void)
{
 misc_register(&rtc_dev);
 create_proc_read_entry("driver/rtc", 0, 0, rtc_read_proc, NULL);
 #if RTC_IRQ
  if (rtc_has_irq == 0)
   goto no_irq2;
  init_timer(&rtc_irq_timer);
  rtc_irq_timer.function = rtc_dropped_irq;
  spin_lock_irq(&rtc_lock);
  /* Initialize periodic freq. to CMOS reset default, which is 1024Hz */
  CMOS_WRITE(((CMOS_READ(RTC_FREQ_SELECT) &0xF0) | 0x06), RTC_FREQ_SELECT);
  spin_unlock_irq(&rtc_lock);
  rtc_freq = 1024;
  no_irq2:
 #endif
 printk(KERN_INFO "Real Time Clock Driver v" RTC_VERSION "\n");
 return 0;
}
static void __exit rtc_exit(void)
{
 remove_proc_entry("driver/rtc", NULL);
 misc_deregister(&rtc_dev);
 release_region(RTC_PORT(0), RTC_IO_EXTENT);
 if (rtc_has_irq)
  free_irq(RTC_IRQ, NULL);
}
static void rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
 /*
 * Can be an alarm interrupt, update complete interrupt,
 * or a periodic interrupt. We store the status in the
 * low byte and the number of interrupts received since
 * the last read in the remainder of rtc_irq_data.
 */
 spin_lock(&rtc_lock);
 rtc_irq_data += 0x100;
 rtc_irq_data &= ~0xff;
 rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) &0xF0);
 if (rtc_status &RTC_TIMER_ON)
  mod_timer(&rtc_irq_timer, jiffies + HZ / rtc_freq + 2 * HZ / 100);
 spin_unlock(&rtc_lock);
 /* Now do the rest of the actions */
 wake_up_interruptible(&rtc_wait);
 kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
}
static int rtc_fasync (int fd, struct file *filp, int on)
{
 return fasync_helper (fd, filp, on, &rtc_async_queue);
}
static void rtc_dropped_irq(unsigned long data)
{
 unsigned long freq;
 spin_lock_irq(&rtc_lock);
 /* Just in case someone disabled the timer from behind our back... */
 if (rtc_status &RTC_TIMER_ON)
  mod_timer(&rtc_irq_timer, jiffies + HZ / rtc_freq + 2 * HZ / 100);
 rtc_irq_data += ((rtc_freq / HZ) << 8);
 rtc_irq_data &= ~0xff;
 rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) &0xF0); /* restart */
 freq = rtc_freq;
 spin_unlock_irq(&rtc_lock);
 printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n", freq);
 /* Now we have new data */
 wake_up_interruptible(&rtc_wait);
 kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
                        }

RTC中斷發生后,激發了一個異步信號,因此本驅動程序提供了對第6節異步信號的支持。并不是每個中斷都需要一個下半部,如果本身要處理的事情并不復雜,可能只有一個上半部,本例中的RTC驅動就是如此。

熱詞搜索:

上一篇:Ubuntu Linux操作系統中自帶的程序介紹
下一篇:深入淺出 Linux設備驅動異步通知介紹

分享到: 收藏
国产一级一区二区_segui88久久综合9999_97久久夜色精品国产_欧美色网一区二区
亚洲国产精品国自产拍av| 免费观看一级特黄欧美大片| 国产ts人妖一区二区| 成人精品在线视频观看| 美女被吸乳得到大胸91| 有坂深雪av一区二区精品| 亚洲人精品午夜| 亚洲电影视频在线| 欧美顶级少妇做爰| 久久99国产精品麻豆| 久久久夜色精品亚洲| 99精品国产91久久久久久| 亚洲乱码日产精品bd| 欧美日本一区二区| 久久精品国产色蜜蜜麻豆| 国产亚洲人成网站| 99久久精品免费看| 亚洲一区中文在线| 精品乱人伦小说| 97久久精品人人做人人爽50路| 亚洲美腿欧美偷拍| 欧美刺激午夜性久久久久久久 | 国产精品亚洲午夜一区二区三区 | 日韩成人免费在线| 精品国产免费视频| 91丨国产丨九色丨pron| 日韩—二三区免费观看av| 国产午夜精品在线观看| 欧美在线观看视频在线| 国产真实乱偷精品视频免| 亚洲美女区一区| 久久午夜电影网| 精品视频在线免费观看| 国产福利91精品一区| 亚洲一区二区三区自拍| 久久久久久久一区| 9191成人精品久久| 91在线国产观看| 国产老女人精品毛片久久| 天天操天天综合网| 国产精品国产三级国产普通话蜜臀 | 日韩avvvv在线播放| 欧美性xxxxx极品少妇| 日韩中文字幕亚洲一区二区va在线 | 色婷婷久久综合| 国产在线视视频有精品| 亚洲va韩国va欧美va精品| 国产精品久久久久aaaa樱花 | 欧洲国产伦久久久久久久| 国产伦精品一区二区三区免费迷| 午夜影院在线观看欧美| 成人免费在线视频观看| 久久久久久久久97黄色工厂| 欧美日韩高清影院| 欧美主播一区二区三区美女| jlzzjlzz欧美大全| 国产一区高清在线| 蜜桃视频一区二区三区在线观看| 亚洲福利电影网| 亚洲美女精品一区| 中文字幕在线一区| 国产人妖乱国产精品人妖| 日韩精品一区二区三区中文精品| 欧美日韩国产成人在线91| 欧洲人成人精品| 日本大香伊一区二区三区| av亚洲精华国产精华| 丁香啪啪综合成人亚洲小说| 国产精品白丝jk白祙喷水网站| 麻豆精品一区二区三区| 男女视频一区二区| 日韩激情视频在线观看| 亚洲成人av一区二区| 亚洲一卡二卡三卡四卡无卡久久| 亚洲美女视频在线| 一区二区三区国产精品| 亚洲精品免费在线播放| 亚洲精品视频在线看| 日韩码欧中文字| 亚洲男人的天堂av| 亚洲欧美激情在线| 亚洲国产日韩一区二区| 同产精品九九九| 热久久免费视频| 久久国产精品72免费观看| 国产在线观看一区二区| 国产成人精品亚洲日本在线桃色| 成人午夜电影网站| 色猫猫国产区一区二在线视频| 日本黄色一区二区| 3d动漫精品啪啪1区2区免费| 日韩精品一区二区三区视频播放| 精品欧美乱码久久久久久1区2区| 久久蜜桃香蕉精品一区二区三区| 国产精品素人视频| 最近中文字幕一区二区三区| 有码一区二区三区| 人人精品人人爱| 国产mv日韩mv欧美| 欧美主播一区二区三区美女| 欧美美女激情18p| 亚洲精品一区二区三区蜜桃下载| 国产欧美日韩另类视频免费观看| 亚洲理论在线观看| 日韩高清一区二区| 国产成人av在线影院| 在线视频一区二区免费| 欧美一级精品在线| 一区二区三区免费网站| 青青草一区二区三区| 国产福利精品一区| 欧美日韩一本到| 精品国产伦一区二区三区免费| 《视频一区视频二区| 亚洲mv在线观看| 国产精品一二三在| 欧美亚洲国产一区二区三区va| 日韩午夜在线影院| 亚洲精品日韩综合观看成人91| 日本美女视频一区二区| 成人午夜精品在线| 日韩视频123| 亚洲欧美日韩在线播放| 美女看a上一区| 一本到不卡免费一区二区| 精品成人在线观看| 亚洲国产日韩av| 粉嫩高潮美女一区二区三区| 717成人午夜免费福利电影| 国产精品美女久久久久久2018| 日韩精品91亚洲二区在线观看| a在线欧美一区| 久久亚洲综合av| 五月婷婷激情综合| av在线播放成人| 国产日韩亚洲欧美综合| 日本视频一区二区| 欧美日韩在线播放三区四区| 国产精品天天摸av网| 国产一区二区伦理片| 欧美高清视频www夜色资源网| 亚洲美女一区二区三区| www.亚洲在线| 国产精品成人免费| 国产酒店精品激情| 婷婷开心久久网| 久久成人综合网| 91精品婷婷国产综合久久| 亚洲精品少妇30p| 成人av动漫在线| 国产日韩精品一区二区三区| 理论电影国产精品| 欧美精品久久99| 天天影视涩香欲综合网| 欧美色图天堂网| 亚洲综合在线电影| 色综合天天性综合| 亚洲欧美另类在线| 一道本成人在线| 玉足女爽爽91| 日韩欧美中文一区二区| 亚洲一二三四久久| 色丁香久综合在线久综合在线观看| 国产欧美精品国产国产专区| 国产呦萝稀缺另类资源| 精品国产髙清在线看国产毛片 | 亚洲va韩国va欧美va| 欧美色视频在线| 亚洲成人动漫一区| 91精品国产品国语在线不卡 | 麻豆一区二区三区| 欧美成人vps| 精品一区免费av| 久久久久国产精品人| 国产一区二区三区在线观看免费视频| www精品美女久久久tv| 国产乱淫av一区二区三区| 久久免费偷拍视频| k8久久久一区二区三区| 亚洲欧美一区二区三区久本道91| 色婷婷av一区二区三区之一色屋| 一区二区三区在线视频观看 | 久久久亚洲国产美女国产盗摄| 国产一区二区网址| 国产精品久久久久久久久免费桃花| www.成人在线| 亚洲制服丝袜在线| 日韩女优av电影| 丁香桃色午夜亚洲一区二区三区| 成人欧美一区二区三区小说| 欧美性大战久久久久久久| 久久精品久久精品| 国产精品嫩草久久久久| 欧美亚洲一区二区在线| 奇米精品一区二区三区四区| 国产精品视频yy9299一区| 欧美亚洲高清一区二区三区不卡| 麻豆国产欧美日韩综合精品二区| 国产午夜精品一区二区| 91福利在线看|