历史上的今天
今天是:2024年10月15日(星期二)
2019年10月15日 | ARM SVC模式源码
2019-10-15 来源:eefocus
采用svc模式可以将SDK(API)和Application分离, 也可以省略很多重复的代码,比如在bootload中用到了usb, 然后在application中想复用的话,可以用svc
原理: 类似软件中断,中添加了一个软件中断源,通过中断源表明调用的函数接口
源程序如下:
#ifndef NRF_SVC__
#define NRF_SVC__
#ifdef SVCALL_AS_NORMAL_FUNCTION
#define SVCALL(number, return_type, signature) return_type signature
#else
#ifndef SVCALL
#if defined (__CC_ARM)
#define SVCALL(number, return_type, signature) return_type __svc(number) signature
#elif defined (__GNUC__)
#define SVCALL(number, return_type, signature)
_Pragma("GCC diagnostic ignored "-Wunused-function"")
_Pragma("GCC diagnostic push")
_Pragma("GCC diagnostic ignored "-Wreturn-type"")
__attribute__((naked)) static return_type signature
{
__asm(
"svc %0n"
"bx r14" : : "I" (number) : "r0"
);
}
_Pragma("GCC diagnostic pop")
#elif defined (__ICCARM__)
#define PRAGMA(x) _Pragma(#x)
#define SVCALL(number, return_type, signature)
PRAGMA(swi_number = number)
__swi return_type signature;
#else
#define SVCALL(number, return_type, signature) return_type signature
#endif
#endif // SVCALL
#endif // SVCALL_AS_NORMAL_FUNCTION
#endif // NRF_SVC__
void C_SVC_Handler(uint8_t svc_num, uint32_t * p_svc_args)
{
switch (svc_num)
{
case NRF_SEC_SVC_HASH:
p_svc_args[0] = nrf_sec_hash((nrf_sec_data_t *) p_svc_args[0],
(uint8_t *) p_svc_args[1],
(nrf_sec_hash_func_t) p_svc_args[2]);
break;
case NRF_SEC_SVC_VERIFY:
p_svc_args[0] = nrf_sec_verify((nrf_sec_data_t *) p_svc_args[0],
(nrf_sec_ecc_point_t *) p_svc_args[1],
(nrf_sec_ecc_signature_t *) p_svc_args[2],
(nrf_sec_algo_t) p_svc_args[3]);
break;
default:
p_svc_args[0] = NRF_ERROR_SVC_HANDLER_MISSING;
break;
}
}
#if defined ( __CC_ARM )
__asm void SVC_Handler(void)
{
EXC_RETURN_CMD_PSP EQU 0xFFFFFFFD ; EXC_RETURN using PSP for ARM Cortex. If Link register contains this value it indicates the PSP was used before the SVC, otherwise the MSP was used.
IMPORT C_SVC_Handler
LDR R0, =EXC_RETURN_CMD_PSP ; Load the EXC_RETURN into R0 to be able to compare against LR to determine stack pointer used.
CMP R0, LR ; Compare the link register with R0. If equal then PSP was used, otherwise MSP was used before SVC.
BNE UseMSP ; Branch to code fetching SVC arguments using MSP.
MRS R1, PSP ; Move PSP into R1.
B Call_C_SVC_Handler ; Branch to Call_C_SVC_Handler below.
UseMSP
MRS R1, MSP ; MSP was used, therefore Move MSP into R1.
Call_C_SVC_Handler
LDR R0, [R1, #24] ; The arguments for the SVC was stacked. R1 contains Stack Pointer, the values stacked before SVC are R0, R1, R2, R3, R12, LR, PC (Return address), xPSR.
; R1 contains current SP so the PC of the stacked frame is at SP + 6 words (24 bytes). We load the PC into R0.
SUBS R0, #2 ; The PC before the SVC is in R0. We subtract 2 to get the address prior to the instruction executed where the SVC number is located.
LDRB R0, [R0] ; SVC instruction low octet: Load the byte at the address before the PC to fetch the SVC number.
LDR R2, =C_SVC_Handler ; Load address of C implementation of SVC handler.
BX R2 ; Branch to C implementation of SVC handler. R0 is now the SVC number, R1 is the StackPointer where the arguments (R0-R3) of the original SVC are located.
ALIGN
}
#elif defined ( __GNUC__ )
void __attribute__ (( naked )) SVC_Handler(void)
{
const uint32_t exc_return = 0xFFFFFFFD; // EXC_RETURN using PSP for ARM Cortex. If Link register contains this value it indicates the PSP was used before the SVC, otherwise the MSP was used.
__asm volatile(
"cmp lr, %0tn" // Compare the link register with argument 0 (%0), which is exc_return. If equal then PSP was used, otherwise MSP was used before SVC.
"bne UseMSPtn" // Branch to code fetching SVC arguments using MSP.
"mrs r1, psptn" // Move PSP into R1.
"b Call_C_SVC_Handlertn" // Branch to Call_C_SVC_Handler below.
"UseMSP: tn" //
"mrs r1, msptn" // MSP was used, therefore Move MSP into R1.
"Call_C_SVC_Handler: tn" //
"ldr r0, [r1, #24]tn" // The arguments for the SVC was stacked. R1 contains Stack Pointer, the values stacked before SVC are R0, R1, R2, R3, R12, LR, PC (Return address), xPSR.
// R1 contains current SP so the PC of the stacked frame is at SP + 6 words (24 bytes). We load the PC into R0.
"sub r0, r0, #2tn" // The PC before the SVC is in R0. We subtract 2 to get the address prior to the instruction executed where the SVC number is located.
"ldrb r0, [r0]tn" // SVC instruction low octet: Load the byte at the address before the PC to fetch the SVC number.
"bx %1tn" // Branch to C implementation of SVC handler, argument 1 (%1). R0 is now the SVC number, R1 is the StackPointer where the arguments (R0-R3) of the original SVC are located.
".aligntn"
:: "r" (exc_return), "r" (C_SVC_Handler) // Argument list for the gcc assembly. exc_return is %0, C_SVC_Handler is %1.
: "r0", "r1" // List of register maintained manually.
);
}
#else
#error Compiler not supported.
#endif
__asm void SVCHandler(void)
{
IMPORT SVCHandler_main
TST lr, #4
ITE EQ
MRSEQ R0, MSP
MRSNE R0, PSP
B SVCHandler_main
}
void SVCHandler_main(unsigned int * svc_args)
{
unsigned int svc_number;
/*
* Stack contains:
* R0, R1, R2, R3, R12, R14, the return address and xPSR
* First argument (R0) is svc_args[0]
*/
svc_number = ((char *)svc_args[6])[-2];
switch(svc_number)
{
case SVC_00:
/* Handle SVC 00 */
break;
case SVC_01:
/* Handle SVC 01 */
史海拾趣
|
哪位有工作经验的大哥大姐请帮帮忙(可以是任何关于电子或编程开发方面的经验) 我们老师最近要求写一篇职业生涯规划,由于我选的是关于嵌入式开发方面的,因此必须找一位有工作经验的人来做一个职业访谈。不需要浪费很长时间,问题我已经写好了,只要填完就行了。只要留下邮箱就行,我会把文档给你 ...… 查看全部问答> |
|
我要在客户端(三星ARM6410SDB)上安装sqlce3.0,首先拷贝sqlce30.ppc.wce5.armv4i.CAB,sqlce30.repl.ppc.wce5.armv4i.CAB,sqlce.dev.ENU.ppc.wce5.armv4i.CAB三个文件至开发板的NandFlash,点击安装,出现错误:“没有应用程序与“s ...… 查看全部问答> |
|
各位,我正在做一个项目,需要有经验的您参与: (1)USB驱动开发。 (2)普通电话机硬件。 (3)地点:上海 需要有丰富经验,酬金面谈,您如果需要挣外快,请和我联系:13818802872。 … 查看全部问答> |
|
因为准备用STM32F103CB,想要一个仿真器。想在U-LINK和J-LINK中选一个,芯片商那说J-LINK性能要好一点的。我是要想 ...… 查看全部问答> |
|
作为老牌的MCU 厂商,飞思卡尔的MCU 曾给开发者留下深刻印象,飞思卡尔不但有 自己架构的32 位MCU,也陆续推出了基于ARM 架构的32 位MCU,并取得骄人的业绩, 如率先推出了全球首款cortex-M0+ 内核架构的MCU 以及目前全球最小的ARM MCU(只 有1. ...… 查看全部问答> |
|
说起TI的无线,就不得不提大名鼎鼎的CC2530了 因为项目需求和自己想做,选了一版还是比较成功的一版分享给大家 主要还是参考了官方的设计 射频部分是0402的其他的是0603的,因为测试需要,搞了两个天线,可以通过跳焊盘来选 实际测试还是可 ...… 查看全部问答> |




