
VxWorks信号中断和定时.ppt
21页VxWorks应用设计中科信软培训中心六、VxWorks中断和定时器6.1中断l设备向CPU发送中断,通知CPU发生了某些事 件l加载用户自定义的程序,在中断到达时执行该程 序l中断服务程序不是一个任务l设备上的板上定时器是一个常见的中断源,可以 通过它来理解中断中断处理举例中断向量表handler中断号硬件中断↗ISR包装代码Handler:Save registercall routineRestore registerRET↗用户ISRmyISR() { … }↗设置中断处理程序lVxWorks提供函数intConnect(), 它允许将指定的C函数 与任意中断相联系STATUS intConnect(){ VOIDFUNCPTR *vector;/*要联系的中断向量*/ VOIDFUNCPTR *routine; /*中断发生时要调用的函数*/ intparameter;/*传递给中断处理函数的参数*/}l该函数将指定的C函数与指定的中断向量相联系,函数 的地址存放在这个中断向量中当发生中断时,系统调 用该函数中断堆栈l大多数体系结构的CPU的ISR使用相同的中断堆 栈l中断堆栈在系统启动时分配l堆栈大小由宏ISR_STACK_SIZE控制,默认值 在configAll.h中定义l堆栈必须足够大,以保证能够处理系统最坏情况 下的中断嵌套lISR没有任务控制块(TCB),并且所有的ISR 共享一个堆栈VxWorks中断处理流程l保存CPU寄存器l从中断控制器读中断向量号l顺序调用该中断服务程序l通知中断控制器中断服务程序结束l恢复CPU寄存器l返回中断和优先级ISR的使用限制lISR执行完成之前,其它任务不能执行lISR中不能调用某些VxWorks函数,尤其是,ISR不能被阻塞 –不能调用semTake() –不能调用malloc(),free() –不能调用I/O系统函数(如printf()) –不能调用使用浮点协处理器的程序l非法指令或总线错导致硬件异常时,该任务被挂起,其他任务继续 执行l如果ISR没有context被挂起,vxworks将在低端内存保存对异常的 描述,并重启系统如何使用ISRl保持ISR尽量短,因为ISR –会延迟低或相同优先级的中断 –延迟所有的任务 –调试起来比较困难l避免在ISR中使用浮点指针操作l尽量将有些工作放到任务中去完成 –持续时间长的工作 –不是非常重要的工作中断与任务间的通信l共享存储器和环缓冲区 –ISR与任务共享变量、存储器和环缓冲区l信号量 –ISR释放信号量,任务等待接收信号量l消息队列 –ISR发送消息,任务等待接收消息,如果消息队列满,该 消息被丢弃l管道 –ISR向管道写消息,任务读消息调试中断l中断处理程序可以调用logMsg()向系统输出诊断 信息–logMsg(“foo= %d\n”,foo,2,3,4,5,6)–向tLogTask发送请求为我们实现printf()的功能l和printf()相似,但必须注意 –参数必须为4字节 –函数有6个入口参数l使用具有系统级调试的机制进行调试 –WDB Agent –emulator6.2 定时器l系统时钟中断服务程序l看门狗定时器l辅助时钟定时器l板上的定时器会周期性地中断CPUl定时器使得用户自定义的程序可以周期性地执行 ,这对下列情况非常有用 –轮询硬件 –检查系统错误lVxWorks提供对两种定时器的相同的接口 –系统时钟 –辅助时钟系统时钟l系统时钟完成下列工作 –增加ticks计数(使用tickGet()获得计数值) –更新延时和超时计数器 –检查循环调度l默认的时钟频率是60Hz–sysClkRateSet()设置时钟频率–sysClkRateGet()获得时钟频率lsysClkRateSet()通常在系统启动时进行设置( VxSim方式下可以随时设置)辅助时钟l相关函数lsysAuxClkConnect()lsysAuxClkRateGet()lsysAuxClkRateSet()lsysAuxClkEnable()lsysAuxClkDisable()看门狗定时器l系统时钟的一个用户接口l能够使C程序在一个给定延时后开始执行l一旦延时超时,指定的程序开始执行l作为系统ISR的一部分,要遵守ISR的编程要求创建看门狗定时器l创建一个看门狗定时器l–WDOG_ID wdCreate() l–返回wotchdogid或NULL或ERRORl启动(或重启)一个看门狗定时器–STATUS wdStart(wdId, delay, pRoutine, parameter )–wdId由wdCreate返回的watchdog Id–delay要延时的ticks–pRoutine当延时超时时,要调用的程序–parameter传递给程序的参数lwdStart()可以在超时时运行看门狗程序,要想周期性执 行,看门狗程序必须调用wdStart()自己重新启动使用看门狗定时器l使用看门狗定时器可以使一段程序周期性地执行wdId= wdCreate();–wdStart( wdId, DELAY_PERIOD, myWdIsr, 0);–void myWdIsr(param)–{doit(param);–wdStart( wdId, DELAY_PERIOD, myWdIsr, 0);l}ldoit程序可以 –轮询某些硬件设备 –解锁某些任务 –检查系统是否出现错误停止看门狗定时器l要取消原来已经启动的看门狗定时器–STATUS wdCancel(wdId)l要删除一个看门狗定时器(并取消原先启动的定 时器)STATUS wdDelete( wdId)轮询的实现l任务级轮询的实现taskDelay()快速,但不够精准wdStart()+semGive()–STATUS wdCancel(wdId)l尽量不要为了轮询而将系统时钟频率设置过高,那样操 作会对更多的clock tick产生额外的开销l高速轮询可以使用辅助时钟。
