以下内容转载自安富莱电子: 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. linux中DHCP服务配置文件/etc/dhcpd.conf详细说明

    DHCP服务的配置 dhcpd.conf 是DHCP服务的配置文件,DHCP服务所有参数都是通过修改dhcpd.conf 文件来实现,安装后dhcpd.conf 是没有做任何配置的,将/usr/sha ...

  2. zabbix3.0 安装时出现PHP Parse error: syntax error

    httpd的错误日志 [Sun Mar :: ] [error] [client 由于系统yum默认安装的php版本是5.3.3 zabbix 3.0支持的平台,只支持php5.4以上的版本https ...

  3. class-dump在osx 10.11以后安装方法

      当Mac升级了OSX 10.11后,配置class-dump的时候,会发现逆向书上推荐的class-dump存放目录/usr/bin,class-dump存放不进去,尝试过用sudo 还是不被允许 ...

  4. C# 自定义控件入门

    原文地址:http://www.itdaan.com/blog/2008/03/29/95500785fa538b3900b34ee824376e8b.html 这几天为了什么"评估&quo ...

  5. ERROR: No query specified

    mysql中执行show命令的时候,提示以下信息: mysql> show variables like 'datadir'\G; *************************** 1. ...

  6. 章节0:MySQl学前知识储备

    一.数据库基础: 1.数据库(database):保存有组织的数据的容器(通常是一个文件或一组文件). 2.数据库管理系统(DBMS):创建和操纵数据库的软件系统. 3.表(table):某种特定类型 ...

  7. echarts legend 的单选模式以及轮播技巧

    1.设置 legend 属性: selectedMode: 'single' 2.使用 myCharts.dispatchAction 来设置legend的聚焦 broadcast (v) { // ...

  8. Sql 查询当天、本周、本月记录

    --查询当天: select * from info where DateDiff(dd,datetime,getdate())=0 --查询24小时内的: select * from info wh ...

  9. unity, Collider2D.attachedRigidbody

    boss根节点上挂RigidBody2D(且boss根节点以下任何子节点均不挂RigidBody2D),boss腿部骨骼节点挂collider2D,标签为"bossLeg",bos ...

  10. 3dmax,查看场景中所有材质