资源描述:
《基于嵌入式操作系统VxWorks的多任务并发程序设计(5)――中断与任务》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、基于嵌入式操作系统VxWorks的多任务并发程序设计(5)――中断与任务中断处理是整个运行系统中优先级最高的代码,可以抢占任何任务级代码运行。中断机制是多任务环境运行的基础,是系统实时性的保证。几乎所有的实时多任务操作系统都需要一个周期性系统时钟中断的支持,用以完成时间片调度和延时处理。VxWorks提供tickAnnounce(),由系统时钟中断调用,周期性地触发内核。 为了快速响应中断,VxWorks的中断服务程序(ISR)运行在特定的空间。不同于一般的任务,中断服务程序没有任务上下文,不包含任务控制块,所有的中断服务
2、程序使用同一中断堆栈,它在系统启动时就已根据具体的配置参数进行了分配和初始化。在ISR中能使用的函数类型与在一般任务中能使用的有些不同,主要体现在: (1)ISR中不能调用可能导致blocking的函数,例如: (a)不能以semTake获取信号量,因如果该信号量不可利用,内核会试图让调用者切换到blocking态; (b)malloc和free可能导致blocking,因此也不能使用; (c)应避免进行VxWorksI/O系统操作(除管道外); (d)应避免在ISR中进行浮点操作。 (2)在ISR中应以logM
3、sg打印消息,避免使用printf; (3)理想的ISR仅仅调用semGive等函数,其它的事情交给semTake这个信号量的任务去做。一个ISR通常作为通信或同步的发起者,它采用发送信号量或向消息队列发送一个消息的方式触发相关任务至就绪态。ISR几乎不能作为信息的接收者,它不可以等待接收消息或信号量。 11.中断服务程序 VxWorks中与中断相关的重要API函数或宏有: (1)intConnect():中断连接,将中断向量与ISR入口函数绑定SYNOPSISSTATUSintConnect ( VOIDFU
4、NCPTR* vector,/*interruptvectortoattachto */ VOIDFUNCPTR routine,/*routinetobecalled */ int parameter/*parametertobepassedtoroutine*/ );intConnect只是调用了下文将要介绍的intHandlerCreate()和intVecSet()函数。 (2)INUM_TO_IVEC(intNum):将中断号转化为中断向量的宏。与INUM_TO_IVEC对应的还有一个I
5、VEC_TO_INUM(intVec),实现相反的过程。INUM_TO_IVEC和IVEC_TO_INUM的具体定义与特定的BSP有关,例如:/*macrostoconvertinterruptvectors<->interruptnumbers*/#defineIVEC_TO_INUM(intVec) ((int)(intVec))#defineINUM_TO_IVEC(intNum) ((VOIDFUNCPTR*)(intNum)) 结合1、2可知一般挂接一个中断服务程序的调用为:intConnect(INUM_T
6、O_IVEC(INTERRUPT_LEVEL),(VOIDFUNCPTR)interruptHandler,i); 例1:中断服务程序/*includes*/#include"vxWorks.h"#include"intLib.h"#include"taskLib.h"#include"sysLib.h"#include"logLib.h" /*functionprototypes*/voidinterruptHandler(int);voidinterruptCatcher(void); /*globals*/#de
7、fineINTERRUPT_NUM2#defineINTERRUPT_LEVEL65#defineITER140#defineLONG_TIME1000000#definePRIORITY100#defineONE_SECOND100 voidinterruptGenerator(void)/*tasktogeneratetheSIGINTsignal*/{ inti,j,taskId,priority; STATUStaskAlive; if((taskId=taskSpawn("interruptCatcher",
8、PRIORITY,0x100,20000,(FUNCPTR) interruptCatcher,0,0,0,0,0,0,0,0,0,0))==ERROR) logMsg("taskSpawninterruptCatcherfailedn",0,0,0,0,0,0); for