中断处理与时间管理.ppt

上传人:小飞机 文档编号:5170583 上传时间:2023-06-10 格式:PPT 页数:47 大小:550KB
返回 下载 相关 举报
中断处理与时间管理.ppt_第1页
第1页 / 共47页
中断处理与时间管理.ppt_第2页
第2页 / 共47页
中断处理与时间管理.ppt_第3页
第3页 / 共47页
中断处理与时间管理.ppt_第4页
第4页 / 共47页
中断处理与时间管理.ppt_第5页
第5页 / 共47页
点击查看更多>>
资源描述

《中断处理与时间管理.ppt》由会员分享,可在线阅读,更多相关《中断处理与时间管理.ppt(47页珍藏版)》请在三一办公上搜索。

1、第4章中断处理与时间管理,4.1 中断处理的基本概念,4.1.1 中断中断定义为CPU对系统内、外发生的异步事件的响应。异步事件是指没有一定时序关系的、随机发生的事件。当中断产生时,由硬件向CPU 发送一个异步事件请求,CPU接收到请求后,中止当前工作,保存当前运行环境,转去处理相应的异步事件任务,这个过程称为中断。事件处理完毕后,程序回到:在前后台系统中,程序回到后台程序;在不可剥夺型内核中,程序回到被中断了的任务;在可剥夺型内核中,让进入就绪态的优先级最高的任务开始运行,若没有高优先级任务准备就绪,则回到被中断了的任务。,4.1.1 中断,使用中断机制的优点在于:CPU无需连续不断地查询是

2、否有新的事件发生,只需在有事件发生时才作出响应。CPU可以通过两条特殊指令:关中断(Disable Interrupt)和开中断(Enable Interrupt)来响应和不响应中断。关中断会影响中断延迟时间,时间太长可能会引起中断丢失。所以在实时环境中,关中断的时间应尽量短。在中断服务期间,CPU一般允许中断嵌套,如图4.1所示,允许新的中断打入,识别中断优先级别更高的事件。,图4.1 中断嵌套,4.1.2 中断延迟,中断延迟定义为从硬件中断发生到开始执行中断处理程序第一条指令所用的时间,也就是说,中断延迟是从中断发生到中断跳转指令执行完毕之间的这段时间它是实时内核最重要的指标。由于实时操作

3、系统考虑得更多的是最坏的情况,而不是平均的情况,因此指令执行的时间必须按照最长的指令执行时间来计算。所以中断延迟时间,通常是由关中断的最长时间来决定的。关中断的时间越长,中断延迟就越长。,4.1.2 中断延迟,中断延迟由下式给出:,在不可剥夺型和不可剥夺内核中:,在前后台系统中:,4.1.3 中断响应,中断响应定义为从中断发生起到开始执行中断用户处理程序的第一条指令所用的时间,换句话说,中断响应是从中断发生到刚刚开始处理异步事件之间的这段时间,它包括开始处理这个中断前的全部开销。一般地,执行用户代码之前要保护现场,将CPU的各个寄存器推入堆栈。这段时间将被称为中断响应时间。,4.1.3 中断响

4、应,在可剥夺型内核中,则要先调用一个特定的函数,通知内核即将进行中断服务,使得内核可以跟踪中断的嵌套。对于C/OS-说来,这个函数是OSIntEnter(),可剥夺型内核的中断响应时间由下式给出:,在前后台系统和不可剥夺型内核中,保存寄存器以后立即执行用户代码,中断响应时间由下式给出:,中断响应考虑的是系统在最坏情况下的响应中断时间,而不是平均时间。如某系统100次中有99次在100s之内响应中断,只有一次响应中断的时间是250s,只能认为中断响应时间是250s。,4.1.4 中断恢复时间,中断恢复时间(Interrupt Recovery)定义为CPU返回到被中断了的程序代码所需要的时间。在

5、前后台系统和不可剥夺型内核中,中断恢复时间只包括恢复CPU内部寄存器值的时间和执行中断返回指令的时间。中断恢复时间由下式给出:,4.1.4 中断恢复时间,对于可剥夺型内核,中断的恢复要复杂一些。一般地,可剥夺型内核在中断服务子程序的末尾,都要调用一个由实时内核提供的中断脱离函数。在C/OS-中,这个函数叫做OSIntExit(),它首先判断是否脱离了所有的中断嵌套,然后再判断是否有更高优先级的任务准备就绪。若还处于中断嵌套中,那么程序返回到前一级中断服务子程序继续执行;若已经脱离了所有的中断嵌套,则检查当前是否有优先级更高的任务准备就绪,若有则返回到这个优先级更高的任务,被中断了的任务只有重新

