在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > arm驅(qū)動(dòng)linux內(nèi)核中斷編程

            arm驅(qū)動(dòng)linux內(nèi)核中斷編程

            作者: 時(shí)間:2016-11-19 來源:網(wǎng)絡(luò) 收藏

            第一部分獲取中斷(開啟硬件中斷)

            本文引用地址:http://www.biyoush.com/article/201611/318227.htm

            一、中斷的申請(qǐng)注銷:
            1)中斷的申請(qǐng)

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

            2)中斷的注銷

            void free_irq(unsigned int irq, void *dev_id)

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

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

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

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

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

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

            3)擴(kuò)展---unsigned long irqflags值
            在includelinuxinterrupt.h中

            /*
            * 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)核)

            /*
            * 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 *)

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

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

            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ù)

            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)申請(qǐng)中斷

            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)存

            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定義,然后

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



            評(píng)論


            技術(shù)專區(qū)

            關(guān)閉