日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

[arm驱动]linux内核中断编程

發(fā)布時間:2023/11/29 linux 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [arm驱动]linux内核中断编程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

第一部分獲取中斷(開啟硬件中斷)
一、中斷的申請注銷:
1)中斷的申請

1 2 int?request_irq(unsigned?int?irq, irq_handler_t handler, ?????????????????????????unsigned?long?irqflags,?const?char?*devname,?void?*dev_id)

2)中斷的注銷

1 void?free_irq(unsigned?int?irq,?void?*dev_id)

3)中斷處理函數(shù)

1 static?irqreturn_t irq_handle(int?irq,?void?*dev__id);

? ?參數(shù):irq:表示中斷號,這個參數(shù)還保留由于歷史遺留問題,往后可能越來越?jīng)]用了。由于第二個參數(shù)信息更強(qiáng)大
dev__id:就是request_irq()中void *dev_id參數(shù)
二、中斷申請函數(shù)參數(shù)

1 2 int?request_irq(unsigned?int?irq, irq_handler_t handler, ?????????????????????????unsigned?long?irqflags,?const?char?*devname,?void?*dev_id)

? ?1)參數(shù):
? ?irq:是要申請的硬件中斷號。
handler:是向系統(tǒng)注冊的中斷處理函數(shù),是一個回調(diào)函數(shù),中斷發(fā)生時,系統(tǒng)調(diào)用這個函數(shù),dev_id參數(shù)將被傳遞給它
? ? irqflags:是中斷處理的屬性,
? ? ? ?a)若設(shè)置了IRQF_DISABLED,則表示中斷處理程序是快速處理程序,快速處理程序被調(diào)用時屏蔽所有中斷,慢速處理程序不屏蔽;
? ? ? ?b)若設(shè)置了 ? ?IRQF_SHARED,則表示多個設(shè)備共享中斷;//在另一篇文章會提到
? ? ? ?c)若設(shè)置了IRQF_SAMPLE_RANDOM,表示對系統(tǒng)熵有貢獻(xiàn),對系統(tǒng)獲取隨機(jī)數(shù)有好處。
? ? ? ? ? ?Tip:(flag是可以通過或的方式同時使用的
? ?devname:設(shè)置中斷名稱,通常是設(shè)備驅(qū)動程序的名稱 ?在cat /proc/interrupts中可以看到此名稱。
? ?dev_id:在中斷共享時會用到,一般設(shè)置為這個設(shè)備的設(shè)備結(jié)構(gòu)體或者不使用時為NULL。因?yàn)樵诠蚕碇袛嘀型粋€中斷線(或可以說同一個中斷號)可能掛載好幾個設(shè)備,當(dāng)使用void free_irq(unsigned int irq, void *dev_id)時,根據(jù)irq和dev_id可以找到中斷線為irq上的標(biāo)識為dev_id的某個具體設(shè)備。dev_id也經(jīng)常在不是共享中斷中的驅(qū)動傳遞數(shù)據(jù)

? ?2)返回值:
? ?a)request_irq()返回0表示成功;
? ?b)返回-EINVAL表示無效的參數(shù),如果返回這個值,應(yīng)該看看傳遞給request_irq()的參數(shù)是否正確;
? ?c)返回-EBUSY表示中斷已經(jīng)被占用且不能共享;
? ?d)返回ENOMEM表示內(nèi)存不足。嵌入式系統(tǒng)由于內(nèi)存資源有限,經(jīng)常會發(fā)生這樣的錯誤。

? ?3)擴(kuò)展---unsigned long irqflags值
? ?在include\linux\interrupt.h中

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 /* ?* These correspond to the IORESOURCE_IRQ_* defines in ?* linux/ioport.h to select the interrupt line behaviour.? When ?* requesting an interrupt without specifying a IRQF_TRIGGER, the ?* setting should be assumed to be "as already configured", which ?* may be as per machine or firmware initialisation. ?*/ #define IRQF_TRIGGER_NONE??? 0x00000000 #define IRQF_TRIGGER_RISING??? 0x00000001 #define IRQF_TRIGGER_FALLING??? 0x00000002 #define IRQF_TRIGGER_HIGH??? 0x00000004 #define IRQF_TRIGGER_LOW??? 0x00000008 #define IRQF_TRIGGER_MASK??? (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW | \ ?????????????????IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING) #define IRQF_TRIGGER_PROBE??? 0x00000010 /* ?* These flags used only by the kernel as part of the ?* irq handling routines. ?* ?* IRQF_DISABLED - keep irqs disabled when calling the action handler ?* IRQF_SAMPLE_RANDOM - irq is used to feed the random generator ?* IRQF_SHARED - allow sharing the irq among several devices ?* IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur ?* IRQF_TIMER - Flag to mark this interrupt as timer interrupt ?* IRQF_PERCPU - Interrupt is per cpu ?* IRQF_NOBALANCING - Flag to exclude this interrupt from irq balancing ?* IRQF_IRQPOLL - Interrupt is used for polling (only the interrupt that is ?*??????????????? registered first in an shared interrupt is considered for ?*??????????????? performance reasons) ?*/ #define IRQF_DISABLED??????? 0x00000020 #define IRQF_SAMPLE_RANDOM??? 0x00000040 #define IRQF_SHARED??????? 0x00000080 #define IRQF_PROBE_SHARED??? 0x00000100 #define IRQF_TIMER??????? 0x00000200 #define IRQF_PERCPU??????? 0x00000400 #define IRQF_NOBALANCING??? 0x00000800 #define IRQF_IRQPOLL??????? 0x00001000


