<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          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.ex-cimer.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;//用戶(hù)的中斷處理函數(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è)肟诘接脩?hù)的中斷處理函數(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í)行用戶(hù)的中斷處理函數(shù)action



          關(guān)鍵詞: ARMLinuxs3c2440中

          評(píng)論


          技術(shù)專(zhuān)區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();