ARM M3内核SVC系统调用的应用

##SVC应用

最近对照CM3指南看了一下SVC系统调用的使用方法,刚好先前碰到了NORDIC的蓝牙协议栈的接口,所以试着去研究了一下实现方式。以下为实验的代码:

/**
  ******************************************************************************
  * @file    svc_port.c
  * @brief   svc call test file.
  * @author  Yuzr
  * @note
  *******************************************************************************
  */

#include "stdint.h"
#include "ARMCM3.h"
//------------------------------------------------------------------------------//

//
// Define unused parameter.
//
#define UNUSED(_param)  (void)_param

/**
  ******************************************************************************
  * @brief  svc call funtion 1,add.
  * @param  a,b
  * @retval a+b
  *******************************************************************************
  */
static unsigned int _svc_call1(unsigned int a, unsigned b)
{
  return (unsigned int)(a+b);
}

/**
  ******************************************************************************
  * @brief  svc call funtion 2,add.
  * @param  a,b
  * @retval a-b
  *******************************************************************************
  */
static unsigned int _svc_call2(unsigned int a, unsigned int b)
{
  return (unsigned int)(a-b);
}

/**
  ******************************************************************************
  * @brief  svc call funtion 3,unused.
  * @param  a,b,c,d
  * @retval none
  *******************************************************************************
  */
static void _svc_call3(unsigned int a, unsigned b, unsigned int c, unsigned int d)
{
  UNUSED(a);
  UNUSED(b);
  UNUSED(c);
  UNUSED(d);
}

/**
  ******************************************************************************
  * @brief  svc handler test function.
  * @param  pwdSF,pwdSF will hold the stack.
  *         pwdSF[0] = R0, pwdSF[1] = R1
  *         pwdSF[2] = R2, pwdSF[3] = R3
  *         pwdSF[4] = R12, pwdSF[5] = LR
  *         pwdSF[6] = The return address,
  *         pwdSF[7] = xPSR
  * @retval
  *******************************************************************************
  */
unsigned int svc_function(unsigned int *pwdSF)
{
  unsigned int svc_number;
  unsigned int param0,param1,param2,param3;
  unsigned int retvalue;
  
  //
  // Hold the parameter.
  //
  svc_number = ((char *)pwdSF[6])[-2];
  param0 = (unsigned int)pwdSF[0];
  param1 = (unsigned int)pwdSF[1];
  param2 = (unsigned int)pwdSF[2];
  param3 = (unsigned int)pwdSF[3];
  UNUSED(param0);UNUSED(param1);
  UNUSED(param2);UNUSED(param3);

  //
  // Choose which call will be used.
  //
  switch (svc_number)
  {
    case 1:
    {
      retvalue = _svc_call1(param0, param1);
      break;
    }
    case 2:
    {
      retvalue = _svc_call2(param0, param1);
      break;
    }
    case 3:
    {
      _svc_call3(param0, param1, param2, param3);
      break;
    }
    default : break;
  }
  
  //
  // Hold and return the return value.
  //
  pwdSF[0] = retvalue;
  
  //
  // The return value will not be 0.
  //
  return 0;
}

/**
  ******************************************************************************
  * @brief  svc handler.
  * @param  none
  * @retval none
  *******************************************************************************
  */
__asm void SVC_Handler(void)
{
  IMPORT svc_function
  //
  // Check if the caller is from handler mode or threaded mode,
  // then call the svc_function.
  //
  TST    LR, #4
  ITE    EQ
  MRSEQ  R0, MSP
  MRSNE  R0, PSP
  B      svc_function
}

/**
  ******************************************************************************
  * @brief  main function.
  * @param  none
  * @retval none
  *******************************************************************************
  */
unsigned int __svc(1) svc_call1(unsigned int a, unsigned b);
unsigned int __svc(2) svc_call2(unsigned int a, unsigned b);
void __svc(3) svc_call3(unsigned int a, unsigned b, unsigned int c, unsigned int d);
 
int main(void)
{
  unsigned int ret=0;

  //
  // Test the interface.
  //
  ret = svc_call1(2,3);
  ret = svc_call2(6,3);
  svc_call3(0,0,0,0);
  UNUSED(ret);
  
  while(1);
  {
  }
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值