《VxWorks7编程指南》笔记(四)——中断服务程序ISR

2024-02-14 18:20

本文主要是介绍《VxWorks7编程指南》笔记(四)——中断服务程序ISR,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

 

1.中断服务程序ISR

2.针对ISR的VxWorks配置

3.ISR可用资源

4.ISR编程与调试

5.修改系统时钟ISR

6.运行时的ISR信息

7.ISR与工作队列死机


1.中断服务程序ISR

外部事件通常通过中断的方式通知系统,因此硬件中断处理是实时操作系统中的关键功能。

为了以最快速度响应中断,VxWorks中断服务程序执行在独有的上下文,而非任何任务是上下文中。除非系统专门进行过配置,否则不会推迟ISR的执行。

2.针对ISR的VxWorks配置

VxWorks系统默认支持SIR。中断栈可以按大小和附加特性进行配置。中断栈必须足够大,以处理中断嵌套时的最坏情况。

中断栈配置

所有的的ISR使用相同的中断栈空间。系统将在初始化时根据设定的配置参数为中断栈分配空间。其大小必须足够大,以应付中断嵌套时的最坏情况。中断栈大小由宏ISR_STACK_SIZE定义。

注意:某些架构不允许使用独立的中断栈,而需要使用被中断任务的栈空间。在这种架构下,必须确保创建任务时分配了足够大的栈空间,以处理中断嵌套和嵌套调用的最坏情况。

 

中断栈填充

默认情况下,中断栈空间被填充为0xEE。对栈空间进行填充的做法,对于开发过程中的调试很有帮助。具体可以使用checkStack()函数进行栈空间检查。

在进行系统配置时,建议不要对中断栈空间进行填充,以获得更佳的性能。可以使用配置参数VX_GLOBAL_NO_STACK_FILL关闭栈空间填充功能。

 

中断栈保护

如果使能了MMU功能,系统就可以通过配置INCLUDE_PROTECT_INTERRUPT_STACK组件,提供对中断栈始末的guard zone保护。

可以通过如下配置参数设置guard zone的大小:

  • INTERRUPT_STACK_OVERFLOW_SIZE:设置中断栈上溢大小;
  • INTERRUPT_STACK_UNDERFLOW_SIZE:设置中断栈下溢大小;

当添加了guard zone,栈空间的大小通常是MMU大小的整数倍。

3.ISR可用资源

所有的VxWorks功能库,如链表、环形缓冲区,都可以在ISR中使用。然而对于从ISR中调用函数还是有一些限制。

全局变量errno可以作为中断进入与退出代码的一部分而被保存和获取。所以,ISR刻意像其他代码一样引用和修改errno。

 

4.ISR编程与调试

对于ISR的最基础的要求就是,ISR代码应该尽可能的短。ISR中不应该添加耗时的函数,此外还有一些限制:ISR不能调用会导致ISR阻塞的函数,也不能调用使用浮点数协处理器的函数;对于C++使用也有限制。

非阻塞函数

虽然ISR中可以使用许多VxWorks功能,但是需要注意一些重要的限制条件。这些限制都是源于如下事实:ISR不是运行在常规的任务上下文中,且没有任务控制块,因此所有的ISR都共享同一个栈空间。

因为上述原因,对于ISR的最基础的限制条件就是,不能在ISR中调用会导致ISR自身阻塞的函数。例如,在ISR中不能尝试获取一个信号量,因为如果当前无法获取该信号量,那么内核将尝试把ISR切换到挂起状态。然而,ISR可以释放信号量,从而释放任何在等待该信号量的任务。

内存相关函数malloc()和free()中会尝试获取信号量,所以在ISR中不应该调用这两个函数。因此在ISR中不应该调用任何创建或删除函数。

ISR也不能通过VxWorks驱动执行I/O操作。尽管对I/O系统没有内在的限制条件,大多数的设备驱动仍然需要一个任务上下文环境,因为它们可能阻塞等待设备的任务。一个例外时VxWorks pipe驱动,ISR可以使用该驱动执行写操作。VxWorks还提供了几个供ISR调用的函数,用于向系统控制台中输出信息:logMsg()、kprintf()、kputs()。

 

