QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 3474|回复: 2

问题和回答 ",关于skyeye 下的 ucOSII 移植

[复制链接]
发表于 2004-1-10 00:47:32 | 显示全部楼层 |阅读模式
求助,关于skyeye 下的 ucOSII 移植
我下载了skyeye下的ucOSII,移植到TI 的ARM7上,可是对于OS_ENTER_CRITICAL() 和 OS_EXIT_CRITICAL()的实现却有一点疑问。
       这两个宏实现在skyeye中如下:

_ARMDisableInt:               
MRS        r0, cpsr
STMFD        sp!, {r0}                 ; push current PSR
ORR        r0, r0, #0x80
MSR        cpsr, r0                 ; disable IRQ Int s
MOV        pc, lr
      
_ARMEnableInt:        
LDMFD        sp!, {r0}                ; pop current PSR
MSR        cpsr_c, r0               ; restore original cpsr        
MSR        cpsr, r0               ; restore original cpsr               
MOV        pc, lr

基本上是这样的,OS_ENTER_CRITICAL ( disable IRQ) 将CPSR
入栈,SP --; OS_EXIT_CRITICAL ( enable IRQ) 将 CPSR
弹出栈,SP ++;可是在这两个中间,如果有用到局部变量,而C中
的局部变量多半是以SP为base索引的,就会出问题。
  
     或者是我什么地方错了? 请多多指教 。。
---------------------------------------------------------------------------
liming's answer
hi, 你好!
    首先,这确实是个好问题,当时我也没有考虑到,现在提出来了,
虽然写论文很忙,但还是仔细想了一下。
    我查看了一下源码,并且对比了 ADS 的 armcc 和 GNU 的
arm-elf-gcc 编译后的汇编代码,发现所有用到局部变量的地方都不是
使用 sp 来标识的,而大多是用的 r1,r2 之类的通用寄存器,没有
用 sp+offset 来定位,所以没有影响局部变量的值。
    但这种做法,在局部变量很少的情况下是可以的,但是如果很多呢?
我也比较疑惑,于是我做了个实验如下,:

这里我开了一个局部数组,看编译器怎么办?

void Task2(void * pParam)
{
int a[100];
y=1000;
    while (1)
        {      
                a[98] = 1234;
                a[97] = 4321;
                a[96] = a[97] + a[98];
                y --;
                which = 1;
                Sleep(6);
        }
}

下面的是编译后得到的汇编码,可以着重看我红色标出来的部分 ——

010014b0 <Task2>:
10014b0:       e1a0c00d        mov     r12, sp
10014b4:       e92dd9f0        stmdb   sp!, {r4, r5, r6, r7, r8, r11, r12, lr, pc}
10014b8:       e24cb004        sub     r11, r12, #4    ; 0x4

void Task2(void * pParam)
{
int a[100];
y=1000;
    while (1)
10014bc:       e3a05e4d        mov     r5, #1232       ; 0x4d0
10014c0:       e2855002        add     r5, r5, #2      ; 0x2
10014c4:       e3a04d43        mov     r4, #4288       ; 0x10c0
10014c8:       e2844021        add     r4, r4, #33     ; 0x21
10014cc:       e0847005        add     r7, r4, r5
10014d0:       e59f203c        ldr     r2, [pc, #3c]   ; 1001514 <Task2+0x64>
10014d4:       e3a03ffa        mov     r3, #1000       ; 0x3e8
10014d8:       e59f8038        ldr     r8, [pc, #38]   ; 1001518 <Task2+0x68>
10014dc:       e1a06002        mov     r6, r2
10014e0:       e24dde19        sub     sp, sp, #400    ; 0x190
10014e4:       e5823000        str     r3, [r2]
        {      
                a[98] = 1234;
10014e8:       e50b5028        str     r5, [r11, -#40]
                a[97] = 4321;
10014ec:       e50b402c        str     r4, [r11, -#44]
                a[96] = a[97] + a[98];
10014f0:       e50b7030        str     r7, [r11, -#48]
                y --;
                which = 1;
10014f4:       e3a03001        mov     r3, #1  ; 0x1
10014f8:       e5962000        ldr     r2, [r6]
                Sleep(6);
10014fc:       e3a00006        mov     r0, #6  ; 0x6
1001500:       e5883000        str     r3, [r8]
1001504:       e2422001        sub     r2, r2, #1      ; 0x1
1001508:       e5862000        str     r2, [r6]
100150c:       eb000003        bl      1001520 <Sleep>
        }
1001510:       eafffff4        b       10014e8 <Task2+0x38>
1001514:       01006060        tsteq   r0, r0, rrx
1001518:       01006064        tsteq   r0, r4, rrx
}
100151c:       e91ba9f0        ldmdb   r11, {r4, r5, r6, r7, r8, r11, sp, pc}


    相信你已经知道为什么没有影响局部变量的值了。
---------------------------------------------------------------
richard hoo的回复:

        多谢,回复很快:-)
        看来ADS是先保存了SP的值到寄存器中,然后一直用这个寄存器
来做基值寻址。
        我目前在TI DSC25上做开发,用的是TI 的CCS,我仔细看了
汇编和反汇编的代码,它都是直接用SP来寻址的,所以这样写
就有问题。
        目前我考虑有两个办法,一个是强行disable IRQ/enable IRQ,
不保存当前的CPSR值; 另外一个办法就是用另外的一个不用的
STACK SP,比如ABT exception 一直不用,用它来push/pop.
不过这样每次disable/enables的时候就要切换工作模式,
比较耗时间。
发表于 2004-1-10 12:27:32 | 显示全部楼层
我正在看ucos2,邵贝贝翻译的2001版本
觉得ucos是基于x86讲的,先看懂x86,再移植到其他系统上

各位大侠:
1,是不是要全部仔细从前往后看,能不能跳着看一些,先上手啊?
2,我要往DSP或者ARM上移植的话,学习哪些内容会比较快一些呢?
3,请搞这个的大侠写点东西吧,让我们快速入门啊,呵呵

也可email联系我,谢谢!!
回复

使用道具 举报

 楼主| 发表于 2004-1-10 23:55:56 | 显示全部楼层
ucosii的书中是基于x86讲的.
不过没有关系.
1 可以跳着看,特别是与具体硬件无关的ucosi部分
2 ARM相关的硬件知识需要有.
3 基于ARM的书籍很多,你可以参考一下.
然后看看与基于skyeye仿真的at91开发板有关的相关文档(可到166.111.68.183/pub/embed 处下载),再用skyeye运行调试一下ucosii 就会有比较快的感受.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-12-4 01:25 , Processed in 0.047917 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表