6、成为优先级最高的就绪态任务时才能恢复运行;如果没有更高优先级任务准备就绪,则返回到被中断的任务继续执行。在这种情况下,可剥夺型内核的中断恢复时间由下式给出:,4.1.5 中断延迟、响应和恢复比较,4.1.6 非屏蔽中断,非屏蔽中断(NMI)是指不能用系统指令来关闭的中断,其特点是中断优先级高、延迟时间短、响应快、不能被嵌套,不能忍受内核的延迟,一般常应用于紧急事件处理,如掉电保护等。作为一种规则:在非屏蔽中断服务子程序中,不能在非屏蔽中断处理内处理临界区代码、不能使用内核提供的服务。在非屏蔽中断处理程序中参数的传递必须用全程变量,且全程变量的字节长度必须能够一次读完。若一定要在非屏蔽中断产生时

7、使用内核服务,则可以通过用非屏蔽中断产生普通可屏蔽中断的方法来实现。,4.2 C/OS-的中断处理,4.2.1 中断处理程序 在C/OS-中,中断处理程序可用汇编语言编写,也可以用C语言编写。一个标准的C/OS-中断服务子程序应该按图4.4所示流程图进行编写。,图4.4 标准中断处理程序流程图,4.2.1 中断处理程序,OSIntEnter()函数源代码如程序清单4.1所示:,4.2.1 中断处理程序,图4.5,OSIntExit()函数程序流程,OSIntExit()函数主要完成4个功能:(1)给中断嵌套层数计数器减1;(2)找出准备就绪的最高优先级任务;(3)检查准备就绪的最高优先级任务是

8、否为被当前服务所中断的任务,若是则返回到被中断的任务;若不是,则进行任务控制块指针切换,将即将运行的任务的任务控制块的指针指向当前准备就绪的优先级最高的任务的任务控制块;(4)调用中断级任务切换函数OSIntCtxSw(),进行任务切换。,4.2.1 中断处理程序,OSIntExit()看起来很像任务调度函数OSSched(),不同之处有三点:OSIntExit()使中断嵌套层数减1,而重新的调度条件是:中断嵌套层数计数器和调度锁定嵌套计数器(OSLockNesting)二者都必须是零。OSRdyTbl所需的检索值Y是保存在全程变量OSIntExitY中的,这样做是为了避免在任务栈中安排局部变

9、量。如果需要做任务切换,OSIntExit()将调用中断级任务切换函数OSIntCtxSw(),而不是调用任务级任务切换函数OS_TASK_SW()。,4.2.2 中断处理过程,图4.6 C/OS-II的中断处理过程示意图,4.3 C/OS-的时钟节拍,4.3.1 时钟节拍时钟节拍是特定的周期性中断(时钟中断),可以看作是系统心脏的脉动。时钟节拍是内核的最小计时单位,它完成两个功能:一是累计时间,C/OS-定义了32位无符号整数OSTime来记录系统启动后时钟节拍滴答的数目;二是通过时钟中断来确定时间间隔,实现任务的延时及确定任务超时。时钟节拍频率取决于不同的应用,一般以10100Hz为宜。时

10、钟节拍频率越快,系统的额外开销就越大,实际频率取决于用户程序的精度。C/OS-II中的时钟节拍服务是通过在中断服务子程序OSTickISR()中调用时钟节拍子程序OSTimeTick()实现的。时钟节拍计时的单位是1个时钟节拍,由于时钟节拍计时存在抖动问题,所以计时的精度可能并不是一个时钟节拍,只是在每个时钟节拍中断到来的时候作一次裁决而已。那么抖动对计时精度是如何影响的呢?下面将分三种情况讨论说明。,4.3 C/OS-的时钟节拍,如图4.7、4.8、4.9所示,假设时钟节拍每20ms发生一次,要求将任务A延时一个时钟节拍即20ms。图中阴影部分表示各个任务的运行时间,由于程序中可能存在循环和

11、条件语句,所以同一任务在不同时期的运行时间的长短可能不同,时钟节拍中断服务子程序的运行时间也不同。为了更方便地说明问题,图中的延时画得有所夸大。,图4.7 将任务延迟一个时钟节拍(第一种情况),第一种情况,如图4.7所示,所有中断和高优先级的任务都超前于要求延时一个时钟节拍的任务A运行,图4.8将任务延迟一个时钟节拍(第二种情况),第二种情况,如图4.8所示,所有高优先级的任务和中断服务的执行时间都小于1个时钟节拍。,图4.9将任务延迟一个时钟节拍(第三种情况),第三种情况,如图4.9所示,中断和所有高优先级的运行时间的总和大于1个时钟节拍。,清楚地认识0到一个节拍之间的延时过程是非常重要的,

12、如果用户只想延时一个时钟节拍,而实际上得到的往往不是一个时钟节拍。即使用户的处理器的负荷不是很重,这种情况依然是存在的。为了保证足够的精度,延时设计时最好多加一个时钟节拍,例如要将任务延时5个时钟节拍,则应该在程序中延时6个。,4.3.1 时钟节拍,延时的抖动在所有的实时操作系统中都会存在,其根本原因可能在于:一是CPU负荷太重;二是系统设计可能不正确。一般解决此类问题的方法主要有:提高时钟节拍的频率;提高CPU微处理器的时钟频率;重新安排任务的优先级;避免使用浮点运算(如果非使用不可,尽量用单精度数);使用能较好地优化程序代码的编译器;时间要求苛刻的代码用汇编语言写;选择处理速率更快的CPU

13、。,4.3.2 时钟节拍程序,C/OS-II中的时钟节拍服务是通过在时钟节拍中断服务子程序OSTickISR()中调用节拍服务子程序OSTimeTick()实现的,在OSTimeTick()中还会调用OSTimeTickHook()函数,即时钟节拍用户扩展函数,该函数保留为用户自己编写,可以扩展应用。,4.3.2.1 时钟节拍中断服务子程序,时钟节拍中断服务子程序的特点如下:每个时钟中断一次,由它调用节拍服务函数OSTimeTick();时钟节拍中断服从C/OS-所描述的全部规则;这段代码必须用汇编语言编写,因为在C语言里不能直接处理CPU的寄存器。,4.3.2.2 节拍服务子程序,节拍服务子

14、程序OSTimeTick()的主要工作是:给每个用户任务控制块OS_TCB中的时间延时项OSTCBDly减1,直到等于零,执行时间直接与任务个数成正比。,4.3.3 时钟节拍器的正确用法,C/OS-时钟节拍的正确用法是应该在多任务系统启动以后再开启时钟节拍器,也即调用OSStart()后的第一件事就是开放时钟节拍中断,这段代码可以由用户嵌入到OSStart()函数内。反之,若在OSInit()与OSStart()之间开放时钟节拍器中断,时钟节拍中断就有可能在C/OS-启动第一个任务之前发生,此时C/OS-处在一种不确定的状态之中。因此,用户应用程序有可能会崩溃。下面是一个错误用法的示意性程序清

15、单,它在多任务调度前就开放了时钟中断。,4.4 C/OS-的时间管理,C/OS-有5个与时钟节拍有关的系统服务,它们分别是:OSTimeDly(),任务延时函数;OSTimeDlyHMSM(),按时分秒毫秒延时函数;OSTimeDlyResume(),让处在延时期的任务结束延时;OSTimeGet(),获得系统时间;OSTimeSet(),设置系统时间。这些函数属于OS_TIME.C文件。要调用这些函数,必须首先在OS_CFG.H文件中设置配置常量。,4.4 C/OS-的时间管理,4.4.1 任务延时函数,OSTimeDly(),C/OS-的任务是一个无限循环,由于C/OS-是可剥夺型内核,如

16、果高优先级任务不主动挂起,低优先级任务就永远无法取得运行权,最高优先级任务将独占CPU的使用权。因此,C/OS-规定:除了永不挂起的空闲任务外,其它所有的任务都要在合适的时候调用系统服务函数,自我挂起,暂时放弃CPU使用权,使低优先权任务能够得以运行。这种系统服务函数就包括这一小节将要介绍的任务延时函数OSTimeDly()和下一小节将要介绍的按时分秒毫秒延时函数OSTimeDlyHMSM()。,4.4.1.1 函数原型,void OSTimeDly(INT16U ticks)OSTimeDly()函数申请一个系统提供的延时,延时的单位是一个时钟节拍,最大可延时65535个时钟节拍。调用该函数

17、后,若延时时间不为0,则立即挂起当前任务,C/OS-进行一次任务调度,并且执行下一个优先级最高的就绪态任务。任务调用OSTimeDly()后,一旦规定的时间期满或者有其它的任务通过调用OSTimeDlyResume()取消了延时,它就会马上进入就绪状态。当然,只有当该任务在所有就绪任务中具有最高的优先级时,它才会立即运行。由于中断不能延时,所以它的调用者一定是任务。函数只有一个参数ticks:要延时的时钟节拍数,无返回值。,4.4.1.2 注意事项,在调用OSTimeDly()函数时必须注意以下事项:时间的长短是用时钟节拍的数目来确定的;可提供的时钟节拍数范围是:165,535;参数为0,表明

