国产强伦姧在线观看无码,中文字幕99久久亚洲精品,国产精品乱码在线观看,色桃花亚洲天堂视频久久,日韩精品无码观看视频免费

      您現(xiàn)在的位置:智能制造網(wǎng)>技術中心>ARM-Linux 中斷分析

      直播推薦

      更多>

      企業(yè)動態(tài)

      更多>

      推薦展會

      更多>

      ARM-Linux 中斷分析

      2008年01月30日 13:42:38人氣:2598來源:浙江啟揚智能科技有限公司

      ARM體系結構中,把復位、中斷、快速中斷等都看作‘ARM-Linux異?!?,當這些‘異?!l(fā)生時,CPU會到固定地址處去找指令,他們對應的地址如下:
      地址 異常類型 進入時的工作模式
      0x00000000 Reset Supervisor
      0x00000004 Und Undefined
      0x00000008 Soft interupt Supervisor
      0x0000000c Abort(prefetch) Abort
      0x00000010 Abort(data) Abort
      0x00000014 Reserved Reserved
      0x00000018 IRQ IRQ
      0x0000001c FIQ FIQ
      首先要明確的一點就是,無論內(nèi)存地址空間是如何ARM-Linux映射的,以上這些地址都不會變,比如當有快速中斷發(fā)生時,ARM將鐵定到0X0000001C這個地址處取指令。這也是BOOTLOADER把操作系統(tǒng)引導以后,內(nèi)存必須重映射的原因!否則操作系統(tǒng)不能真正接管整套系統(tǒng)!
      LINUX啟動以后要初始化這些區(qū)域,初始化代碼在main.c中ARM-Linux的start_kernel()中,具體是調(diào)用函數(shù)trap_ini()來實現(xiàn)的。如下面所示(具體可參照entry-armv.S):
      .LCvectors: swi SYS_ERROR0
      b __real_stubs_start + (vector_undefinstr - __stubs_start)
      ldr pc, __real_stubs_start + (.LCvswi - __stubs_start)
      b __real_stubs_start + (vector_prefetch - __stubs_start)
      b __real_stubs_start + (vector_data - __stubs_start)
      b __real_stubs_start + (vector_addrexcptn - __stubs_start)
      b __real_stubs_start + (vector_IRQ - __stubs_start)
      b __real_stubs_start + (vector_FIQ - __stubs_start)

      ENTRY(__trap_init)
      stmfd ARM-Linux sp!, {r4 - r6, lr}

      adr r1, .LCvectors @ set up the vectors
      ldmia r1, {r1, r2, r3, r4, r5, r6, ip, lr}
      stmia r0, {r1, r2, r3, r4, r5, r6, ip, lr}ARM-Linux

      add r2, r0, #0x200
      adr r0, __stubs_start @ copy stubs to 0x200
      adr r1, __stubs_end
      1: ldr r3, [r0], #4ARM-Linux
      str r3, [r2], #4
      cmp r0, r1
      blt 1b
      LOADREGS(fd, sp!, {r4 - r6, pc})

      以上可以看出這個函數(shù)初始化了中斷向量,實際ARM-Linux上把相應的跳轉指令拷貝到了對應的地址。
      當發(fā)生中斷時,不管是從ARM-Linux用戶模式還是管理模式調(diào)用的,zui終都要調(diào)用do_IRQ():
      __irq_usr: sub sp, sp, #S_FRAME_SIZE
      stmia sp, {r0 - r12} @ save r0 - r12
      ldr r4, .LCirq
      add r8, sp, #S_PC
      ldmia r4, {r5 - r7} @ get saved PC, SPSR
      stmia r8, {r5 - r7} ARM-Linux @ save pc, psr, old_r0
      stmdb r8, {sp, lr}^
      alignment_trap r4, r7, __temp_irq
      zero_fp
      1: get_irqnr_and_base r0, r6, r5, lr
      movne r1, sp
      adrsvc ne, lr, 1b
      @
      @ routine called with r0 = irq number, r1 = struct pt_regs *
      @
      bne do_IRQ @ 調(diào)用do_IRQ來實現(xiàn)具體的中斷ARM-Linux處理
      mov why, #0
      get_current_task tsk
      b ret_to_user

      對于以上代碼,在很多文章中都有過分析,這里不再贅述。
      ARM-Linux

      Linux每個中斷通過一個結構irqdesc來描述,各中斷的信息都在這個結構中得以ARM-Linux體現(xiàn):
      struct irqdesc {
      unsigned int nomask : 1; /* IRQ does not mask in IRQ */
      unsigned int enabled : 1; /* IRQ is currently enabled */
      unsigned int triggered: 1; /* IRQ has occurred */
      unsigned int probing : 1; /* IRQ in use for a probe */
      unsigned int probe_ok : 1; ARM-Linux /* IRQ can be used for probe */
      unsigned int valid : 1; /* IRQ claimable */
      unsigned int noautoenable : 1; /* don"t automatically enable IRQ */
      unsigned int unused :25;
      void (*mask_ack)(unsigned int irq); /* Mask and acknowledge IRQ */
      void (*mask)(unsigned int irq); /* Mask IRQ */
      void (*unmask)(unsigned int irq); /* Unmask IRQ */
      struct irqaction *action;
      /*ARM-Linux
      * IRQ lock detection
      */
      unsigned int lck_cnt;
      unsigned int lck_pc;
      unsigned int lck_jif;
      };

      在具體ARM-Linux的ARM芯片中會有很多的中斷類型,每一種類型的中斷用以上結構來表示:
      struct irqdesc irq_desc[NR_IRQS]; /* NR_IRQS根據(jù)不同的MCU會有所區(qū)別*/
      在通過request_irq()函數(shù)注冊中斷服務程序的時候ARM-Linux,將會把中斷向量和中斷服務程序?qū)饋怼?BR>我們來看一下request_irq的源碼:
      int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
      unsigned long irq_flags, const char * devname, void *dev_id)
      {
      unsigned long retval;
      struct irqaction *action;ARM-Linux

      if (irq >= NR_IRQS || !irq_desc[irq].valid || !handler ||
      (irq_flags & SA_SHIRQ && !dev_id))
      return -EINVAL;
      action = (struct irqaction *)kmallocARM-Linux(sizeof(struct irqaction), GFP_KERNEL);
      if (!action) /* 生成action結構*/
      return -ENOMEM;

      action->handler = handler;
      action->flags = irq_flags;ARM-Linux
      action->mask = 0;
      action->name = devname;
      action->next = NULL;
      action->dev_id = dev_id;

      retval = setup_arm_irq(irq, action); /*把中斷號irq和action 對應ARM-Linux起來*/

      if (retval)
      kfree(action);ARM-Linux
      return retval;
      }
      其中*個參數(shù)irq就是中斷向量,第二個參數(shù)即是要注冊的中斷服務程序。很多同仁可能疑惑的是,我們要注冊的中斷向量號是怎么確定的呢?這要根據(jù)具體芯片的中斷控制器,比如三星的S3C2410,需要 通過讀取其中的中斷狀態(tài)寄存器,來獲得是哪個設備發(fā)生了中斷:
      ARM-Linux

      if defined(CONFIG_ARCH_S3C2410)
      #Include

      .macro disable_fiq
      .endm
      .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
      mov r4, #INTBASE @ virtual address of IRQ registers
      ldr \irqnr,ARM-Linux [r4, #0x8] @ read INTMSK 中斷掩碼寄存器
      ldr \irqstat, [r4, #0x10] @ read INTPND 中斷寄存器
      bics \irqstat, \irqstat, \irqnr
      bics \irqstat, \irqstat, \irqnr
      beq 1002f
      mov \irqnr, #0ARM-Linux
      1001: tst \irqstat, #1
      bne 1002f @ found IRQ
      add \irqnr, \irqnr, #1
      mov \irqstat, \irqstat, lsr #1
      cmp \irqnr, #32
      bcc 1001b
      1002:
      .endm
      .macro irq_prio_table
      .endm
      以上代碼也告訴了ARM-Linux我們,中斷號的確定,其實是和S3C2410手冊中SRCPND寄存器是一致的,即:

      /* Interrupt Controller */
      #define IRQ_EINT0 0 /* External interrupt 0 */
      #define IRQ_EINT1 1 /* External interrupt 1 */
      #define IRQ_EINT2 2 /* External interrupt 2 */
      #define IRQ_EINT3 3 ARM-Linux /* External interrupt 3 */
      #define IRQ_EINT4_7 4 /* External interrupt 4 ~ 7 */
      #define IRQ_EINT8_23 5 /* External interrupt 8 ~ 23 */
      #define IRQ_RESERVED6 6 /* Reserved for future use */
      #define IRQ_BAT_FLT 7
      #define IRQ_TICK 8 /* RTC time tick interrupt */
      #define IRQ_WDT 9 /* Watch-Dog timer interrupt */
      #define IRQ_TIMER0 10 /* Timer 0 interrupt */
      #define IRQ_TIMER1 11 /* Timer 1 interrupt */ARM-Linux
      #define IRQ_TIMER2 12 ARM-Linux /* Timer 2 interrupt */
      #define IRQ_TIMER3 13 /* Timer 3 interrupt */
      #define IRQ_TIMER4 14 /* Timer 4 interrupt */
      #define IRQ_UART2 15 /* UART 2 interrupt */
      #define IRQ_LCD 16 /* reserved for future use */
      #define IRQ_DMA0 17 /* DMA channel 0 interrupt */
      #define IRQ_DMA1 18 /* DMA channel 1 interrupt */
      #define IRQ_DMA2 19 /* DMA channel 2 interrupt */ARM-Linux
      #define IRQ_DMA3 20 /* DMA channel 3 interrupt */
      #define IRQ_SDI 21 ARM-Linux /* SD Interface interrupt */
      #define IRQ_SPI0 22 /* SPI interrupt */
      #define IRQ_UART1 23 /* UART1 receive interrupt */
      #define IRQ_RESERVED24 24
      #define IRQ_USBD 25 /* USB device interrupt */
      #define IRQ_USBH 26 /* USB host interrupt */
      #define IRQ_IIC 27 /* IIC interrupt */
      #define IRQ_UART0 28 /* UART0 transmit interrupt */
      #define IRQ_SPI1 29 /* UART1 transmit interrupt */
      #define IRQ_RTC 30 /* RTC alarm interrupt */
      #define IRQ_ADCTC 31 /* ADC EOC interrupt */
      #define NORMAL_IRQ_OFFSET 32
      這些宏定義在文件irqs.h中,大家ARM-Linux可以看到它的定義取自S3C2410的文檔。
      總結: linux在初始化的時候已經(jīng)把每個中斷向量的地址準備好了!就是說添加中斷服務程序的框架已經(jīng)給出,當某個中斷發(fā)生時,將會到確定的地址處去找指令,所以我們做驅(qū)動程序時,只需要經(jīng)過request_irq()來掛接自己編寫的中斷服務ARM-Linux程序即可。

      另:對于快速中斷,linux在初始化時是空的,所以要對它掛接中斷處理程序,就需要單獨的函數(shù)set_fiq_handler()來實現(xiàn),此函數(shù)在源文件fiq.c中,有興趣的讀者可進一步ARM-Linux研究。

      全年征稿/資訊合作 聯(lián)系郵箱:1271141964@qq.com

      免責聲明

      • 凡本網(wǎng)注明"來源:智能制造網(wǎng)"的所有作品,版權均屬于智能制造網(wǎng),轉載請必須注明智能制造網(wǎng),http://towegas.com。違反者本網(wǎng)將追究相關法律責任。
      • 企業(yè)發(fā)布的公司新聞、技術文章、資料下載等內(nèi)容,如涉及侵權、違規(guī)遭投訴的,一律由發(fā)布企業(yè)自行承擔責任,本網(wǎng)有權刪除內(nèi)容并追溯責任。
      • 本網(wǎng)轉載并注明自其它來源的作品,目的在于傳遞更多信息,并不代表本網(wǎng)贊同其觀點或證實其內(nèi)容的真實性,不承擔此類作品侵權行為的直接責任及連帶責任。其他媒體、網(wǎng)站或個人從本網(wǎng)轉載時,必須保留本網(wǎng)注明的作品來源,并自負版權等法律責任。
      • 如涉及作品內(nèi)容、版權等問題,請在作品發(fā)表之日起一周內(nèi)與本網(wǎng)聯(lián)系,否則視為放棄相關權利。

      <
      更多 >

      工控網(wǎng)機器人儀器儀表物聯(lián)網(wǎng)3D打印工業(yè)軟件金屬加工機械包裝機械印刷機械農(nóng)業(yè)機械食品加工設備制藥設備倉儲物流環(huán)保設備造紙機械工程機械紡織機械化工設備電子加工設備水泥設備海洋水利裝備礦冶設備新能源設備服裝機械印染機械制鞋機械玻璃機械陶瓷設備橡塑設備船舶設備電子元器件電氣設備


      我要投稿
      • 投稿請發(fā)送郵件至:(郵件標題請備注“投稿”)1271141964.qq.com
      • 聯(lián)系電話0571-89719789
      工業(yè)4.0時代智能制造領域“互聯(lián)網(wǎng)+”服務平臺
      智能制造網(wǎng)APP

      功能豐富 實時交流

      智能制造網(wǎng)小程序

      訂閱獲取更多服務

      微信公眾號

      關注我們

      抖音

      智能制造網(wǎng)

      抖音號:gkzhan

      打開抖音 搜索頁掃一掃

      視頻號

      智能制造網(wǎng)

      公眾號:智能制造網(wǎng)

      打開微信掃碼關注視頻號

      快手

      智能制造網(wǎng)

      快手ID:gkzhan2006

      打開快手 掃一掃關注
      意見反饋
      關閉
      企業(yè)未開通此功能
      詳詢客服 : 0571-87858618