IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 嵌入式中断:统计各中断关键信息 (中断执行/挂起/被打断次数,中断优先级异常等) -> 正文阅读

[嵌入式]嵌入式中断:统计各中断关键信息 (中断执行/挂起/被打断次数,中断优先级异常等)


先上图

统计并查看各中断优先级、执行次数,被挂起次数、被打断次数及异常中断情况。

在这里插入图片描述

在这里插入图片描述


实现方法:

核心方法是在中断处理函数(ISR)中,根据中断寄存器的数据,记录下当前中断执行次数、挂起Pending次数、被打断次数等数据,形成log统计并打印/存储。

因为每个中断产生时都会进入ISR,所以随着系统运行一定时间, 就可以统计出来所有中断的真实执行情况。

从代码实现上,就是创建一个统一API,例如interruptLog(),然后在每一个使用的IRQ Handler中调用该函数:
在这里插入图片描述

在这里插入图片描述


实现代码:

数据结构

下面进入代码讲解:

首先数据结构开始,创建一个数组InterruptLog[MAX_IRQNUM],用来记录各中断数据

在这里插入图片描述

InterruptInfo 格式如下, 具体含义参见注释:
在这里插入图片描述

其中主要的是中断执行次数count、被挂起次数pendingCnt、被打断(抢占)次数preemptCnt。

violatedCnt则代表当前中断优先级 大于BasePRI 这种异常情况,(因为我们程序中定义各中断都不允许被打断,所以都不能大于BasePRI)

BASEPRI为优先级屏蔽寄存器,优先级数值大于或等于该寄存器的中断都会被屏蔽,为零时不屏蔽任何中断在这里插入图片描述

初始化

然后我们在初始化中,根据使用的MCU和IRQ,填充InterruptLog数组的一些Name和irqNum。

这里使用多少中断 就填写,其他的都是Unknown。
不同的MCU irqNum也不同,需要根据Datasheet找到正确的num,具体可以查看MCU中断向量表

在这里插入图片描述

获取中断寄存器数据:ICSR

首先,因为我们要知道当前中断控制寄存器的内容,需要获取 ICSR (Interrupt Control and State Register) 中断控制状态寄存器内容

ARM NVIC Controller 寄存器说明(CortexM7):https://developer.arm.com/documentation/dui0646/c/cortex-m7-peripherals/nested-vectored-interrupt-controller?lang=en

因为我们用的MCU基于CortexM, 通过上面链接查询到ARM定义的CortexM7,基地址0xE000ED04就是ICSR数据,
如下图:
在这里插入图片描述
而通过ICSR数据定义,我们可以知道

  • [8:0] Bit (VectActive)代表了当前Active且需要执行的中断Num
  • [20:12] (VectPending)是被Pending的最高优先级中断Num

在这里插入图片描述

如下图VectActive 和VectPending描述
在这里插入图片描述
在这里插入图片描述

这样我们就可以统计出当前中断执行的次数count,和该中断执行时,被Pending的中断,并将相应的Cnt++:

代码如下:
在这里插入图片描述

获取中断寄存器数据:IABR

根据IABR(Interrupt Active Bit Register)获取中断活动状态寄存器数据,用来得到其他中断被抢占的次数等

还是通过ARM NVIC寄存器表格,我们找到地址0xE000E300- 0xE000E31C为中断Active寄存器(也叫中断活动状态寄存器):
在这里插入图片描述
既我们可以通过NVIC_IABR0-NVIC_IABR7 知道,中断处理的当前时刻,有哪些其他中断是Active的
在这里插入图片描述

代码上, preemptCnt 和 violatedCnt 则需要通过CheckActiveRegister() ,检查当前所有Active的中断信息来换算,先将各IABR寄存器数据读出来:
在这里插入图片描述

通过For循环,遍历IABR0 - IABR7寄存器的数据
如果有Actived,则将IrqNum 通过IncreasePreemptCount(IrqNum, CurrentIndex)处理
在这里插入图片描述

换算中断抢占数据

在IncreasePreemptCount中,首先通过__get_BASEPRI()获取当前BasePRI的数值。

既程序设置configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 的数值
(相关知识介绍可参考上篇博文:深入Contex-M中断优先级原理及设置 (万字总结)

之后判断如果IRQ_Index 不是当前中断,既该中断打断了其他中断,则将被打断的IRQ preemptCnt++, (记录中断被打断次数)

同时根据CurrentBasePRI和configMAX_SYSCALL_INTERRUPT_PRIORITY 数值,判断是否是异常情况,如果是,则记录异常的中断优先级和异常次数:
在这里插入图片描述

CheckActiveRegister整体代码如下:

#pragma optimize=none
void CheckActiveRegister(uint32_t CurrentIndex)
{
	uint32_t IABR0 = ( * ( ( volatile uint32_t * ) 0xE000E300 ) );
	uint32_t IABR1 = ( * ( ( volatile uint32_t * ) 0xE000E304 ) );
	uint32_t IABR2 = ( * ( ( volatile uint32_t * ) 0xE000E308 ) );
	uint32_t IABR3 = ( * ( ( volatile uint32_t * ) 0xE000E30C ) );
	uint32_t IABR4 = ( * ( ( volatile uint32_t * ) 0xE000E310 ) );
	uint32_t IABR5 = ( * ( ( volatile uint32_t * ) 0xE000E314 ) );
	uint32_t IABR6 = ( * ( ( volatile uint32_t * ) 0xE000E318 ) );
	uint32_t IABR7 = ( * ( ( volatile uint32_t * ) 0xE000E31C ) );
	
	uint32_t IrqNum = 0;
	uint32_t BitCmp = 0;
	for ( int i = 0 ; i <32 ; i++ )
	{	
		BitCmp = (1<<i);
		
	    if ( IABR0 & BitCmp )
	    {
	    	 IrqNum = i; //for IABR0
	    	 IncreasePreemptCount(IrqNum, CurrentIndex);
	    }

		 if ( IABR1 & BitCmp )
	    {
	    	 IrqNum = i + 32; 
	    	 IncreasePreemptCount(IrqNum, CurrentIndex);
	    }

		 if ( IABR2 & BitCmp )
	    {
	    	 IrqNum = i + 64;
	    	 IncreasePreemptCount(IrqNum, CurrentIndex);
	    }

		 if ( IABR3 & BitCmp )
	    {
	    	 IrqNum = i + 96;
	    	 IncreasePreemptCount(IrqNum, CurrentIndex);
	    }
		 if ( IABR4 & BitCmp )
	    {
	    	 IrqNum = i + 128;
	    	 IncreasePreemptCount(IrqNum, CurrentIndex);
	    }
	}

	

}

打印/存储全部中断数据

在程序运行中,通过命令行或者定时等触发方式,将中断数据信息打印出来供分析:

在这里插入图片描述

在这里插入图片描述


Debug查看运行情况

查看BasePRI :

在这里插入图片描述

我这里BasePRI 最大是0x20, 因为程序定义configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 为2 在这里插入图片描述

查看中断记录情况
在这里插入图片描述


博主热门文章推荐:

一篇读懂系列:

LoRa Mesh系列:

网络安全系列:

嵌入式开发系列:

AI / 机器学习系列:


  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-09-12 13:19:13  更:2021-09-12 13:19:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/30 0:52:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码