c6x Linux 内核中断分析

 

 

1. 内核中断介绍

 

1.1 中断简介

 

所有支持Linux的平台都采用了中断(interrupt)的概念,以便(因种种原因)引入周期性的中断。需要区分两种类型的中断。

 

1. 硬件中断(hardware interrupt):由系统自身和与之连接的外设自动产生。它们用于支持更高效地实现设备驱动程序,也用于引起处理器自身对异常或错误的关注,这些是需要与内核代码进行交互的。 

 

2. 软中断(SoftIRQ):用于有效实现内核中的延期操作。 

 

在Linux中用于处理中断和系统调用相关部分的代码中,汇编和C代码交织在一起, 以解决C语言无法独立处理的一些特殊问题。在中断处理中涉及到许多C代码和底层的硬件交互代码。

 

在C6678处理器上,硬件中断的最大数目通常是15,这个值可不怎么大,还有考虑到有些中断编号已经永久性地分配给了标准的系统组件(键盘、定时器等),因而限制了可用于其他外部设备的中断编号数目。

 

外设可共享同一个中断号这个现象称为中断共享(interrupt sharing)。但必须硬件和内核同时支持才能使用共享中断,因为必须要识别出中断来源于哪个设备。

 

1.2 中断处理

 

在CPU得知发生中断后,它将进一步的处理委托给一个软件例程,该例程可能会修复故障、提供专门的处理或将外部事件通知用户进程。

 

由于每个中断和异常都有唯一的编号,内核使用一个数组,数组项是指向处理程序函数的指针。相关的中断号根据数组项在数组中的位置判断。

 

▲图1.1 中断处理过程

 

因为需要C语言代码和汇编语言代码之间的交互,所以必须特别小心,才能正确设计在汇编语言层次和C语言层次上的数据交换。对应的代码位于arch/arch/kernel/entry.S中,彻底利用了各个处理器的具体特性。

 

1.3 中断处理程序

 

中断处理程序可能会遇到困难,特别是在处理程序执行期间,发生了其他中断。尽管可以通过在处理程序执行期间禁用中断来防止,但这会引起其他问题,如遗漏重要的中断。屏蔽(Masking, 这个术语用于表示选择性地禁用一个或多个中断)因而只能短时间使用。

 

中断处理数据结构:IRQ相关信息管理的关键点是一个全局数组,每个数组项对应一个IRQ编号。因为数组位置和中断号是相同的,很容易定位与特定的IRQ相关的数组项:IRQ 0在位置0IRQ 15在位置15,等等。IRQ最终映射到哪个处理器中断。irq_desc存储了中断相关信息。

 

action链表提供了一个操作链,需要在中断发生时执行。由中断通知的设备驱动程序,可以将与之相关的处理程序函数放置在此处。有一个专门的数据结构用于表示这些操作。

 

chip硬件处理和芯片相关操作被封装在chip中。为此引入了一个专门的数据结构用来处理硬件相关操作。

 

1.4 处理程序函数的表示

 

irqaction结构定义如下,每个处理程序函数都对应该结构的一个实例:

 

<code>

 

该结构中最重要的成员是处理程序函数本身,即handler成员,这是一个函数指针,位于结构的起始处。在设备请求一个系统中断,而中断控制器通过引发中断将该请求转发到处理器的时候,内核将调用该处理程序函数。

 

在考虑如何注册处理程序函数时,我们再仔细考察其参数的语义。但请注意,处理程序的类型为irq_handler_t,与电流处理程序的类型irq_flow_handler_t显然是不同的。

 

name和dev_id唯一地标识一个中断处理程序。name是一个短字符串,用于标识设备(例如, 「e100」、「ncr53c8xx」等等),而dev_id是一个指针,指向在所有内核数据结构中唯一标识了该设备的数据结构实例,例如网卡的net_device实例。如果几个设备共享一个IRQ,那么IRQ编号自身不能标识该设备,此时,在删除处理程序函数时,将需要上述信息。

 

▲图1.2 中断结构体关系描述图

 

2. 中断向量表以及中断子程序

 

2.1 中断子程序实现

 

在汇编源文件arch/c6x/kernel/vectors.S 中定义了中断子程序,使用宏IRQVEC可以实现不同的中断子程序:

arch/c6x/kernel/vectors.S第 30 行实现了中断处理宏定义IRQVEC

 

▲图2.1 中断处理向量宏定义

 

根据如上IRQVEC宏定义结合实际代码使用情况可以生成不同的中断子程序。

 

▲图2.2 生成中断向量

 

例如:

79行 IRQVEC INT4,_int4_handler可生成如下中断子程序。

 

<code>

 

当中断发生时,进入到汇编代码中的中断子程序,首先保存寄存器A0的值保存在栈中,然后拷贝相应的中断子程序入口地址到A0寄存器中,然后跳转到相应的中断子程序,中断子程序执行完毕后从栈中恢复寄存器A0的值。

 

在中断子程序_int4_handler中执行如下指令

 

<code>

 

SAVE_ALL_INT此行作用为保存所有的寄存器到栈中,然后调用MASK_SYSCALL关闭系统调用,使用CALL_INT 4先将中断号存入A4,然后调用kernel 中的 c6x_do_IRQ 中断处理函数。调用结束后将返回结果存入寄存器B3。

 

▲图2.3 CALL_INT宏定义

 

在arch/c6x/kernel/entry.S 中定义了诸多 _DEFINE_MACRO 汇编宏定义。

1. 220行 _DEFINE_MACRO(SAVE_ALL_INT)  中断保存所有寄存器。

2. 325行 _DEFINE_MACRO(MASK_SYSCALL) 屏蔽系统调用。

 

2.1 c6x_do_IRQ处理流程

 

c6x_do_IRQ函数的是实现在arch/c6x/kernel/irq.c文件中

64行 asmlinkage void c6x_do_IRQ(unsigned int prio, struct pt_regs *regs)

 

▲图2.4 c6x_do_IRQ中断函数

 

获取kernel中断号:

 

c6x_do_IRQ 获取中断号prio,将中断号通过hw_to_kernel_irq将硬件中断号转换为kernel中断号,转换后传入kernel的中断处理函数generic_handle_irq。

 

在代码中hw_to_kernel_irq如何将硬件中断号转换为kernel中断号?

 

在中断初始化的过程中构建prio_to_irq的中断对应数组,将硬件中断号和kernel中断号产生对应关系。当使用hw_to_kernel_irq的时候,hw_to_kernel_irq从中断对应数组 prio_to_irq[(hw)] 中取出kernel中断号。

 

常规内核处理函数generic_handle_irq 处理中断流程:

 

在include/linux/irq.h 头文件中实现了generic_handle_irq和

generic_handle_irq_desc两个内联函数。

 

generic_handle_irq 使用kernel中断号irq获取irq中断号相对应的irq_to_desc,既irq_desc结构体数组,然后调用generic_handle_irq_desc将中断号,和获取的irq_desc结构体数组传给generic_handle_irq_desc。

 

▲图2.5 generic_handle_irq_desc

 

在generic_handle_irq_desc函数中检测irq对应的irq_desc结构体中是否有中断处理函数handle_irq。

 

如果有handle_irq就执行此中断的中断处理函数,这里执行的是handle_level_irq函数,在irq_desc->handle_irq中我们无法直接看到其对应的中断处理函数,可以通过init_IRQ 初始化函数中获得此处填入的中断处理函数名称。

 

▲图2.6 init_IRQ 中断初始化函数

 

handle_level_irq函数中执行的流程如下:

1. lock中断。

2. 检测中断是否为处理中状态:IRQ_INPROGRESS。

3. 如果中断为正在处理的状态直接跳到结尾处unlock中断并推出函数。

4. 如果中断为触发状态,将中断设置为正在处理的状态,并且调用handle_IRQ_event执行相应中断处理函数。

 

如果没有handle_irq就说明此中断为共享中断(IRQ线)执行__do_IRQ(irq)。

__do_IRQ 处理所有普通设备的中断,每一个设备都有其特定的中断处理函数,存在放action列表中。

 

在kernel/irq/handler.c文件中实现了__do_IRQ函数。__do_IRQ函数主要遍历irq_desc 结构体中的action链表处理中断。

 

449行 unsigned int __do_IRQ(unsigned int irq)

接下来使用共享中断处理函数:handle_IRQ_event 来遍历irq_desc 里的 action共享中断链表。

 

handle_IRQ_event函数:

 

在kernel/irq/handle.c 368行irqreturn_t handle_IRQ_event( unsigned int irq,struct irqaction *action)Handle_IRQ_event 用来处理irq实际的action链表。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/566756.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

系统建模、分析、仿真和验证软件工具ModelCodoer

在安全关键领域&#xff0c;基于模型的软件工程已逐渐进入了我国的装备研制过程中。使用SimuLink或者SCADE等嵌入式软件建模工具进行可视化建模&#xff0c;然后生成高可靠的二进制代码逐渐成为了安全关键领域的主流软件开发方式。由迪捷软件自主研发的系统建模、分析、仿真和验…

如何构建裸机hello world目标程序并在SkyEye全数字实时仿真平台上运行及调试?

SkyEye全数字实时仿真平台&#xff0c;简称SkyEye&#xff0c;是一款支持 ARM、TI DSP、PowerPC、X86、SPARC、龙芯、飞腾等多种处理器体系架构的指令级仿真平台。 SkyEye可以部署在桌面计算机上&#xff0c;开发人员可以基于SkyEye提供的已有模型库的组件&#xff08;如处理器…

「基于模型的系统工程」的发展历程

节选自《「基于模型的系统工程」的发展历程》&#xff0c;因篇幅有限&#xff0c;完整报告文末领取。 当下&#xff0c;人们热衷于讨论基于计算机的建模、模型、数据库和敏捷设计方法。然而&#xff0c;很少有人会耐心地审视和理解大量的技术创新&#xff0c;这些技术创新和发…

Unity使用Rider作为默认编辑器

01.Edit -> Preferences 02.Externel Tools -> Open by file extension 如果界面选项有Rider直接选择&#xff0c;如果没有选择Browse) 03.选择rider64.exe 04.成功关联

同步数据流语言代码生成工具的研究进展

摘要 同步数据流语言(如Lustre,Signal)近年来在航空、高铁、核电等安全关键领域得到了广泛应用&#xff0c;因此与这类语言相关的开发工具本身的安全性问题受到高度关注.同步数据流语言到串行命令式语言的代码生成工具是此类工具的典型代表(如Scade)。构造代码生成工具的途径可…

一种全数字实时仿真的安全关键领域解决方案

随着科技的发展&#xff0c;系统工程的设计体量逐渐庞大起来&#xff0c;尤其是对于轨道交通、航空航天、核电站等安全关键领域中&#xff0c;如何在复杂度逐年变大的同时保证其安全性和可靠性&#xff0c;是近年来各大公司需要研究的课题。最近比较火热的基于模型的系统工程&a…

应用在核电站DCS系统的代码自动生成工具ModelCoder

对标航空航天领域&#xff0c;核电新型号作为典型复杂系统在未来的发展趋势和任务变得十分明确&#xff0c;即正规化、标准化地应用MBSE从概念设计、初步设计、持续贯穿至详细设计、施工、调试、运维、退役的全生命周期各阶段&#xff0c;开发出符合核工业本身的需求&#xff0…

怎样在电脑上上传图片_电脑上回收站怎样恢复

把桌面上的文件删除&#xff0c;如果想再次找回&#xff0c;只要在电脑的回收站就可以原封不动的把文件找回来。但不小心删除了回收站的信息&#xff0c;怎么办呢?大家遇以这样的情况&#xff0c;也不要太着急&#xff0c;电脑上回收站怎样恢复呢&#xff1f;小编带分享一下解…

基于模型的系统工程设计软件ModelCoder在航空发动机控制设计中的应用

基于模型的系统工程&#xff08;MBSE&#xff09;使用数字模型的方式表达描述工程系统的完整生命周期中的需求和设计等活动&#xff0c;以无歧义、模块化等优点快速覆盖了如航空航天、船舶、卫星等相关安全关键领域。在系统工程的初期&#xff0c;系统产生的信息都以文档得形式…

基于模型的系统工程MBSE软件工具(ModelCoder)

我们一直致力于提供给航空航天制造商一套全数字的MBSE建模与仿真优化解决方案——基于模型的系统工程MBSE软件工具&#xff08;ModelCoder&#xff09;。我们的仿真验证技术可用于开发高复杂度和高保真度的模型&#xff0c;对飞机发动机&#xff0c;飞机的飞控进行预测性的虚拟…

