系统中断与时钟节拍
1 系统中断与时钟节拍
1.1 系统中断
中断是种硬件机制用于通知CPU有个异步事件发生了中断旦被系统识别CPU则保存部分(或全部)现场
(context)即部分(或全部)寄存器值跳转到专门子称为中断服务子(ISR)中断服务子做事件处理处理完成后执行任务调度回到就绪态优先级最高任务开始运行(对于可剥夺型内核)
中断使得CPU可以在事件发生时才予以处理而不必让微处理器连续不断地查询(polling)是否有事件发生通过两条特殊指令:关中断(disable errupt)和开中断(enable errupt)可以让微处理器不响应或响应中断在实时环境中关中断时间应尽量短关中断影响中断响应时间关中断时间太长可能会引起中断丢失中断服务处理时间应该尽可能短中断服务所做事情应该尽可能少应把大部分工作留给任务去做
1.2 系统时钟节拍
时钟节拍是特定周期性中断(时钟中断)这个中断可以看作是系统心脏脉动操作系统通过时钟中断来确定时间间隔实现时间延时及确定任务超时中断之间时间间隔取决于不同应用般在10,200 ms之间时钟节拍式中断使得内核可以将任务延时若干个整数时钟节拍以及当任务等待事件发生时提供等待超时依据时钟节拍频率越快系统额外开销就越大系统定义了32位无符号整数OSTime来记录系统启动后时钟滴答数目用户必须在多任务系统启动以后再开启时钟节拍器也就是在OSStart之后μC/OSII中时钟节拍服务是通过在中断服务子中 OSTimeTick实现时钟节拍中断服务子示意代码如下:
void OSTickISR(void) {
保存处理器寄存器值;
OSIntEnter 或是将OSIntNesting加1;
OSTimeTick ;
OSIntExit ;
恢复处理器寄存器值;
执行中断返回指令;
}
2 时钟管理系统
2.1 μC/OSII时钟管理系统
μC/OSII原有时钟管理系统类似于Linux但是比Linux简单得多它仅向用户提供个周期性信号OSTime时钟频率可以设置在10,100 Hz时钟硬件周期性地向CPU发出时钟中断系统周期性响应时钟中断每次时钟中断到来时中断处理更新个全局变量OSTimeμC/OSII时钟中断服务核心是OSTimeTick OSTimeTick 用来判断延时任务是否延时结束从而将其置于就绪态其伪代码如下:
void OSTimeTick(void) {
OSTimeTickHook;// 用户定义时钟节拍外连
while { (除空闲任务外所有任务)
OS_ENTER_CRITICAL;//关中断
对所有任务延时时间递减;
扫描时间到期任务并且唤醒该任务;
OS_EXIT_CRITICAL;//开中断
指针指向下个任务;
}
OSTime;//累计从开机以来时间
}
在μC/OSII时钟节拍中需要执行用户定义时钟节拍外连OSTimeTickHook 以及对任务链
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
进行扫描并且递减任务延时这样就造成了时钟节拍OSTimeTick 有两点不足:
? 在时钟中断中处理额外任务OSTimeIickHook 这样增加了中断处理负担影响了定时服务准确性;
? 在关中断情况下扫描任务链表任务越多所需要时间越长而长时间关中断对中断响应有不利影响是中断处理应当避免
2.2 改进时钟管理系统
针对上述OSTimeTick 不足之处需加以改进来优化时钟节拍在Linux中般对中断响应分为两部分:立即中断服务和底半中断处理(bottom half)立即中断服务仅仅做重要并且能快速完成工作而把不太重要需要较长时间完成工作放在底半处理部分来完成这样就可以提高中断响应速度μC/OSII不支持底半处理为了减轻时钟中断处理工作量来提高μC/OSII时钟精确度可以将部分在每次时钟中断需处理工作内容放在任务级来完成这样就可以减少每次时钟中断处理CPU消耗从而提高中断响应速度和μC/OSII时钟精确度为此定义任务OSTimeTask 由它来处理原来在OSTimeTick中需要处理操作μC/OSII采用基于优先级抢占式调度策略而每次时钟中断处理结束后需要首先调度该任务执行因此让任务OSTimeTask具有系统内最高优先级由它执行用户定义时钟节拍外连OSTimeTickHook 以及对所有任务延时时间进行递减并把到期任务链入到链表OSTCBRList中OSTCBRList管理所有到期任务OSTimeTask伪代码如下:
void OSTimeTask {
OSTimeTickHook//用户定义时间处理
while { (除空闲任务外所有任务)
对所有任务延时时间进行递减;
把所有要到期任务链入到OSTCBRList链表中;
} 任务状态改为睡眠OSSched 进行任务调度;
}
在任务OSTimeTask中执行原来在时钟中断处理用户OSTimeIickHook 并实现将延时到期任务链入到OSTCBRList链表中这样在时钟中断中就只需要扫描任务到期链表而不需要扫描整个链表减少了关中断时间 ,OSTCBRList为新建链表它管理所有到期任务,同时需要减少OSTimeTick 执行工作量只对OSTCBRList链表扫描这样也减少了关中断时间OSTimeTick 伪
代码如下:
void OSTimeTick(void) {
OSTime;
OS_TCB* ptcb=OSTCBList;// OSTCBRList指向所有到期任务链表 while(ptchb!=null){
关中断;
唤醒任务;
开中断;
指针指向下个任务;
}
}