以下内容转载自安富莱电子: http://forum.armfly.com/forum.php

本章节为大家讲解如何采用 SVC 中断方式调用用户函数。 当用户将 RTX 任务设置为工作在非特权级
模式时,任务中是不允许访问特权级寄存器的,这个时候使用 SVC 中断,此问题就迎刃而解了。

SVC 功能介绍
SVC 用于产生系统函数的调用请求。例如,操作系统通常不让用户程序直接访问硬件,而是通过提供
一些系统服务函数,让用户程序使用 SVC 发出对系统服务函数的呼叫请求,以这种方法调用它们来间接
访问硬件。因此,当用户程序想要控制特定的硬件时,它就要产生一个 SVC 异常,然后操作系统提供的
SVC 异常服务例程得到执行,它再调用相关的操作系统函数,后者完成用户程序请求的服务。
SVC 这种“提出要求——得到满足”的方式很好:
 它使用户程序从控制硬件的繁文缛节中解脱出来,而是由 OS 负责控制具体的硬件。
 OS 的代码可以经过充分的测试,从而能使系统更加健壮和可靠。
 它使用户程序无需在特权级下执行,用户程序无需承担因误操作而瘫痪整个系统的风险。
 通过 SVC 的机制,还让用户程序变得与硬件无关,因此在开发应用程序时无需了解硬件的操作细节,
从而简化了开发的难度和繁琐度,并且使应用程序跨硬件平台移植成为可能。开发应用程序唯一需要
知道的就是操作系统提供的应用编程接口(API),并且在了解了各个请求代号和参数表后,就可以
使用 SVC 来提出要求了(事实上,为使用方便,操作系统往往会提供一层封皮,以使系统调用的形
式看起来和普通的函数调用一致。各封皮函数会正确使用 SVC 指令来执行系统调用)。其实,严格
地讲,操作硬件的工作是由设备驱动程序完成的,只是对应用程序来说,它们也相当于操作系统的一
部分。如下图所示:

SVC 异常通过执行” SVC”指令来产生。该指令需要一个立即数,充当系统调用代号。 SVC 异常服务
例程稍后会提取出此代号,从而获知本次调用的具体要求,再调用相应的服务函数。例如,
SVC 0x3 ; 调用 3 号系统服务
在 SVC 服务例程执行后,上次执行的 SVC 指令地址可以根据自动入栈的返回地址计算出。找到了 SVC
指令后,就可以读取该 SVC 指令的机器码,从机器码中萃取出立即数,就获知了请求执行的功能代号。
如果用户程序使用的是 PSP,服务例程还需要先执行 MRS Rn, PSP 指令来获取应用程序的堆栈指针。通
过分析 LR 的值,可以获知在 SVC 指令执行时,正在使用哪个堆栈。
注意,我们不能在 SVC 服务例程中嵌套使用 SVC 指令(事实上这样做也没意义),因为同优先级的
异常不能抢占自身。这种作法会产生一个用法 fault。同理,在 NMI 服务例程中也不得使用 SVC,否则将
触发硬 fault。

SVC 触发方式
SVC 的异常号是 11,支持可编程。 SVC 异常可以由 SVC 指令来触发,也可以通过 NVIC 来软件触发
(通过寄存器 NVIC->STIR 触发软中断)。这两种方式触发 SVC 中断有一点不同:软件触发中断是不精
确的,也就是说,抢占行为不一定会立即发生,即使当时它没有被掩蔽,也没有被其它 ISR 阻塞,也不能
保证马上响应。这也是写缓冲造成的,会影响到与操作 NVIC STIR 相临的后一条指令:如果它需要根据中
断服务的结果来决定如何工作(如条件跳转),则该指令可能会误动作——这也可以算是紊乱危象的一种
表现形式。为解决这个问题,必须使用一条 DSB 指令,如下例所示:
MOV R0, #SOFTWARE_INTERRUPT_NUMBER
LDR R1,=0xE000EF00 ; 加载 NVIC 软件触发中断寄存器的地址
STR R0, [R1] ; 触发软件中断
DSB ; 执行数据同步隔离指令
...
但是这种方式还有另一种隐患:如果欲触发的软件中断被除能了,或者执行软件中断的程序自己也是个异

常服务程序,软件中断就有可能无法响应。因此,必须在使用前检查这个中断已经在响应中了。为达到此
目的,可以让软件中断服务程序在入口处设置一个标志。而 SVC 要精确很多,SVC 指令后,只要此时没
有其它高优先级的异常也发生了,SVC 中断服务程序可以得到立即执行。

SVC 的使用
SVC 是用于呼叫 OS 所提供的 API(RTX 是采用的这种方式)。用户程序只需知道传递给 OS 的参数,
而不必知道各 API 函数的地址。 SVC 指令带一个 8 位的立即数,可以视为是它的参数,被封装在指令本身
中,如:
SVC 3 ;呼叫 3 号系统服务
则 3 被封装在这个 SVC 指令中。因此在 SVC 服务例程中,需要读取本次触发 SVC 异常的 SVC 指令,并
提取出 8 位立即数所在的位段,来判断系统调用号。

RTX 使用的 SVC 中断服务号
SVC 的 0 号系统服务被 RTX 系统占用,即 SVC 0,用户只能使用从 1 开始的服务号。而且用户使
用的时候一定要保证从 1 开始,连续递增使用,范围 1 – 255。

RTX 中 SVC 中断方式调用函数方法
用户实现 SVC 中断方式调用函数方法如下(下面以添加两个 SVC 中断为例):
 第 1 步:添加 SVC_Table.s 文件。
