spaceaky 发表于 2008-9-21 15:51:56

zlgucos移植的问题,关于swi软件中断返回的理解。【恢复】

问各位朋友一个zlgucos移植的问题



在SoftwareInterrupt 

LDR SP, StackSvc ; 重新设置堆栈指针 

STMFD SP!, {R0-R3, R12, LR} 

MOV R1, SP ; R1指向参数存储位置 

MRS R3, SPSR 

TST R3, #T_bit ; 中断前是否是Thumb状态 

LDRNEH R0,  ; 是: 取得Thumb状态SWI号 

BICNE R0, R0, #0xff00 

LDREQ R0,  ; 否: 取得arm状态SWI号 

BICEQ R0, R0, #0xFF000000 

; r0 = SWI号,R1指向参数存储位置 

CMP R0, #1 

LDRLO PC, =OSIntCtxSw ;swi 0x00调用OSIntCtxSw 

LDREQ PC, =__OSStartHighRdy ; SWI 0x01为第一次任务切换 



BL SWI_Exception 

LDMFD SP!, {R0-R3, R12, PC}^

中,程序有可能会跳到最后这个代码LDMFD SP!, {R0-R3, R12, PC}^ 处嘛?



LDRLO PC, =OSIntCtxSw ;swi 0x00调用OSIntCtxSw 

LDREQ PC, =__OSStartHighRdy ; SWI 0x01为第一次任务切换 

BL SWI_Exception  

这三个语句都跳到相应的处理程序地方去了,没有看到它们跳回来的语句啊?

METAL_MAX 发表于 2008-9-21 18:35:06

自问自答?太强大了!

ARM体系与结构书里绝对要提到这个上标的。

spaceaky 发表于 2008-9-21 16:11:49

小三角的问题我找到答案了 

答案:

'^'是一个后缀标志,不能在User模式和Sys系统模式下使用该标志.该标志有两个存在目的:

6.1.对于LDM操作,同时恢复的寄存器中含有pc(r15)寄存器,那么指令执行的同时cpu自动将spsr拷贝到cpsr中

如:在IRQ中断返回代码中[如下为ads环境下的代码gliethttp]

ldmfd {r4}          //读取sp中保存的的spsr值到r4中

msr spsr_cxsf,r4    //对spsr的所有控制为进行写操作,将r4的值全部注入spsr

ldmfd {r0-r12,lr,pc}^//当指令执行完毕,pc跳转之前,将spsr的值自动拷贝到cpsr中

6.2.数据的送入、送出发生在User用户模式下的寄存器,而非当前模式寄存器

如:ldmdb sp,{r0 - lr}^;表示sp栈中的数据回复到User分组寄存器r0-lr中,而不是恢复到当前模式寄存器r0-lr  当然对于User,System,IRQ,SVC,Abort,Undefined这6种模式来说r0-r12是共用的,只是r13和r14

  为分别独有,对于FIQ模式,仅仅r0-r7是和前6中模式的r0-r7共用,r8-r14都是FIQ模式下专有.





还有那个返回的问题没有

spaceaky 发表于 2008-9-21 15:53:13

__OSStartHighRdy 程序如下

__OSStartHighRdy

        MSR     CPSR_c, #(NoInt | SYS32Mode)

                                                ;告诉uC/OS-II自身已经运行

        LDR     R4, =OSRunning

        MOV     R5, #1

        STRB    R5, 



        BL      OSTaskSwHook                    ;调用钩子函数



        LDR     R6, =OSTCBHighRdy

        LDR     R6, 

        B       OSIntCtxSw_1



        AREA    SWIStacks, DATA, NOINIT,ALIGN=2

SvcStackSpace      SPACE   SVC_STACK_LEGTH * 4  ;管理模式堆栈空间

spaceaky 发表于 2008-9-21 16:02:24

还有个问题 这个汇编语言 LDMFD   SP!, {R0-R12, LR, PC }^  程序后面的这个小三角^ ,表示什么意思 在arm体系结构这书里面怎么没有看到介绍呢?

spaceaky 发表于 2008-9-21 15:53:49

我就看不懂软件中断在这里是怎么返回了的

spaceaky 发表于 2008-9-21 15:52:30

OSIntCtxSw 

程序如下

