首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

UC OS ARM移植(3)

UC OS ARM移植(3)

软件中断异常SWI服务程序C语言部分

    void SWI_Exception(int SWI_Num, int *Regs):参数SWI_Num对应前面文件中定义的功能号,其中0、1号的功能在后面的文件中定义,这里只定义了其他10个功能。

    2、3分别对应关中断和开中断

    关中断:MRS     R0, SPSR         //在软件中断的时候直接对程序状态保存寄存器SPSR操作也就是对CPSR的操作
                   ORR     R0, R0, #NoInt    //在汇编语言中对寄存器的对应位置位用ORR,清零用BIC
                   MSR     SPSR_c, R0        //SPSR_c表示的是只改变SPSR的控制段的8位代码,其他三段_f,_s,_x中标志位在_f段,其他为保留位

    开中断:MRS     R0, SPSR       //在开中断中基本与上面相同,只是ORR改成BIC清零
                   BIC     R0, R0, #NoInt
                   MSR     SPSR_c, R

    由于需要实现中断嵌套,所以只有当关中断的计数器减为0的时候才能够开中断,而且每次关中断的时候该计数器都应该加1。另外,插入汇编语言时用_asm指令。


    80、81、82、83分别对应系统模式、用户模式、ARM指令集、THUMB指令集

    系统模式:MRS     R0, SPSR
                        BIC     R0, R0, #0x1f     //先将控制模式的低5位清零
                        ORR     R0, R0, #SYS32Mode       //设置成系统模式的1F
                        MSR     SPSR_c, R0

    用户模式:MRS     R0, SPSR
                        BIC     R0, R0, #0x1f
                        ORR     R0, R0, #USR32Mode     //设置成用户模式的10
                        MSR     SPSR_c, R0

__OSStartHighRdy
        MSR     CPSR_c, #(NoInt | SYS32Mode)  ;MSR:在ARM中只有MSR能够直接设置状态寄存器CPSR或SPSR,可以是立即数或者源寄存器,NoInt是禁止中断,SYS32Mode是系统模式
                                                ;告诉uC/OS-II自身已经运行
        LDR     R4, =OSRunning  ;OSRunning正在运行多任务的标志,=OSRunning是把OSRunning的地址加载到R4,R4里存的是一个地址。。。
        MOV     R5, #1  
        STRB    R5, [R4]   ;将R5存储到R4存的地址的变量即OSRunning中,也就是将OSRunning置1

        BL      OSTaskSwHook                    ;调用钩子函数,OSTaskSwHook 是用于扩展的,在任务切换的时候执行用户自己定义的功能。

        LDR     R6, =OSTCBHighRdy    ;OSTCBHighRdy指向最高优先级任务的控制块TCB的指针!!!将放指针的地址放到R6中。
        LDR     R6, [R6]  ;将R6地址处的数据读出即OSTCBHighRdy的地址放到R6中
        B       OSIntCtxSw_1   ;跳转到OSIntCtxSw_1

        AREA    SWIStacks, DATA, NOINIT,ALIGN=2
SvcStackSpace      SPACE   SVC_STACK_LEGTH * 4  ;管理模式堆栈空间


继续昨天没有看完的代码

OSIntCtxSw
                                                    ;下面为保存任务环境
        LDR     R2, [SP, #20]                       ;获取PC,放入R2
        LDR     R12, [SP, #16]                      ;获取R12,//R12存的什么东西啊???
        MRS     R0, CPSR

        MSR     CPSR_c, #(NoInt | SYS32Mode)   ;进入系统模式并禁止中断
        MOV     R1, LR    ;R1放LR值
        STMFD   SP!, {R1-R2}                        ;保存LR,PC,将R1,R2存入SP
        STMFD   SP!, {R4-R12}                       ;保存R4-R12,将R4-12存入SP

        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, [R1]
        STMFD   SP!, {R2, R3}                       ;保存CPSR,OsEnterSum

                                                    ;保存当前任务堆栈指针到当前任务的TCB
        LDR     R1, =OSTCBCur
        LDR     R1, [R1]
        STR     SP, [R1]

        BL      OSTaskSwHook                        ;调用钩子函数
                                                    ;OSPrioCur <= OSPrioHighRdy
        LDR     R4, =OSPrioCur
        LDR     R5, =OSPrioHighRdy
        LDRB    R6, [R5]
        STRB    R6, [R4]
                                                    ;OSTCBCur <= OSTCBHighRdy
        LDR     R6, =OSTCBHighRdy
        LDR     R6, [R6]
        LDR     R4, =OSTCBCur
        STR     R6, [R4]
OSIntCtxSw_1
                                                    ;获取新任务堆栈指针
        LDR     R4, [R6]      ;把OSTCBHighRdy指向最高优先级任务的控制块TCB的指针给R4
        ADD     SP, R4, #68                         ;17寄存器:CPSR,OsEnterSum,R0-R12,LR,SP
        LDR     LR, [SP, #-8]   ;取出LR放到LR
        MSR     CPSR_c, #(NoInt | SVC32Mode)        ;进入管理模式并且保持禁止中断
        MOV     SP, R4                              ;设置堆栈指针

        LDMFD   SP!, {R4, R5}                       ;CPSR,OsEnterSum。LDMFD数据出栈,放入R4,R5
                                                    ;恢复新任务的OsEnterSum
        LDR     R3, =OsEnterSum   ;OsEnterSum的地址存入R3
        STR     R4, [R3]   ;把R4的值赋给OsEnterSum
   
        MSR     SPSR_cxsf, R5                       ;恢复CPSR;在管理模式里是修改SPSR
        LDMFD   SP!, {R0-R12, LR, PC }^             ;运行新任务  ,恢复现场,异常处理返回


返回列表