一般来说如果要运行uCos对处理器跟编译器有如下要求:
1 处理器的C编译器能产生可重入型代码;
这点一般的编译器都可以满足这个要求,记得当年学习 51单片机的时候,keil编译器不把局部变量放在栈中,这样就无法做到可重入了,写51ucos有些时候需要特殊处理。这是特殊情况,因为ram很少,所以这么做。
http://blog.csdn.net/xsckernel/article/details/8521837
2.支持开关中断,因为uCos很多关键操作要进入临界区才能执行,mips status 寄存器IE位可以满足要求。可以用内嵌汇编形式完成。
3.处理器能支持一定数量的数据存储硬件堆栈
龙芯1d有4K的ram空间,可以做几个进程的栈空间了
4.处理器有将堆栈指针以及其他CPU寄存器的内容读出、并存储到堆栈或内存中去的指令。
mips架构没有类似于x86上的push pop等指令,这些可以用普通的 寄存器/内存传送数据指令 来完成。
uCos移植过程:
首先是 os_cpu.h 文件
1.设置正确的数据类型;
用typedef 而不是define 稍微有点c 基础的都知道了,龙芯1d还具有浮点寄存器,因此还要定义浮点数据类型,虽然uCos系统用不到,但是
应用程序还是会用到的,另外为了减少切换时间 跟 进程栈空间,在栈中没有为浮点寄存器保留位置,因此只允许一个进程做浮点计算。实际上这也就够了。
2.设置开/关中断(进入临界区)的方法,因为mips的中断是由status上的IE位控制的,并且每次进出中断不会更改IE位,所以需要手动处理,这里是将处理器标志寄存器存储在局部变量中,只要编译器 把这个变量放在栈中就不会出错。
3.设置堆栈增长方向; 通过反汇编分析查看 mips 生成的汇编代码 栈向低地址生长的。
4.设置任务切换方式 OSCtxSw() 每一次任务切换大概消耗4us。这个过程没什么,仔细点,注意堆栈平衡就可以了。
修改os_cpu_c.c文件
1.编写任务堆栈初始化函数,中断发生的时候mips架构的cpu只做极少量的保存工作,寄存器保存几乎没有,也就没有一个固定的压栈出栈顺序,因此可自定义顺序。
OS_TSK OSTaskStkInit()
但一定要把出栈和入栈对应起来, 栈上面保存的status寄存器,其IE位需要为1,这样切换到这个进程的时候总中断是开着的。其它的赋值0也无所谓。
2.编写运行优先级最高的就绪态任务函数(调用任务):void OSStartHighRdy(void)
这个函数主要是用汇编实现,从 OSTCBHighRdy 得到在最高优先级的进程栈指针,然后把栈中内容放到寄存器中并jr reg 即可。
3. 编写中断级任务切换函数void OSIntCtxSw()
这个函数会在 OSIntExit 调用到,当中断把一些任务就绪的时候从中断退出时需要切换进程,就调用这个函数,出栈用宏 RESTORE_REG_ERET 实现,
注意最末尾要给 CP0_EPC 赋值然后eret。能
另外需要注意的一点就是进入中断之后status 里的 IXL位是置位的,如果直接把这个status保存到被中断进程栈中,并且被中断进程在这次中断退出时 也没得到执行,
而是被更高优先级进程剥夺cpu使用权,那么当下次这个进程再次执行的时候IXL位仍然置位,(这个进程本身没有任何感觉自己被中断过一次) 但是IXL位却被置位了
(这点跟x86不同,在x86上因为指令集的支持这些有原子性不用考虑),因此需要中断入栈的时候把这个位清零:
li t1,0xfffffffd; \
and t0,t0,t1; \
附上移植好的代码下载 ,这里面还包括了基于ucos的应用层代码一个热表程序:
http://www.kuaipan.cn/file/id_86604815773232309.htm?source=1