;/***************************************Copyright (c)**************************************************** ;** Guangzhou ZHIYUAN electronics Co.,LTD. ;** ;** http://www.embedtools.com ;** ;**-------------File Info--------------------------------------------------------------------------------- ;** File name: os_cpu_s.s ;** Latest modified Date: 2007-11-20 ;** Latest Version: 1.0 ;** Descriptions: μCOS-II在lpc210x上的移植代码汇编代码部分,用ads1.2编译 ;**------------------------------------------------------------------------------------------------------- ;** Created by: Chenmingji ;** Created date: 2007-11-20 ;** Version: 1.0 ;** Descriptions: The original version ;** ;**------------------------------------------------------------------------------------------------------- ;** Modified by: ;** Modified date: ;** Version: ;** Descriptions: ;** ;********************************************************************************************************/ ;/******************************************************************************************************** ; 宏定义 ;********************************************************************************************************/ NoInt EQU 0xc0 USR32Mode EQU 0x10 SVC32Mode EQU 0x13 SYS32Mode EQU 0x1f IRQ32Mode EQU 0x12 FIQ32Mode EQU 0x11 T_bit EQU 0x20 CODE32 AREA |subr|, CODE, READONLY IMPORT OSTCBCur ; 指向当前任务TCB的指针 IMPORT OSTCBHighRdy ; 指向将要运行的任务TCB的指针 IMPORT OSPrioCur ; 当前任务的优先级 IMPORT OSPrioHighRdy ; 将要运行的任务的优先级 IMPORT OSTaskSwHook ; 任务切换的钩子函数 IMPORT OSRunning ; uC/OS-II运行标志 IMPORT OSIntNesting ; 中断嵌套计数器 EXPORT OSIntCtxSw ; 中断退出时的入口 EXPORT softwareInterrupt ; 软中断入口 ;/******************************************************************************************************** ;** Function name: SoftwareInterrupt ;** Descriptions: 软件中断,用于提供一些系统服务 ;** input parameters: 依功能而定 ;** output parameters: 依功能而定 ;** Returned value: 依功能而定 ;** Created by: chenmingji ;** Created Date: 2007/11/20 ;**------------------------------------------------------------------------------------------------------- ;** Modified by: ;** Modified date: ;**------------------------------------------------------------------------------------------------------- ;********************************************************************************************************/ softwareInterrupt CMP R0, #8 LDRLO PC, [PC, R0, LSL #2] MOVS PC, LR SwiFunction DCD TASK_SW ; 0 DCD _OSStartHighRdy ; 1 DCD ENTER_CRITICAL ; 2 DCD EXIT_CRITICAL ; 3 DCD ChangeToSYSMode ; 4 DCD ChangeToUSRMode ; 5 DCD ISRBegin ; 6 DCD OSISRNeedSwap ; 7 ;/******************************************************************************************************** ;** Function name: TASK_SW ;** Descriptions: 任务级调度 ;** input parameters: none ;** output parameters: none ;** Returned value: none ;** Created by: chenmingji ;** Created Date: 2007/11/20 ;**------------------------------------------------------------------------------------------------------- ;** Modified by: ;** Modified date: ;**------------------------------------------------------------------------------------------------------- ;********************************************************************************************************/ TASK_SW MRS R3, SPSR ; 保存任务的CPSR MOV R2, LR ; 保存任务的PC MSR CPSR_c, #(NoInt | SYS32Mode) ; 切换到系统模式 STMFD SP!, {R2} ; 保存PC到堆栈 STMFD SP!, {R0-R12, LR} ; 保存R0-R12,LR到堆栈 ; 因为R0~R3没有保存有用数据, ; 所以可以这样做 B OSIntCtxSw_0 ; 真正进行任务切换 ;/******************************************************************************************************** ;** Function name: ENTER_CRITICAL ;** Descriptions: 进入临界区 ;** input parameters: none ;** output parameters: none ;** Returned value: none ;** Created by: chenmingji ;** Created Date: 2007/11/20 ;**------------------------------------------------------------------------------------------------------- ;** Modified by: ;** Modified date: ;**------------------------------------------------------------------------------------------------------- ;********************************************************************************************************/ ENTER_CRITICAL ; GulOsEnterSum++ LDR R1, =GulOsEnterSum LDRB R2, [R1] CMP R2, #0xff MOVEQS PC, LR ADD R2, R2, #1 STRB R2, [R1] ; 关中断 MRS R0, SPSR ORR R0, R0, #NoInt MSR SPSR_c, R0 MOVS PC, LR ;/******************************************************************************************************** ;** Function name: EXIT_CRITICAL ;** Descriptions: 退出临界区 ;** input parameters: none ;** output parameters: none ;** Returned value: none ;** Created by: chenmingji ;** Created Date: 2007/11/20 ;**------------------------------------------------------------------------------------------------------- ;** Modified by: ;** Modified date: ;**------------------------------------------------------------------------------------------------------- ;********************************************************************************************************/ EXIT_CRITICAL ; GulOsEnterSum-- LDR R1, =GulOsEnterSum LDRB R2, [R1] CMP R2, #0 MOVEQS PC, LR SUB R2, R2, #1 STRB R2, [R1] ; if(GulOsEnterSum == 0) 开中断; CMP R2, #0 MRSEQ R0, SPSR BICEQ R0, R0, #NoInt MSREQ SPSR_c, R0 MOVS PC, LR ;/******************************************************************************************************** ;** Function name: ChangeToSYSMode ;** Descriptions: 任务切换到系统模式 ;** input parameters: none ;** output parameters: none ;** Returned value: none ;** Created by: chenmingji ;** Created Date: 2007/11/20 ;**------------------------------------------------------------------------------------------------------- ;** Modified by: ;** Modified date: ;**------------------------------------------------------------------------------------------------------- ;********************************************************************************************************/ ChangeToSYSMode ; 切换到系统模式 MRS R0, SPSR BIC R0, R0, #0x1f ORR R0, R0, #SYS32Mode MSR SPSR_c, R0 MOVS PC, LR ;/******************************************************************************************************** ;** Function name: ChangeToSYSMode ;** Descriptions: 任务切换到用户模式 ;** input parameters: none ;** output parameters: none ;** Returned value: none ;** Created by: chenmingji ;** Created Date: 2007/11/20 ;**------------------------------------------------------------------------------------------------------- ;** Modified by: ;** Modified date: ;**------------------------------------------------------------------------------------------------------- ;********************************************************************************************************/ ChangeToUSRMode ; 切换到用户模式 MRS R0, SPSR BIC R0, R0, #0x1f ORR R0, R0, #USR32Mode MSR SPSR_c, R0 MOVS PC, LR ;/******************************************************************************************************** ;** Function name: ISRBegin ;** Descriptions: ISR开始处理 ;** input parameters: none ;** output parameters: none ;** Returned value: none ;** Created by: chenmingji ;** Created Date: 2007/11/20 ;**------------------------------------------------------------------------------------------------------- ;** Modified by: ;** Modified date: ;**------------------------------------------------------------------------------------------------------- ;********************************************************************************************************/ ISRBegin ; OSIntNesting++ LDR R1, =OSIntNesting LDRB R2, [R1] ADD R2, R2, #1 STRB R2, [R1] MOVS PC, LR ;/******************************************************************************************************** ;** Function name: OSISRNeedSwap ;** Descriptions: 查看任务是否需要切换 ;** input parameters: none ;** output parameters: none ;** Returned value: none ;** Created by: chenmingji ;** Created Date: 2007/11/20 ;**------------------------------------------------------------------------------------------------------- ;** Modified by: ;** Modified date: ;**------------------------------------------------------------------------------------------------------- ;********************************************************************************************************/ OSISRNeedSwap LDR R1, =OSTCBHighRdy LDR R2, =OSTCBCur CMP R1, R2 MOVEQ R0, #0 MOVNE R0, #1 MOVS PC, LR ;/******************************************************************************************************** ;** Function name: OSIntCtxSw ;** Descriptions: 中断退出时的入口 ;** input parameters: R3: 当前任务的状态寄存器CPSR(即SPSR的值) ;** R4-R12: 当前任务的R4-R11 ;** 当前处理器模式的堆栈结构(出栈次序):R0-R3、R12、PC(当前任务的) ;** output parameters: none ;** Returned value: none ;** Created by: chenmingji ;** Created Date: 2007/11/20 ;**------------------------------------------------------------------------------------------------------- ;** Modified by: ;** Modified date: ;**------------------------------------------------------------------------------------------------------- ;********************************************************************************************************/ 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 OSIntCtxSw_0 LDR R1, =GulOsEnterSum ; 获取OsEnterSum LDR R2, [R1] STMFD SP!, {R2, R3} ; 保存CPSR,GulOsEnterSum ; 保存当前任务堆栈指针到当前任务的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,GulOsEnterSum,R0-R12,LR,SP LDR LR, [SP, #-8] MSR CPSR_c, #(NoInt | SVC32Mode) ; 进入管理模式 MOV SP, R4 ; 设置堆栈指针 LDMFD SP!, {R4, R5} ; CPSR,GulOsEnterSum ; 恢复新任务的OsEnterSum LDR R3, =GulOsEnterSum STR R4, [R3] MSR SPSR_cxsf, R5 ; 恢复CPSR LDMFD SP!, {R0-R12, LR, PC }^ ; 运行新任务 ;/******************************************************************************************************** ;** Function name: _OSStartHighRdy ;** Descriptions: uC/OS-II启动时使用OSStartHighRdy运行第一个任务, ;** OSStartHighRdy会调用_OSStartHighRdy ;** input parameters: none ;** output parameters: none ;** Returned value: none ;** Created by: chenmingji ;** Created Date: 2007/11/20 ;**------------------------------------------------------------------------------------------------------- ;** Modified by: ;** Modified date: ;**------------------------------------------------------------------------------------------------------- ;********************************************************************************************************/ _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 ;/******************************************************************************************************** ;** Function name: TaskEntry ;** Descriptions: 所有任务的入口 ;** input parameters: 与任务一样 ;** output parameters: 与任务一样 ;** Returned value: 与任务一样 ;** Created by: chenmingji ;** Created Date: 2007/11/20 ;**------------------------------------------------------------------------------------------------------- ;** Modified by: ;** Modified date: ;**------------------------------------------------------------------------------------------------------- ;********************************************************************************************************/ EXPORT TaskEntry TaskEntry BX R14 ;/********************************************************************************************************* ;** Function name: OSTaskStkInit ;** Descriptions: 任务堆栈初始化代码,本函数调用失败会使系统崩溃 ;** input parameters: task: 任务开始执行的地址 ;** pdata: 传递给任务的参数 ;** ptos: 任务的堆栈开始位置 ;** opt: 附加参数,当前版本对于本函数无用,具体意义参见OSTaskCreateExt()的opt参数 ;** output parameters: none ;** Returned value: 新堆栈位置 ;** Created by: LinEnqiang ;** Created Date: 2008/05/02 ;**-------------------------------------------------------------------------------------------------------- ;** Modified by: ;** Modified date: ;**-------------------------------------------------------------------------------------------------------- ;*********************************************************************************************************/ EXPORT OSTaskStkInit OSTaskStkInit MOV R3, R0 ;/* ; * 建立任务环境,ADS1.2使用满递减堆栈 ; */ MOV R0, R2 LDR R2, =TaskEntry SWP R2,R2,[R0] ; pc,所有任务的入口 STMDB R0!,{R3} ; lr,任务真正的入口 MOV R2, #0 MOV R3, #0 STMDB R0!,{R2,R3} ; R12、R11 STMDB R0!,{R2,R3} ; R10、R9 STMDB R0!,{R2,R3} ; R8、R7 STMDB R0!,{R2,R3} ; R6、R5 STMDB R0!,{R2,R3} ; R4、R3 STMDB R0!,{R2,R3} ; R2、R1 MOV R2 , #0x10 STMDB R0!,{R1-R3} ; r0,第一个参数使用R0传递 ; spsr,允许 IRQ, FIQ 中断 ; 关中断计数器OsEnterSum; BX R14 AREA MyEnterSumDatas, DATA, ALIGN = 2; EXPORT GulOsEnterSum ; 任务关中断计数器 GulOsEnterSum DCD 0 END ;/******************************************************************************************************** ;** End Of File ;********************************************************************************************************/