📄 interrupts.html
字号:
*pEVT14 = evt_system_call; asm<span class="br0">(</span><span class="st0">"csync;"</span><span class="br0">)</span>; *pEVT15 = evt_soft_int1; asm<span class="br0">(</span><span class="st0">"csync;"</span><span class="br0">)</span>; *pIMASK = <span class="nu0">0</span>; asm<span class="br0">(</span><span class="st0">"csync;"</span><span class="br0">)</span>; ilat = *pILAT; asm<span class="br0">(</span><span class="st0">"csync;"</span><span class="br0">)</span>; *pILAT = ilat; asm<span class="br0">(</span><span class="st0">"csync;"</span><span class="br0">)</span>; printk<span class="br0">(</span>KERN_INFO <span class="st0">"Configuring Blackfin Priority Driven Interrupts<span class="es0">\n</span>"</span><span class="br0">)</span>; program_IAR<span class="br0">(</span><span class="br0">)</span>; <span class="coMULTI">/* IMASK=xxx is equivalent to STI xx or irq_flags=xx, local_irq_enable() */</span> search_IAR<span class="br0">(</span><span class="br0">)</span>; <span class="coMULTI">/* Therefore it's better to setup IARs before interrupts enabled */</span> <span class="coMULTI">/* Enable interrupts IVG7-15 */</span> *pIMASK = irq_flags = irq_flags | IMASK_IVG15 | IMASK_IVG14 |IMASK_IVG13 |IMASK_IVG12 |IMASK_IVG11 | IMASK_IVG10 |IMASK_IVG9 |IMASK_IVG8 |IMASK_IVG7 |IMASK_IVGHW; asm<span class="br0">(</span><span class="st0">"csync;"</span><span class="br0">)</span>; local_irq_enable<span class="br0">(</span><span class="br0">)</span>; <span class="kw1">return</span> <span class="nu0">0</span>; <span class="br0">}</span></pre></div><!-- SECTION [8291-10095] --><h3><a name="blackfin_interrupt_service" id="blackfin_interrupt_service">Blackfin Interrupt Service</a></h3><div class="level3"><p> This is from <strong>linux-2.6.x/arch/blackfin/mach-bf533/interrupt.S</strong> </p><pre class="code c"> <span class="coMULTI">/* interrupt routine for core timer - 6 */</span> evt_timer: SAVE_CONTEXT r0 = IRQ_CORETMR; r1 = sp; SP += <span class="nu0">-12</span>; call process_int; <span class="coMULTI">/* call do_timer; */</span> SP += <span class="nu0">12</span>; RESTORE_CONTEXT rti; <span class="coMULTI">/* interrupt routine for evt2 - 2 */</span> evt_evt2: SAVE_CONTEXT r0 = <span class="nu0">2</span>; r1 = sp; SP += <span class="nu0">-12</span>; call process_int; SP += <span class="nu0">12</span>; RESTORE_CONTEXT rti;</pre></div><!-- SECTION [10096-11341] --><h2><a name="blackfin_system_timer" id="blackfin_system_timer">Blackfin System Timer</a></h2><div class="level2"><p> The system timer is set up using an inline statement in the file <strong>linux-2.6.x/arch/blackfin/mach-bf533/config.c</strong></p><pre class="code c"> <span class="co2">#include <asm/machdep.h> </span> <span class="co2">#include <asm/blackfin.h> </span> <span class="co2">#include <asm/bf533_rtc.h> </span> <span class="coMULTI">/* * By setting TSCALE such that TCOUNT counts a binary fraction * of microseconds, we can read TCOUNT directly and then with * a logical shift trivially calculate how many microseconds * since the last tick, allowing do_gettimeofday() to yield * far better time resolution for real time benchmarking. */</span> <span class="kw4">void</span> BSP_sched_init<span class="br0">(</span>irqreturn_t<span class="br0">(</span>*timer_routine<span class="br0">)</span><span class="br0">(</span><span class="kw4">int</span>, <span class="kw4">void</span> *, <span class="kw4">struct</span> pt_regs*<span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span> <span class="coMULTI">/* power up the timer, but don't enable it just yet */</span> *pTCNTL = <span class="nu0">1</span>; asm<span class="br0">(</span><span class="st0">"csync;"</span><span class="br0">)</span>; <span class="coMULTI">/* make TCOUNT a binary fraction of microseconds using * the TSCALE prescaler counter */</span> *pTSCALE = TSCALE_COUNT - <span class="nu0">1</span>; asm<span class="br0">(</span><span class="st0">"csync;"</span><span class="br0">)</span>; *pTCOUNT = *pTPERIOD = CLOCKS_PER_JIFFY - <span class="nu0">1</span>; asm<span class="br0">(</span><span class="st0">"csync;"</span><span class="br0">)</span>; <span class="coMULTI">/* now enable the timer */</span> *pTCNTL = <span class="nu0">7</span>; asm<span class="br0">(</span><span class="st0">"csync;"</span><span class="br0">)</span>; <span class="coMULTI">/* set up the timer irq */</span> request_irq<span class="br0">(</span>IRQ_CORETMR, timer_routine, IRQ_FLG_LOCK, <span class="st0">"timer"</span>, <span class="kw2">NULL</span><span class="br0">)</span>; enable_irq<span class="br0">(</span>IRQ_CORETMR<span class="br0">)</span>; <span class="br0">}</span></pre></div><!-- SECTION [11342-14321] --><h2><a name="linux_interrupt_overview" id="linux_interrupt_overview">Linux Interrupt Overview</a></h2><div class="level2"><p> On the BF533 platforms the interrupt system uses a priority scheme to manage interrupts. A vector is provided for each priority.</p><p>The interrupt service routing has to monitor each interrupt associated with a given priority and detect the IRQ NUMBER for any given interrupt.</p><p>Once this number is detected the usual Linux interrupt handling can continue.</p><p> The following files define and set up the interrupt system </p><ul><li class="level1"><div class="li"> linux-2.6.x/include/asm/irq.h</div></li><li class="level1"><div class="li"> linux-2.6.x/arch/blackfin/mach-bf533/ints-priority.c</div></li><li class="level1"><div class="li"> linux-2.6.x/arch/blackfin/mach-bf533/interrupt.S</div></li></ul><p> Here the priorities for each interrupt are set up</p><pre class="code c"> <span class="co1">//extract from linux-2.6.x/arch/blackfin/mach-bf533/ints-priority.c </span> <span class="coMULTI">/* Program the IAR0 Register with the configured priority */</span> *pSIC_IAR0 = <span class="br0">(</span><span class="br0">(</span>CONFIG_PLLWAKE_ERROR<span class="nu0">-7</span><span class="br0">)</span> << PLLWAKE_ERROR_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_DMA_ERROR <span class="nu0">-7</span><span class="br0">)</span> << DMA_ERROR_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_PPI_ERROR <span class="nu0">-7</span><span class="br0">)</span> << PPI_ERROR_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_SPORT0_ERROR<span class="nu0">-7</span><span class="br0">)</span> << SPORT0_ERROR_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_SPI_ERROR <span class="nu0">-7</span><span class="br0">)</span> << SPI_ERROR_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_SPORT1_ERROR<span class="nu0">-7</span><span class="br0">)</span> << SPORT1_ERROR_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_UART_ERROR <span class="nu0">-7</span><span class="br0">)</span> << UART_ERROR_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_RTC_ERROR <span class="nu0">-7</span><span class="br0">)</span> << RTC_ERROR_POS<span class="br0">)</span>; asm<span class="br0">(</span><span class="st0">"ssync;"</span><span class="br0">)</span>; *pSIC_IAR1 = <span class="br0">(</span><span class="br0">(</span>CONFIG_DMA0_PPI<span class="nu0">-7</span><span class="br0">)</span> << DMA0_PPI_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_DMA1_SPORT0RX<span class="nu0">-7</span><span class="br0">)</span> << DMA1_SPORT0RX_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_DMA2_SPORT0TX<span class="nu0">-7</span><span class="br0">)</span> << DMA2_SPORT0TX_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_DMA3_SPORT1RX<span class="nu0">-7</span><span class="br0">)</span> << DMA3_SPORT1RX_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_DMA4_SPORT1TX<span class="nu0">-7</span><span class="br0">)</span> << DMA4_SPORT1TX_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_DMA5_SPI<span class="nu0">-7</span><span class="br0">)</span> << DMA5_SPI_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_DMA6_UARTRX<span class="nu0">-7</span><span class="br0">)</span> << DMA6_UARTRX_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_DMA7_UARTTX<span class="nu0">-7</span><span class="br0">)</span> << DMA7_UARTTX_POS<span class="br0">)</span>; asm<span class="br0">(</span><span class="st0">"ssync;"</span><span class="br0">)</span>; *pSIC_IAR2 = <span class="br0">(</span><span class="br0">(</span>CONFIG_TIMER0<span class="nu0">-7</span><span class="br0">)</span> << TIMER0_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_TIMER1<span class="nu0">-7</span><span class="br0">)</span> << TIMER1_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_TIMER2<span class="nu0">-7</span><span class="br0">)</span> << TIMER2_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_PFA<span class="nu0">-7</span><span class="br0">)</span> << PFA_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_PFB<span class="nu0">-7</span><span class="br0">)</span> << PFB_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_MEMDMA0<span class="nu0">-7</span><span class="br0">)</span> << MEMDMA0_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_MEMDMA1<span class="nu0">-7</span><span class="br0">)</span> << MEMDMA1_POS<span class="br0">)</span> | <span class="br0">(</span><span class="br0">(</span>CONFIG_WDTIMER<span class="nu0">-7</span><span class="br0">)</span> << WDTIMER_POS<span class="br0">)</span>; asm<span class="br0">(</span><span class="st0">"ssync;"</span><span class="br0">)</span>; <span class="br0">}</span></pre><p> The actual interrupt service routines are here</p><pre class="code c"> <span class="co1">// extract from linux-2.6.x/arch/blackfin/mach-bf533/interrupts.S</span> <span class="coMULTI">/* interrupt routine for core timer - 6 */</span> evt_timer: SAVE_CONTEXT r0 = IRQ_CORETMR; r1 = sp; SP += <span class="nu0">-12</span>; call process_int; <span class="coMULTI">/* call do_timer; */</span> SP += <span class="nu0">12</span>; RESTORE_CONTEXT rti; <span class="coMULTI">/* interrupt routine for evt12 - 12 */</span> evt_evt12: SAVE_CONTEXT r0 = <span class="nu0">12</span>;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -