在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,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首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ARM-Linux s3c2440 之中斷分析(三)

            ARM-Linux s3c2440 之中斷分析(三)

            作者: 時(shí)間:2016-11-19 來(lái)源:網(wǎng)絡(luò) 收藏
            Linux通過(guò)以下函數(shù)來(lái)注冊(cè)中斷以及中斷相關(guān)的入口函數(shù)handle,只有先注冊(cè)IRQ,才能正常使用。

            本文引用地址:http://www.biyoush.com/article/201611/318130.htm
            1. intset_irq_chip(unsignedintirq,structirq_chip*chip)
            2. staticinlinevoidset_irq_handler(unsignedintirq,irq_flow_handler_thandle)
            3. staticinlinevoidset_irq_chained_handler(unsignedintirq,irq_flow_handler_thandle)

            實(shí)現(xiàn)的代碼如下:


            1. for(irqno=IRQ_EINT4t7;irqno<=IRQ_ADCPARENT;irqno++){
            2. /*setallthes3c2410internalirqs*/
            3. switch(irqno){
            4. /*dealwiththespecialIRQs(cascaded)*/
            5. caseIRQ_EINT4t7:
            6. caseIRQ_EINT8t23:
            7. caseIRQ_UART0:
            8. caseIRQ_UART1:
            9. caseIRQ_UART2:
            10. caseIRQ_ADCPARENT:
            11. set_irq_chip(irqno,&s3c_irq_level_chip);
            12. set_irq_handler(irqno,handle_level_irq);//電平觸發(fā)型
            13. break;
            14. caseIRQ_RESERVED6:
            15. caseIRQ_RESERVED24:
            16. /*noIRQhere*/
            17. break;
            18. default:
            19. //irqdbf("registeringirq%d(s3cirq)n",irqno);
            20. set_irq_chip(irqno,&s3c_irq_chip);
            21. set_irq_handler(irqno,handle_edge_irq);//邊緣觸發(fā)型
            22. set_irq_flags(irqno,IRQF_VALID);
            23. }
            24. /*級(jí)聯(lián)中斷的注冊(cè)*/
            25. set_irq_chained_handler(IRQ_EINT4t7,s3c_irq_demux_extint4t7);
            26. set_irq_chained_handler(IRQ_EINT8t23,s3c_irq_demux_extint8);
            27. set_irq_chained_handler(IRQ_UART0,s3c_irq_demux_uart0);
            28. set_irq_chained_handler(IRQ_UART1,s3c_irq_demux_uart1);
            29. set_irq_chained_handler(IRQ_UART2,s3c_irq_demux_uart2);
            30. set_irq_chained_handler(IRQ_ADCPARENT,s3c_irq_demux_adc);
            31. /*externalinterrupts*/
            32. for(irqno=IRQ_EINT0;irqno<=IRQ_EINT3;irqno++){
            33. irqdbf("registeringirq%d(extint)n",irqno);
            34. set_irq_chip(irqno,&s3c_irq_eint0t4);
            35. set_irq_handler(irqno,handle_edge_irq);
            36. set_irq_flags(irqno,IRQF_VALID);
            37. }
            38. for(irqno=IRQ_EINT4;irqno<=IRQ_EINT23;irqno++){
            39. irqdbf("registeringirq%d(extendeds3cirq)n",irqno);
            40. set_irq_chip(irqno,&s3c_irqext_chip);
            41. set_irq_handler(irqno,handle_edge_irq);
            42. set_irq_flags(irqno,IRQF_VALID);
            43. }
            44. /*registertheuartinterrupts*/
            45. irqdbf("s3c2410:registeringexternalinterruptsn");
            46. for(irqno=IRQ_S3CUART_RX0;irqno<=IRQ_S3CUART_ERR0;irqno++){
            47. irqdbf("registeringirq%d(s3cuart0irq)n",irqno);
            48. set_irq_chip(irqno,&s3c_irq_uart0);
            49. set_irq_handler(irqno,handle_level_irq);
            50. set_irq_flags(irqno,IRQF_VALID);
            51. }
            52. for(irqno=IRQ_S3CUART_RX1;irqno<=IRQ_S3CUART_ERR1;irqno++){
            53. irqdbf("registeringirq%d(s3cuart1irq)n",irqno);
            54. set_irq_chip(irqno,&s3c_irq_uart1);
            55. set_irq_handler(irqno,handle_level_irq);
            56. set_irq_flags(irqno,IRQF_VALID);
            57. }
            58. for(irqno=IRQ_S3CUART_RX2;irqno<=IRQ_S3CUART_ERR2;irqno++){
            59. irqdbf("registeringirq%d(s3cuart2irq)n",irqno);
            60. set_irq_chip(irqno,&s3c_irq_uart2);
            61. set_irq_handler(irqno,handle_level_irq);
            62. set_irq_flags(irqno,IRQF_VALID);
            63. }
            64. for(irqno=IRQ_TC;irqno<=IRQ_ADC;irqno++){//具體注冊(cè)IRQ_TC、IRQ_ADC
            65. irqdbf("registeringirq%d(s3cadcirq)n",irqno);
            66. set_irq_chip(irqno,&s3c_irq_adc);
            67. set_irq_handler(irqno,handle_edge_irq);
            68. set_irq_flags(irqno,IRQF_VALID);
            69. }

            從以上代碼中可以看出,注冊(cè)中斷主要是注冊(cè)中斷服務(wù)程序入口。Linux中將所有的中斷號(hào)用一個(gè)stuctirq_desc數(shù)據(jù)結(jié)構(gòu)進(jìn)行統(tǒng)一管理,每個(gè)中斷號(hào)或者一組中斷號(hào)(如級(jí)聯(lián)的中斷),對(duì)應(yīng)一個(gè)structirq_desc, 所以根據(jù)相應(yīng)的中斷號(hào),可以獲取對(duì)應(yīng)的中斷描述結(jié)構(gòu)irq_desc:


            1. structirq_desc*desc=irq_to_desc(irq);
            2. irq_desc數(shù)據(jù)結(jié)構(gòu)如下:
            3. structirq_desc{
            4. unsignedintirq;//中斷號(hào)
            5. irq_flow_handler_thandle_irq;//系統(tǒng)中斷處理的入口函數(shù)
            6. structirq_chip*chip;//對(duì)應(yīng)的irq_chip結(jié)構(gòu),定義了與中斷處理有關(guān)的函數(shù)
            7. structirqaction*action;//用戶的中斷處理函數(shù),調(diào)用request_irq時(shí)添加
            8. unsignedintstatus;//IRQ的狀態(tài)
            9. spinlock_tlock;
            10. constchar*name;
            11. }____cacheline_internodealigned_in_smp;

            irq_chip結(jié)構(gòu)定義了各種中斷相關(guān)的處理行為,如開(kāi)啟或禁止中斷以及中斷服務(wù)完成的之后對(duì)相關(guān)的中斷寄存器進(jìn)行處理。關(guān)于電平觸發(fā)型和邊緣型觸發(fā)中斷入口函數(shù)可以從irq_chip結(jié)構(gòu)中的看出只有ack函數(shù)的處理不同:


            1. structirq_chips3c_irq_level_chip={
            2. .name="s3c-level",
            3. .ack=s3c_irq_maskack,
            4. .mask=s3c_irq_mask,
            5. .unmask=s3c_irq_unmask,
            6. .set_wake=s3c_irq_wake
            7. };
            8. structirq_chips3c_irq_chip={
            9. .name="s3c",
            10. .ack=s3c_irq_ack,
            11. .mask=s3c_irq_mask,
            12. .unmask=s3c_irq_unmask,
            13. .set_wake=s3c_irq_wake
            14. };

            在s3cirq_maskack中多了以下代碼:

            mask = __raw_readl(S3C2410_INTMSK);

            __raw_writel(mask|bitval, S3C2410_INTMSK);

            實(shí)現(xiàn)的功能是,屏蔽相應(yīng)的中斷。

            在early_trap_init()中已經(jīng)進(jìn)行了中斷(異常)向量的初始化,將異常向量表從物理地址0x00000000拷貝到虛擬0xffff0000的虛擬地址處。異常向量在arch/arm/kernel/entry-armv.S中定義:


            1. .globl__vectors_start
            2. rs_start:
            3. swiSYS_ERROR0
            4. bvector_und+stubs_offset
            5. ldrpc,.LCvswi+stubs_offset
            6. bvector_pabt+stubs_offset
            7. bvector_dabt+stubs_offset
            8. bvector_addrexcptn+stubs_offset
            9. bvector_irq+stubs_offset
            10. bvector_fiq+stubs_offset
            11. .globl__vectors_end

            那么當(dāng)有中斷產(chǎn)生時(shí):

            1. /*
            2. *Interrupthandling.Preservesr7,r8,r9
            3. */
            4. .macroirq_handler
            5. get_irqnr_preambler5,lr
            6. 1:get_irqnr_and_baser0,r6,r5,lr
            7. movner1,sp
            8. @
            9. @routinecalledwithr0=irqnumber,r1=structpt_regs*
            10. @
            11. adrnelr,1b
            12. bneasm_do_IRQ//跳轉(zhuǎn)到這里中斷的總?cè)肟诤瘮?shù)

            這里的asm_do_IRQ對(duì)應(yīng)arch/arm/kernel/irq.c中:


            1. asmlinkagevoid__exceptionasm_do_IRQ(unsignedintirq,structpt_regs*regs)

            所以這是Linux中所有中斷的總?cè)肟诤瘮?shù)。asm_doIRQ()調(diào)用generic_handle_irq()再后調(diào)用

            generic_handle_irq_desc(),最后到各個(gè)irq_desc的處理。


            1. staticinlinevoidgeneric_handle_irq_desc(unsignedintirq,structirq_desc*desc)
            2. {
            3. #ifdefCONFIG_GENERIC_HARDIRQS_NO__DO_IRQ
            4. desc->handle_irq(irq,desc);
            5. #else
            6. if(likely(desc->handle_irq))
            7. desc->handle_irq(irq,desc);
            8. else
            9. __do_IRQ(irq);
            10. #endif
            11. }

            從總?cè)肟诘接脩舻闹袛嗵幚砗瘮?shù)的流程:

            asm_do_IRQ() –-> generic_handle_irq() –->irq_dsc->handle() à handle_IRQ_event() à irq_des->action()

            最后對(duì)中斷處理流程進(jìn)行簡(jiǎn)單總結(jié):

            (1)總?cè)肟诤瘮?shù)asm_do_IRQ,獲取中斷號(hào)irq

            (2)asm_do_IRQ根據(jù)中斷號(hào)調(diào)用各中斷號(hào)所注冊(cè)的中斷入口函數(shù)irq_desc[irq]->handle_irq

            (3)最后在中斷入口函數(shù)中調(diào)用handle_IRQ_event()依次執(zhí)行用戶的中斷處理函數(shù)action



            關(guān)鍵詞: ARMLinuxs3c2440中

            評(píng)論


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

            關(guān)閉