18、不进行延时操作,而立即返回调用者;为了确保设定的延时时间,建议设定的时钟节拍数加1;只能在任务中调用,无开关量。,4.4.1.3程序流程和源代码,4.4.2 按时分秒毫秒延时函数,OSTimeDlyHMSM(),4.4.2.3 注意事项,要使用该函数,首先要用OS_CPU.H文件中定义的全局常数OS_TICKS_PER_SEC将时间转换为时钟节拍数,这个全局常数表示的是每秒钟时钟节拍器产生的节拍数量,称为时钟节拍频率,其值一般设置在10100Hz之间;4个参数全为0,表示不进行任何操作,直接返回;当时钟周期1ms时,计时最小单位是一个时钟节拍,精度是0.5个节拍。例如,若将时钟节拍频率(OS_

19、TICKS_PER_SEC)设置成100Hz(10ms),4ms的延时不会产生任何延时!而5ms的延时就等于延时10ms;当时钟周期 1ms时,最小计数值 OS_TICKS_PER_SEC/1000个时钟节拍,分辨率500L/OS_TICKS_PER_SEC/1000L。例如,OS_TICKS_PER_SEC1000,最小计数单位是1ms,精度=0.5(个最小计算单位)。,4.4.2.3 注意事项,C/OS-支持的延时最长为65,535个节拍。要想支持更长时间的延时,需采用一定的算法,一般的做法是将延时时钟数分割为两部分:一部分是65,535个节拍的数目,另一部分是总数减去65,535后剩下的

20、节拍数,然后先算剩下的节拍数,再算65,535节拍数。例如,若OS_TICKS_PER_SEC的值为100,用户想延时15分钟,则OSTimeDlyHMSM()会延时1560100 90,000个时钟。这个延时会被分割成两次32,768个节拍的延时(因为用户只能延时65,535个节拍而不是65536个节拍)和一次24,464个节拍的延时。在这种情况下,OSTimeDlyHMSM()首先考虑剩下的节拍,然后是超过65,535的节拍数(即两个32,768个节拍延时)。由于受到OSTimeDlyHMSM()具体实现方法的限制,用户不能结束延时调用OSTimeDlyHMSM()要求延时超过65,535

21、个节拍的任务。假如,时钟节拍的频率是100Hz,用户就不能调用OSTimeDlyHMSM(0,10,55,350)或更长延迟时间的任务;只能在任务中调用。,4.4.2.4 源代码及其注释,4.4.2.5 范例,让处在延时期的任务结束延时,OSTimeDlyResume(),4.4.3.1 函数原型 INT8UOSTimeDlyResume(INT8U prio)OSTimeDlyResume()函数用于唤醒一个用OSTimeDly()或OSTimeDlyHMSM()函数延时的任务。正在延时的任务可以通过调用该函数取消延时来使自己处于就绪态,而不必等待延时期满。OSTimeDlyResume()

22、还可以唤醒正在等待事件的任务,但不推荐使用这种方法。另外,如果任务是通过等待信号量、邮箱或消息队列来延时自己的,那么可以简单地通过控制信号量、邮箱或消息队列来恢复任务。这种情况存在的唯一问题是可能会多占用一些内存,因为它要求用户分配事件控制块。函数只需要1个参数prio,即指定要唤醒任务的优先级。,4.4.3.2 返回值,函数的返回值如下述内容之一:OS_ON_ERR 调用成功;OS_PRIO_INVALID 参数指定的优先级大于OS_LOWEST_PRIO;OS_TASK_NOT_DLY 要唤醒的任务不在挂起状态;OS_TASK_NOT_EXIST 指定的任务不存在。,4.4.3.3 注意事

23、项,一般不推荐去唤醒一个设置了等待超时操作且等待事件发生的任务,尽管操作的结果可以使该任务结束等待;不能唤醒一个用OSTimeDlyHMSM()延时且总延时时间超过65,536个时钟节拍的任务。例如,若系统时钟为100Hz,不能唤醒延时OSTimeDlyHMSM(0,10,55,350)或更长时间的任务;可以唤醒正在等待事件的任务,但不推荐使用;只能在任务中调用。,范例,4.4.4 系统时间,OSTimeGet()和OSTimeSet(),时钟节拍每发生一次,C/OS-就会给一个32位计数器OSTime加1,这个计数器在调用OSStart()启动多任务时和执行完毕65,53665,5364,2

24、94,967,295个节拍后从0开始计数。如果时钟节拍的频率等于100Hz,即10ms计数1次,那么这个32位的计数器每隔497天就从0开始计数。用户可以通过调用OSTimeGet()函数来获得该计数器的当前值,通过调用OSTimeSet()函数来改变该计数器的值。,4.4.4.1 函数原型,INT32U OSTimeGet(void)获取系统时间,返回获取当前时钟节拍数。void OSTimeSet(INT32U ticks)设置系统时间,参数是需要设置的时钟数量,单位是时钟节拍数。它们的调用者可以是任务,也可以是中断。,OSTimeGet()和OSTimeSet()两个函数的代码如程序清单4.10所示。因为OSTime是全局变量,所以访问OSTime时,需要关闭中断。在大多数8位CPU上增加和复制一个32位的数都需要多条指令,这些指令需要一次执行完毕,而不能被打断。,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号