原创
关于移植ucosii到windows和linux平台下的思路
最近给学生上ucosii,因为课本上是在dos下运行ucosii,我不知道怎么的,对此一点兴趣没有,总觉得dos古老的东西了,再没兴趣去玩它。但是学校条件很差,没有开发板来实际玩ucosii,因此光看代码效果比较差。于是我原先想在linux下运行ucosii,后来又想既然linux下可以做,那么windows下也就同样可以。
受原书作者的影响,我开始是打算采用和dos下相同的办法移植,即修改中断描述符表IDT,把时钟节拍中断isr改成自己的,这个isr就是ucosii需要的那个时钟节拍产生器,当然调用完自定义的IRQ0 isr后再去调用linux/windows的IRQ0 isr。不过昨天仔细一想觉得这个办法很困难,修改IDT需要写个驱动完成,更重要的是任务切换这块的代码很难实现,用个 软件中断INT x了模拟?可是为了能直接操作寄存器可能必须在内核模式下完成,包括时钟的 isr更是必须在内核模式下运行,内核模式下回调ucosii的OTimeTick等 函数将非常复杂,毕竟ucosii要运行在用户模式下。最后觉得最主要的问题是无法再内核模式程序与ucosii之间通信,共享许多全局变量,比如就绪表那些数据结构。
昨天夜里想到3点多,想到可以完全用软件模拟个虚拟的硬件环境来运行ucosii。我的思路如下(以windows为例,linux是完全类似的)
1. 首先用个软件定时器(win32 API中的timer)实现模拟时钟节拍中断。定时器到期时候会触发个事件(最好可能还是用win32的那种可等待的定时器),专门创建个线程等待这个定时器事件,这个线程就相当于模拟了ucosii里面需要的那个时钟节拍isr。该线程一旦等到定时器事件,则执行OSTimeTick,这样就模拟了时钟节拍
2.每个任务用一个windows线程模拟,在调用OSTaskCreate创建一个任务的时候,需要调用OSTaskStkInit函数初始化堆栈,这个函数是移植过程需要实现的,我的想法就是实现这个函数,在这个函数里面CreateThread创建个线程,这个线程就运行该任务的代码。线程创建的时候指定不运行,而是在挂起状态
3.整个ucosii当作一个windows进程,里面各个任务是该进程的线程,为模拟任务调度,可以设置个全局的数组变量OSThreadHandle[63],改数组保存与每个任务对应的线程句柄,且位置与任务的优先级对应,比如优先级为0的任务对应的线程句柄放在OSThreadHandle[0]中。
4.任务调度过程这样模拟:OSSched()函数(不需要修改它)根据优先级找到就绪的最高优先级,放在OSPrioHighRdy中,然后唤醒一个专门用于调度的线程,该线程通过这个OSPrioHighRdy在OSThreadHandle中找到对应的线程句柄,如果需要切换,则挂起当前线程,唤醒OSPrioHighRdy对应的那个线程,模拟了任务调度过程。
win32 api中的ResumeThread,SuspendThread正好干这些事情
5.OSINTEnter和OSINTExit的模拟:这个只要停止定时器就能实现
6.任务删除也很好模拟,写个OSTaskDelHook,在这个函数里调用api函数TerminateThread然后closehandle就可以把任务对应的线程干掉,从而达到删除任务的要求
这样ucosii将完全是个windows下的用户模式的进程,大体想了这么多,觉得应该可以实现。但是最近事情多,不一定有工夫做。这个包括linux版本的实现还是有意思的,可以学到不少东西。
用户1599209 2014-2-7 02:41
挺好的。。。。。。
用户433095 2012-11-29 09:34
用户1361860 2009-9-25 15:12
用户1190478 2009-9-25 11:40
用户143405 2008-4-20 21:08