Linux設備驅動程序之中斷與時鐘(二)

 
 

“小濤哥,快醒醒,快醒醒..”小王使勁推着睡夢中的我,“你不是說今天要講昨天有關的典型模板實例嗎…”

“啊?小姐啊,現在才早上8點,還讓人睡覺不,別吵”我一頭鑽進被子裏說。

“不管,誰讓你昨天不說完,還賣個小關子,害我昨天晚上都沒睡好,想了一晚上…”

我揉揉濛濛的眼說:“行,權當看在你渴求的心情上,但只此一次,下不爲例,我還想好好睡懶覺呢..”

昨天我們講了有關中斷方面的東西,鑑於小王你不太懂,我今天就專門拿出一章來說說前邊中斷的使用典型模版,你照抄也方便不是:

1)在中斷分類中,我們說到了有關向量中斷和非向量中斷,向量中斷就是入口地址不同,進不同的地址做不同的事。那非向量中斷則是進同一地址,至於區分就放在了進去後用條件判斷,請看下邊的模板:

irq_handler()
{
    ...
    int int_src = read_int_status();   //讀硬件的中斷相關寄存器
     switch(int_src)  //判斷中斷源case DEV_A:
           dev_a_handler();
           break;
      case DEV_B:
           dev_b_handler();
           break;
      ....
      default:
           break;
   }
}

2)在底半部機制中,我們講了tasklet,工作隊列和軟中斷先來看tasklet

tasklet使用模版:

void xxx_do_tasklet(unsigned long);
DECLARE_TASKLET(XXX_tasklet, xxx_do_tasklet, 0);
void xxx_do_tasklet(unsigned long)   //中斷處理底半部
{
    .....
}
irqreturn_t xxx_interrupt(int irq, void *dev_id, struct pt_regs *regs)  //中斷處理頂半部
{
  ...
  tasklet_schedule(&xxx_tasklet);
}
int __init xxx_init(void)   //設備驅動模塊加載函數
{
  ..
  result= request_irq(xxx_irq, xxx_interrupt, SA_INTERRUPT, "XXX",NULL);  //申請中斷
  ...
}
void __exit xxx_exit(void)   //設備驅動卸載模塊
{
  ..
  free_irq(xxx_irq, xxx_interrupt);   //釋放中斷
  ..
}
工作隊列模版:
struct work_struct xxx_wq;
void xxx_do_work(unsigned long);
void xxx_do_work(unsigned long)   //中斷處理底半部
{
    .....
}
irqreturn_t xxx_interrupt(int irq, void *dev_id, struct pt_regs *regs)  //中斷處理頂半部
{
  ...
  schedule_work(&xxx_wq);
}
int xxx_init(void)   //設備驅動模塊加載函數
{
  ..
  result= request_irq(xxx_irq, xxx_interrupt, SA_INTERRUPT, "XXX",NULL);  //申請中斷
  ...
  INIT_WORK(&xxx_wq, (void (*)(void *))xxx_do_work, NULL);
    ...
}
void __exit xxx_exit(void)   //設備驅動卸載模塊
{
  ..
  free_irq(xxx_irq, xxx_interrupt);   //釋放中斷
  ..
}

3)在上節最後我還給你講了有關中斷共享的東西吧,小王,也把模版給你:

irqreturn_t xxx_interrupt(int irq, void *dev_id, struct pt_regs *regs)  //中斷處理頂半部
{
  ...
  int status = read_int_status();  //獲取終端源
  if(!is_myint(dev_id, status))  //判斷是否是本設備的中斷
  {
     return  IRQ_NONE://立即返回
  }
  ..
  return IRQ_HANDLED;
}
int __init xxx_init(void)   //設備驅動模塊加載函數
{
  ..
  result= request_irq(xxx_irq, xxx_interrupt, SA_SHIRQ, "XXX",xxx_dev);  //申請共享中斷
  ...
}
void __exit xxx_exit(void)   //設備驅動卸載模塊
{
  ..
  free_irq(xxx_irq, xxx_interrupt);   //釋放中斷
  ..
}

共享中斷中,我們仔細看一下其實也沒什麼,不是。就是在和前邊中斷中要修改一下中斷標誌,在中斷處理中判斷一下是否是自己本地的中斷,這個我都用紅色的標識出來了。

 

“小王,看,小濤哥說話算數吧,上邊給出了所有模版,結合前一篇,相信你可以看的很順利的。好了,我要補補剛的覺了,中間不許叫我哈,想我也不行”我打打哈欠說。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章