浮点数协处理器函数

默认条件下,中断驱动代码不保存和读取浮点数寄存器。如果一个ISR需要执行浮点数指令,那么它必须使用fppArchLib库中提供的函数,对浮点数协处理器中的寄存器进行显示的保存和读取。

 

共享数据区的间接访问

ISR不应该直接访问共享数据区。一个ISR将继承被它抢占的任务的内存环境,如果该任务不包括共享数据区,那么ISR就不能访问共享内存,否则会导致系统异常。

为了可靠地访问共享数据区,ISR必须使用一个已经包含了共享数据区的任务。该任务在ISR执行完毕后可以执行对共享数据区的相关操作。

 

中断与任务之间的通信

尽管VxWorks支持直接连接运行在中断级的ISR,但是中断事件通常会传播到任务级代码中。许多VxWorks功能不适用于中断级代码,包括任何设备的I/O(除了pipe)。然而,如下技术可以用于ISR到任务级代码之间的通信。

  • 共享内存与环形缓冲区

ISR可以与任务级代码共享变量、缓冲区和环形缓冲区。

  • 信号量

ISR可以释放任务所需要的信号量(除了互斥信号量和VxMP共享信号量)。

  • 消息队列

ISR可以向等待接收消息队列中的消息的任务发送消息(除了VxMP中使用的共享消息队列)。如果队列已满,则该消息将被丢弃。

  • 管道

ISR可以向供任务读取的管道中写入消息。任务和ISR可以向同一个管道中写入消息。因为ISR不能被阻塞,所以如果管道已满,那么写入的消息将被丢弃。除了write()函数,ISR中不能在管道中触发任何I/O函数。

  • 信号

ISR可以向任务发送信号,从而异步调度相关的信号处理函数。

  • VxWorks事件

ISR可以向任务发送VxWorks事件。

 

高中断优先级保留

大多数应用程序都可以使用VxWorks中断。但是有些情况下,类似于关键运动控制或系统失效响应等事件,需要拥有低级别的控制。在这些情况下,最好能够保留最高级别的中断,确保以零延时响应这些事件。为了实现零延时,VxWorks提供了intLockLevelSet()函数,用于将系统范围内的中断锁级别设定到一个特定的级别。如果没有指定一个级别,那么将使用处理器架构所支持的最高级别。

 

对高中断级别ISR的限制

对链接到未屏蔽的中断优先级(既可以是比intLockLevelSet()函数设置的中断优先级高的级别,也可以是由硬件定义的非屏蔽中断优先级)的ISR由特殊的限制:

  • ISR只能通过intVecSet()函数连接
  • ISR不能使用任何基于中断锁的VxWorks操作系统功能。否则后果就是,除了系统重启,ISR不能安全地执行任何VxWorks函数调用。

 

对于I/O的使用限制

通常,ISR不能通过VxWorks驱动执行I/O操作,因为这些操作会导致ISR阻塞。这意味着标准的I/O函数,如printf()和puts()不能用于调试ISR。基础的供ISR调试使用的方法包括:

  • 在ISR中使用全局变量,该全局变量可以根据相关数据进行更新。之后就可以在运行时通过shell显示这些变量的值。
  • 在ISR中使用如下函数向控制台输出信息:logMsg()、kprintf()、kputs()。

使用全局变量的优点在于:实现简单且对ISR执行的性能影响最小。缺点在于如果系统因为ISR中的某个bug导致挂起,就不能使用shell显示变量的值了。

使用logMsg()函数的优点在于:可以自动向控制台打印消息,相较于kprintf()和kputs(),对于ISR的执行性能的影响更小。缺点在于,如果系统在调用该函数后短暂地挂起了,那么消息可能无法显示在控制台中。原因是由于logMsg()的异步操作首先是把消息写入到一个消息队列,然后logging任务将消息打包再发送到控制台。

使用kprintf()与kputs()的优点在于:它们可以同步地输出消息(使用轮询模式),因此可以在bug出现时精确地反映出ISR已经执行到哪个阶段(也可用于内核启动期间或任务切换钩子函数中)。缺点在于,因为它们使用串口输出信息,所以或显著影响ISR的执行性能。

 

