您的位置:首页 > 其它

UCOS移植到leon2上

2007-03-19 21:48 176 查看
移植的代码早就写好了,但是测试发了更多的时间,现在测试还在进行中。

先前移植ucos是基于sparc v8的register window 模型,后来写完代码,发现问题重重,于是在老师的建议下还是重新返工了,重写了基于mflat模型的代码,重写的时间也就是一天的时间,后来就是一直在测试。

一直是没有找到很好的测试方法,所以只能用直接写几个任务,然后向串口打印东西。要是谁有好的方法,告诉我一声呵。下面还是说说把ucos移植到sparc v8上需要注意的问题吧。

最先碰到的是中断返回的问题,sparc 跟其它的处理器在这点上很不同。当发生中断的时候,sparc是还未执行当前指令,而其它处理器一般是已执行完当前指令了。所以当我们中断返回时,要用这么一条语句

jmpl %l1,%g0

rett %l2

nop

这样,就会跳回了原来程序了。

在ucos移植过程中,要把data cache以及MMU关掉,因为有data cache 可能会导致cache的数据和外部的IO数据不一致,而ucos操作系统是不支持MMU的。

在修改os_cpu_a.s这个文件中,不管是OSCtxSw还是OSIntCtxSw,返回时最好用rett指令,因为这才不会改变原窗口的寄存器。

当然了,在移植的过程中要特别注意sparc结构的堆栈。

__________ ___________ %sp ( foo() )
%sp | %l0-%l7 | 8*4 保存foo()的%l0-%l7寄存器
|__________|
%sp+32 | %i0-%i7 | 8*4 保存foo()的%i0-%i7寄存器 (%i7包含foo()的返回地址)
|__________|
%sp+64 |返回值地址| 1*4 为下一个被调函数保留的返回值地址空间
|__________|
%sp+68 | 参数地址 | 6*4 为下一个被调函数保留(前6个)参数的空间
|__________|
%sp+92 | 参数地址 | n*4 n>=1 如果下一个被调函数的参数>6,多出的参数在这里分配
|__________|
|局部变量 |
| .... | n*8 为foo()的局部变量分配空间,每8个字节为一个分配单元
| |
|__________|
| 临时区域 | 4*4 C编译器用来计算表达式时储存一些临时变量的区域
|__________|___________ %fp ( main() )
%fp | %l0-%l7 | 8*4 保存main()的%l0-%l7寄存器
|__________|
%fp+32 | %i0-%i7 | 8*4 保存main()的%i0-%i7寄存器(%i7包含main()的返回地址)
|__________|
%fp+64 |返回值地址| 1*4 为被调函数(这里是foo())保留的返回值地址空间
|__________|
%fp+68 | 参数地址 | 6*4 为被调函数(这里是foo())保留前6个参数的地址间
|__________|
%fp+92 | 参数地址 | n*4 n>=1 如果下一个被调函数的参数>6,多出的参数在这里分配
|__________|
|局部变量 |
| .... | n*8 为main()的局部变量分配空间,每8个字节为一个单元
| |
|__________|
| 保留区域 | 4*4 4个字的保留区域
|__________|
| %l0-%l7 |
|__________|
....

堆栈高址

如上面所示,%sp+64为下一个被调函数的返回地址空间,所以在我们为每个任务分配堆栈时,要为每个任务的堆栈的高地址空间预留出一些
如,我是这样创建任务的
OSTaskCreate(Task1, (void *)&TaskData[0], &TaskStk[0][TASK_STK_SIZE - 0x19], 1);
这样子我就为任务预留了0x18*4 byte

最后说让我折腾最久的一个问题,leon2的板的时钟主频是120M,发现程序跑得怪怪的,后来的老师的提醒下,把它改为了100M,程序运行就较为正常了

测试中。。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: