⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_cpu_a.s

📁 TFT LCD gui 液晶屏测试程序。
💻 S
字号:
        AREA    os_cpu_a, CODE, READONLY
        CODE32

        IMPORT  OSTCBCur                                ; 指向当前任务TCB的指针.
        IMPORT  OSTCBHighRdy                            ; 指向将要运行的任务TCB的指针.
        IMPORT  OSPrioCur                               ; 当前任务的优先级.
        IMPORT  OSPrioHighRdy                           ; 将要运行的任务的优先级.
        IMPORT  OSTaskSwHook                            ; 任务切换的钩子函数.
        IMPORT  OsEnterSum                              ; 关中断计数器(关中断信号量).
        IMPORT  OSRunning                               ; uC/OS-II运行标志.
		IMPORT  SWI_Exception
        EXPORT  OSIntCtxSw                            ; 中断级任务切换函数.
        EXPORT  OS_TASK_SW                              ; 任务级任务切换函数.
        EXPORT  OSStartHighRdy                          ; 开始最高优先级任务.
		EXPORT  SoftwareInterrupt
        EXPORT  OS_ENTER_CRITICAL
        EXPORT  OS_EXIT_CRITICAL

NoInt       EQU 0x80                                    ; 关中断.
SYS32Mode   EQU 0x1f                                    ; 系统模式代码.
IRQ32Mode   EQU 0x12                                    ; IRQ中断模式代码.
SVC32Mode   EQU 0x13                                    ; 管理模式代码.
SVC_STACK_LEGTH EQU 32
;/*********************************************************************************************************
;** 函数名称: SoftwareInterrupt
;** 功能描述: 软件中断,用于提供一些系统服务,功能参考os_cpu_c.c文件
;** 输 入:   依功能而定
;** 输 出 :  依功能而定
;** 全局变量: 无
;** 调用模块: SWI_Exception
;** 
;** 作 者: 陈明计
;** 日 期: 2003年6月5日
;**-------------------------------------------------------------------------------------------------------
;** 修 改: 陈明计
;** 日 期: 2003年6月11日
;**-------------------------------------------------------------------------------------------------------
;** 修 改: 陈明计
;** 日 期: 2003年6月13日
;**-------------------------------------------------------------------------------------------------------
;** 修 改: 陈明计
;** 日 期: 2003年6月19日
;**-------------------------------------------------------------------------------------------------------
;********************************************************************************************************/

;软件中断
SoftwareInterrupt
        LDR     SP, StackSvc            ; 重新设置堆栈指针
        STMFD   SP!, {R0-R3, R12, LR}
        MOV     R1, SP                  ; R1指向参数存储位置

        MRS     R3, SPSR
        TST     R3, #0x20              ; 中断前是否是Thumb状态
        LDRNEH  R0, [LR,#-2]            ; 是: 取得Thumb状态SWI号
        BICNE   R0, R0, #0xff00
        LDREQ   R0, [LR,#-4]            ; 否: 取得arm状态SWI号
        BICEQ   R0, R0, #0xFF000000
                                        ; r0 = SWI号,R1指向参数存储位置
        CMP     R0, #1
        LDRLO   PC, =OSIntCtxSw
        LDREQ   PC, =OSStartHighRdy   ; SWI 0x01为第一次任务切换

        BL      SWI_Exception
        
        LDMFD   SP!, {R0-R3, R12, PC}^
        
StackSvc           DCD     (SvcStackSpace + SVC_STACK_LEGTH * 4 - 4)

;/*******************************************************************************************************
;* 函数: OS_ENTER_CRITICAL.
;* 描述: 关 IRQ 中断.
;*******************************************************************************************************/
OS_ENTER_CRITICAL
        STMFD   SP!,        {R0,LR}
        MRS     R0,         CPSR
        ORR     R0,         R0, #(1<<7)
        MSR     CPSR_c,     R0

        LDR     R0,         =OsEnterSum
        LDR     R1,         [R0]
        ADD     R1,         R1, #1
        STR     R1,         [R0]

        LDMFD   SP!,        {R0,PC}

;/******************************************************************************************************
;* 函数: OS_EXIT_CRITICAL.
;* 描述: 开 IRQ 中断.
;******************************************************************************************************/
OS_EXIT_CRITICAL
        STMFD   SP!,        {R0-R1,LR}

        LDR     R0,         =OsEnterSum
        LDR     R1,         [R0]
        SUBS    R1,         R1, #1
        STR     R1,         [R0]

        MRS     R0,         CPSR
        BICEQ   R0,         R0, #(1<<7)
        MSREQ   CPSR_c,     R0

        LDMFD   SP!,        {R0-R1,PC}

;/*
;*********************************************************************************************************
;* 函数:OSIntCtxSw.
;* 描述: IRQ 中断级任务切换.
;*********************************************************************************************************
;*/
OSIntCtxSw
	     LDR     R2, [SP, #20]                       ;获取PC
        LDR     R12, [SP, #16]                      ;获取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, [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]
        ADD     SP, R4, #68                         ;17寄存器CPSR,OsEnterSum,R0-R12,LR,SP
        LDR     LR, [SP, #-8]
        MSR     CPSR_c, #(NoInt | SVC32Mode)        ;进入管理模式
        MOV     SP, R4                              ;设置堆栈指针

        LDMFD   SP!, {R4, R5}                       ;CPSR,OsEnterSum
                                                    ;恢复新任务的OsEnterSum
        LDR     R3, =OsEnterSum
        STR     R4, [R3]
    
        MSR     SPSR_cxsf, R5                       ;恢复CPSR
        LDMFD   SP!, {R0-R12, LR, PC }^             ;运行新任务

;/*
;*********************************************************************************************************
;* 函数: OS_TASK_SW.
;* 描述: 任务级任务切换.
;*********************************************************************************************************
;*/
OS_TASK_SW
        STMFD   SP!,        {LR}                        ; 保存 PC.
        STMFD   SP!,        {LR}                        ; 保存 LR.
OSCtxSw_01
        STMFD   SP!,        {R0-R12}                    ; 保存 R12-R0.

        LDR     R0,         =OsEnterSum
        LDR     R0,         [R0]
        MRS     R1,         CPSR
        STMFD   SP!,        {R0-R1}                     ; 保存 CPSR,OsEnterSum.

        LDR     R1,         =OSTCBCur
        LDR     R1,         [R1]
        STR     SP,         [R1]                        ; OSTCBCur->OSTCBStkPtr = SP.

        BL      OSTaskSwHook                            ; 调用钩子函数.

        LDR     R0,         =OSPrioCur                  ; OSPrioCur = OSPrioHighRdy.
        LDR     R1,         =OSPrioHighRdy
        LDRB    R1,         [R1]
        STRB    R1,         [R0]

        LDR     R0,         =OSTCBCur                   ; OSTCBCur  = OSTCBHighRdy.
        LDR     R1,         =OSTCBHighRdy
        LDR     R1,         [R1]
        STR     R1,         [R0]
OSCtxSw_10
        LDR     SP,         [R1, #0]                    ; 获取新任务堆栈指针 OSTCBHighRdy->OSTCBStkPtr.

        LDMFD   SP!,        {R0-R1}                     ; 恢复 CPSR,OsEnterSum.
        LDR     R2,         =OsEnterSum
        STR     R0,         [R2]
        MSR     CPSR_cxsf,  R1

        LDMFD   SP!,        {R0-R12,LR,PC}^             ; 恢复 R12-R0,LR,PC.

;/*********************************************************************************************************
;* 函数: OSStartHighRdy.
;* 描述: uC/OS-II启动时使用OSStartHighRdy运行第一个任务.
;*********************************************************************************************************/
OSStartHighRdy
        MSR     CPSR_c, #(NoInt | SYS32Mode)
                                                ;告诉uC/OS-II自身已经运行
        LDR     R4, =OSRunning
        MOV     R5, #1
        STRB    R5, [R4]

        BL      OSTaskSwHook                    ;调用钩子函数

        LDR     R6, =OSTCBHighRdy
        LDR     R6, [R6]
        B       OSIntCtxSw_1

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

    END

;/*
;*********************************************************************************************************
        END
;*********************************************************************************************************
;*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -