ucosii的中断和时钟

来源:互联网 发布:卡巴斯基网络防火墙 编辑:程序博客网 时间:2024/05/22 19:26

ucosii的中断

为了处理任务延时、任务调度等一些和时间有关的事件,任何一个计算机系统都应该有一个系统时钟。与其他计算机系统一样,ucosii的时钟是通过硬件定时器产生定时中断来实现的。

应中断请求而运行的程序叫做中断服务子程序,中断服务子程序的入口地址叫做中断向量。不支持在ISR中创建、删除、挂起、恢复任务,并且不支持在中断中调用延时函数。

对于可剥夺型内核来说,中断服务子程序运行结束之后,系统将会根据情况进行一次任务调度去运行优先级别最高的任务,而并不一定要继续运行被中断的任务。

为了记录中断嵌套的层数,ucos定义了一个全局变量OSIntNesting,在编写ucosii的中断服务程序时,要用到两个重要的函数OSIntEnter()和OSIintExit()

函数OSIntEnter()的作用就是把全局变量OSIntNesting加1,从而用它来记录中断嵌套的层数。该函数通常发生在中断服务程序保护了被中断的断点数据之后,运行用户中断服务代码之前,所以称之为进入中断服务函数。

OSIntExit为退出中断服务函数,这个函数在中断嵌套层数计数器为0、调度器未被锁定且从任务就绪表中查找到的最高级别就绪任务又不是被中断的任务的条件下将要进行任务切换,否则就返回被中断的服务子程序。

应用程序中的临界段,在ucos中那些不希望被中断的代码段被称为临界段,从代码上看,处在关中断和开中断之间的代码段就是临界段。

OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()这两个宏封装了与系统硬件相关的关中断和开中断指令。

例:void USART1_IRQHandler(void)

{  

OSIntEnter();  

//中断服务程序  

OSIntExit();

}

并且ucos提示不要在临界段调用ucos提供的功能函数(不能调用延时函数),以免系统崩溃。

ucosii的时钟

任何操作系统都要提供一个周期性的信号源,以供系统处理诸如延时、超时等与时间有关的时间,这个周期型的信号源就叫做时钟。

ucosii用硬件定时器产生一个周期性中断来实现系统时钟。最小的时钟单位就是两次中断之间相间隔的时间,这个最小时钟单位叫做时钟节拍(就是系统以固定的频率产生中断(时基中断))。

OSTimeTick()的任务就是在每个时钟节拍了解每个任务的延时状态,其中已经到了延时时限的非挂起任务就进入就绪状态


每次产生系统节拍的时候,系统会执行中断服务程序SysTick定时中断函数OS_CPU_SysTickHandler()(时钟中断服务函数),在中断服务程序中会调用函数OSTimeTick(),在OSTimeTick()执行过程中首先执行的是OSTimeTickHook()(钩子函数)是用户自由编写的函数,如果某段函数的执行周期是一个时钟节拍,那么最好放在钩子函数中,这样定义的函数自然就以系统的时钟节拍的频率运行,因为OSTimeTick函数每一个时钟节拍都要执行一次。

节拍列表就是一个双向链表,其中每个OSCfgTickWheel数组元素代表着一个时间点的节拍列表,相邻OSCfgTickWheel元素代表的时间点对OSCfgTickWheel数组的长度的余数相差一个时钟节拍。

对于那些延时或有限期限等待的任务的任务控制块OS_TCB,会先根据其延时或等待的节拍对OSCfgTickWheel数组长度的余数来决定将其插入到哪个节拍列表,然后再把节拍列表里的任务控制块按照其延时或等待的节拍的大小顺序串联成双向链表。


总结:CPU以一定的频率产生中断,这就是时钟节拍,每个时钟节拍到来时,会进入中断服务程序,在中断服务程序中调用时钟节拍服务函数给时钟节拍任务发送一个信号量,时钟节拍任务收到信号量之后就会更新TickList。Ticklist更新的主要内容是查找是否有任务完成延时,主要方式是哈希查找在查找时,也是将当前的节拍数对OSCfgTickWheel取余找到所在的节拍列表,在一个节拍列表中是TickCtrMatch从小到大排序的,所以当遍历到OSTickCtr和TickCtrMatch相等时,还要继续遍历,因为下一个TickCtrMatch可能和当前是相等的(即有两个要等待时间相同的任务),如果遍历到OSTickCtr和TickCtrMatch不想等时,后面的肯定也不相等,就不用继续遍历了,表明当前达到时间的任务只有一个。如果有任务完成延迟则将其设置为就绪状态。

时间戳是为了测量任务的运行时间、任务等待内核对象的时间等,ucosiii保存了很多时间戳。时间戳可以理解为记录时间点的一个量。

当任务插入列表的时候,会将某常数余数相同的妨碍特定数组的一个相同的元素里,并用链表将其串起来。系统首先会计算OSTickCtr对常数的余数取出数组中存放与这个余数相等的那个元素,然后根据链表的指向找出任务并进行判断和相应的操作。







下边这句话是我认为很重要的但是不知道正确与否(以我现在的能力来看我认为它是对的),即所有硬件的中断的优先级是高于任务优先级的



0 0
原创粉丝点击