7049|11

86

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

急!!关于ARM7 工作模式的问题 [复制链接]

(环境:ucos,CPU:arm7 )当任务被中断时,那么此时CPU进入IRQ(异常)模式,则此时的SP是R13_IRQ吗?书上说CPU寄存器(r1~r12)以及PC是保存在任务的堆栈里,但我的疑问是既然此时进入的是IRQ模式,那为何不是保存在R13_irq,也即在堆栈初始化时的SP=IRQStack里(初始化堆栈时有ld sp,=IRQStack)?如果保存在任务堆栈里,那IRQStack还有何用处?

以上问题盼各位能给予答复,感激不尽!
此帖出自ARM技术论坛

最新回复

这个问题值得讨论,可以不结贴,让大伙也深入理解一下,呵呵  详情 回复 发表于 2008-12-30 21:51
点赞 关注
 

回复
举报

71

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
R13_irq应该是进入IRQ模式后被用做堆栈的,而不应该是保存到这个里面吧
当CPU产生IRQ中断的时候是先保存SPSR等相关信息后才切换到IRQ模式的,而不是产生IRQ马上就切入IRQ模式
IRQStack应该是在IRQ模式下需要堆栈的时候用到吧
此帖出自ARM技术论坛
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
ucos源代码是把现场保存在了任务堆栈里,但进入中断时并没有切换模式的代码,这似乎很令人困惑!
此帖出自ARM技术论坛
 
 
 

回复

59

帖子

0

TA的资源

一粒金砂(初级)

4
 
那你说代码里SP指的是什么?难道不是在工作模式固定后,自动切换到各种模式下吗?
此帖出自ARM技术论坛
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

5
 
当有IRQ中断发生时,首先应该是保存当前PC值到R14_irq中,然后保存CPSR到SPSR_irq中,接下来就是在CPSR中将处理器模式切换到IRQ模式,禁止新的IRQ中断,然后就跳转到IRQ异常的中断向量表,这过程应该是由CPU内部来完成的,不需要手动来切换的
另外一点你说的切换好象是指任务之间的切换,现场的保存等,这跟CPU模式的切换好象有些不同吧
此帖出自ARM技术论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

6
 
刚回顾了一下IRQHandler的代码,原来跳到IRQ中断向量表后,先保存了IRQ模式下的现场(这里的SP是IRQ模式下的堆栈,保存的也是IRQ模式下的寄存器),然后马上切换到SVC模式,调用相关的中断处理函数ISR,当取得返回的逻辑中断后系统再次切回IRQ模式,然后再判断进入IRQ模式前的运行模式,切回原来的模式。这样才完整的完成了一次IRQ过程
这里一个关键是系统发生IRQ中断时,ARMCPU自动保存当前模式下的CPSR等切换到IRQ中断向量表。
我参考的代码是Wince下面的处理,我想这应该跟操作系统关系不大
此帖出自ARM技术论坛
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

7
 
