Cortex-M 内核支持系统服务调用SVC(SuperVisor Call)指令,用户可以用这个指令手动触发一个异常,这有时候非常有用,例如当内核运行在非特权模式时想要修改只有在特权模式才能接入的特殊寄存器,异常处理只能运行在特权模式。
但是它如何运行和用户使用的编译器版本息息相关,如果有其他的软件模块可用的话,他们通常已经实现了SVC异常的处理,比如CMSIS RTOS。
1 触发SVC
首先程序代码中必须要插入SVC指令,这个指令有一个参数(Thumb code 0-255)来选择不同的SVC调用函数,下面的例子用来产生 SVC 0 。但请考虑到,工程中的其它软件模块或许已经使用了,那样请使用其他参数值。
若使用ARMCC,这个编译器能识别 __svc 关键字,因此能很简单的定义SVC函数如下,调用该函数能在当前位置产生一个SVC指令。
void __svc(0) EnablePrivilegedMode( void ) ;
2 处理SVC
当使用RTOS时,一般都已经实现了SVC的处理,这样需要查看RTOS的文档来确定如何添加一个额外的用户SVC请求。在其他需要用户程序实现SVC的情况下,一般都需要特定的语法并使用汇编代码实现。下面使用Cortex-M3的例子用来说明(ARMCC编译器),它支持有条件的执行指令。
这个函数以SVC_Handler_Main()结束,这是个普通的c函数,这个函数需要在堆栈返之前查看指令以确定SVC号,SVC0在本例中用来关闭特权模式。