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