06.TMS570LC43入门指南——中断操作
文章目录
- 06.TMS570LC43入门指南——中断操作
- 一、简介
- 二、中断(VIM)介绍
- 2.1 VIM架构
- 2.2 CPU 中断处理
- 2.3 VIM中断通道映射
- 2.4 中断请求默认分配
- 三、项目实现
- 3.1 硬件部分
- 3.2 软件部分
- 3.2.1 HALCoGen 配置
- 3.2.2 CCS 配置
- 3.2.3 运行结果
- 四、一些小问题
- 4.1 中断服务函数生成相关
- 4.2 中断映射相关的问题
- 五、写在最后
一、简介
在之前的文章中,想必我们对中断有了初步的了解。那么在本文章中我们将对 TMS570LC43
的中断进行详细认知。
通过这篇文章,你将学到以下内容:
- 中断的认识
- 如何使用中断
使用平台:
- Windows x64
- TMS570LC43开发板
二、中断(VIM)介绍
通过上一篇文章的认知,我们知道:TMS570LC43
具有两个中断管理模块(VIM),但两个 VIM
模块被内存映射到相同的地址空间,因此,从编程的角度上来看,其实际上只有一个 VIM
模块存在。而我们对 VIM
的操作只对 VIM1
起作用,而 VIM2
不会被影响。其这样设计,官方称之为 Dual VIM for safety(双VIM安全架构)。
2.1 VIM架构
首先,我们需要了解的是 VIM
框架,正如我上述提到的,其具有两个 VIM
模块,那么是如何做到这一点的呢?接下来就是它的框图:
前面说到,VIM1
和 VIM2
具有相同的地址空间,而在同一时间访问同一块地址空间是不被允许的。因此,其为VIM2
提供了两个时钟周期的延时操作(2 cyc delay),使得其不会在同一时间访问同一块地址空间。
这里需要注意的是,
VIM2
用户是无法进行访问的,我们之所以说“不会在同一时间访问同一块地址空间”,是为了便于我们理解。VIM2
的访问是由CPU
完成的!!!
当发生中断请求(Interrupt Requests)的时候,其会立即给 VIM1
,而延迟两个时钟周期后给 VIM2
。
VIM1
对中断请求的处理输出会延迟两个时钟周期和 VIM2
一起进入 CCM-R5F
模块进行不断对比,如果发生错误将错误信息传递到 ESM
模块进行错误处理。
如果没有错误则将中断信号传递给 CPU
进行进一步处理。
这里有以下几个问题需要注意:
-
在上图所示中,
Cortex-R5 Processor Group
中包含着两个R5F
核,这是因为该芯片出于安全架构考虑,在核心上也采用了双核对比的形式。- 在技术手册的498页
13.1.2 Block Diagram
小节中写到以下内容:
Figure 13-1 shows the interconnect diagram of the CCM-R5F with the two Cortex-R5F CPUs and the two VIMs. The core bus outputs of the CPUs are compared in the CCM-R5F. To avoid common mode impacts, the signals of the CPUs to be compared are temporally diverse. The output signals of the master CPU are delayed 2 cycles while the input signals of checker CPU are delayed 2 cycles. The two cycle delay strategy is also deployed between the two VIM modules.
[简单翻译]:CCM-R5F与2个Cortex-R5F cpu和2个VIM的互连图如图13-1所示。在CCM-R5F中比较了cpu的核心总线输出。为了避免共模影响,需要比较的cpu的信号在时间上是不同的。主CPU的输出信号延时2个周期,检查CPU的输入信号延时2个周期。在两个VIM模块之间也部署了两周期延迟策略。
这里我放出图13-1供大家参考:
图片及原文来源:ti.com/lit/ug/spnu563a/spnu563a.pdf
那么大家可以了解到,其
CPU
也进行了类似于VIM
的架构形式,这一切据官方所说都是为了安全考虑。 - 在技术手册的498页
-
另一个问题就是
PCR
是什么,这里在技术手册中也能找到相应的答案,这里我也贴出对应原文:The PCR manages the accesses to the peripheral registers and peripheral memories. It provides a global reset for all the peripherals. It also supports the capability to selectively enable or disable the clock for each peripheral individually. The PCR also manages the accesses to the system module registers required to configure the device’s clocks, interrupts, and so on. The system module registers also include status flags for indicating exception conditions – resets, aborts, errors, interrupts. This device has three PCR modules with each capable to access different peripherals as shown in the block diagram. The three PCRs are slaves to the Peripheral Interconnect Subsystem.
[简单翻译]:PCR管理对外围寄存器和外围存储器的访问。它为所有外设提供全局重置。它还支持选择性地为每个外设单独启用或禁用时钟的功能。PCR还管理对配置设备时钟、中断等所需的系统模块寄存器的访问。系统模块寄存器还包括状态标志,用于指示异常条件——重置、中止、错误、中断。该设备有三个PCR模块,每个模块都能够访问不同的外设。
同样的,这里也贴出其结构框图,如下所示:
图片及原文来源:ti.com/lit/ug/spnu563a/spnu563a.pdf
由此我们可以知道,
PCR
对外设进行了统一的管理。
2.2 CPU 中断处理
解决了以上两个问题,言归正传,该 CPU
为中断请求提供了两个向量——快速中断请求(FIQ
)和正常中断请求(IRQ
)。FIQ
的优先级高于 IRQ
, FIQ
中断可能会中断 IRQ
中断。那么如下所示是 VIM
内部中断处理框图:
当中断请求到来以后,首先需要根据通道映射表找到对应的中断通道,然后判断该中断是否使能,如果该中断已经被使能则判断中断类型,即是 FIQ
中断还是 IRQ
中断,判断完成后进入对应的优先级编码器(我这里是这样理解,大家可以理解为一个优先级控制器),获取到对应的 INDEX
寄存器,然后使用它的向量值访问中断向量表以获取对应的 ISR
地址。
通俗来讲,如果一个中断请求是 FIQ
类中断,经过上述一系列步骤后,在中断向量表中得到其对应的 ISR
地址,该地址将被写入 FIQVECREG
寄存器,后续 CPU
将会通过该寄存器对 ISR
函数进行跳转。而如果是 IRQ
类中断,则地址将会被写入 IRQVECREG
寄存器中,同时写入 CPU
的 VIC
端口上。
2.3 VIM中断通道映射
接下来我们将介绍 VIM
的中断通道映射。
VIM
支持 128个中断通道(包括虚中断)。从外设模块到中断通道的 VIM
中断请求安排的框图如下图所示。每个中断通道(CHANx
)都有一个对应的映射寄存器位域(CHANMAPx[6:0]
)。这个映射寄存器决定它映射每个 VIM
中断请求的中断通道。使用此方案,可以将相同的请求映射到多个通道。每个 FIQ
和 IRQ
中编号较低的通道具有较高的优先级,VIM
的可编程性允许软件对其进行控制。
如图所示,CHANMAPx[6:0]
寄存器位域是 CHANCTRL
寄存器的一部分,对于该寄存器,后续文中会进行解释。
根据上图我们需要知道以下两点:
- 其 128个中断通道 中,
CHAN0
和CHAN1
是硬件连接的, 不支持重新映射。 CHAN127
没有专用的中断向量表项。因此,CHAN127
也 不支持重新映射。
那么接下来将对 CHANCTRL
寄存器进行解释,如下图所示是其寄存器的相关描述:
其拥有32个中断控制寄存器(CHANCTRL
)控制着 VIM
的 128 个中断通道。每个寄存器控制着四个中断通道,每个通道的索引是从 0 到 127。表 19-23 展示了所有寄存器的构成部分和每个寄存器的复位值。
这里我们只需简单进行了解即可,结合图片大家就可以明白 CHANMAPx[6:0]
寄存器位域是怎么来的了。
2.4 中断请求默认分配
通过上述对 VIM
的相关叙述,相必大家对中断有了一定的了解。
在该开发板上,对 VIM
有默认的中断请求分配,我这里截取一部分用作示例:
完整表格信息见官方数据手册 P118 6.15.3 Interrupt Request Assignments
网页链接: ti.com/lit/ds/spns195c/spns195c.pdf
如图所示,例如我们需要使用 GIO
中断,可以看到表中有两个 GIO
中断相关的通道,一个是通道 9 的 GIO high level interrupt
中断,另一个是通道 23 的 GIO low level Interrupt
中断。相必从字面意思大家都能猜出来一个是 GIO 高优先级中断,另一个是 GIO低优先级中断。
在此表格中,中断通道越靠前,优先级越高。当然了,有很多中断是我们一般用不到的,具体内容大家可自行阅读数据手册。
三、项目实现
相信在上一篇文章中,大家对 VIM
有了一定的认识(这里就不再附链接了,感兴趣的朋友可以点进 专栏 进行查看),这篇文章将带领大家熟练使用其他中断。
首先,还是需要大家自行建立工程文件,这里不再赘述。
在本项目中,我们将 使用开发板上的两个按键进行中断实验。主要实验内容是,两个按键分别控制着 LED
闪烁速度的加快和减慢,通过这样的方式,使得我们能够更方便观察实验结果。
这里说句题外话,有些类似于
STM32
的外部中断,但又有不同点。在STM32
中可以对每一组GPIOx
进行不同中断通道的映射。但在该芯片中,GPIOA
和GPIOB
不再进行分组映射,其交给统一的GIO
中断进行分配。这里不用过多纠结,在后文中会提到相关这方面的问题。
3.1 硬件部分
在本章中,将会用到两个按键进行中断实验,其原理图如下所示:
如上图所示为两个按键的硬件电路图,可以对其进行简单分析,当按键没有按下的时候,单片机 IO
口将会检测到高电平信号,当按键被按下以后,IO
口将会变为低。后续我们会根据这样的特性进行相关设置。
此外为了能够明显观察到中断产生的影响,这里将使用一个 LED
闪烁对按键按下进行反馈。其中,将会使用到 LED2
,其原理图如下所示:
那么这两个按键以及 LED2
在开发板上的示意图如下所示:
如图中绿色框所示为使用到的两个按键,橙色框所示为使用到的 LED2
。
综上所述,我们需要使用到的 IO
口有 GIOB_4、GIOB_5、GIOB_6
,后续我们将会依次对其进行配置。
3.2 软件部分
3.2.1 HALCoGen 配置
在硬件部分中,明确了我们所需的管脚,接下来将会对其进行一系列的相关配置。
-
在
TMS570LC4357ZWT -> Driver Enable
中使能GIO
驱动 -
在
GIO->Port B
中对Bit 4
和Bit 5
分别进行以下设置: -
在
GIO->Port B
中对Bit 6
分别进行以下设置: -
再回到
TMS570LC4357ZWT -> VIM Channel 0-31
中使能GIO High
和GIO Low
,如下所示: -
配置完上述功能后,即可生成程序。依旧使用快捷键
F5
或依次点击File -> Generate Code
。
3.2.2 CCS 配置
生成文件后,依旧在 CCS
中进行编写逻辑代码操作。还是先找到我们的 HL_sys_main.c
文件。这里我给出我写的示例代码:
/* USER CODE BEGIN (0) */
/* USER CODE END *//* Include Files */#include "HL_sys_common.h"/* USER CODE BEGIN (1) */
#include "HL_gio.h"
/* USER CODE END *//** @fn void main(void)
* @brief Application main function
* @note This function is empty by default.
*
* This function is called after startup.
* The user can use this function to implement the application.
*//* USER CODE BEGIN (2) */
#define CNT_MAX 10000000 // 计数值最大值
#define CNT_MIN 1000000 // 计数值最小值#define LED2_PORT gioPORTB // LED2 GIO接口
#define LED2_BIT 6U // LED2 bituint32_t CNT = 5000000; // 计数值,通过更改此数值更改闪烁频率
/* USER CODE END */int main(void)
{
/* USER CODE BEGIN (3) */int i;_enable_interrupt_(); // 使能中断gioInit(); // GPIO 初始化while (1) {for (i = 0; i < CNT; i++);gioToggleBit(LED2_PORT, LED2_BIT);}
/* USER CODE END */return 0;
}/* USER CODE BEGIN (4) */
/** @brief : GIO通知函数* @param : [port]: gio端口寄存器* [bit]: gio bit位* @return : void* @author : Liu Jiahao* @date : 2024-07-09* @version : v1.1* @copyright : Copyright By Liu Jiahao, All Rights Reserved*/
void gioNotification(gioPORT_t *port, uint32 bit)
{if (port == gioPORTB) {switch (bit) {// S3case 4U:CNT = ((CNT + 1000000) >= CNT_MAX) ? CNT_MAX : CNT + 1000000;break;// S4case 5U:CNT = ((CNT - 1000000) <= CNT_MIN) ? CNT_MIN : CNT - 1000000;break;default: break;}}
}
/* USER CODE END */
在上述代码中,其中 gioNotification
函数不是我们自己命名的,是在 HL_notification.c
文件中,有如下代码:
/* USER CODE BEGIN (11) */
/* USER CODE END */
#pragma WEAK(gioNotification)
void gioNotification(gioPORT_t *port, uint32 bit)
{
/* enter user code between the USER CODE BEGIN and USER CODE END. */
/* USER CODE BEGIN (22) */
/* USER CODE END */
}
这里我是将其复制过去重新进行编写,推荐使用这种方式。
而这个通知函数是经由 gioHighLevelInterrupt
和 gioLowLevelInterrupt
调用的,这两个函数位于 HL_gio.c
文件中,在下一小节将详细阐述这两个函数是怎么来的,这里只做简单介绍。
3.2.3 运行结果
烧录下载后,当我们按下 S3
按键后,可以观察到 LED2
闪烁变慢,当我们按下 S4
按键后,LED2
闪烁将变快。由于我们在代码中对其快慢设置了阈值,一旦达到这个阈值,就无法再次加快或减慢。
四、一些小问题
4.1 中断服务函数生成相关
在 HALCoGen
软件中的 TMS570LC4357ZWT -> VIM RAM
中存在着中断服务函数的相关内容:
这个中断服务函数我们可以自己进行更改,在我们生成代码后,会自动帮我们写好中断服务函数,我们需要做的是在 通知函数 中进行逻辑代码的书写。
而在 CCS
代码中的 HL_sys_vim.c
中有以下内容:
可以看到所有的 ISR
(即中断服务函数) 函数都会在这里进行注册,但前提是需要我们先使能中断。
4.2 中断映射相关的问题
想必对 STM32
中断熟悉的朋友,都知道其每个中断线上对应了最多 9 个 IO
口(以 STM32F1 为例),如下所示:
而我们现在使用的芯片处理逻辑与 STM32
并不相同,其是针对相应外设单独设立的中断线。
而对于中断优先级的设置,文档中提到可以通过
CHANMAPx
进行配置。
五、写在最后
本文介绍了 如何在TMS570LC43上使用中断以及一些问题的阐述。希望能够对大家的学习提供一点帮助。
在后续的文章中,将继续对 TMS570LC43x 进行详细的入门指导,欢迎读者关注!!!
目前暂时没有考虑整合的打算,所以各位读者如果需要看别的教程,可以点进 专栏 进行查找。在后续的更新中,将会逐步加入各个文章的链接,以便大家快速翻阅。另外源码会逐步开源。
欢迎广大读者提出问题以及修改意见,本人看到后会给予回应,欢迎留言,后续会逐步进行开源!!!
另外,由于文章是作者手打的文字,有些地方可能文字会出错,望谅解,也可私信联系我,我对其进行更改。
-
个人CSDN账号:刘梓谦_-CSDN博客
-
Gitee:刘佳豪 (liu-jiahaohappy) - Gitee.com
-
GitHub:Jiahao-Liu29 (github.com)