Cortex SVC 中断
SVC(系统管理调用) 异常优先级为1,SVC异常是由SVC指令触发
也可以直接设置NVIC寄存器触发异常
应用程序工作在非特权访问模式,当需要特权模式访问系统资源时,可以使用SVC实现
参考例程:
- main
#include <stdio.h>
int __svc(0x00) svc_service_add(int x,int y);
int __svc(0x01) svc_service_sub(int x,int y);
int __svc(0x02) svc_service_inc(int x);
void SVC_Handler_main(unsigned int * svc_args);
使用 __svc 关键字,在调用svc_service_add时,编译器将会调用SVC指令
13: x=3;y=5;
0x08000F28 2403 MOVS r4,#0x03
0x08000F2A 2505 MOVS r5,#0x05
14: z=svc_service_add(x,y);
0x08000F2C 4629 MOV r1,r5
0x08000F2E 4620 MOV r0,r4
0x08000F30 DF00 SVC 0x00
0x08000F32 4606 MOV r6,r0
在调用SVC 指令后,如果没有更高优先级存在,那么就会根据异常向量表,跳转到SVC_Handler函数
int main(void)
{
int x,y,z;
x=3;y=5;
z=svc_service_add(x,y);
//printf("3+5=%d\n",z);
x=9;y=2;
z=svc_service_sub(x,y);
//printf("9-2=%d\n",z);
x=3;
z=svc_service_inc(x);
//printf("3++=%d\n",z);
while(1);
}
__asm void SVC_Handler(void)
{
TST LR,#4 ;测试EXC_RETURN的第2位
ITE EQ
MRSEQ R0,MSP ;主栈地址
MRSNE R0,PSP ;进程栈地址
B __cpp(SVC_Handler_main) ;
ALIGN 4
}
SVC 异常的处理函数,选择堆栈地址后,跳转到SVC_Handler_main中进行资源访问
void SVC_Handler_main(unsigned int* svc_args)
{
unsigned int svc_number;
svc_number=((char*)svc_args[6])[-2];
switch(svc_number)
{
case 0:
svc_args[0]=svc_args[0]+svc_args[1];
break;
case 1:
svc_args[0]=svc_args[0]-svc_args[1];
break;
case 2:
svc_args[0]=svc_args[0]+1;
break;
default:
break;
}
return;
}
参数svc_args中,svc_args[0]-svc_args[3],为参数或者返回值。
svc_args[4]为服务号,就是在调用SVC 指令时传入的立即数
svc_args[5]为EXC_RETURN的地址
svc_args[6]为pc寄存器的值,svc_args[7]为状态寄存器xPSR的值
- startup.s
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
;IMPORT SystemInit
;LDR R0, =SystemInit
;BLX R0
LDR R0, =__main
BX R0
ENDP
使用keil 软件调试 所以注释 SystemInit 函数
ARM Cortex-M3 Cortex-M4 权威指南(第3版)
版权声明:本文为qq_31208451原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。