搜索
bottom↓
回复: 1

ucos 移植到2440上出问题,请帮忙分析下

[复制链接]

出0入0汤圆

发表于 2011-1-2 01:40:01 | 显示全部楼层 |阅读模式
我到目前为止的不良情况就一个:就是,当我所有任务按顺序执行完后,就进入空闲模式,但是当第二次任务就绪,在中断级任务切换时,就出现问题了。
                              当我的任务切换回主程序运行后再进入空闲任务,此时的空闲任务的断点就被指向了boot的复位向量,相当于程序跑飞了,                          请各位分析下,是什么情况

汇编调度的代码如下:
SRCPND           EQU  0x4a000000    ; Source pending
INTPND           EQU  0x4a000010    ; Interrupt request status

rEINTPEND   EQU  0x560000a8
INTOFFSET   EQU  0x4a000014


USERMODE    EQU         0x10
FIQMODE     EQU         0x11
IRQMODE     EQU         0x12
SVCMODE     EQU         0x13
ABORTMODE   EQU         0x17
UNDEFMODE   EQU         0x1b
MODEMASK    EQU         0x1f
NOINT       EQU         0xc0


;*********************************************************************************************************
;                                    EXPORT and EXTERNAL REFERENCES
;*********************************************************************************************************/
        IMPORT  OSRunning
        IMPORT  OSTCBCur
        IMPORT  OSTCBHighRdy
        IMPORT  OSPrioCur
        IMPORT  OSPrioHighRdy
        IMPORT  OSIntNesting
        IMPORT  OS_IntCtxSwFlag
        IMPORT  Int_ReturnAddr
                       
        IMPORT  OSIntEnter
        IMPORT  OSIntExit
        IMPORT  OSTaskSwHook
        IMPORT  C_IRQHandler
       

        EXPORT  OSStartHighRdy
        EXPORT  OSCtxSw       
        EXPORT  OSIntCtxSw

        EXPORT  OSCPUSaveSR
        EXPORT  OSCPURestoreSR
        EXPORT  OS_IRQHandler
       
        PRESERVE8
        AREA UCOS_ARM, CODE, READONLY
       
;====================================================================
; 函数名 : OS_StartHighRdy
; 功  能 : 启动系统第一个任务
; 版  本 : 1.0
;====================================================================
OSStartHighRdy  
        ;----------------------------------------------------------------------------------       
        ; OSRunning = TRUE;
        ;----------------------------------------------------------------------------------       
       
        MSR     CPSR_cxsf,#SVCMODE|NOINT     ;Switch to SVC mode with IRQ&FIQ disable
       
        BL                OSTaskSwHook            ;Call user define Task switch hook
       
        LDR                R0, =OSRunning          ; OSRunning =TRUE
        MOV                R1, #1
        STRB         R1, [R0]

        ;----------------------------------------------------------------------------------               
        ;                 SP = OSTCBHighRdy->OSTCBStkPtr;
        ;----------------------------------------------------------------------------------       
        LDR         R0, =OSTCBHighRdy
        LDR         R0, [R0]         
        LDR         SP, [R0]
        B       POP_ALL        




;====================================================================
; 函数名 : OSCtxSw
; 功  能 : 任务级任务的切换
; 版  本 : 1.0
;====================================================================
OSCtxSw                                                                ; 任务级的任务切换                                                                                                               
                        stmfd sp!,{lr}              ; PC 入栈
                        stmfd sp!,{r0-r12,lr}                ; r0-r12,lr入栈
PUAH_CPSR                       
                        mrs r4,cpsr
                        stmfd sp!,{r4}                                ; cpsr入栈       

        ;----------------------------------------------------------------------------------               
        ; OSTaskSwHook();
        ;---------------------------------------------------------------------------------       
        BL                 OSTaskSwHook               
;====================================================================
; 函数名 : SaveCurTcb
; 功  能 : 保存当前任务执行的断点
; 版  本 : 1.0
;====================================================================
SaveCurTcb                                                 
               
                        ldr r1,=OSPrioCur
                        ldr r2,=OSPrioHighRdy
                        ldrb r3,[r2]
                        strb r3,[r1]
                       
                       

                        ldr r4,=OSTCBCur                ; 取出当前任务的TCB地址
                ldr r5,[r4]                                        ;
                str sp,[r5]                 ; 保存当前任务的堆顶指针到它的TCB(因为TaskCtrBlock地址亦即OSTCBStkPtr的地址)       

       
                        ldr r1,=OSTCBCur
                        ldr r2,=OSTCBHighRdy
                        ldr r2,[r2]
                        str r2,[r1]       