OSIntCtxSw

                                                    ;下面为保存任务环境

        LDR     R2,                        ;获取PC

        LDR     R12,                       ;获取R12

        MRS     R0, CPSR



        MSR     CPSR_c, #(NoInt | SYS32Mode)

        MOV     R1, LR

        STMFD   SP!, {R1-R2}                        ;保存LR,PC

        STMFD   SP!, {R4-R12}                       ;保存R4-R12



        MSR     CPSR_c, R0

        LDMFD   SP!, {R4-R7}                        ;获取R0-R3

        ADD     SP, SP, #8                          ;出栈R12,PC

        

        MSR     CPSR_c, #(NoInt | SYS32Mode)

        STMFD   SP!, {R4-R7}                        ;保存R0-R3

        

        LDR     R1, =OsEnterSum                     ;获取OsEnterSum

        LDR     R2, 

        STMFD   SP!, {R2, R3}                       ;保存CPSR,OsEnterSum



                                                    ;保存当前任务堆栈指针到当前任务的TCB

        LDR     R1, =OSTCBCur

        LDR     R1, 

        STR     SP, 



        BL      OSTaskSwHook                        ;调用钩子函数

                                                    ;OSPrioCur <= OSPrioHighRdy

        LDR     R4, =OSPrioCur

        LDR     R5, =OSPrioHighRdy

        LDRB    R6, 

        STRB    R6, 

                                                    ;OSTCBCur <= OSTCBHighRdy

        LDR     R6, =OSTCBHighRdy

        LDR     R6, 

        LDR     R4, =OSTCBCur

        STR     R6, 

OSIntCtxSw_1

                                                    ;获取新任务堆栈指针

        LDR     R4, 

        ADD     SP, R4, #68                         ;17寄存器CPSR,OsEnterSum,R0-R12,LR,SP

        LDR     LR, 

        MSR     CPSR_c, #(NoInt | SVC32Mode)        ;进入管理模式

        MOV     SP, R4                              ;设置堆栈指针



        LDMFD   SP!, {R4, R5}                       ;CPSR,OsEnterSum

                                                    ;恢复新任务的OsEnterSum

        LDR     R3, =OsEnterSum

        STR     R4, 

    

        MSR     SPSR_cxsf, R5                       ;恢复CPSR

        LDMFD   SP!, {R0-R12, LR, PC }^             ;运行新任务

spaceaky 发表于 2008-9-21 21:19:53

LDRLO PC, =OSIntCtxSw ;swi 0x00调用OSIntCtxSw  

LDREQ PC, =__OSStartHighRdy ; SWI 0x01为第一次任务切换   

这两个跳转返回软件中断的问题还没有解决,希望哪位做过的朋友帮忙解答一下。

wymzzu 发表于 2009-4-8 19:15:33

本来就不需要返回的吧,调用swi中断有三个功能,上面的两个和bl 那条语句。每次swi执行其中的一个

xintai404 发表于 2009-7-15 19:35:28

1   LDRLO PC, =OSIntCtxSw ;swi 0x00调用OSIntCtxSw
2   LDREQ PC, =__OSStartHighRdy ; SWI 0x01为第一次任务切换
3   BL SWI_Exception   ,
4   LDMFD SP!, {R0-R3, R12, PC}^

1,2最后都会执行到OSIntCtxSw_1 ,就是进行任务的切换:
    如果没有更高优先级的任务,则进入中断的任务出栈,此时执行4,执行楼主说没有执行的中断返回。
    如果有更高优先级的任务,则把高优先级任务有关的寄存器出栈。
    而OSIntCtxSw 到OSIntCtxSw_1工作是执行任务栈的保存
4 就更要返回了,因为是BL,就是跳转到C程序的,SWI_Exception执行完后就返回。


    第一次回帖,不知道有没有讲清楚。

blueflag 发表于 2010-3-22 10:45:11

任务级切换采用软中断SWI方式实现,需要注意的是此时SWI中断处理程序并不返回,所以每次SWI中断一开始就重新初始化SVC管理模式的堆栈地址空间,否则会造成内存泄漏或溢出。

l19830312 发表于 2010-4-1 15:27:18

你要要仔细看看ARM汇编指令集

peavey 发表于 2011-1-17 15:00:21

g

qiushui 发表于 2011-3-7 14:00:48

RL-RTX, 也用到SWI. Mark
页: [1]
查看完整版本: zlgucos移植的问题,关于swi软件中断返回的理解。【恢复】