面向航空航天工业领域的基于模型的仿真验证工具SkyEye

我们一直致力于提供给航空航天制造商一套全数字的优化方案——面向航空航天工业领域的基于模型的仿真验证工具SkyEye。我们的仿真验证技术可用于开发高复杂度和高保真度的模型&#xff0c;对发动机&#xff0c;飞机的飞控进行预测性的虚拟验证和测试。我们能够准确地进行全数字…

高性能高可靠性的全数字嵌入式仿真测试软件SkyEye

随着科技的发展&#xff0c;系统工程的设计体量逐渐庞大起来&#xff0c;尤其是对于轨道交通、航空航天、核电站等安全关键领域中&#xff0c;如何在复杂度逐年变大的同时保证其安全性和可靠性&#xff0c;是近年来各大公司需要研究的课题。最近比较火热的基于模型的系统工程&a…

二元一次函数最值问题_初二上学期,一次函数方案设计最值问题,两类题目解题思路不一样...

方案设计问题在一元一次方程实际问题中有所接触&#xff0c;在一次函数实际应用题中也有。一次函数中的方案设计问题&#xff0c;常与一次函数的性质、不等式(组)、方程组等知识点相结合&#xff0c;这类题目一旦掌握解题方法&#xff0c;难度不是很大。本篇文章主要介绍一次函…

高性能全数字嵌入式仿真测试软件SkyEye支持多达70余种核心

全数字仿真平台作为工业领域不可缺少的重要软件之一&#xff0c;除了可以与MATLAB或者Simulink集成外&#xff0c;还支持哪些优秀的功能&#xff1f;在了解新一代全数字仿真平台SkyEye之前&#xff0c;先来学习一下什么是全数字仿真平台。 什么是全数字仿真平台 全数字仿真平…

SystemC 代码添加和测试方法

1.启动流程 在 code/utils/ 下添加 new_systemc 相关代码&#xff0c;启动流程如下&#xff1a; 2.调用关系 3.地址映射 假设有两个 systemc 设备&#xff1a;device1 和 device2&#xff0c;device1 的内存地址映射区域为 0x20000x2fff&#xff0c;device2 的内存映射区域为 …

支持多达70余种嵌入式核心的嵌入式仿真软件SkyEye

SkyEye 介绍 SkyEye&#xff0c;中文全称天目全数字实时仿真软件&#xff0c;应用软件仿真技术&#xff0c;逼真地模拟出被测软件的物理环境。用图形化方式构建虚拟目标系统&#xff0c;有效降低了硬件工程师和软件工程师之间的沟通成本&#xff0c;软件工程师可以不依赖硬件工…

嵌入式仿真平台SkyEye的覆盖率分析

随着嵌入式系统也越来越复杂&#xff0c;功能迭代越来越多&#xff0c;代码中就可能就会存在部分无用代码&#xff0c;或者在执行过程中无法测试覆盖的分支&#xff0c;这可能就会给软件带来很大的漏洞&#xff0c;严重降低软件的可靠性。因此&#xff0c;需要一个能够动态分析…

access重复数据累计_小程序·云开发之数据库自动备份丨云开发101

小程序云开发之数据库自动备份数据是无价的&#xff0c;我们通常会把重要的业务数据存放在数据库中&#xff0c;并需要对数据库做定时的自动备份工作&#xff0c;防止数据异常丢失&#xff0c;造成无法挽回的损失。小程序云开发提供了方便的云数据库供我们直接使用&#xff0c;…

嵌入式系统实时仿真解决方案SkyEye

SkyEye介绍 SkyEye&#xff0c;中文全称天目全数字实时仿真软件&#xff0c;应用软件仿真技术&#xff0c;逼真地模拟出被测软件的物理环境。用图形化方式构建虚拟目标系统&#xff0c;有效降低了硬件工程师和软件工程师之间的沟通成本&#xff0c;软件工程师可以不依赖硬件工…

read函数头文件 window_of_property_read_string 剖析

前言今天在一个群里面看到的一个朋友提交&#xff0c;说of_property_read_string 这个函数有两个定义&#xff0c;到底是用了哪个呢&#xff1f;所以这篇文章就说下这个函数。函数引用的头文件引用的头文件位置在kernel-4.4includelinuxof.h其中一个是extern int of_property_r…