首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

基于μC/OS-II的中断下半部设计方案 02

基于μC/OS-II的中断下半部设计方案 02

因为在下半部的实现中已通过巧妙的设计消除了重入的可能性。softirq遵循μC/OS—II对编写中断服务程序的限制要求,例如中断服务函数不能执行可能会导致任务阻塞的函数等,在此不再赘述。
  2 中断下半部的实现
  基于操作系统设计全局的考虑,中断下半部的实现应遵循以下几点原则:
  ①中断下半部也将运行于中断空间,这意味着任务空间的所有任务都要被阻塞。中断下半部与中断上半部(即中断服务程序)一个根本的不同是:中断下半部允许中断。
  ②尽量对原μC/0S—II体系结构做最小化的修改,如任务调度机制、任务空间的各种保护和同步机制等。改动所涉及的范围越大,引入bug的可能性也越大。在所增加的代码中尽量利用原μC/0S—II提供的系统调用,如开关中断还有任务调度等函数,这样兼顾了效率和安全性。

  ③尽量减少使用平台相关性代码,保证μC/OS—II的可移植性。
  ④设计简洁明确的API接口,以方便其他开发者能够轻松使用这种机制。
  根据中断下半部的设计方案,其实现分为以下4个主要的模块。
 2.1 中断下半部入口的实现
  μC/OS—II核心代码os_core.c中的OSIntExit()函数是μC/OS—II中断处理程序的出口。为了实现中断下半部的入口,应将OSIntExit()函数中if((OSIntNesting=0)&&(OSLockNesting==O))语句以下列代码来代替:




  第1条if语句判断是否所有中断服务程序都已经结束,注意这里也包括softirq。因为在进入下半部管理函数后会执行OSIntNesting++,若softirq正在执行则OSInt-Nesting一定大于O。这个简单的if判断语句消除了soft—irq的重入的可能性。判断条件为真后,继续判断全局变量softirq_flag,若其值为SOFTIRQ_ENABLE则启用中断下半部。全局变量softirq_stat可能的值有3个:
  ①SOFTIRQ_READY,说明有就绪的softirq等待运行;
  ②SOFTIRQ_RUNNING,说明softirq正在被调度但其状态可能为被中断态;
  ③SOFTIRQ_NONE,说明没有softirq处于就绪状态。



  此判断语句条件为真时,函数OSIntCallSirq()将会保存被中断任务的上下文,初始化中断下半部堆栈指针,并执行下半部管理函数OSDo-Sirq()。若判断结果为假,则中断处理返回被中断的语句继续执行。而这条语句可能为中断下半部的代码,也可能为任务空间的代码。0S—IntCallSirq()是一段具有平台相关性的汇编代码,在不同的处理器平台上有不同的实现代码,其流程如图2所示。

  2.2 下半部管理函数OSDoSirq()的实现
  这是中断下半部实现的核心部分。其代码如下:

点击看原图






  首先,通过使用OSIntNesting++以防止softirq的重入,设置softirq_stat的值为S0FTIRQ_RUNNING以标识softirq在执行。通过检查softirq_pending的值来判断是否还有就绪的softirq等待执行。
  然后,利用INTS_0N()显示允许中断,并执行getHighPrioSirq()函数快速地判断已就绪最高优先级的softirq的序号。getHighPrioSirq()利用了PendingMap[]数组实现了以空间换时间的思想,能够快速计算出一个32位无符号整数中最低一位“1”的序号。PendingMap口是有256个INT32U类型数据的数组,PendingMap[temp]的值就是以二进制表示的8位无符号整数temp中最低一位“1”的序号。
返回列表