中断架构总览

说明:

  • 总共有16路中断送入CPU。其中INT1~INT12的来源是ePIE,INT13和INT14是TIMER1和TIMER2.另外还有NMI和RTOSINT
  • TIMER0中断与TIMER1和TIMER2不同,它不是直接送给CPU,而是先送到ePIE。
  • 外部输入中断:从GPIO口经过Input X-BAR的选择后送给XINT1~XINT5,再送到ePIE
  • 其他外设的中断都是先经过ePIE。

中断传播路径

说明:

  • 外设中断先到达外设中断标志寄存器中锁存:PIEIFRx.y。其中,x最大有12路,y最大有16路。外设中断最多可以有12 * 16 = 192个。
  • 每一个都有对应的中断使能寄存器:PIEIERx.y。最多也有192个。
  • 每一组中的16个外设中断源通过“或”操作,送到PIEACK。每一组只占PIEACK的一个位。
  • 当PIEACK=0时,中断可以传播全局中断标志寄存器IFR。当PIEACK=1时,传播路径断开。
  • 中断应答寄存器PIEACK具备“自锁”功能。也就是说,当有中断过来的时候,PIEACK会自动断开,需要在处理完中断响应函数后由软件清除PIEACK位(写1清零)。这样可以确保同一组中的多个中断同时发生时能依次处理,而不会遗漏。

多路复用中断

INTM

最靠近CPU的是全局使能开关:INTM。是全局中断掩码(Interrupt global mask)。它是CPU核心寄存器ST1中的一个位。

这个位是个“掩码位”,不是个“使能位”。因此,当INTM=1时,屏蔽所有中断;为0时才开启全局中断。复位后的默认值是1,即关闭全局中断。

开启全局中断的方法是,将ST1.INTM位清零。使用宏定义语句:EINT

#define  EINT   __asm(" clrc INTM")

关闭中断是:DINT

#define  DINT   __asm(" setc INTM")

中断使能和中断标志

分别是IER和IFR。这两个寄存器也是属于CPU内核寄存器。

IER

中断使能寄存器。共16位。

其中,INT1~INT12用于PIE。INT13是定时器1(TIMER1)中断;INT14是定时器2(TIMER2)中断。bit14是DLOGINT;bit15是RTOSINT。

IFR

中断标志寄存器。每个位的所对应的中断与IER相同。

PIE

PIE是外设中断扩展模块(Peripheral Interrupt Expansion)

总共有12组外设中断。

PIE中断通道映射

不同的CPU型号,中断通道映射也不同。具体要查芯片手册。比如280025的PIE通道映射如下:

中断向量表

当发生中断时,CPU从中断向量表(Interrupt Vectors)中取出中断服务函数(ISR)的地址。

中断向量表保存在0x0D00 ~ 0x0EFF地址空间。

CPU中断向量表

PIE中断向量表

中断优先级

数字越小,优先级越高。

  • 首先看CPU级别的中断,INT1比INT14的优先级要高。
  • 再看ePIE级别的中断。比如,在INT1组内,INT1.1比INT1.16的优先级要高。

中断向量表的初始化

可以调用库函数:Interrupt_initVectorTable()。该函数先将默认的中断处理函数Interrupt_defaultHandler()的地址保存到中断向量表中。然后再更改INT_NMI中断和INT_ILLEGAL中断的响应函数。

//*****************************************************************************
//
// Interrupt_initVectorTable
//
//*****************************************************************************
void
Interrupt_initVectorTable(void)
{uint16_t i;EALLOW;//// We skip the first three locations because they are initialized by Boot// ROM with boot variables.//for(i = 3U; i < 224U; i++){HWREG(PIEVECTTABLE_BASE + (2U * i)) =(uint32_t)Interrupt_defaultHandler;}//// NMI and ITRAP get their own handlers.//HWREG((uint32_t)PIEVECTTABLE_BASE + ((INT_NMI >> 16U) * 2U)) =(uint32_t)Interrupt_nmiHandler;HWREG((uint32_t)PIEVECTTABLE_BASE + ((INT_ILLEGAL >> 16U) * 2U)) =(uint32_t)Interrupt_illegalOperationHandler;EDIS;
}

更新中断服务函数

即:注册一个中断处理函数。

//*****************************************************************************
//
//! Registers a function to be called when an interrupt occurs.
//!
//! \param interruptNumber specifies the interrupt in question.
//! \param handler is a pointer to the function to be called.
//!
//! This function is used to specify the handler function to be called when the
//! given interrupt is asserted to the processor.  When the interrupt occurs,
//! if it is enabled (via Interrupt_enable()), the handler function will be
//! called in interrupt context.  Since the handler function can preempt other
//! code, care must be taken to protect memory or peripherals that are accessed
//! by the handler and other non-handler code.
//!
//! The available \e interruptNumber values are supplied in
//! <tt>inc/hw_ints.h</tt>.
//!
//! \note This function assumes that the PIE has been enabled. See
//! Interrupt_initModule().
//!
//! \return None.
//
//*****************************************************************************
static inline void
Interrupt_register(uint32_t interruptNumber, void (*handler)(void))
{uint32_t address;//// Calculate appropriate address for the interrupt number//address = (uint32_t)PIEVECTTABLE_BASE +(((interruptNumber & 0xFFFF0000U) >> 16U) * 2U);//// Copy ISR address into PIE table//EALLOW;HWREG(address) = (uint32_t)handler;EDIS;
}

PIE控制寄存器

包含2个字段:PIE使能位(ENPIE)和PIE向量。

PIE使能

不使能时,从BOOTROM中读取中断向量;

使能后,从PieVectTable中取中断向量。

PIE向量

这个字段是只读的。当发生中断时,这里会保存取中断向量的位置。

由于每个中断向量的地址都是32位的(2个字),因此,中断向量地址的最低位全都是0. 在PIE控制寄存器中就把这一位省掉了(用作PIE使能位)。实际理解的时候,应把这一位补上。或者这样理解:中断向量地址PIEVECT=PIE控制寄存器PIECTRL & 0xFFFE。

实例

当发生ADCD1中断时,PIECTRL = 0x0D4B。

查看手册:

ADCD1中断为INT1.6

中断INT1.6的向量地址为:0x0D4A

中断向量地址0x0D4A + ENPIE = 0x0D4B。与实际情况刚好相符。

小结

中断处理流程

C280x多路复用的中断请求流程

步骤 操作
步骤 1: PIE 组内的任何外设或外部中断生成中断。 如果在外设模块内启用了这些中断,则向 PIE 模块发送中断请求。
步骤 2: PIE 模块识别 PIE 组 x 内的中断 y (INTx.y) 已发出中断且已锁定适当的 PIE 中断标志位:PIEIFRx.y = 1。
步骤 3: 要将中断请求从 PIE 发送到 CPU,以下两个条件必须同时为真:
3a:必须设置了正确的启用位 (PIEIERx.y = 1) 且
3b:该组 的 PIEACKx 位必须已清除。
步骤 4: 如果 3a 和 3b 中的两个条件同时为真,则中断请求被发送到 CPU 且再次设置确认位 (PIEACKx = 1)。
PIEACKx 位将保持设置,直到您清除它以指示可以将来自该组的其它中断从 PIE 发送到 CPU。
步骤 5: 设置 CPU 中断标志位 (CPU IFRx = 1) 以指示 CPU 级别的暂挂中断 x。
步骤 6 和步骤 7: 如果已启用该 CPU 中断(CPU IER 位 x = 1 或 DBGIER 位 x = 1)且全局中断屏蔽已清除 (INTM = 0),则CPU 将为 INTx 提供服务
步骤 8: CPU 识别中断,然后执行自动背景保存、清除 IER 位、设置 INTM 并清除 EALLOW。 TMS320C28x DSP CPU 和指令集参考指南(文献编号 SPRU430)中描述了 CPU 准备服务中断时所执行的所有步骤。
步骤 9: CPU 然后将向 PIE 请求合适的变量。 对于多路复用中断,PIE 模块使用 PIEIERx 和 PIEIFRx 寄存器中的当前值来解码应使用哪个矢量地址。

可屏蔽中断的标准操作流程

流程图如下:

具体流程:

  1. 中断请求发送到CPU
  2. IFR寄存器相关的标志位置位
  3. 相应的中断是否使能(IER使能位是否为1)?全局中断是否使能(INTM为0)?
  4. 中断允许后,送到CPU处理。此时,立即清除IFR标志位。
  5. 清空流水线。
  6. 程序计数器PC指针增加(指向中断返回后的第一条指令),然后临时保存到CPU内部。
  7. 取中断向量。PC 中填充了相应中断向量的地址,然后从该位置获取该向量。
  8. 栈指针(SP)加一。准备保存中断上下文。堆栈指针 (SP) 增加 1 以准备自动上下文保存(步骤 9)。
  9. 执行自动上下文保存。
  10. 清除相应的IER位。在步骤 9 中将 IER 寄存器保存到堆栈中后,CPU 会清除与正在处理的中断对应的 IER 位。 这可以防止重新进入同一中断。 如果您想嵌套发生的中断,请让 ISR 再次设置该 IER 位。
  11. 设置 INTM 和 DBGM。 清除 LOOP、EALLOW 和 IDLESTAT。 所有这些位都在状态寄存器 ST1 中。 通过将 INTM 设置为 1,CPU 可以防止可屏蔽中断干扰 ISR。 如果您希望嵌套中断,请让 ISR 清除 INTM 位。 通过将 DBGM 设置为 1,CPU 可以防止调试事件干扰 ISR 中的时间关键代码。 如果您不想阻止调试事件,请让 ISR 清除 DBGM。 CPU 清除 LOOP、EALLOW 和 IDLESTAT,以便 ISR 在新的上下文中运行。

  12. 用获取的向量加载 PC。 PC 加载了在步骤 7 中获取的中断向量。该向量将程序控制强制给 ISR。

  13. 执行中断服务程序。 这是 CPU 执行您准备处理中断的程序代码的地方。 
    虽然在步骤 10 中自动保存了一些寄存器值,但如果 ISR 使用其他寄存器,您可能需要在 ISR 的开头保存这些寄存器的内容。 然后必须在从 ISR 返回之前恢复这些值。 
    如果希望 ISR 通知外设正在处理中断,可以使用 IACK 指令发送中断确认信号。 IACK 指令接受一个 16 位常量作为操作数。 有关 IACK 指令的详细说明,请参见C28x 汇编语言指令。

  14. 程序继续。 如果中断没有得到 CPU 的批准,则忽略该中断,程序不中断地继续运行。 如果中断被批准,则执行其中断服务程序,程序从中断处继续(在返回地址处)

中断上下文保存的寄存器

许多寄存器值会自动保存到堆栈中。
这些寄存器成对保存; 每对都保存在一个 32 位操作中。 在每个 32 位保存操作结束时,SP 会增加 2。下表显示了寄存器对及其保存顺序。 CPU 期望所有 32 位保存都由内存包装器进行偶数字对齐。 如表中所示,SP 不受此对齐方式的影响。

参考:C28x 中断上下文的保存和恢复

C28x 中断上下文的保存和恢复_booksyhay的专栏-CSDN博客C28x 上下文保存和恢复介绍本文介绍了 C28x CPU 的自动上下文保存/恢复。这也适用于带有 FPU 和 VCU 扩展的设备。其他资源上下文保存和恢复的详细内容在 《C28x TMS320C28x CPU 和指令集参考指南》(TMS320C28x CPU and Instruction Set Reference Guide (Rev. F)-spru430f.pdf)文档中。堆栈基础首先是关于 C28x 堆栈指针的一些事实:C28x 堆栈指针 (SP) 始终指向堆栈中的.https://blog.csdn.net/booksyhay/article/details/120347937

中断嵌套

上文已提到,在保存中断上下文时,会自动禁止全局中断,并清除当前中断的IER位。因此,默认情况下,CPU是不支持中断嵌套的。

如果想要支持中断嵌套,必须在中断服务函数中重新使能IER标志位,并打开全局中断。

具体内容请见参考文档.

TI C28x DSP的中断嵌套_booksyhay的专栏-CSDN博客介绍一个常见的问题是 C28x 中断是否可以嵌套。本文解释了如何通过对中断服务例程 (ISR) 代码进行简单更改来实现中断嵌套。本文假设读者已经熟悉以下内容:C28x PIE 模块:控制寄存器、向量表、PIE 组C28x 中断控制寄存器:特别是 IER、IFR、INTM。有关这些主题的更多信息,请参阅以下内容:TMS320C28x CPU 和指令集参考指南 (spru430) 中记录了 CPU 级别的中断以及 CPU 如何响应中断该研讨会材料包含的C2.https://blog.csdn.net/booksyhay/article/details/120349053

参考文档

TMS320x280x DSP-系统控制和中断参考指南.pdf(中文版)

TMS320C28x CPU and Instruction Set Reference Guide (Rev. F)-spru430f.pdf

C28x Interrupt NestingC28x Interrupt Nestinghttps://software-dl.ti.com/C2000/docs/c28x_interrupt_nesting/html/index.html

