⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basic_exception_handling.html

📁 ADI 公司blackfin系列的用户使用文挡。
💻 HTML
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><head>  <title></title>  <link rel="stylesheet" media="screen" type="text/css" href="./style.css" />  <link rel="stylesheet" media="screen" type="text/css" href="./design.css" />  <link rel="stylesheet" media="print" type="text/css" href="./print.css" />  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body><a href=start.html>start</a></br><div class="toc"><div class="tocheader toctoggle" id="toc__header">Table of Contents</div><div id="toc__inside"><ul class="toc"><li class="clear"><ul class="toc"><li class="level2"><div class="li"><span class="li"><a href="#exceptions" class="toc">Exceptions</a></span></div><ul class="toc"><li class="level3"><div class="li"><span class="li"><a href="#interrupt_types" class="toc">Interrupt Types</a></span></div></li><li class="level3"><div class="li"><span class="li"><a href="#interrupt_numbers" class="toc">Interrupt Numbers</a></span></div></li></ul></li></ul></li></ul></div></div><h2><a name="exceptions" id="exceptions">Exceptions</a></h2><div class="level2"><p> The uClinux system runs on exceptions. If this would not true it would act like a brick. Interrupts and exceptions are the way the system responds to real world events including the timer tick. THe list of exceptions that are managed include </p><ul><li class="level1"><div class="li"> external interrupts</div></li><li class="level1"><div class="li"> system timer </div></li><li class="level1"><div class="li"> access errors</div></li><li class="level1"><div class="li"> soft interrupts</div></li></ul><p>The Exception handling is contained in these files </p><ul><li class="level1"><div class="li"> linux-2.6.x/arch/blackfin/mach-common/entry.S</div></li><li class="level1"><div class="li"> linux-2.6.x/arch/blackfin/mach-common/interrupt.S</div></li></ul><p> The vectors are set up in a C file <strong>linux-2.6.x/arch/blackfin/kernel/traps.c</strong></p><pre class="code c"><span class="coMULTI">/* Initiate the event table handler */</span><span class="kw4">void</span> __init trap_init <span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><span class="br0">&#123;</span>     __builtin_bfin_csync<span class="br0">&#40;</span><span class="br0">&#41;</span>;        *pEVT3= trap;        __builtin_bfin_csync<span class="br0">&#40;</span><span class="br0">&#41;</span>;        *pEVT14 = evt_system_call;        __builtin_bfin_csync<span class="br0">&#40;</span><span class="br0">&#41;</span>;        *pEVT15 = evt_soft_int1;        __builtin_bfin_csync<span class="br0">&#40;</span><span class="br0">&#41;</span>;<span class="br0">&#125;</span>&nbsp;</pre><p>And here in <strong>linux-2.6.x/arch/blackfin/mach-common/ints-priority-sc.c</strong></p><pre class="code c"><span class="kw4">int</span> __init  init_arch_irq<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><span class="br0">&#123;</span>        <span class="kw4">int</span> irq;        <span class="kw4">unsigned</span> <span class="kw4">long</span> ilat = <span class="nu0">0</span>;        <span class="coMULTI">/*  Disable all the peripheral intrs  - page 4-29 HW Ref manual */</span>        *pSIC_IMASK = SIC_UNMASK_ALL;        __builtin_bfin_ssync<span class="br0">&#40;</span><span class="br0">&#41;</span>;&nbsp;        local_irq_disable<span class="br0">&#40;</span><span class="br0">&#41;</span>;&nbsp;<span class="co2">#ifndef CONFIG_KGDB</span>        *pEVT0 = evt_nmi;<span class="co2">#endif</span>        *pEVT2  = evt_evt2;        *pEVT3  = trap;        *pEVT5  = evt_ivhw;        *pEVT6  = evt_timer;        *pEVT7  = evt_evt7;        *pEVT8  = evt_evt8;        *pEVT9  = evt_evt9;        *pEVT10 = evt_evt10;        *pEVT11 = evt_evt11;        *pEVT12 = evt_evt12;        *pEVT13 = evt_evt13;        *pEVT14 = evt_system_call;        *pEVT15 = evt_soft_int1;        __builtin_bfin_csync<span class="br0">&#40;</span><span class="br0">&#41;</span>;&nbsp;&nbsp;</pre><p>NOTE there is some setup duplication here.</p><p>Most of the user interrupts are in the range 7-13 and are handled by dedicated service routines. evt_evtx where x ranges from 7 to 13.</p><p> These service routines are found in <strong>linux-2.6.x/arch/blackfin/mach-common/interrupt.S</strong>.</p><p>Here is an example  </p><pre class="code c">* interrupt routine <span class="kw1">for</span> evt7 - <span class="nu0">7</span> */ENTRY<span class="br0">&#40;</span>evt_evt7<span class="br0">&#41;</span>         SAVE_CONTEXT         r0 = EVT_IVG7_P;         r1 =  sp;         SP += <span class="nu0">-12</span>;         call do_irq;         SP += <span class="nu0">12</span>;         RESTORE_CONTEXT         rti;&nbsp;</pre><p> This code records the source of the interrupt and calls a common function to service the interrupt</p><p>The <strong>do_irq</strong> function is in <strong>linux-2.6.x/arch/blackfin/mach-common/ints-priority-sc.c</strong>. Each interrupt device can be assigned to a specific interrupt level ( 7-13 ).  Each interrupt device will have a  Linux interrupt number.   The <strong>do_irq</strong> discovers the actual interrupting source and hence the <strong>Interrupt Number</strong> allocated to the interrupt source and then calls <strong>asm_do_IRQ(vec, fp)</strong>.</p><p> This code is in <strong>linux-2.6.x/arch/blackfin/kernel/irqchip.c</strong></p><p> The final service code is here.</p><pre class="code c"><span class="kw4">static</span> <span class="kw4">int</span>__do_irq<span class="br0">&#40;</span><span class="kw4">unsigned</span> <span class="kw4">int</span> irq, <span class="kw4">struct</span> irqaction *action, <span class="kw4">struct</span> pt_regs *regs<span class="br0">&#41;</span><span class="br0">&#123;</span>        <span class="kw4">unsigned</span> <span class="kw4">int</span> status;        <span class="kw4">int</span> retval = <span class="nu0">0</span>;&nbsp;        spin_unlock<span class="br0">&#40;</span>&amp;irq_controller_lock<span class="br0">&#41;</span>;&nbsp;        <span class="kw1">if</span> <span class="br0">&#40;</span>!<span class="br0">&#40;</span>action-&gt;flags &amp; SA_INTERRUPT<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>                local_irq_enable<span class="br0">&#40;</span><span class="br0">&#41;</span>;        <span class="br0">&#125;</span>&nbsp;        status = <span class="nu0">0</span>;        <span class="kw1">do</span> <span class="br0">&#123;</span>                status |= action-&gt;flags;                retval |= action-&gt;handler<span class="br0">&#40;</span>irq, action-&gt;dev_id, regs<span class="br0">&#41;</span>;                action = action-&gt;next;        <span class="br0">&#125;</span> <span class="kw1">while</span> <span class="br0">&#40;</span>action<span class="br0">&#41;</span>;&nbsp;        <span class="kw1">if</span> <span class="br0">&#40;</span>status &amp; SA_SAMPLE_RANDOM<span class="br0">&#41;</span>                add_interrupt_randomness<span class="br0">&#40;</span>irq<span class="br0">&#41;</span>;&nbsp;        spin_lock_irq<span class="br0">&#40;</span>&amp;irq_controller_lock<span class="br0">&#41;</span>;&nbsp;        <span class="kw1">return</span> retval;<span class="br0">&#125;</span></pre><p> The timer is an exception</p><pre class="code c">&nbsp;ENTRY<span class="br0">&#40;</span>evt_timer<span class="br0">&#41;</span>         SAVE_CONTEXT         p2.<span class="me1">l</span> = lo<span class="br0">&#40;</span>IPEND<span class="br0">&#41;</span>;         p2.<span class="me1">h</span> = hi<span class="br0">&#40;</span>IPEND<span class="br0">&#41;</span>;         r0 = <span class="br0">&#91;</span>p2<span class="br0">&#93;</span>;              <span class="coMULTI">/* Read current IPEND */</span>         csync;         <span class="br0">&#91;</span>sp + PT_IPEND<span class="br0">&#93;</span> = r0;   <span class="coMULTI">/* Store IPEND */</span>&nbsp;         r0 = IRQ_CORETMR;         r1 = sp;         SP += <span class="nu0">-12</span>;     call timer_interrupt;         SP += <span class="nu0">12</span>;         call return_from_int;         RESTORE_CONTEXT         rti;&nbsp;</pre></div><!-- SECTION [1-3951] --><h3><a name="interrupt_types" id="interrupt_types">Interrupt Types</a></h3><div class="level3"><p> Different interrupt types can be define to allow generic interrupt behaviour. </p><ul><li class="level1"><div class="li"> Simple - the user handler  does ack, clear , mask and unmask</div></li><li class="level1"><div class="li"> Edge - dont mask and allow it to trigger while the service is running </div></li><li class="level1"><div class="li"> Level - mask and disable then service</div></li></ul><p> For any given irq the required handler can be chosen using the <strong>set_irq_handler</strong> function</p><pre class="code c">&nbsp;   set_irq_handler<span class="br0">&#40;</span>irq, do_simple_IRQ<span class="br0">&#41;</span>;   set_irq_handler<span class="br0">&#40;</span>irq, do_level_IRQ<span class="br0">&#41;</span>;   set_irq_handler<span class="br0">&#40;</span>irq, do_edge_IRQ<span class="br0">&#41;</span>;&nbsp;&nbsp;</pre><p>You can add your own handler if needed just use the code for one of the existing handlers a an example.</p></div><!-- SECTION [3952-4576] --><h3><a name="interrupt_numbers" id="interrupt_numbers">Interrupt Numbers</a></h3><div class="level3"><p> uClinux works on an interrupt number assigned to a device these are defined in   <strong>linux-2.6.x/include/asm-blackfin/mach-bf533/irq.h</strong>. The default layout is shown here.</p><p>NOTE The Levels of each interrupt can be reassigned during kerenl configuration.</p><pre class="code c"><span class="coMULTI">/* * Interrupt source definitions             Event Source    Core Event NameCore        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></pre></div><!-- SECTION [4577-] --></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -