📄 os_cpu_a.s
字号:
;/*********************************************************************************************************
;** Small RTOS
;** The Real-Time Kernel
;** (c) Copyright 2004-2004, chenmingji
;** All Rights Reserved
;**--------------文件信息--------------------------------------------------------------------------------
;**文 件 名: os_cpu_s.s
;**创 建 人: 陈明计
;**最后修改日期: 2004年8月4日
;**描 述: Small RTOS V1.50在ARM7上的移植代码汇编代码部分,用ADS1.2编译
;**
;**--------------历史版本信息----------------------------------------------------------------------------
;** 创建人: 陈明计
;** 版 本: V1.0
;** 日 期: 2004年8月4日
;** 描 述: 原始版
;**
;**------------------------------------------------------------------------------------------------------
;** 修改人:
;** 版 本:
;** 日 期:
;** 描 述:
;**
;**--------------当前版本修订------------------------------------------------------------------------------
;** 修改人:
;** 日 期:
;** 描 述:
;**
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
NoInt EQU 0x80 ;用于开关中断
USR32Mode EQU 0x10 ;用户模式
SVC32Mode EQU 0x13 ;管理模式
SYS32Mode EQU 0x1f ;系统模式
IRQ32Mode EQU 0x12 ;IRQ模式
FIQ32Mode EQU 0x11 ;FIQ模式
;T_bit用于检测进入异常前cpu是否处于THUMB状态
T_bit EQU 0x20
CODE32
AREA |subr|, CODE, READONLY
IMPORT OsEnterSum ;关中断计数器(关中断信号量)
IMPORT OSIntNesting ;中断嵌套层次
EXPORT __OSIntCtxSw ;中断退出时的入口,参见startup.s中的IRQ_Handler
EXPORT SoftwareInterrupt ;软中断入口
;/*********************************************************************************************************
;** 函数名称: SoftwareInterrupt
;** 功能描述: 软件中断,用于提供一些系统服务,功能参考os_cpu_c.c文件
;** 输 入: 依功能而定
;** 输 出 : 依功能而定
;** 全局变量: 无
;** 调用模块: SWI_Exception
;**
;** 作 者: 陈明计
;** 日 期: 2003年6月5日
;**-------------------------------------------------------------------------------------------------------
;** 修 改: 陈明计
;** 日 期: 2003年6月11日
;**-------------------------------------------------------------------------------------------------------
;** 修 改: 陈明计
;** 日 期: 2003年6月13日
;**-------------------------------------------------------------------------------------------------------
;** 修 改: 陈明计
;** 日 期: 2003年6月19日
;**-------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
;软件中断
SoftwareInterrupt
CMP R0, #7
LDRLO PC, [PC, R0, LSL #2]
MOVS PC, LR
SwiFunction
DCD TASK_SW ;0
DCD OSIntCtxSw ;1
DCD ENTER_CRITICAL ;2
DCD EXIT_CRITICAL ;3
DCD ISRBegin ;4
DCD ChangeToSYSMode ;5
DCD ChangeToUSRMode ;6
TASK_SW
MRS R3, SPSR ;保存任务的CPSR
MOV R0, LR ;保存任务的PC
MSR CPSR_c, #(NoInt | SYS32Mode) ;切换到系统模式
STMFD SP!, {R0} ;保存PC到堆栈
STMFD SP!, {R0-R12, LR} ;保存R0-R12,LR到堆栈
;因为R0~R3没有保存有用数据,所以可以这样做
LDR R0, =OsEnterSum ;获取OsEnterSum
LDRB R0, [R0]
B OSIntCtxSw_0 ;真正进行任务切换
OSIntCtxSw
MOVS PC, LR
ENTER_CRITICAL
;OsEnterSum++
LDR R1, =OsEnterSum
LDRB R2, [R1]
ADD R2, R2, #1
STRB R2, [R1]
;关中断
MRS R0, SPSR
ORR R0, R0, #NoInt
MSR SPSR_c, R0
MOVS PC, LR
EXIT_CRITICAL
;OsEnterSum--
LDR R1, =OsEnterSum
LDRB R2, [R1]
SUB R2, R2, #1
STRB R2, [R1]
;if(OsEnterSum == 0) 开中断;
CMP R2, #0
MRSEQ R0, SPSR
BICEQ R0, R0, #NoInt
MSREQ SPSR_c, R0
MOVS PC, LR
ISRBegin
;OSIntNesting++
LDR R1, =OSIntNesting
LDRB R2, [R1]
ADD R2, R2, #1
STRB R2, [R1]
MOVS PC, LR
ChangeToSYSMode
;切换到系统模式
MRS R0, SPSR
BIC R0, R0, #0x1f
ORR R0, R0, #SYS32Mode
MSR SPSR_c, R0
MOVS PC, LR
ChangeToUSRMode
;切换到用户模式
MRS R0, SPSR
BIC R0, R0, #0x1f
ORR R0, R0, #USR32Mode
MSR SPSR_c, R0
MOVS PC, LR
;/*********************************************************************************************************
;** 函数名称: __OSIntCtxSw
;** 功能描述: 中断退出时的入口
;** 输 入: R3 :当前任务的状态寄存器CPSR(即SPSR的值)
;** R4-R12:当前任务的R4-R11
;** 当前处理器模式的堆栈结构(出栈次序):R0-R3、R12、PC(当前任务的)
;** 输 出 : 无
;** 全局变量: OSPrioCur,OSPrioHighRdy,OSPrioCur,OSPrioHighRdy
;** 调用模块: 无
;**
;** 作 者: 陈明计
;** 日 期: 2003年6月5日
;**-------------------------------------------------------------------------------------------------------
;** 修 改: 陈明计
;** 日 期: 2003年6月11日
;**-------------------------------------------------------------------------------------------------------
;** 修 改: 陈明计
;** 日 期: 2003年6月13日
;**-------------------------------------------------------------------------------------------------------
;** 修 改: 陈明计
;** 日 期: 2003年6月19日
;**-------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
__OSIntCtxSw
;下面为保存任务环境
LDR R3, [SP, #20] ;获取PC
LDR R12, [SP, #16] ;获取R12
MRS R0, CPSR
MSR CPSR_c, #(NoInt | SYS32Mode) ;切换到系统模式
STMFD SP!, {R3} ;保存PC
STMFD SP!, {R4-R12,LR} ;保存R4-R12,LR
MSR CPSR_c, R0 ;切换到原来的模式
LDMFD SP!, {R4-R7} ;获取R0-R3
ADD SP, SP, #8 ;出栈R12,PC
MRS R3, SPSR ;保存状态
MSR CPSR_c, #(NoInt | SYS32Mode)
STMFD SP!, {R4-R7} ;保存R0-R3
MOV R0, #0
OSIntCtxSw_0
STMFD SP!, {R0, R3} ;保存CPSR,OsEnterSum
STR SP, [R1] ;保存当前任务堆栈指针到当前任务的TCB
OSIntCtxSw_1
;获取新任务堆栈指针
ADD SP, R2, #68 ;17寄存器CPSR,OsEnterSum,R0-R12,LR,SP
LDR LR, [SP, #-8]
MSR CPSR_c, #(NoInt | SVC32Mode) ;进入管理模式
MOV SP, R2 ;设置堆栈指针
LDMFD SP!, {R4, R5} ;CPSR,OsEnterSum
;恢复新任务的OsEnterSum
LDR R3, =OsEnterSum
STRB R4, [R3]
MSR SPSR_cxsf, R5 ;恢复CPSR
LDMFD SP!, {R0-R12, LR, PC }^ ;运行新任务
END
;/*********************************************************************************************************
;** End Of File
;********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -