讲座视频 - 调试实时系统 - 中断

展开字幕 关闭字幕 时长:19分59秒
评论 收藏 分享 上传者:hi5
大家好, 我是 Jon Valvano。 在本视频中,我们将讨论中断。 现在,我们要介绍它们是什么、我们为什么需要它们以及 我们如何使用它们。 我们将讨论中断向量和优先级等内容。 然后,我们将在最后讨论 我们如何同步中断系统中的不同 线程。 这将是一种非常强大的 软件工具,它帮助我们极大地提高 系统的复杂性。 什么是中断? 从根本上说,中断是软件执行的转移。 它像是函数调用,但它由硬件触发。 因此,计算机中一个称为触发器的事件, 一个物理事件,将导致软件进行响应。 因此,它将是一个称为中断服务程序的特殊 函数,它会得到执行以响应该事件。 这就是中断驱动程序的本质。 现在,我们要把它称为多线程, 因为我们将有主线程,即我们 通常具有的主程序。 我们将具有1、2、3 或 20 个 此类中断驱动线程,用于响应 物理事件。 那么,通过这种方法,我们将能够提高 软件的复杂性,而无需 把我们软件的所有组件、所有部分都混合到 主程序中。 因此,这将是一种非常强大的软件 技术,它称为多线程或中断服务程序。 我们将把它们用于很多功能。 我们可以把它们用于传感器、避障等。 或者当电机过载将丢失特定的数据时, 用于触发中断的警报 这些事件。 某些计算机把它们用于可能发生的 内部事件。 我们的系统中不会有任何此类内部事件, 但我们将有周期性事件。 换句话说,我们将有 一个会触发中断的计时器,因此我们可以定期 执行某段程序。 这在我们的实时系统中非常重要。 系统设计中,我们 将讨论该触发器。 触发器是导致中断的触发源。 因此,我们可以提出一个简单的问题, 对于一个嵌入式系统,哪些类型的触发器是适用的? 我们通常可以非常简单地描述它们。 也就是说,如果某件事需要发生, 某个事件需要得到处理,它将 触发一个中断。 例如,如果我们有一个输入端口, 并且新数据已经到达该输入端口, 那么我们将处理它。 新数据的到达将触发一个中断。 如果我们有一个输出通道,通常来说,我们 将在输出设备空闲时触发它。 换句话说,它需要一个软件为它提供更多数据。 正如我说过的,我们将使用计时器。 具体来说,我们将在本章中使用Systick 来生成周期性中断。 我们为什么使用中断? 这是因为,如果我们考虑我们系统的复杂性, 如果我必须执行两件、三件或四件 事情,如果我必须把它们全部一起放在一个主程序中, 那么我们现在面临的情况是, 操作 a 与操作 b 和操作 c相关或者与它们进行交互。 我的软件必须执行的这四个看起来独立的 任务现在相互纠缠在一起, 这样一来,如果执行 b需要很长时间,那么 c 的执行将延迟。 或者,如果 d 碰巧崩溃,那么这一切都将崩溃。 而利用中断,我要做的是, 我将为其中的每项任务调用触发器, 无论它是周期性触发器、输入触发器还是输出 触发器,都没有关系。 现在,我已经在逻辑上 完成的是,我现在已经分离了这些任务,这样它们就不会 并行运行。 这称为并发。 只有一个程序计数器。 我们将看到这是如何发生的。 但是,它们在逻辑上是分离的。 如果我想把这些线程连接在一起, 我将使用一个消息传递机制,控制 我们在线程之间传递和同步 数据。 但它允许我以一种对系统 使用而言很自然的方式来提高系统的复杂性。 我们将反复不断地实践中断的方式。 对中断来说另一个重要的应用 是对重要事件进行响应。 例如小车撞到墙壁了。 这时,最好停止电机 这就是我们要在本章中 执行的操作。 撞墙,停止电机,撞墙,停止电机 此外,中断还用于处理我们 从不会预期发生的事情, 但如果它们发生,我们将 快速处理它们。 好的。 那么让我们讨论一下细节。 正如我说过的,我们有多个线程。 线程是正在运行的程序的 执行或操作。 在一个双线程系统中,我们有 前台线程、主程序和后台线程,即中断 服务程序。 再说一次,后台线程由硬件触发,但具有 软件的特征。 中断就是这么回事儿。 那么,如果它是一个嵌入式系统 这意味着所有任务、所有功能 都尝试解决同一个问题,因此我们需要 在线程之间共享同步数据,这是很有意义的。 那么,我们要实现它的方法是使用 共享全局变量。 无论它们是全局变量还是静态变量,都没有关系。 它永久性地分配在 RAM 中。 好的。 那么,我们将在 RAM 中建立一个架构 我们将使用一个线程对它进行写入,并通过另一个线程 对它进行读取。 或者,通过这个线程对它进行写入,并读取到另一个线程中。 我们要将该全局变量用作在线程之间传递 数据的方法。 如果我们把某个线程视为正在执行, 将要发生的是, 触发器将触发。 那么正在执行的该软件将挂起。 另一个线程在这里执行。 它从该位置发生的中断处获取返回值。 因此,如果这是 a,那是 b,那是 c, 那么接下来要发生的事情是 d。 这个东西将恢复运行。 这就是我如何使用单个程序 计数器在系统上实现多线程的本质。 我们要把该数据保存到堆栈中, 更改程序计数器,执行新的线程。 当需要恢复运行时,我们 将从堆栈返回参数。 因此,几微秒之后我们将 在这里返回。 让我们更深入地进行探究 发生的实际步骤。 那么,我们有触发事件。 在本例中,它将是SysTick从 1 变为 0 的 过程。 它将设置计数标志。 从而触发一个中断。 将要发生的是,它会将当前线程挂起。 完成它的启动指令。 将一组寄存器入栈。 我们将在下一张幻灯片中看到它。 把连接寄存器设置为特殊的寄存器。 这里的代码意味着我将运行一个中断。 有几百个可能的中断。 因此有一个寄存器,它使用中断号进行 设置,然后它将获得向量并跳转到 该中断服务子程序。 这就是整个过程。 请记住它。 这就是目的。 中断就是这么回事儿 -- 一个硬件触发器。 它用作一个硬件标志。 它将被设置。 它将触发该中断 事件的执行。 这就是中断的本质。 当我们运行中断服务程序时,触发器标志将被清除。 在这里,我们把它称为清除触发器标志。 我们将执行需要发生的任何服务, 比如与全局变量进行通信。 那么我们完成了。 我们将执行该指令。 编译器已经生成。 那么,如果在我执行分支连接时 连接寄存器是FFFFFFF9,这将 使八个寄存器出栈, 从而使我返回到发生中断时我刚 完成的指令。 好的。 那么,这里是一些更多细节。 这些还是相同的步骤。 当我们完成该指令后,我们 会使寄存器入栈。 这些是实际的入栈寄存器。 程序状态寄存器,其中包含标志 -- 旧程序计数器,旧连接寄存器, R12,R3,R2,R1,R0。 您会注意到它没有使 R4 到 R11 入栈。 如果需要,编译器将自动保存它们。 它执行向量获取。 有一大堆向量, 我们将在下一张幻灯片中看到一个表。 这是位于低位 RAM中的 SysTick 向量。 它是一个存储在RAM 中的该位置的 32 位地址,其中包含 中断服务程序的地址。 SysTick 碰巧是中断 15。 我们再次把它设置为连接寄存器。 那么,基本来说,它要将八个寄存器入栈。 更改 IPS。 现在,主掩码中的I 位对于启用 中断而言意味着零。 事实上,即使我正在运行中断 它也不会禁用中断。 这里允许一个中断中断另一个中断。 我们一会儿将讨论优先级。 总之,当发生上下文切换时, 这意味着从前台线程转向后台线程, 它将使八个寄存器入栈, 从而保存它所处位置的上下文。 然后,当它执行BXLR 时,这八个 寄存器会重新放置到处理器中,包括程序计数器, 然后在它中断的位置恢复执行。 好的。 那么,我说过有很多的向量。 有很多的中断 我们将在本章中执行的中断是 SysTick。 它是中断向量号15。 我们将使用一系列的另外的定时器寄存器, 我们将在后续实验中使用它们。 当我们开始使用蓝牙和 Wi-Fi 时, 我们可以使用这些IRQ 向量中的一部分。 实验 14 将使用边沿触发端口中断。 因此,当小车撞到墙时, 将会有一个端口产生IRQ 请求。 如果您想在您的系统上查看该代码 请在CCS.C中查找这个称为startup... 的文件中进行查看。 该文件中给出了所有向量。 中断向量表加载于 RAM 的 起始处。 为了使用中断,您需要做的是, 在您的系统中使用该向量表中的名称定义一个函数。 那么,如果您定义一个称为SysTick 处理程序的函数, 它将成为在发生SysTick 中断时执行的 SysTick 中断服务程序。 我曾提到过优先级。 中断的作用 是使我们的系统变得复杂。 那么,我们有一个主程序 我们始终有该程序 -- 同时我们可以有多个中断程序。 我们看过这张幻灯片。 我在这里有五个线程。 其中的某些线程 比其他线程更重要。 比如小车撞到墙。 这是一件糟糕的事情。 我们应快速地对它进行处理。 因此,我要做的是,将为我的每个 线程分配一个优先级。 我可以使它们具有相同的优先级。 这样,我平等地对待每个线程, 没有任何线程受到优待。 但是,我们其实有 3 个位可进行优先级设定, 其中0为最高优先级,7 为最低优先级 我可以,或者说必须为我的所有中断分配该值。 因此,如果我有四个中断, 那么我将为我的每个中断设置一个优先级。 现在,它所做的 -- 假设 c 是最重要的。 因此我要使它具有优先级一。 b 是第二重要的。 它具有优先级二。 假设 a 和 d具有低优先级, 但它们的优先级相同。 那么它们不必是唯一的。 那么现在,如果我正在运行主程序,会发生什么, 这四个中断中的任何一个都可能发生,因为这就是 中断的作用。 但是,如果我正在运行一个优先级为一的中断, 是的,它最重要。 此时发生了其他三个中断之一, 该中断将延迟,直到优先级为一的中断结束。 然后才允许它执行。 另一方面,如果我正在执行 一个优先级为三的中断。 现在,一个优先级为二的中断触发,它将去执行这个优先级高的中断。 当它完成后,它将重新返回到这里。 但是,如果我正在执行一个优先级为三的中断, 并且另一个优先级为三的中断触发, 它将延迟。 因此,如果某个中断具有更高的优先级,那么它将 打断或中断另一个中断。 它其实是一个 3 位值。 想弄清编译器 中断处理的机制,是有点儿复杂的。 但 SysTick 中断的 3 位值位于该地址的 最高有效字节中,采用小字节序。 在该编译器中,使这发生的方法是, 存储该寄存器的顶部三个位。 这将指定SysTick 优先级。 在其他中断之中, 语法稍有不同。 因此,如果我想设串行端口A2的优先级, 我将访问一个32 位寄存器。 按照这种方法设置位 23 至 21。 您可以看到,这两个代码 都会将它们对应的中断的优先级设置为2, 这有点儿高,但不是最高。 因此,当我们具有多个中断时,优先级很重要, 它使系统能够确定一个中断是否能够中断另一个中断。 如果您想使它变得很简单,那么您可以做的是,把所有 优先级设置为彼此相等。 这样就没有中断会中断任何其他中断。 这就是您想要的结果。 您也可以通过这种方法来实现它。 我们讨论了中断。 它是一个被执行的线程。 我们将在本课程中使用一些很简单的 数据结构,我们在处理中断时会使用它们。 这些数据结构可能仅仅是一个标志。 如果一个线程设置一个标志,它可以仅向共享全局 变量中写入 1。 然后其他线程可以查看该标志 并看到该标志是否已设置。 我们要在该试验中操作的数据 是一个邮箱,它其实是一个信号标志加数据的组合。 如果我们有一个输入设备, 比如 IR 传感器或线传感器,那么, 如果中断读取了该线传感器的内容, 我们将获取该线传感器数据。 把它存储在一个全局变量中,该变量 称为 mail 或您喜欢的任何名称, 它是一个全局变量。 然后,我们要把该标志设置为真。 然后,将处理它的主程序可以查看 该标志,并确定 数据是否有效。 如果该标志已设置,那么您现在可以处理它,并且 可以在下一次清除该标志。 那么,指示一个信号量。 现在,如果您了解我们在本课程中 并不需要的更复杂的方法, 或者在我们开始执行实验 18 时将使用该方法, 在我们开始执行实验 18 时,我们 将使用另一种称为先入先出队列的结构, 该结构允许数据以保持先入先出 方法的方式流入。 但是,我们直到开始执行实验18 时才会使用 FIFO 队列。 总之,中断是一种非常强大的编程工具 它允许我们提高复杂性。 我们将使用堆栈来执行上下文切换。 中断向量是硬编码地址,它告知系统 所有中断服务程序位于 何处。 再说一次,中断服务程序 是针对触发器执行的软件 该向量是此中断服务程序的地址。 它将一组寄存器入栈。 设置连接寄存器。 该来自中断的返回值与来自 函数的返回值类似,除非连接寄存器碰巧 等于 FFFFFFF9 -- 此时该返回值将使所有寄存器 出栈。 现在,存在几百个中断。 我们将对我们感兴趣的中断提供支持。 如果我们有多个中断,我们将为每个中断 分配优先级。 此外,处理器中有一个 I 位, 它位于主掩码寄存器中,我们 将通过执行启用中断函数来清除该位。 那么,启用中断函数将清除 I 位。 如果您想禁用中断, 还有一个禁用中断函数。 这是一个内置在启动代码中的函数, 它将设置 I 位,这不会消除或除去中断。 它只是延迟中断。 再说一次,我们将使用常规公共 全局变量或私有永久静态变量 共享数据。 本实验比较难于实施,但对于 本章而言,实际上它较为简单。 因此,我们鼓励您开始 了解如何使用中断的过程, 今天就开始。 好的。 祝您愉快。412
课程介绍 共计4课时,1小时4分14秒

TI-RSLK 模块 10 - 调试实时系统

TI 机器人 闪存 RSLK 实时系统

此模块介绍闪存的工作原理,包括实时系统的调试方法以及如何使用 SysTick 产生周期性中断。系统运行于真实环境下时,干扰最小的调试对于实时系统进行性能评估至关重要。
展开

  • 相关产品
  • 样品申请
  • EVM购买
  • 文档下载
  • 软件/工具
  • TI Design
分享到X
微博
QQ
QQ空间
微信

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新文章 手机版

站点相关: EEWORLD首页 EE大学堂 论坛 下载中心 Datasheet 活动专区 博客

北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2017 EEWORLD.com.cn, Inc. All rights reserved