📄 swi.s
字号:
;/*****************************************************************************/
;/* SWI.S: SWI Handler */
;/*****************************************************************************/
;/* <<< Use Configuration Wizard in Context Menu >>> */
;/*****************************************************************************/
;/* 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
;/* Offsets from the 'struct OS_TCB' */
TCB_FCTX EQU 33
TCB_TSTACK EQU 36
;/*****************************************************************************/
;/* Keil RealView编译器软中断SWI.S通用非典代码 */
;/*文 件 名 : SWI.S */
;/*改 造 人 : ARM水鸟 HotPower@126.com */
;/*版 本 号 : V1.10 (测试版) 详细使用说明参见以后将发表的相关文挡 */
;/*菜 农 水 潭 :http://blog.21ic.com/blog.asp?name=hotpower */
;/*改 造 日 期 : 2006.2.18 3:38 */
;/*改 造 地 点 :西安大雁塔村队部 */
;/*升 级 时 间 : 2006.2.24 11:18 */
;/*说 明 :可在ARTX及非ARTX环境下可靠运行 */
;/*****************************************************************************/
;// <e> System Setup
;// <o0> Artx_SETUP <0-1:0>
;// <o1> Store_SPSR <0-1:0>
;// <o2> SWI_Cnt <0-16:0>
;// <o3> Swi_RESET <0-1:0>
;// </e>
Artx_SETUP EQU 1;0-在非ARTX上运行 1-在ARTX上运行
Store_SPSR EQU 1;0-在非ARTX上可以修改I/F
; 1-在非ARTX上不可以修改I/F,即对Disable_IRQ()函数无效
SWI_Cnt EQU 10;__SWI_8
Swi_RESET EQU 1;0-非法软件中断死机,1-非法软件中断不死机复位
;千万注意:若SWI_Cnt定义少时,Swi_RESET=1时也将复位!
;/*****************************************************************************/
;/*备 注 :在ARTX环境下,系统保留__SWI_0~__SWI_7 */
;/* 用户从__SWI_8开始,所以在ARTX时至少取SWI_Cnt=8+1 */
;/* 在非ARTX环境下,用户从__SWI_0开始,所以取SWI_Cnt=0+1 */
;/*注 意 :未定义软中断时,在非ARTX环境下SWI_Cnt=0 否则SWI_Cnt=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();//这个才能在用户级上使用 */
;/*//...以下省略 */
;/*} */
;/*****************************************************************************/
IF Artx_SETUP <> 0;使用ARTX
IMPORT os_runtask
ENDIF
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,#TCB_TSTACK];#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,#TCB_TSTACK];#TCB_TSTACK]; p_new->tsk_stack
LDRB R0,[R4,#TCB_FCTX];#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) || (Store_SPSR = 0)
STMDB SP!,{R8,LR} ;SWI1~SWI7
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命令
IF Swi_RESET = 0;非法软件中断死机
SWI_Dead B SWI_Dead ; None Existing SWI
ELSE ;非法软件中断不死机复位
IMPORT Reset_Handler
SWI_Dead B Reset_Handler;仿真时,若Swi_RESET=1时最好在此处设置断点跟踪
ENDIF
EXPORT SWI_Count
SWI_Count DCD SWI_Cnt
;本版本启动文件暂支持最多16个软中断,其中包含ARTX自带的8个。
EXPORT SWI_Table
SWI_Table
IF SWI_Cnt > 0
IMPORT __SWI_0;ARTX占用
IF SWI_Cnt > 1
IMPORT __SWI_1;ARTX保留
IF SWI_Cnt > 2
IMPORT __SWI_2;ARTX保留
IF SWI_Cnt > 3
IMPORT __SWI_3;ARTX保留
IF SWI_Cnt > 4
IMPORT __SWI_4;ARTX保留
IF SWI_Cnt > 5
IMPORT __SWI_5;ARTX保留
IF SWI_Cnt > 6
IMPORT __SWI_6;ARTX占用
IF SWI_Cnt > 7
IMPORT __SWI_7;ARTX占用
IF SWI_Cnt > 8
IMPORT __SWI_8;用户SWI8
IF SWI_Cnt > 9
IMPORT __SWI_9;用户SWI9
IF SWI_Cnt > 10
IMPORT __SWI_10;用户SWI10
IF SWI_Cnt > 11
IMPORT __SWI_11;用户SWI11
IF SWI_Cnt > 12
IMPORT __SWI_12;用户SWI12
IF SWI_Cnt > 13
IMPORT __SWI_13;用户SWI13
IF SWI_Cnt > 14
IMPORT __SWI_14;用户SWI14
IF SWI_Cnt > 15
IMPORT __SWI_15;用户SWI15
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
IF SWI_Cnt > 0
DCD __SWI_0;ARTX占用
IF SWI_Cnt > 1
DCD __SWI_1;ARTX保留
IF SWI_Cnt > 2
DCD __SWI_2;ARTX保留
IF SWI_Cnt > 3
DCD __SWI_3;ARTX保留
IF SWI_Cnt > 4
DCD __SWI_4;ARTX保留
IF SWI_Cnt > 5
DCD __SWI_5;ARTX保留
IF SWI_Cnt > 6
DCD __SWI_6;ARTX占用
IF SWI_Cnt > 7
DCD __SWI_7;ARTX占用
IF SWI_Cnt > 8
DCD __SWI_8;用户SWI8
IF SWI_Cnt > 9
DCD __SWI_9;用户SWI9
IF SWI_Cnt > 10
DCD __SWI_10;用户SWI10
IF SWI_Cnt > 11
DCD __SWI_11;用户SWI11
IF SWI_Cnt > 12
DCD __SWI_12;用户SWI12
IF SWI_Cnt > 13
DCD __SWI_13;用户SWI13
IF SWI_Cnt > 14
DCD __SWI_14;用户SWI14
IF SWI_Cnt > 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
DCD os_runtask
ENDIF
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -