关于ucos在lpc上移植:
主要有四个文件,传统的有三个文件:os_cpu_c.c,os_cpu_a.s,os_cpu.h
还有一个是IRQ.inc
Os_cpu.h:这个文件相对来说还是很简单的,关于变量的重新定义,堆栈生长度,临界区了,最有特色的是运用swi软中断。
Os_task_sw()肯定是用软中断了,在mdk中要声明一个没有定义的函数,就要在这个函数前面加上__SWI(),也就是用它声明,而__swi()就是一个关键字了。uc在x86上移植也是用的软中断int 0x80。在lpc中一旦调用os_task_sw()就会触发__swi(0x00)这个软中断,那它就会使arm进入管理模式然后执行软中断函数SoftwareInterrupt,这个函数在os_cpu_a.s中定义,后续。
关于os_task_sw() osstartHighRdy() 进入临界区的两个函数 还有一些ARM用到的函数 它们为什么要用软中断而不用普通函数调用呢?答案是这样的:ARM处理核有两个指令集,用户任务还可以使用两种模式:用户和系统,组合起来就有4种方式了,各种方式对系统资源有不同的访问控制权限。为了使底层接口函数与处理器状态无关,同时在任务调用相应的函数时不需要知道函数位置,也就是说:统一进入管理模式,统一用软中断调用。
Os_cpu_a.s:这个文件主要当然是SoftwareInterrupt了,在这个函数里有三方面跳转:
1.os_task_sw 2.osstartHighRdy 3. SWI_Exception
1.一个任务切换也调用OSIntCtxSw这个标号,说明它和中断切换过程一样,都是先保存老的再迎取新的,但是有一点不同:就是这两个函数调用的模式不同:任务级切换是进入管理模式而中断级是进入IRQ模式。妙就妙在虽然是进入的不同模式但一进来都是在SP指针下取老任务的数据然后保存,然后迎新。可以看出这时的SP指针一个是管理的一种情况是IRQ的。Spsr记录了任务的环境,而不管什么模式都用R3来记录spsr,然后保存,总之陈明计写得太效率和有技巧了。
2.osstartHighRdy 其实就是调用OSIntCtxSw_1,就不多说了它就是迎新呗
3.这个函数在.c文件里,后续。
Os_cpu_c.c:文件有一个OSTaskStkInit函数就很明显了,按照堆栈格式模拟,就不多说了。
SWI_Exception这个函数有好几路转向,去除了第一和第二路,因为在os_cpu_a.s中定义了。
临界区函数其实就是进去把中断位关闭就行了。但是还有一个陈添上去的一个全局变量OsEnterSum:主要来实现临界区嵌套,当OsEnterSum = 0的时候才开中断。
剩下的函数也是改变cpsr就完了没什么。
主要是在调用完SWI_Exception这个函数后还得回SoftwareInterrupt里面实现
任务的继续运行
关于函数的参数问题两个参数一个放到R0一个放到R1中传过来,呵呵。
IRQ.inc: 这个文件是汇编头文件里面定义了一个宏,在不少应用里直接把它复制到IRQ.S中了,然后在写上
;/*中断*/
IRQ_Handler HANDLER IRQ_Exception
;/*定时器0中断*/
Timer0_Handler HANDLER Timer0_Exception
这就是对这个宏的运用,分别套用就行了,它实现了os 对IRQ的管理。
在这个宏里面调用了两个函数:一个是IRQ_Exception_Function,一个是OSIntExit。第一个可以是Timer0_Exception在它里面调用timetick(),第二个调用OSIntExit(),在这个函数里调用osIntctxSw(),但是在includes.h中#define OSIntCtxSw() return,把这个函数给费了,呵呵,直接返回啦。然后在
宏里判断是否执行中断级切换。但是我就不明白陈为什么这样做了。
也可以还用os的osIntctxSw()调用啊,如果回来了说明不切换,然后直接恢复现场也行吧。切换就调用osIntctxSw呗。