📄 swi.s
字号:
;/*****************************************************************************/
;/* SWI.S: SWI Handler */
;/*****************************************************************************/
;/* This file is part of the uVision/ARM development tools. */
;/* Copyright (c) 2005-2006 Keil Software. All rights reserved. */
;/* This software may only be used under the terms of a valid, current, */
;/* end user licence from KEIL for a compatible version of KEIL software */
;/* development tools. Nothing else gives you the right to use this software. */
;/*****************************************************************************/
T_Bit EQU 0x20
;/*****************************************************************************/
;/* Keil RealView编译器软中断SWI.S通用代码 */
;/*文 件 名 : SWI.S */
;/*改 造 人 : ARM水鸟 HotPower@126.com */
;/*菜 农 水 潭 :http://blog.21ic.com/blog.asp?name=hotpower */
;/*改 造 日 期 : 2006.2.18 3:38 */
;/*改 造 地 点 :西安大雁塔村队部 */
;/*说 明 :可在ARTX及非ARTX环境下可靠运行 */
;/* 应“老乡”网友云中月8888要求发表---很无奈... */
;/*****************************************************************************/
Artx_SETUP EQU 1;0-在非ARTX上运行 1-在ARTX上运行
Store_SPSR EQU 1;0-在非ARTX上可以修改I/F
; 1-在非ARTX上不可以修改I/F,即对Disable_IRQ()函数无效
Swi_COUNT EQU 9 + 1;__SWI_9(在ARTX时至少取Swi_COUNT=7+1)
;/*****************************************************************************/
;/*备 注 :在ARTX环境下,系统保留__SWI_0~__SWI_7 */
;/* 用户从__SWI_8开始,所以在ARTX时至少取Swi_COUNT=8+1 */
;/* 在非ARTX环境下,用户从__SWI_0开始,所以取Swi_COUNT=0+1 */
;/*注 意 :未定义软中断时,在非ARTX环境下Swi_COUNT=0 否则Swi_COUNT=8 */
;/*****************************************************************************/
;/*****************************************************************************/
;/*应用: */
;/*extern "C" __inline void __enable_IRQ(void) */
;/*{ */
;/*int tmp; */
;/* __asm */
;/* { */
;/* MRS tmp, SPSR */
;/* BIC tmp, tmp, #0x80 */
;/* MSR SPSR_cxsf, tmp */
;/* } */
;/*} */
;/*extern "C" __inline void __disable_IRQ(void) */
;/*{ */
;/*int tmp; */
;/* __asm */
;/* { */
;/* MRS tmp, SPSR */
;/* ORR tmp, tmp, #0x80 */
;/* MSR SPSR_cxsf, tmp */
;/* } */
;/*} */
;/*extern "C" void __swi(0) Enable_IRQ(void); */
;/*extern "C" void __SWI_0 (void) {//注意:在ARTX下至少为__SWI_8 */
;/* __enable_IRQ(); */
;/*} */
;/*extern "C" void __swi(1) Disable_IRQ(void); */
;/*extern "C" void __SWI_1 (void) {//注意:在ARTX下至少为__SWI_9 */
;/* __disable_IRQ(); */
;/*} */
;/*int main (void) */
;/*{ */
;/*//__disable_irq();//RV自带的只能在特权模式下使用 */
;/* Disable_IRQ();//这个才能在用户级上使用 */
;/*//...以下省略 */
;/*//__enable_irq();//RV自带的只能在特权模式下使用 */
;/* Enable_IRQ();//这个才能在用户级上使用 */
;/*//...以下省略 */
;/*} */
;/*****************************************************************************/
PRESERVE8 ; 8-Byte aligned Stack
AREA SWI_Area, CODE, READONLY
ARM
EXPORT SWI_Handler
SWI_Handler
IF Artx_SETUP <> 0
;ARTX入口
OsEnter_swi
MRS R12, SPSR ; Get SPSR
ELSE
;非ARTX入口
Enter_swi
IF Store_SPSR <> 0
STMFD SP!, {R12, LR} ; Store R12, LR//在ARTX中没有保护SPSR
ENDIF
MRS R12, SPSR ; Get SPSR
IF Store_SPSR <> 0
STMFD SP!, {R8, R12} ; Store R8, SPSR//在ARTX中没有保护SPSR
ENDIF
ENDIF
TST R12, #T_Bit ; Check Thumb Bit
LDRNEH R12, [LR,#-2] ; Thumb: Load Halfword
BICNE R12, R12, #0xFF00 ; Extract SWI Number
LDREQ R12, [LR,#-4] ; ARM: Load Word
BICEQ R12, R12, #0xFF000000 ; Extract SWI Number
IF Artx_SETUP <> 0
;ARTX需要默认软中断判断,一般直接进入User_swi
CMP R12, #0;//SWI号判断,R12=0--os_switch_tasks,R12=1~7---SWI1~SWI7
BNE User_swi
;/*------------------- os_switch_tasks ------------------------*/
Artx_swi
STMDB SP,{SP}^ ;ARTX专用SWI0
NOP
LDMDB SP,{R1}
MRS R12,SPSR
STMDB R1!,{R4-R7,R12,LR}
LDR R4,=os_runtask ; os_runtask->tsk_stack
LDR R4,[R4,#0x0]
STR R1,[R4,#0x0024];#TCB_TSTACK]
MOV R4,R0
ADR R12, SWI_Table;?SWI?Table+4
LDR R12,[R12,#0x0] ; SWI function address
MOV LR, PC ; Return Address
BX R12 ; Call SWI Function
LDR LR,[R4,#0x0024];#TCB_TSTACK]; p_new->tsk_stack
LDRB R0,[R4,#0x0021];#TCB_FCTX] ; p_new->full_ctx
CMP R0,#0x0
BNE Full_ctx
LDMIA R14!,{R4-R8,R12}
MSR SPSR_cxsf,R8
STMDB SP,{LR}
LDMDB SP,{SP}^ ; Set User SP
NOP
MOVS PC,R12 ; RETI
Full_ctx
ADD R0,LR,#64
LDMDB R0,{R1-R3} ; LR, CPSR (R3=dummy)
MSR SPSR_cxsf,R2 ; Set User CPSR
STMDB SP,{R0-R1}
LDMDB SP,{SP,LR}^ ; Set User SP,LR
NOP ; required for generic ARM7TDMI support
LDMIA LR,{R0-R12} ; Restore R12-R0
LDR LR,[LR,#60] ; PC
MOVS PC,LR ; RETI
ENDIF
; /*------------------- User SWI -------------------------------*/
User_swi
IF Artx_SETUP <> 0
STMDB SP!,{R8,LR} ;SWI1~SWI7
ELSE
IF Store_SPSR = 0
STMDB SP!,{R8,LR} ;SWI1~SWI7
ENDIF
ENDIF
LDR R8,SWI_Count
CMP R12,R8
BCS SWI_Dead;//BHS SWI_Dead
ADR R8,SWI_Table
LDR R12, [R8,R12,LSL #2] ; Load SWI Function Address
MOV LR,PC
BX R12 ; Call SWI function
IF Artx_SETUP <> 0
;ARTX的SWI出口
OsExit_swi
LDMIA SP!,{R8,PC}^;返回调用SWI命令入口的下一条指令
ELSE
;非ARTX的SWI出口
Exit_swi
IF Store_SPSR <> 0
LDMFD SP!, {R8, R12} ; Load R8, SPSR
MSR SPSR_cxsf, R12 ; Set SPSR
LDMFD SP!, {R12, PC}^ ; Restore R12 and Return
ELSE
LDMIA SP!,{R8,PC}^;返回调用SWI命令入口的下一条指令
ENDIF
ENDIF
;非法SWI命令
SWI_Dead B SWI_Dead ; None Existing SWI
SWI_Cnt EQU (SWI_End-SWI_Table)/4 ;
SWI_Count DCD SWI_Cnt
IF Swi_COUNT > 0
IMPORT __SWI_0;ARTX占用
IF Swi_COUNT > 1
IMPORT __SWI_1;ARTX保留
IF Swi_COUNT > 2
IMPORT __SWI_2;ARTX保留
IF Swi_COUNT > 3
IMPORT __SWI_3;ARTX保留
IF Swi_COUNT > 4
IMPORT __SWI_4;ARTX保留
IF Swi_COUNT > 5
IMPORT __SWI_5;ARTX保留
IF Swi_COUNT > 6
IMPORT __SWI_6;ARTX占用
IF Swi_COUNT > 7
IMPORT __SWI_7;ARTX占用
IF Swi_COUNT > 8
IMPORT __SWI_8;用户SWI8
IF Swi_COUNT > 9
IMPORT __SWI_9;用户SWI9
IF Swi_COUNT > 10
IMPORT __SWI_10;用户SWI10
IF Swi_COUNT > 11
IMPORT __SWI_11;用户SWI11
IF Swi_COUNT > 12
IMPORT __SWI_12;用户SWI12
IF Swi_COUNT > 13
IMPORT __SWI_13;用户SWI13
IF Swi_COUNT > 14
IMPORT __SWI_14;用户SWI14
IF Swi_COUNT > 15
IMPORT __SWI_15;用户SWI15
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
SWI_Table
IF Swi_COUNT > 0
DCD __SWI_0;ARTX占用
IF Swi_COUNT > 1
DCD __SWI_1;ARTX保留
IF Swi_COUNT > 2
DCD __SWI_2;ARTX保留
IF Swi_COUNT > 3
DCD __SWI_3;ARTX保留
IF Swi_COUNT > 4
DCD __SWI_4;ARTX保留
IF Swi_COUNT > 5
DCD __SWI_5;ARTX保留
IF Swi_COUNT > 6
DCD __SWI_6;ARTX占用
IF Swi_COUNT > 7
DCD __SWI_7;ARTX占用
IF Swi_COUNT > 8
DCD __SWI_8;用户SWI8
IF Swi_COUNT > 9
DCD __SWI_9;用户SWI9
IF Swi_COUNT > 10
DCD __SWI_10;用户SWI10
IF Swi_COUNT > 11
DCD __SWI_11;用户SWI11
IF Swi_COUNT > 12
DCD __SWI_12;用户SWI12
IF Swi_COUNT > 13
DCD __SWI_13;用户SWI13
IF Swi_COUNT > 14
DCD __SWI_14;用户SWI14
IF Swi_COUNT > 15
DCD __SWI_15;用户SWI15
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
SWI_End
IF Artx_SETUP <> 0;使用ARTX
IMPORT os_runtask
DCD os_runtask
ENDIF
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -