嵌入式


中断处理程序架构

<p>对于上半部分和下半部分之间的划分没有严格的规则,靠驱动程序开发人员自己的编程习惯来划分,不过还是有一些习惯供参考:</p> <ul> <li> <p>如果该任务对时间比较敏感,将其放在上半部中执行。</p> </li> <li> <p>如果该任务和硬件相关,一般放在上半部中执行。</p> </li> <li> <p>如果该任务要保证不被其他中断打断,放在上半部中执行(因为这是系统关中断)。</p> </li> <li>其他不太紧急的任务, 一般考虑在下半部执行。</li> </ul> <p>通常下半部分在中断处理程序一返回就会马上运行,目前已经从最原始的BH(bottom half)衍生出BH(在2.5中去除)、软中断(softirq在2.3引入)、tasklet(在2.3引入)、工作队列(work queue在2.5引入)</p> <h3>Linux中断编程</h3> <ol> <li> <p>申请中断 在Linux设备驱动中,使用中断的设备需要先申请对应的中断</p> <pre><code>int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *dev_name, void *dev_id);</code></pre> <ul> <li>irq:请求的中断号</li> </ul> </li> </ol> <ul> <li> <p>handler:中断处理函数指针,中断发生时系统调用该函数。</p> </li> <li> <p>flags:一个与中断管理相关的选项,如果设置成SA_INTERRUPT表示一个&quot;快速&quot;中断处理, 快速中断被处理时屏蔽当前处理器上的所有中断。如果设置成SA_SHIRQ表示中断可以在设备间共享。</p> </li> <li> <p>dev_name:这个字串用在 /proc/interrupts来显示中断的拥有者。</p> </li> <li>dev_id:用作共享中断的指针。如果中断没有被共享, dev_id 可以设置为 NULL,或者指向设备的设备结构体。</li> </ul> <p><code>request_irq()</code>函数返回0表示成功,返回-INVAL表示中断号无效或处理函数指针为NULL,返回-EBUSY表示中断已经被占用且不能共享。</p> <ol> <li> <p>屏蔽单个中断</p> <pre><code>void disable_irq(int irq); void disable_irq_nosync(int irq);</code></pre> </li> <li> <p>使能单个中断 <code>void enable_irq(int irq)函数重新使能被禁止的中断</code></p> </li> <li> <p>禁止所有中断</p> <pre><code>void local_irq_save(unsigned long flags); void local_irq_disable(void); local_irq_save函数禁止当前处理器上所有中断, 并保存当前状态到 flags; local_irq_disable关闭本地中断而不保存状态。</code></pre> </li> <li> <p>使能所有中断</p> <pre><code>void local_irq_restore(unsigned long flags); void local_irq_enable(void);</code></pre> <h3>tasklet机制</h3> <ul> <li>软件中断的派生,调度时机和软中断一样</li> <li>内核中需要延迟执行的多数任务都可以用tasklet来完成</li> <li>在中断期间运行,即使被调度多次,tasklet也只运行一次。</li> <li>asklet把任务延迟到安全时间执行的一种方式</li> </ul> </li> </ol> <blockquote> <p>软中断和tasklet都是运行在中断上下文中,它们与任一进程无关,没有支持的进程完成重新调度。所以软中断和tasklet不能睡眠、不能阻塞,它们的代码中不能含有导致睡眠的动作,如减少信号量、从用户空间拷贝数据或手工分配内存等。</p> </blockquote> <h3>工作队列机制</h3> <ul> <li><strong>它可以把工作推后,交由一个内核线程去执行</strong></li> <li>该工作队列总是会在进程上下文执行</li> <li>工作队列允许重新调度甚至是睡眠</li> </ul> <h3>软中断处理时机</h3> <ol> <li>硬中断处理完成,do_IRQ即将退出时处理</li> <li>softirqd内核线程被唤醒后处理</li> </ol>

页面列表

ITEM_HTML