📄 interrupts.html
字号:
r1 = sp; SP += <span class="nu0">-12</span>; call process_int; SP += <span class="nu0">12</span>; RESTORE_CONTEXT rti;</pre><p>The interrupt service routines are here...</p><pre class="code c"> <span class="co1">//extract from linux-2.6.x/arch/blackfin/mach-bf533/traps.c </span> asmlinkage <span class="kw4">void</span> process_int<span class="br0">(</span><span class="kw4">unsigned</span> <span class="kw4">long</span> vec, <span class="kw4">struct</span> pt_regs *fp<span class="br0">)</span> <span class="br0">{</span> <span class="kw1">if</span> <span class="br0">(</span>mach_process_int<span class="br0">)</span> mach_process_int<span class="br0">(</span>vec, fp<span class="br0">)</span>; <span class="kw1">else</span> panic<span class="br0">(</span><span class="st0">"Can't process interrupt vector %ld<span class="es0">\n</span>"</span>, vec<span class="br0">)</span>; <span class="kw1">return</span>; <span class="br0">}</span> <span class="co1">//See also arch/blackfin/mach-bf533/ints-priority.c: </span> mach_process_int = bfin_do_irq;</pre><p>The final interrupt service routine</p><pre class="code c"> <span class="co1">//Extract from </span> <span class="co1">//arch/blackfin/mach-bf533/ints-priority.c </span> <span class="kw4">void</span> bfin_do_irq<span class="br0">(</span><span class="kw4">int</span> vec, <span class="kw4">struct</span> pt_regs *fp<span class="br0">)</span> <span class="br0">{</span> <span class="kw1">if</span> <span class="br0">(</span>vec > IRQ_CORETMR<span class="br0">)</span> <span class="br0">{</span> <span class="kw4">struct</span> ivgx *ivg = ivg7_13<span class="br0">[</span>vec<span class="br0">]</span>.<span class="me1">ifirst</span>; <span class="kw4">struct</span> ivgx *ivg_stop = ivg7_13<span class="br0">[</span>vec<span class="br0">]</span>.<span class="me1">istop</span>; <span class="kw4">unsigned</span> <span class="kw4">long</span> sic_status; asm<span class="br0">(</span><span class="st0">"ssync;"</span><span class="br0">)</span>; sic_status = *pSIC_IMASK & *pSIC_ISR; <span class="kw1">for</span><span class="br0">(</span>;; ivg++<span class="br0">)</span> <span class="br0">{</span> <span class="kw1">if</span> <span class="br0">(</span>ivg >= ivg_stop<span class="br0">)</span> <span class="br0">{</span> <span class="coMULTI">/* printk("unregistered interrupt ivg=%d\n",vec);*/</span> <span class="kw1">return</span>; <span class="br0">}</span> <span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">(</span><span class="br0">(</span>sic_status & ivg->isrflag<span class="br0">)</span> != <span class="nu0">0</span><span class="br0">)</span> <span class="kw2">break</span>; <span class="br0">}</span> vec = ivg->irqno; <span class="br0">}</span> <span class="kw1">if</span><span class="br0">(</span>int_irq_list<span class="br0">[</span>vec<span class="br0">]</span>.<span class="me1">handler</span><span class="br0">)</span> <span class="co1">// HERE WE CALL THE LINUX HANDLER </span> <span class="br0">{</span> int_irq_list<span class="br0">[</span>vec<span class="br0">]</span>.<span class="me1">handler</span><span class="br0">(</span>vec,int_irq_list<span class="br0">[</span>vec<span class="br0">]</span>.<span class="me1">dev_id</span>, fp<span class="br0">)</span>; kstat_cpu<span class="br0">(</span><span class="nu0">0</span><span class="br0">)</span>.<span class="me1">irqs</span><span class="br0">[</span>vec<span class="br0">]</span>++; <span class="br0">}</span> <span class="kw1">else</span> printk<span class="br0">(</span><span class="st0">"unregistered interrupt irq=%d<span class="es0">\n</span>"</span>,vec<span class="br0">)</span>; <span class="br0">}</span></pre><p> The interrupt definitions are in this file <strong>linux-2.6.x/include/asm-blackfin/board/bf533_irq.h</strong> </p><pre class="code c"> <span class="coMULTI">/* * Interrupt source definitions Event Source Core Event Name Core Emulation ** Events (highest priority) EMU 0 Reset RST 1 NMI NMI 2 Exception EVX 3 Reserved -- 4 Hardware Error IVHW 5 Core Timer IVTMR 6 * PLL Wakeup Interrupt IVG7 7 DMA Error (generic) IVG7 8 PPI Error Interrupt IVG7 9 SPORT0 Error Interrupt IVG7 10 SPORT1 Error Interrupt IVG7 11 SPI Error Interrupt IVG7 12 UART Error Interrupt IVG7 13 RTC Interrupt IVG8 14 DMA0 Interrupt (PPI) IVG8 15 DMA1 (SPORT0 RX) IVG9 16 DMA2 (SPORT0 TX) IVG9 17 DMA3 (SPORT1 RX) IVG9 18 DMA4 (SPORT1 TX) IVG9 19 DMA5 (PPI) IVG10 20 DMA6 (UART RX) IVG10 21 DMA7 (UART TX) IVG10 22 Timer0 IVG11 23 Timer1 IVG11 24 Timer2 IVG11 25 PF Interrupt A IVG12 26 PF Interrupt B IVG12 27 DMA8/9 Interrupt IVG13 28 DMA10/11 Interrupt IVG13 29 Watchdog Timer IVG13 30 Software Interrupt 1 IVG14 31 Software Interrupt 2 -- (lowest priority) IVG15 32 * */</span> <span class="co2">#define SYS_IRQS 33 /*Number of interrupt levels that the kernel sees.*/</span> <span class="coMULTI">/* The ABSTRACT IRQ definitions */</span> <span class="coMULTI">/** the first seven of the following are fixed, the rest you change if you need to **/</span> <span class="co2">#define IRQ_EMU 0 /*Emulation*/</span> <span class="co2">#define IRQ_RST 1 /*reset*/</span> <span class="co2">#define IRQ_NMI 2 /*Non Maskable*/</span> <span class="co2">#define IRQ_EVX 3 /*Exception*/</span> <span class="co2">#define IRQ_UNUSED 4 /*- unused interrupt*/</span> <span class="co2">#define IRQ_HWERR 5 /*Hardware Error*/</span> <span class="co2">#define IRQ_CORETMR 6 /*Core timer*/</span> <span class="co2">#define IRQ_PLL_WAKEUP 7 /*PLL Wakeup Interrupt*/</span> <span class="co2">#define IRQ_DMA_ERROR 8 /*DMA Error (general)*/</span> <span class="co2">#define IRQ_PPI_ERROR 9 /*PPI Error Interrupt*/</span> <span class="co2">#define IRQ_SPORT0_ERROR 10 /*SPORT0 Error Interrupt*/</span> <span class="co2">#define IRQ_SPORT1_ERROR 11 /*SPORT1 Error Interrupt*/</span> <span class="co2">#define IRQ_SPI_ERROR 12 /*SPI Error Interrupt*/</span> <span class="co2">#define IRQ_UART_ERROR 13 /*UART Error Interrupt*/</span> <span class="co2">#define IRQ_RTC 14 /*RTC Interrupt*/</span> <span class="co2">#define IRQ_PPI 15 /*DMA0 Interrupt (PPI)*/</span> <span class="co2">#define IRQ_SPORT0 16 /*DMA1 Interrupt (SPORT0 RX)*/</span> <span class="co2">#define IRQ_SPARE1 17 /*DMA2 Interrupt (SPORT0 TX)*/</span> <span class="co2">#define IRQ_SPORT1 18 /*DMA3 Interrupt (SPORT1 RX)*/</span> <span class="co2">#define IRQ_SPARE2 19 /*DMA4 Interrupt (SPORT1 TX)*/</span> <span class="co2">#define IRQ_SPI 20 /*DMA5 Interrupt (SPI)*/</span> <span class="co2">#define IRQ_UART 21 /*DMA6 Interrupt (UART RX)*/</span> <span class="co2">#define IRQ_SPARE3 22 /*DMA7 Interrupt (UART TX)*/</span> <span class="co2">#define IRQ_TMR0 23 /*Timer 0*/</span> <span class="co2">#define IRQ_TMR1 24 /*Timer 1*/</span> <span class="co2">#define IRQ_TMR2 25 /*Timer 2*/</span> <span class="co2">#define IRQ_PROG_INTA 26 /*Programmable Flags A (8)*/</span> <span class="co2">#define IRQ_PROG_INTB 27 /*Programmable Flags B (8)*/</span> <span class="co2">#define IRQ_MEM_DMA0 28 /*DMA8/9 Interrupt (Memory DMA S Stream 0)*/ </span> <span class="co2">#define IRQ_MEM_DMA1 29 /*DMA10/11 Interrupt (Memory DMA A Stream 1)*/ </span> <span class="co2">#define IRQ_WATCH 30 /*Watch Dog Timer*/</span> <span class="co2">#define IRQ_SW_INT1 31 /*Software Int 1*/</span> <span class="co2">#define IRQ_SW_INT2 32 /*Software Int 2 (reserved for S SYSCALL)*/ </span> <span class="co2">#define IVG7 7</span> <span class="co2">#define IVG8 8</span> <span class="co2">#define IVG9 9</span> <span class="co2">#define IVG10 10</span> <span class="co2">#define IVG11 11</span> <span class="co2">#define IVG12 12</span> <span class="co2">#define IVG13 13</span> <span class="co2">#define IVG14 14</span> <span class="co2">#define IVG15 15</span></pre></div><!-- SECTION [14322-28010] --><h2><a name="linux_interrupt_servicing" id="linux_interrupt_servicing">Linux Interrupt Servicing</a></h2><div class="level2"><p> An interrupt service routine looks just like a regular function call. Linux takes care of any special handling required to get in and out of the interrupt context.</p><p>The following code is an extract from the file <strong>linux-2.6.x/arch/blackfin/kernel/time.c</strong></p><p>Here the timer interrupt service is processed.</p><pre class="code c"> <span class="coMULTI">/* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */</span> <span class="kw4">static</span> irqreturn_t timer_interrupt<span class="br0">(</span><span class="kw4">int</span> irq, <span class="kw4">void</span> *dummy, <span class="kw4">struct</span> pt_regs * regs<span class="br0">)</span> <span class="br0">{</span> <span class="coMULTI">/* last time the cmos clock got updated */</span> <span class="kw4">static</span> <span class="kw4">long</span> last_rtc_update=<span class="nu0">0</span>; write_seqlock<span class="br0">(</span>&xtime_lock<span class="br0">)</span>; do_timer<span class="br0">(</span>regs<span class="br0">)</span>; <span class="coMULTI">/* * If we have an externally synchronized Linux clock, then update * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be * called as close as possible to 500 ms before the new second starts. */</span>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -