Cortex-M3利用SVC中断调用系统服务的例子

2023-05-16

SVC(系统服务调用,亦简称系统调用)和PendSV(可悬起系统调用),它们多用在上了操作系统的软件开发中。SVC用于产生系统函数的调用请求。例如,操作系统通常不让用户程序直接访问硬件,而是通过提供一些系统服务函数,让用户程序使用SVC发出对系统服务函数的呼叫请求,以这种方法调用它们来间接访问硬件。因此,当用户程序想要控制特定的硬件时,它就要产生一个SVC异常,然后操作系统提供的SVC异常服务例程得到执行,它再调用相关的操作系统函数,后者完成用户程序请求的服务。

下面的代码是利用SVC异常来请求系统服务的例子,这个例子仅适用于MDK ARM Compiler 5,在ARM Compiler 6里取消了__svc()这个关键字,需要用户自己实现

__svc(4) uint32_t svc_service_add(uint32_t x, uint32_t y);    //__svc是编译器关键字,编译器会插入svc指令,触发svc异常
__svc(5) uint32_t svc_service_sub(uint32_t x, uint32_t y);

void SVC_Handler_C(uint32_t* svc_args)           //这里的svc_args是栈指针SP的值
{
    uint32_t svc_number;
    
    svc_number = ((uint8_t*)svc_args[6])[-2];    //svc_args[6]是栈里保存的PC值,倒数2字节,得到svc编号
    
    switch(svc_number)                           //根据svc编号执行需要的功能
    {
        case 4:
            svc_args[0] = svc_args[0] + svc_args[1];
            break;
        case 5:
            svc_args[0] = svc_args[0] - svc_args[1];
            break;
        default:
            break;
    }    
    
    return;
}

__asm void SVC_Handler(void)
{
    IMPORT SVC_Handler_C        //导入外部函数
    TST LR, #4                  //检查LR的bit2,这里LR的值是异常返回值EXC_RETURN
    ITE EQ
    MRSEQ R0, MSP               //如果bit2是0,说明进异常前使用的是MSP,把MSP值赋给R0
    MRSNE R0, PSP               //否则说明进异常前使用的是PSP,把PSP值赋给R0
    B SVC_Handler_C             //跳转到函数SVC_Handler_C()
}

uint32_t x = 13;
uint32_t y = 6;
uint32_t z1, z2;

int main(void)
{
    z1 = svc_service_add(x, y);
    z2 = svc_service_sub(x, y);
    
    printf("x + y = %d \r\n", z1);
    printf("x - y = %d \r\n", z2);
    
    while(1);
}

 下面这个是使用ARM Compiler 6的例子,本人水平有限,不会写带有返回值的C嵌汇编函数,只好用一个指针参数来传递结果。注意ARM编译器6的C嵌汇编语法格式与编译器5不同

__attribute__((always_inline)) void svc_service_add(uint32_t x, uint32_t y, uint32_t* res)
{
    register unsigned r0 __asm("r0") = x;
    register unsigned r1 __asm("r1") = y;
    register unsigned r2 __asm("r2") = (uint32_t)res;

    __asm volatile("SVC #4" :: "r" (r0), "r" (r1), "r" (r2));
    __asm volatile("STR R0, [R2]");
}

__attribute__((always_inline)) void svc_service_sub(uint32_t x, uint32_t y, uint32_t* res)
{
    register unsigned r0 __asm("r0") = x;
    register unsigned r1 __asm("r1") = y;
    register unsigned r2 __asm("r2") = (uint32_t)res;

    __asm volatile("SVC #5" :: "r" (r0), "r" (r1), "r" (r2));
    __asm volatile("STR R0, [R2]");
}

void SVC_Handler_C(uint32_t* svc_args)
{
    uint32_t svc_number;
    
    svc_number = ((uint8_t*)svc_args[6])[-2];
    
    switch(svc_number)
    {
        case 4:
            svc_args[0] = svc_args[0] + svc_args[1];
            break;
        case 5:
            svc_args[0] = svc_args[0] - svc_args[1];
            break;
        default:
            break;
    }    
    
    return;
}

void SVC_Handler(void)
{
    __asm volatile
    (
        "TST LR, #4       \n"
        "ITE EQ           \n"
        "MRSEQ R0, MSP    \n"
        "MRSNE R0, PSP    \n"
        "B SVC_Handler_C  \n"
    );
}

uint32_t x = 13;
uint32_t y = 6;
uint32_t z1, z2;

int main(void)
{
    svc_service_add(x, y, &z1);
    svc_service_sub(x, y, &z2);
    
    printf("x + y = %d \r\n", z1);
    printf("x - y = %d \r\n", z2);
    
    while(1);
}

这里有一篇文章,是Keil官方关于ARM Compiler 6如何实现svc函数的:

https://www.keil.com/support/docs/4022.htm

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Cortex-M3利用SVC中断调用系统服务的例子 的相关文章

  • FreeRTOS记录(三、RTOS任务调度原理解析_Systick、PendSV、SVC)

    RTOS的任务调度原理和所使用的内核中断 寄存器息息相关 文中截图大多是 Cortex M3与Cortex M4权威指南 翻译版本里面的内容 需要对内核有一定的了解 xff0c 本文尽量用简单的描述表达清楚 虽然是FreeRTOS的记录 x
  • Cortex-A7中断控制器GIC

    Cortex A7中断控制器GIC 中断号 芯片内部的中断都会引起IRQ InterruptGIC将所有的中断源 最多1020个中断ID 分为三类 SPI SharedPeripheralInterrupt 共享中断 xff0c 外部中断都
  • Error: Flash Download failed - “Cortex-M3“错误解决办法

    在使用STM32F103的时候 xff0c 使用DAP仿真器下载程序 xff0c 出现下载不了的情况 xff0c 错误信息如下 xff1a 输出框里打印信息如下 xff1a No Algorithm found for 08000000H
  • FreeRTOS进不了任务 卡在SVC_Handler

    网上看的 xff1a 第一次移植FreeRTOS单步调试卡在SVC Handler 汇编上面看SVC Handler后面有个 WEAK xff0c 意思是如果该函数不存在也不报错 xff0c 这意思是SVC Handler不存在 xff0c
  • Cortex M4 SVC 中断

    Cortex SVC 中断 SVC 系统管理调用 异常优先级为1 xff0c SVC异常是由SVC指令触发 也可以直接设置NVIC寄存器触发异常 应用程序工作在非特权访问模式 xff0c 当需要特权模式访问系统资源时 xff0c 可以使用S
  • uC/OSIII在Cortex-M3的任务切换和中断退出分析

    uC OSIII在任务中执行OSSched相关的函数和在中断退出后都会开始执行调度 xff0c 这是它的调度机制 而按uC OSIII书中所讲 xff0c 普通任务切换和从中断中退出后的任务切换应该是不同的函数 xff0c 因为普通任务切换
  • FreeRTOS卡在SVC_Handler

    FreeRTOS已经实现了SVC Handler 和PendSV Handler 两个函数的功能 xff0c 对应port c中的vPortSVCHandler 和xPortPendSVHandler 为了使用FreeRTOS的这两个函数
  • 集成Cortex-M0内核-- Integration and Implementation Manual手册学习

    根据使用场景 xff0c 配置并集成一个Cortex M0的内核 xff0c 暂时不涉及的实现的部分 目录 阅读手册 Chapter1 Introduction 1 1 About the processor 1 2 About integ
  • 基于Cortex-M的RTOS上下文切换详解及FreeRTOS实例

    文章目录 1 Cortex M MCU特性 1 1 操作模式 1 2 寄存器 1 2 1 核心寄存器 1 2 2 浮点寄存器 Floating Point registers 1 2 3 特殊寄存器 Special Registers 1
  • 《Cortex-M0权威指南》之Cortex-M0技术综述

    Cortex M0权威指南 之Cortex M0技术综述 转载请注明来源 xff1a cuixiaolei的技术博客 Cortex M0 处理器简介 1 Cortex M0 处理器基于冯诺依曼架构 xff08 单总线接口 xff09 xff
  • ARM Cortex-M4和Cortex-M0+中断优先级及嵌套抢占问题

    转自 xff1a http blog chinaaet com jihceng0622 p 5100001238 坐在上海回北京的高铁上 xff0c 漫长的旅途着实让人感到无聊 xff08 没买到直达的高铁 xff0c 只能慢悠悠的走一站停
  • ARM Cortex M4 SVC指令作用

    xff08 1 xff09 SVC指令 xff1a 摘自 http infocenter arm com help index jsp topic 61 com arm doc dui0203ic Cacdfeci html 与更早版本的
  • SVC和PendSV

    转载于 xff1a http book 2cto com 201209 4625 html 1 xff0e SVC SVC xff08 Supervisor Call xff09 指令用于产生一个SVC异常 它是用户模式代码中的主进程 xf
  • IAR ARM Cortex-M3下载程序至RAM中运行

    默认icf文件中ROM地址为0x0800 0000 xff0c 通过修改其中地址可实现将代码下载到RAM中 新建Configuration 新建Configuration用于区分 Project gt Edit Configurations
  • 意外发现,Cortex-M7的性能和诸多关键参数碾压A7和R7

    origin https www amobbs com thread 5676525 1 1 html 之前一直以为ARM A R M M排在最后也最便宜 xff0c 肯定性能最低 xff0c 但最近意外发现并非如此 xff0c M7居然完
  • ARM Cortex-M0+中断机制与中断编程步骤

    中断基础知识 为什么需要使用中断 xff1f 如果通过查询接收标志查看一个字节是否收到 xff0c 则需要时刻花费CPU等资源 但中断机制能够在收到一个字节后 xff0c 通知CPU把收到的字节取走 异常 xff1a CPU强行从正常运行的
  • 机器学习实战5-天气预测系列:利用数据集可视化分析数据,并预测某个城市的天气情况

    大家好 我是微学AI 最近天气真的是多变啊 忽冷忽热 今天再次给大家带来天气的话题 机器学习实战5 天气预测系列 我们将探讨一个城市的气象数据集 并利用机器学习来预测该城市的天气状况 该数据集包含年平均温度和湿度等信息 一 准备工作 首先
  • 手动计算SVM的决策函数

    我正在尝试使用Python库SKLearn手动计算SVC分类器的decision function 而不是使用内置方法 我已经尝试了几种方法 但是 当我don t扩展我的数据 z是一个测试数据 已缩放 我认为其他变量本身就说明了问题 另外
  • 如何更改默认的WCF服务绑定?

    在我的 WCF 中 我有一些服务 其中之一必须对消息大小有更大的限制 因此我必须创建另一个绑定并更改配置 但是 我在 Web config 中看不到我的服务的任何配置 什么也没有 有什么是默认的吗 那么我可以在哪里更改服务绑定呢 在 WCF
  • 将自定义对象从客户端 (Jquery) 发送到服务器 (WCF)

    如何将自定义对象从客户端 jquery 发送到服务器 WCF 服务 传递对象的方式是什么 下面是我的代码 当我在萤火虫中看到时 这就是我得到的 请查看屏幕截图 http img88 imageshack us img88 205 54211

随机推荐