中断级异常

当一个任务产生了硬件异常,如非法指令或总线错误,那么该任务将被挂起。系统中的其他任务将继续执行,而不被中断。然而,当一个ISR导致了类似的异常,系统中将没有相应的安全保障用于处理这些异常。ISR不具备可以挂起的上下文环境。相反,VxWorks将这些异常描述信息保存在内存空间的一个特殊区域,并执行系统重启。

VxWorks的BootLoader将检测低内存空间中的异常描述信息是否存在,如果检测到,则会在系统控制台中显示出来。BootLoader的“e”命令用于重新显示异常描述信息。类似的异常信息如下:

workQPanic:Kernel work queued from ISR overflowd.

 

ISR与内核工作队列死机(work queueu panic)

为了减少工作队列溢出,可以使用WIND_JOBS_MAX内核配置参数增加内核工作队列大小。

与内核工作队列死机相关的错误信息如下:

workQPanic:kernel work queue overflow

5.修改系统时钟ISR

可以根据应用程序需要,在usrClock()函数中添加相关的函数。

在系统启动的初始化过程中,系统时钟ISR usrClock()函数被挂接到系统时钟定时器中断上。每个系统时钟中断都将调用usrClock(),用于更新系统tick值并执行调度。

在usrClock()函数中添加代码也要遵守在ISR中调用函数的要求。

6.运行时的ISR信息

针对每个与VxWorks连接的ISR,系统都创建了一个内核对象。ISR对象提供了一种管理系统中所有ISR信息的方法。

可以参考isrLib和isrShow API参考手册,了解用于获取ISR信息的相关函数。

INCLUDE_ISR_SHOW组件提供了isrShow(),INCLUDE_ISR_OBJECT提供了isrLib。

7.ISR与工作队列死机

如果ISR以非常高的频率填充内核工作队列,导致内核处理不过来,那么会将工作队列填满,使得无法再将新的工作项添加到工作队列中。这将导致称为工作队列死机(work queue panic)的致命错误。

为了降低中断响应时间,VxWorks内核在执行关键区代码时不会锁中断,如任务状态改变、上下文切换、重新调度等等。使能中断后,ISR将以尽可能快的速度执行。如果在内核执行关键区代码的过程中产生了一个中断,而ISR同样调用了需要执行关键代码的内核函数,那么内核将延迟关键区代码的执行,知道具备安全执行的条件为止。这个过程是通过内核工作队列实现的。工作队列可以高效地将内核关键区排入队列,并且不会阻塞ISR中非关键区的代码执行。

考虑到性能因素,工作队列被设计为一个具有固定大小的环形缓冲区。可以通过WIND_JOBS_MAX配置参数配置其大小,该大小必须是2的幂次。

 

工作队列死机(work queue panic)

通常,工作队列死机是由于设备驱动不恰当的写操作导致的。例如:

  • 确认中断失败。如果一个ISR未能确认一个中断,那么将导致一直产生相同的中断。
  • 在中断上下文执行了太多的操作。为了最佳的实时性能,可以将ISR中的复杂操作转移到与中断源相关的合适优先级的任务中执行。ISR应该使用一个内核调用唤醒该任务(例如semGive()).
  • 将设备突发事件作为独立中断处理。应该在关闭设备相关的中断之后在任务上下文中处理突发事件。当没有再检测到未处理的事件且任务将会挂起时,就可以再次使能中断源了。

这篇关于《VxWorks7编程指南》笔记(四)——中断服务程序ISR的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/709236

相关文章

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(五):Blender锥桶建模

前言 本系列教程旨在使用UE5配置一个具备激光雷达+深度摄像机的仿真小车,并使用通过跨平台的方式进行ROS2和UE5仿真的通讯,达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础,Nav2相关的学习教程可以参考本人的其他博客Nav2代价地图实现和原理–Nav2源码解读之CostMap2D(上)-CSDN博客往期教程: 第一期:基于UE5和ROS2的激光雷达+深度RG

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

Go Playground 在线编程环境

For all examples in this and the next chapter, we will use Go Playground. Go Playground represents a web service that can run programs written in Go. It can be opened in a web browser using the follow