TMS320C28x的中断相关推荐

  1. C28x 中断上下文的保存和恢复

    C28x 上下文保存和恢复 介绍 本文介绍了 C28x CPU 的自动上下文保存/恢复.这也适用于带有 FPU 和 VCU 扩展的设备. 其他资源 上下文保存和恢复的详细内容在 <C28x TM ...

  2. TI C28x DSP的中断嵌套

    介绍 一个常见的问题是 C28x 中断是否可以嵌套.本文解释了如何通过对中断服务例程 (ISR) 代码进行简单更改来实现中断嵌套. 本文假设读者已经熟悉以下内容: C28x PIE 模块:控制寄存器. ...

  3. 记一次阿里云RDS与自建数据库同步中断的补救过程

    背景 2018年4月24日上午9点左右,小编在即将托管的服务器上建立数据库,并通过openvpn建立加密隧道,从而实现阿里云RDS和本地自建数据库之间同步.在托管服务器上配置openvpn后,重启op ...

  4. 面试题----中断的一些知识

    中断的一些知识 什么是中断 中断指处理机处理程序运行中出现的紧急事件的整个过程.程序运行过程中,系统外部.系统内部或者现行程序本身若出现紧急事件,处理机立即中止现行程序的运行,自动转入相应的处理程序( ...

  5. [Linux内核]软中断与硬中断

    转自:http://blog.csdn.net/zhangskd/article/details/21992933 本文主要内容:硬中断 / 软中断的原理和实现 内核版本:2.6.37 Author: ...

  6. 【DSP开发】C6000非多核非KeyStone系列DSP中断系统

    C6000系列DSP的中断系统 上一篇介绍了C6455的GPIO系统,最后把GPIO4配置成了中断/事件模式,本文将介绍C6455的中断系统,介绍完基本概念后,给出把GPIO4映射到INT4的代码. ...

  7. cocos2d-x 音效中断问题

    做跑酷重吃金币播音效时,播放其它音效会使得音效所有中断,最后发现时音效上限的问题,2.2.3默认的似乎是5个音效,改动成50后问题解决. 在java中的org.cocos2dx.lib包下有一个Coc ...

  8. io vivado 怎么查看ps_ZYNQ 7020学习笔记之PL侧普通信号中断PS的实验

    1.参考 UG585 网络笔记 2.理论知识 见中断部分 3.实验目的 练习使用PL侧的普通信号来中断PS处理器. 4.实验过程 建立工程,设置并初始化串口中断,在运行程序之后,如果串口接收到N(1- ...

  9. 中断原理在计算机中的应用,计算机组成原理期末考试简答题重点

    6.DMA方式和程序中断方式比较有什么不同? DMA:采用内在和外设直接数据交换的方式,只有当有一段数据传送时才会请求CPU中断,减少了CPU的负担. 程序中断:只适用于简单的少量外设的计算机系统,会 ...

最新文章

  1. 实验7.2 二维数组 7-4 判断上三角矩阵
  2. vueform表单文件上传_峰哥说技术系列-8.Spring Boot文件上传(Form表单和Ajax方式)
  3. python安装jupyterlab_【python】jupyter lab安装与配置
  4. Linux GPIO键盘驱动开发记录_OMAPL138
  5. 人工智能实验评价指标_人工智能实验报告.pdf
  6. IDEA中Maven项目导入依赖包,出现红线波浪线
  7. SourcesTree使用手册3:文件贮藏与删除
  8. WPF案例 (五) 对控件界面使用倒影
  9. jupyter notbook远程连接配置(Ubuntu16.04)
  10. 红蓝对抗之win10 权限提升
  11. layui树形组件渲染
  12. 【可解释机器学习】-线性回归案例【基础版】(python代码)
  13. 怎么样向云服务器上传文件_如何上传文件到阿里云服务器?
  14. 计算机基础文献检索考核,文献检索实验
  15. mac android studio plantuml,Mac 配置 PlantUML
  16. 汇编语言(二)之将十进制数的ASCⅡ码转换为BCD码
  17. vscode怎么对选定的代码格式化?ctrl+k,ctrl+f(格式化代码)
  18. clickhouse SLB 服务搭建
  19. 冲鸭!羊毛薅起来!当当618专享不到4折,Python书籍囤起来!
  20. 【Python】Yahoo股票时间序列预测

热门文章

  1. 蜜蜂认证服务器证书失败,认证ssl证书失败怎么办
  2. srs源码解析2【http-flv播放】
  3. 读麦田反思BBS社区的文章有感
  4. 解决对给定一个时间段补全成整周并且按周分割时间的问题
  5. 2018-2019 ACM-ICPC, Asia East Continent FinalsGym 102056F Interstellar … Fantasy(计算几何)
  6. 浅谈api工厂:前端Paas中台
  7. 浪潮服务器2016销售额,Gartner:2016前三季度,浪潮服务器销售额中国第一
  8. String为什么不可变?(Java源码解析)
  9. Deepin / UOS 中配置 DTK 开发环境
  10. office账户中有多个激活信息,删除其他多余账户信息