搜索
bottom↓
回复: 1

ucosii移植新手发问:ucosii移植到ARM为什么要切换模式?

[复制链接]

出0入0汤圆

发表于 2011-1-3 22:28:11 | 显示全部楼层 |阅读模式
问一个很菜的问题,为什么在UCOS移植到ARM上时,在中断处理时为什么要切换模式?(在S32440上测试的)
   问题:1、在ARM上,当进入中断后不是只需保存{R0-R12,PC}吗?,为什么还要切换模式的保存过去有保存过来,不是R0_R12在除了FIQ模式下都是向通的
            吗?
         2、在ARM中断里面,在调用OSIntCtxSw时,我们不是可以直接把中断模式下把进入中断时的PC保存了,进而直接在调用OSIntCtxSw时,把调用     
            OSIntCtxSw当做退出中断的PC(退出中断时直接跳到OSIntCtxSw,把开始保存的那个中断的PC入栈,再保存到OSTCBCur中),这样可以吗?

请大家帮忙分析这个代码可以吗:
                        sub lr,lr,#4                ; 计算中断返回地址
                        stmfd sp!,{r0-r3,r12,lr}        ; 保护现场,此时处于中断模式下,sp指向中断模式下的堆栈       
                          BL OSIntEnter                                        
                        bl C_IRQHandler                ; 调用c语言的中断处理程序
                        bl OSIntExit                ; 判断中断后是否有更高优先级的任务进入就绪而需要进行任务切换
                        ldr r0,=OS_IntCtxSwFlag        ; if(OSIntCtxSwFlag == 1) OSIntCtxSw()
                        ldr r1,[r0]
                        cmp r1,#1                                       
                        beq OSIntCtxSw                ; 有更高优先级的任务进入了就绪状态,则跳转到OSIntCtxSw进行中断级的任务切换
                        ldmfd sp!,{r0-r3,r12,pc}^        ; 不进行任务切换,出栈返回被中断的任务。
OS_IntCtxSw                                        ; 把中断的返回地址保存到Int_ReturnAddr变量中
                        ldr r0,=OS_IntCtxSwFlag
                        mov r1,#0
                        str r1,[r0]                ; OSIntCtxSwFlag = 0
                       
                        add sp,sp,#20                ; 调整SP,使之指向之前入栈的lr(中断模式下的lr保存的是中断返回地址),
                        ldr r0,[sp]                                       
                        ldr r1,=Int_ReturnAddr          ; 将中断返回地址赋值给Int_ReturnAddr      
                        str r0,[r1]                ;保存中断退出的地址                               
                        ldr r0,=OS_TASK_SW_INT                       
                        str r0,[sp]                ; 保存中断任务执行的地址,即把进入中断的断点地址更新
                        sub sp,sp,#20                ; 调整SP回到栈顶
                        ldmfd sp!,{r0-r3,r12,pc}^        ; 退出中断后跳到OS_TASK_SW_INT而不返回中断前运行的程序
OS_TASK_SW_INT                                                                               
                                sub sp,sp,#4                ; 为PC保留位置
                        stmfd sp!,{r0-r12,lr}                ; r0-r12,lr入栈
                        ldr r0,=Int_ReturnAddr          ; 取出进入中断之前保存的PC
                        ldr r0,[r0]                                       
                        add sp,sp,#56                ; 调整SP 到堆栈格式的保存PC的位置
                        stmfd sp,{r0}                ; PC入栈 ,把进入中断时断点地址给保存起来,为下面的保存当前任务控制块做准备
                        sub sp,sp,#56                ; 调整SP回到栈顶
                        b        PUSH_CPSR       


PUSH_CPSR                       
                        mrs r4,cpsr
                        stmfd sp!,{r4}                                ; cpsr入栈       

                             BL  OSTaskSwHook               
SaveCurTcb                                                 
               
                        ldr r1,=OSPrioCur                 ;更新当前的运行任务的优先级ID号
                        ldr r2,=OSPrioHighRdy
                        ldrb r3,[r2]
                        strb r3,[r1]
                       
                       

                        ldr r4,=OSTCBCur                    ; 取出当前任务的TCB地址
                                     ldr r5,[r4]                                        ;
                                     str sp,[r5]                 ; 保存当前任务的堆顶指针到它的TCB的堆栈指针上       

       
                        ldr r1,=OSTCBCur                 ;更新指向当前任务控制块指针的指向
                        ldr r2,=OSTCBHighRdy
                        ldr r2,[r2]
                        str r2,[r1]       

GetHighTcb                                                         
               
               

                        ldr r6,=OSTCBHighRdy        ; 取出更高优先级就绪任务的TCB的地址
                                     ldr r6,[r6]
                        ldr sp,[r6]                 ; 取出更高优先级任务的堆顶指针到SP                
                        b   POP_ALL                                        ; 根据设定的栈结构顺序出栈       

POP_ALL                       
                               ldmfd sp!,{r4}              ; cpsr出栈
                               msr CPSR_cxsf,r4       
                          ldmfd sp!,{r0-r12,lr,pc}    ; r0-r12,lr,pc出栈

以上就是一个中断级任务切换的汇编代码,请问这个可行吗?我认为可行,但是为什么移植UCOS时老是出问题,这里我没有用到模式切换,我的程序运行在管理模式下,没有用系统模式。

请前辈解答下!  这个代码是不是有错?...

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2011-1-4 12:57:59 | 显示全部楼层
没研究过,中断中切换模式可能是为了支持中断嵌套
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 23:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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