? ?Tip:下面是老版本(2.4內(nèi)核irqflags的值),不要在新版本使用。(2.6 內(nèi)核及2.6以上內(nèi)核都為新內(nèi)核)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 /* ?* Migration helpers. Scheduled for removal in 9/2007 ?* Do not use for new code !//不要的新版本使用,2.6 內(nèi)核及2.6以上內(nèi)核都為新內(nèi)核 ?*/ static?inline unsigned?long?__deprecated deprecated_irq_flag(unsigned?long?flag) { ????return?flag; } #define SA_INTERRUPT??????? deprecated_irq_flag(IRQF_DISABLED) #define SA_SAMPLE_RANDOM??? deprecated_irq_flag(IRQF_SAMPLE_RANDOM) #define SA_SHIRQ??????? deprecated_irq_flag(IRQF_SHARED) #define SA_PROBEIRQ??????? deprecated_irq_flag(IRQF_PROBE_SHARED) #define SA_PERCPU??????? deprecated_irq_flag(IRQF_PERCPU) #define SA_TRIGGER_LOW??????? deprecated_irq_flag(IRQF_TRIGGER_LOW) #define SA_TRIGGER_HIGH??????? deprecated_irq_flag(IRQF_TRIGGER_HIGH) #define SA_TRIGGER_FALLING??? deprecated_irq_flag(IRQF_TRIGGER_FALLING) #define SA_TRIGGER_RISING??? deprecated_irq_flag(IRQF_TRIGGER_RISING) #define SA_TRIGGER_MASK??????? deprecated_irq_flag(IRQF_TRIGGER_MASK)

三、使用模板
? ?使用步驟:以外部中斷為例
a)定義結(jié)構(gòu)體,相當(dāng)于定義(void *dev_id)中的(void *)

1 2 3 4 5 struct pin_desc{//聲明一個引腳描述的結(jié)構(gòu)體pin_desc ???????unsigned?int?pin;//引腳值,參考數(shù)據(jù)手冊及板子電路原理圖 ???????unsigned?int?key_val;//值自已隨便定義;看自己的項(xiàng)目需要 ???????//................... ???};

b)實(shí)例化結(jié)構(gòu)體,相當(dāng)于(void *dev_id)中的 dev_id

1 2 3 4 5 struct?pin_desc pins_desc[3] = {//實(shí)例化結(jié)構(gòu)體,以jz2440按鍵為列 ???????{S3C2410_GPF0, 0x01},//S3C2410_GPFn在內(nèi)核中定義好了 ???????{S3C2410_GPF2, 0x02}, ???????{S3C2410_GPG3, 0x03}, ???};

c)定義中斷處理函數(shù)

1 2 3 4 5 static?irqreturn_t irq_handle(int?irq,?void?*dev__id){ ????struct pin_desc *pindesc = (struct pin_desc *)dev__id; ????//................ ????return?IRQ_RETVAL(IRQ_HANDLED);//返回IRQ_HANDLED表示中斷已經(jīng)處理 ????}

d)申請中斷

1 2 3 request_irq(IRQ_EINT0, irq_handle, IRQ_TYPE_EDGE_BOTH,?"s2", &pins_desc[0]);//IRQ_EINTn在內(nèi)核中定義好了 ???request_irq(IRQ_EINT2, irq_handle, IRQ_TYPE_EDGE_BOTH,?"s3", &pins_desc[1]); ???request_irq(IRQ_EINT11, irq_handle, IRQ_TYPE_EDGE_BOTH,?"s4", &pins_desc[2]);

e)釋放內(nèi)存

1 2 3 free_irq(IRQ_EINT0, &pins_desc[0]); ????free_irq(IRQ_EINT2, &pins_desc[1]); ????free_irq(IRQ_EINT11, &pins_desc[2]);


Tip:可以直接將IRQ_EINTn也在pins_desc定義,然后

1 2 3 4 int?i =?0; ???for(i =?0; i <?3; i++){ ???free_irq(pins_desc[i].irqnum, &pins_desc[i]); ???}

? ?實(shí)例見[arm驅(qū)動]Linux內(nèi)核開發(fā)之阻塞非阻塞IO----輪詢操作?中的實(shí)例(按鍵中斷雙邊沿觸發(fā))



本文轉(zhuǎn)自lilin9105 51CTO博客,原文鏈接:http://blog.51cto.com/7071976/1392439,如需轉(zhuǎn)載請自行聯(lián)系原作者

總結(jié)

以上是生活随笔為你收集整理的[arm驱动]linux内核中断编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。