;====================================================================
; 函数名 : GetHighTcb
; 功  能 : 获取高优先级的任务的断点
; 版  本 : 1.0
;====================================================================
GetHighTcb                                                         
               
               

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

;====================================================================
; 函数名 : POP_ALL
; 功  能 : 出栈保存的断点,PC跳转到程序
; 版  本 : 1.0
;====================================================================
POP_ALL                       
            ldmfd sp!,{r4}              ; cpsr出栈
            msr CPSR_cxsf,r4       
                        ldmfd sp!,{r0-r12,lr,pc}    ; r0-r12,lr,pc出栈

OS_IRQHandler                                                        ; 中断入口地址,在中断向量表初始化时被设置
                        sub lr,lr,#4                                ; 计算中断返回地址
                        stmfd sp!,{r0-r3,r12,lr}        ; 保护现场,此时处于中断模式下,sp指向中断模式下的堆栈.不能进行任务切换(各任务堆栈处在管理模式堆栈).
                                                                                ; R4-R11装的是局部变量,在进行函数跳转时,编译器它会自动保护它们,
                        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}^        ; 不进行任务切换,出栈返回被中断的任务。寄存器出栈同时将spsr_irq的值复制到CPSR,实现模式切换                                       

OSIntCtxSw
        ;----------------------------------------------------------------------------------               
        ; Call OSTaskSwHook();
        ;----------------------------------------------------------------------------------       
        BL                 OSTaskSwHook

OS_IntCtxSw                                                                ; 把中断的返回地址保存到Int_Return_Addr_Save变量中
                        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            
                        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而不返回中断前运行的程序       
       
;====================================================================
; 函数名 : OS_TASK_SW_INT
; 功  能 : 中断级任务的切换
; 版  本 : 1.0
;====================================================================                       
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
                        stmfd sp,{r0}                                ; PC入栈
                        sub sp,sp,#56                                ; 调整SP回到栈顶
                        b        PUAH_CPSR
               
       
OSCPUSaveSR
            mrs r0,CPSR                                        ; 保存当前的CPSR值
                       LDR R2,=0xc0
                        orr r1,r0,R2                        ; 关闭所有中断
                msr CPSR_c,r1
                mov pc,lr

OSCPURestoreSR
        MSR     CPSR_c, R0
        MOV     PC, LR
                
        END

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

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

出0入0汤圆

 楼主| 发表于 2011-1-2 01:43:18 | 显示全部楼层
OS_IntCtxSwFlag  这是把源代码中的OSIntCtxSw 变换成用一个标志来判断。

堆栈如下:
    stk      = ptos;                /* Load stack pointer                                      */
   
    *(stk)   = (OS_STK)task;        /* Entry Point                                             */
    *(--stk) = (OS_STK)0;                 /* LR                                                      */
    *(--stk) = (OS_STK)0;                 /* R12                                                     */
    *(--stk) = (OS_STK)0;                 /* R11                                                     */
    *(--stk) = (OS_STK)0;                 /* R10                                                     */
    *(--stk) = (OS_STK)0;                 /* R9                                                      */
    *(--stk) = (OS_STK)0;                 /* R8                                                      */
    *(--stk) = (OS_STK)0;                 /* R7                                                      */
    *(--stk) = (OS_STK)0;                 /* R6                                                      */
    *(--stk) = (OS_STK)0;                 /* R5                                                      */
    *(--stk) = (OS_STK)0;                 /* R4                                                      */
    *(--stk) = (OS_STK)0;                 /* R3                                                      */
    *(--stk) = (OS_STK)0;                 /* R2                                                      */
    *(--stk) = (OS_STK)0;                 /* R1                                                      */
    *(--stk) = (OS_STK)p_arg;       /* R0 : argument                                           */
    *(--stk) = (OS_STK)0x00000013;  /* SVC模式                                                 */
                                                                                
    return (stk);
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-8-26 22:14

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

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