欢迎来到天天文库
浏览记录
ID:39195084
大小:94.50 KB
页数:4页
时间:2019-06-26
《UCOSII多任务》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、1VC下时钟的获得《嵌入式实时操作系统uC/OS-II》这本书已经安排了大量篇幅来专门讲解uC/OS-II的移植:第13章移植uC/OS-II,第14章uC/OS-II在80x86上的移植,第15章uC/OS-II在带有硬件浮点运算单元的80x86上的移植。所以本文只是重点讲解移植到VC下和其他处理器上的不同地方,更详细的介绍读者可以参考《嵌入式实时操作系统uC/OS-II》这本书。和所有其他的移植一样,本文所做的移植也只需要修改uC/OS-II处理器相关代码,一共包括3个文件:OS_CPU.H,OS_CPU_A.ASM,OS_CPU_C.C。考虑到VC可以嵌入汇编代
2、码,并不需要专门的汇编代码文件,所以OS_CPU_A.ASM是多余的,最终只有OS_CPU.H和OS_CPU_C.C两个文件。所以这两个文件成了移植的关键,首先要解决的问题就是时钟“滴答”的获得。移植到BC下的uC/OS-II是通过修改DOS下的硬件时钟中断来得到时钟滴答的,VC下时钟滴答从哪里来呢?这是移植uC/OS-II到VC下第一个要考虑的问题。在windows的保护模式下不能像DOS下面那么容易,直接通过一个函数调用就能够修改中断。windows下要修改中断涉及到驱动程序,这样就加大了移植的困难度与复杂度,但好处是只有真正硬件时钟的“滴答”才能够保证uC/OS
3、-II的实时性。另外一种解决方法是采用windows下的软件定时器,通过定时器来产生模拟时钟“滴答”。考虑到本移植只是为了教学和学习,并没有应用到对实时性要求高的产品,所以最终决定采用软件定时器来模拟时钟中断。Windows下软件定时器种类很多,下面分别简要介绍一下这些定时器:1.SetTimer()函数有windows下编程经验的最先想到的应该是SetTimer这个API函数,但本文采用的移植程序是基于控制台的,也就是说最开始建立VC工程的时候选择的是创建win32consoleapplication,控制台下的程序是没有消息循环的,所以要使用SetTimer函数则
4、必须再创建一个线程来专门处理消息循环,这样一来事情就复杂了,而且这个函数定时精度非常不高。所以这种方法不是特别合适。2.timeSetEvent()函数这个函数很简单,不需要消息循环,定时精度为ms级,主要应用在多媒体定时方面,能够在非常精确的时间间隔内完成一个事件、函数或过程的调用。函数原型:MMRESULTtimeSetEvent(UINTuDelay,UINTuResolution,LPTIMECALLBACKlpTimeProc,WORDdwUser,UINTfuEvent),可以通过调用timeSetEvent()函数,将需要周期性执行的任务定义在LpTim
5、eProc回调函数中,从而完成所需处理的事件。调用这个函数后会增加一个线程,时间一到则在这个线程中调用回调函数,对于主线程来说,非常类似外部中断调用,我们需要的正是这样的效果,所以本文最终选择这个函数来产生时钟“滴答”。3.QueryPerformanceFrequency()和QueryPerformanceCounter()函数这两个函数可以实现更高精度的定时,误差不超过1微秒,进行定时之前,先调用QueryPerformanceFrequency()函数获得机器内部定时器的时钟频率,然后在需要严格定时的事件发生之前和发生之后分别调用QueryPerformanc
6、eCounter()函数,利用两次获得的计数之差及时钟频率,计算出事件经历的精确时间。可见,这两个函数主要是应用在计算时间方面,并没有设置回调函数机制,如果我们要使用这个函数的话,则需要首先创建一个线程,然后在这个线程中计算时间调用我们要定时处理的函数,等于需要手动实现定时函数回调机制,远比timeSetEvent()函数来得复杂。当然还有更多的定时器函数,这里不一一介绍,读者可以自行参考相关书籍。本文选择的是timeSetEvent函数,调用这个函数后uC/OS-II就已经开始它的脉搏了。2模拟时钟中断的产生中断指的是中止当前的事务,处理别的更要紧的事情。我们通过软
7、件定时器来模拟产生uC/OS-II的时钟中断,但timeSetEvent()函数调用定时回调函数是和主线程同时被windows操作系统调度的,并没有起到中断的作用。所以在调用定时回调函数的时候必须停止主线程的运行,退出回调函数则恢复主线程的运行,自然这些事情可以都放在定时回调函数,也就是uC/OS-II的时钟中断处理函数中完成。Windows下要挂起一个线程的运行,首先要得到这个线程的句柄,然后调用SuspendThread(hangdler)和ResumeThread(handler)就可以挂起和继续执行线程。如图1所示。主线程定时器线程主线程调用
此文档下载收益归作者所有