我们在前面讲解 RTX 的源码移植方式时这个文件已经加上。
 第 2 步:使用属性__svc(x)声明函数,x 从 1 开始,范围 1-255。函数名随便命名,但是 x 的数值一
定要保证是连续递增的。
void __svc(1) SVC_1_FunCall(uint8_t _arg1, uint16_t _arg2, uint32_t _arg3, uint64_t *_arg4);
void __svc(2) SVC_2_FunCall(void);
 第 3 步:写上面两个函数的实际代码,并将函数名更改成__SVC_x 格式(统一改成这种命名方式是为
了跟 RTX 系统的调用方式__SVC_0 统一),x 是从 1 开始,范围 1-255。 上面声明的两个函数不要动,
这里修改的是实际函数名。 另外用户可以根据需要加上中断开关操作,因为 SVC 中断可以被其它高
优先级的中断抢占。

RTX——第19章 SVC 中断方式调用用户函数(后期补历程)的更多相关文章

  1. 通过队列实现进程间的通信(使用阻塞方式调用func函数)

    #_author:来童星#date:2019/12/17#通过队列实现进程间的通信from multiprocessing import Poolimport osimport timedef fun ...

  2. 如何在tornado中以异步的方式调用同步函数

    问题 如何在tornado的coroutine中调用同步阻塞的函数 解决方案 使用python内置标准库的concurrent.futures.ThreadPoolExecutor和tornado.c ...

  3. RTX——第18章 内存管理

    以下内容转载自安富莱电子: http://forum.armfly.com/forum.php 内存管理介绍在 ANSI C 中,可以用 malloc()和 free()2 个函数动态的分配内存和释放 ...

  4. 以WCF安全认证方式调用通用权限管理系统获取基础信息资料

    在B/S开发中,涉及到获取系统基础资料的问题,因为是在不同平台下的开发,采用了WCF方式获取. 下面是一个调用通用权限管理系统(吉日嘎拉)基础信息资料的一个demo供参考 调用原理图: web.con ...

  5. JavaScript中以构造函数的方式调用函数

    转自:http://www.cnblogs.com/Saints/p/6012188.html 构造器函数(Constructor functions)的定义和任何其它函数一样,我们可以使用函数声明. ...

  6. 《深入Java虚拟机学习笔记》- 第19章 方法的调用与返回

    <深入Java虚拟机学习笔记>- 第19章 方法的调用与返回

  7. RTX——第11章 临界段,任务锁和中断锁

    以下内容转载自安富莱电子: http://forum.armfly.com/forum.php 临界段代码的临界段也称为临界区,一旦这部分代码开始执行,则不允许任何中断打断.为确保临界段代码的执行不被 ...

  8. 【RL-TCPnet网络教程】第19章 RL-TCPnet之BSD Socket服务器

    第19章      RL-TCPnet之BSD Socket服务器 本章节为大家讲解RL-TCPnet的BSD Socket,学习本章节前,务必要优先学习第18章的Socket基础知识.有了这些基础知 ...

  9. RTX——第9章 任务运行在特权级或非特权级模式

    以下内容转载自安富莱电子: http://forum.armfly.com/forum.php 本章教程为大家讲解 RTX 运行模式的一个重要知识点,特权级模式和非特权级模式,有些资料或者书籍将非特权 ...

随机推荐

  1. 安装 Linuxbrew

    在 OS X 平台上非常流行的包管理器 Homebrew 最近正被移植到 Linux 上而成为 Linuxbrew.虽然各种 Linux 发行都带有自己的包管理工具,诸如 apt-get.yum.pa ...

  2. POJ 1637 Sightseeing tour (SAP | Dinic 混合欧拉图的判断)

    Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6448   Accepted: 2654 ...

  3. HSSFWorkbook 与 XSSFWorkbook

    刚开始使用new HSSFWorkbook(new FileInputStream(excelFile))来读取Workbook,对Excel2003以前(包括2003)的版本没有问题,但读取Exce ...

  4. 【Visual Studio】Visual C# 中XML注释的使用(含注释在开发时显示换行)

    为函数方法注释说明要用到 xml 语句 <summary> 段落说明 </summary> .<para> 新段示例说明 </para>.<par ...

  5. sqlyog v12.09 注册码

    1.小巧的自动完成.2.HTTP/HTTPS和SSH通道.3.向导化的汇入工具包.4.结构化的同步,可以设定任务计划,按照特定的时间进行同步作业,并对同步数据进行校验.5.工作管理器.计划备份.以及通 ...

  6. Oracle 12C -- CDB的启动过程

    以启动DB12为例子 $ sqlplus '/as sysdba' SQL*Plus: Release Production on Sun Nov :: Copyright (c) , , Oracl ...

  7. 1142 - show view command denied to user

    原因是没有给test用户授予"show_view_priv"权限 mysql> SELECT * FROM mysql.user WHERE User = 'test' an ...

  8. 【转】给Java说句公道话

    有些人问我,在现有的语言里面,有什么好的推荐?我说:“Java.” 他们很惊讶:“什么?Java!” 所以我现在来解释一下. Java超越了所有咒骂它的“动态语言” 也许是因为年轻人的逆反心理,人们都 ...

  9. Java读取excel的示例

    一.引用的jar包,apache的POI // https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml compile group: ' ...

  10. VMware Linux 共享文件夹 虚拟机无共享文件解决方法

    恢复虚拟机ubuntu后,首先,点击 虚拟机——安装VMware Tools(Install VMware Tools),这时我们会在Ubuntu系统桌面上发现VMware Tools的光盘图标. 双 ...