这是Windows CE下面的IRQ处理函数代码:
;-------------------------------------------------------------------------------
        NESTED_ENTRY IRQHandler
        sub     lr, lr, #4                      ; fix return address
        stmfd   sp!, {r0-r3, r12, lr}
        PROLOG_END
        ;
        ; Test interlocked API status.
        ;
        sub     r0, lr, #INTERLOCKED_START
        cmp     r0, #INTERLOCKED_END-INTERLOCKED_START
        bllo    CheckInterlockedRestart

        ;
        ; CAREFUL! The stack frame is being altered here. It's ok since
        ; the only routine relying on this was the Interlock Check. Note that
        ; we re-push LR onto the stack so that the incoming argument area to
        ; OEMInterruptHandler will be correct.
        ;
        mrs     r1, spsr                        ; (r1) = saved status reg
        stmfd   sp!, {r1}                       ; save SPSR onto the IRQ stack
        mov     r0,lr                           ; parameter to OEMInterruptHandler

        msr     cpsr_c, #SVC_MODE:OR:0x80       ; switch to supervisor mode w/IRQs disabled
        stmfd   sp!, {lr}                       ; save LR onto the SVC stack
        stmfd   sp!, {r0}                       ; save IRQ LR (in R0) onto the SVC stack (param)

        ;
        ; Now we call the OEM's interrupt handler code. It is up to them to
        ; enable interrupts if they so desire. We can't do it for them since
        ; there's only on interrupt and they haven't yet defined their nesting.
        ;

        CALL    OEMInterruptHandler

        ; (r0) = SYSINTR returned
        ; call the ISR hook (pfnOEMIntrOccurs is set to a faked function if not changed by OEM)
        ldr     r1, =pfnOEMIntrOccurs           
        ldr     r1, [r1]                        ; (r1) = pfnOEMIntrOccurs
        mov     lr, pc                          ; (lr) = return address
  IF Interworking :LOR: Thumbing
        bx      r1                              ; call the pfnOEMIntrOccurs
  ELSE
        mov     pc, r1                          ; call the pfnOEMIntrOccurs
  ENDIF

        ldmfd   sp!, {r1}                       ; dummy pop (parameter)
        ldmfd   sp!, {lr}                       ; restore SVC LR from the SVC stack
        msr     cpsr_c, #IRQ_MODE:OR:0x80       ; switch back to IRQ mode w/IRQs disabled

        ;
        ; Restore the saved program status register from the stack.
        ;
        ldmfd   sp!, {r1}                       ; restore IRQ SPSR from the IRQ stack
        msr     spsr, r1                        ; (r1) = saved status reg

        ldr     lr, =KData                      ; (lr) = ptr to KDataStruct
        cmp     r0, #SYSINTR_RESCHED
        beq     %F10
        sub     r0, r0, #SYSINTR_DEVICES
        cmp     r0, #SYSINTR_MAX_DEVICES
        ;
        ; If not a device request (and not SYSINTR_RESCHED)
        ;        
        ldrhsb  r0, [lr, #bResched]             ; (r0) = reschedule flag
        bhs     %F20                            ; not a device request

        cmp     r0, #32                         ; (r0 >= 32)?
        subge   r0, r0, #32                     ; r0 -= 32 if true
        ldrlt   r2, [lr, #PendEvents1]          ; (r2) = pending interrupt event mask (lower 32)
        ldrge   r2, [lr, #PendEvents2]          ; (r2) = pending interrupt event mask (upper 32)
        mov     r1, #1
        orr     r2, r2, r1, LSL r0              ; (r2) = new pending mask
        strlt   r2, [lr, #PendEvents1]          ; save it
        strge   r2, [lr, #PendEvents2]          ; save it

        ;
        ; mark reschedule needed
        ;
10      ldrb    r0, [lr, #bResched]             ; (r0) = reschedule flag
        orr     r0, r0, #1                      ; set "reschedule needed bit"
        strb    r0, [lr, #bResched]             ; update flag

20      mrs     r1, spsr                        ; (r1) = saved status register value
        and     r1, r1, #0x1F                   ; (r1) = interrupted mode
        cmp     r1, #USER_MODE                  ; previously in user mode?
        cmpne   r1, #SYSTEM_MODE                ; if not, was it system mode?
        cmpeq   r0, #1                          ; user or system: is resched == 1
        ldmnefd sp!, {r0-r3, r12, pc}^          ; can't reschedule right now so return
        
        sub     lr, lr, #4
        ldmfd   sp!, {r0-r3, r12}
        stmdb   lr, {r0-r3}
        ldmfd   sp!, {r0}
        str     r0, [lr]                        ; save resume address
        mov     r1, #ID_RESCHEDULE              ; (r1) = exception ID

        b       CommonHandler

        ENTRY_END IRQHandler

        ;;;NESTED_ENTRY FIQResched
此帖出自ARM技术论坛
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

8
 
很好,讲到俺心坎里去了,我也是这样认为的!只不过我下载的ucos可是别人移植的,里面并没有切换工作模式的代码!呵呵
此帖出自ARM技术论坛
 
 
 

回复

85

帖子

0

TA的资源

一粒金砂(初级)

9
 
mark
此帖出自ARM技术论坛
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

10
 
LZ咋不结贴呢?哈哈,突破3000分准备要散分了
此帖出自ARM技术论坛
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

11
 
ls的,哭吧,LZ的结贴率为0 啊 哈哈。。。。。。。
此帖出自ARM技术论坛
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

12
 
这个问题值得讨论,可以不结贴,让大伙也深入理解一下,呵呵
此帖出自ARM技术论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表