驱动-异常处理结构、中断处理结构

合集下载

计算机的基本组成和基本工作过程

计算机的基本组成和基本工作过程

02
硬件系统包括中央处理器、存储器、输入输出 设备等,是计算机的物理基础。
04
计算机的基本工作过程是通过中央处理器执行程序 中的指令,对数据进行运算和处理,并将结果输出
到相应的设备上。
02
计算机硬件系统
中央处理器(CPU)
1 2
3
控制器
负责从存储器中取出指令,并解析指令,根据指令的要求, 向计算机的各个部件发出控制信号,协调计算机的工作。
通常包括操作码、地址码等部分,用于标识操作类型和操作对象。
计算机执行程序的过程
取指令 分析指令 执行指令 存储结果 下一条指令
从存储器中取出要执行的指 令。
对取出的指令进行分析,确 定操作类型和操作对象。
根据分析结果,执行相应的 操作。
将执行结果存储到指定位置 。
取下一条要执行的指令,重 复上述过程。
中断与异常处理
中断
计算机在执行程序过程中,由于外部事件或内部原因引起的暂停当前程序执行,转去执行另一段 程序的过程。
异常
计算机在执行程序过程中出现的非正常情况,如算术溢出、非法操作等。
中断与异常处理机制
计算机通过中断与异常处理机制,实现对外部事件和内部异常的响应和处理,保证系统的稳定性 和可靠性。包括中断请求、中断响应、中断服务和中断返回等过程。
存储和处理数据的能力。
计算机的发展经历了机械计算机、 电子管计算机、晶体管计算机、 集成电路计算机和超大规模集成
电路计算机等阶段。
随着技术的不断进步,计算机的 性能不断提高,体积不断缩小, 价格不断降低,应用领域也不断
扩展。
计算机的分类与应用领域
根据计算机的运算速度、字长、存储容量等指标,计算机可分为巨型机、大型机、 小型机、微型机和工作站等类型。

Cortex-M4的中断与异常处理

Cortex-M4的中断与异常处理

Cortex-M4的中断与异常处理11.4.3异常模式11.4.3.1异常状态不活跃.这种异常是不活跃,不等待。

等待.例外的是等待由处理器处理。

来⾃外设或软件的中断请求可以将相应的中断状态更改为挂起。

活跃。

这种异常是被服务处理器,但还没有完成。

异常处理程序可以中断另⼀个异常处理程序的执⾏。

在这种情况下,两个异常都处于活动状态。

活跃和等待。

该异常服务由处理器和存在来⾃相同源的现⾏异常。

11.4.3.2异常类型重置异常。

重置是⼀种复位调⽤上电或热复位。

这种异常模式将复位作为⼀种特殊形式。

当发⽣复位时,处理器运⾏停⽌,有可能在⼀个指令的任何点。

当复位置为⽆效,重新开始执⾏从向量表中复位⼊⼝的地址。

执⾏是特权执⾏的线程模式。

NMI异常。

⾮屏蔽中断(NMI)可以通过⼀个外设或由软件触发发出信号。

这是最⾼优先级的异常,⽐其他复位都⾼。

它是永久启⽤并拥有-2⼀个固定的优先级。

NMI不能被掩蔽或通过任何其它异常阻⽌激活,也不能被通过⽐复位之外的任何异常抢占。

硬故障的发⽣是由于异常处理期间有错误的异常,或者因为异常不能被任何异常机制管理。

硬故障拥有-1固定的优先级,这意味着他们有更⾼的优先级⽐配置优先级的任何异常。

内存管理故障。

内存管理故障的发⽣是由于内存保护相关的故障异常引起的。

该MPU或固定存储器保护限制决定了该故障指令和数据存储器事务。

该故障⽤来取消指令对不执⾏(XN)存储区域的操作,即使MPU被禁⽤。

总线故障。

总线故障的发⽣是因为⼀个指令或数据存储器事务的存储器相关的故障异常。

这可能是由⼀个总线上的存储器系统中检测到错误。

应⽤故障。

应⽤故障是因为涉及到指令执⾏的故障发⽣了异常,包括:未定义指令;⼀个⾮法的未对齐访问;⽆效状态的指令执⾏;异常返回⼀个错误。

SVCall异常。

系统调⽤(SVC)是由SVC指令触发了异常。

在OS环境,应⽤程序可以使⽤SVC指令来访问OS内核函数和器件驱动。

PendSV异常。

PendSV的是系统级的服务中断驱动的请求。

VxWorks开发教程(2024)

VxWorks开发教程(2024)

03
无线通信应用案例分 析
通过分析一个具体的无线通信应用案 例,展示如何在VxWorks系统中实现 无线通信功能,并提供一些优化和改 进的建议。
2024/1/28
35
08
图形界面开发与多媒体应用支 持
Chapter
2024/1/28
36
图形界面开发框架介绍
WindML
2024/1/28
29
设备驱动开发流程
01
需求分析
明确设备的功能需求、性能需求 和接口需求,为后续的设备驱动
开发提供基础。
03
编码实现
依据设计文档,使用C语言等编程 语言实现设备驱动的代码编写。
2024/1/28
02
设计阶段
根据需求分析结果,设计设备驱 动的整体架构、数据结构和函数
接口等。
04
测试与验证
2024/1/28
10
建立工程及源代码管理
创建新工程
在Workbench中,选择“File”->“New”>“VxWorks Project”,然后按照向导创建一个 新的VxWorks工程。
配置工程属性
在工程属性中,你可以设置编译选项、包含路径 、链接库等。确保这些配置与你的目标机和源代 码相匹配。
配的内存。
使用memPartAlloc和memPartFree函数:VxWorks提供了内存分区管理功能,可以 使用memPartAlloc函数从指定的内存分区中分配内存,使用memPartFree函数释放
内存到相应的分区。
2024/1/28
使用taskAlloc和taskFree函数:针对任务相关的内存分配,可以使用taskAlloc和 taskFree函数。这些函数会从任务的控制块中分配和释放内存。

设备驱动程序和中断服务机制

设备驱动程序和中断服务机制

例如,存储设备驱动程序、网 络设备驱动程序、图形设备驱 动程序等。
每种类型的设备驱动程序都有 特定的功能和操作方式,以支 持设备的特性和功能。
02
设备驱动程序与操作系统 的交互
设备驱动程序与操作系统的关系
设备驱动程序是操作系统与硬件设备之间的桥梁,它负责将操作系统的抽象接口 转换为硬件设备的具体操作指令。
中断服务程序的组成
中断服务程序的入口地址、中断处理函数、中断返回函数等。
04
设备驱动程序和中断服务 机制的实现
设备驱动程序的实现方法
01
基于操作系统的设备驱动程序框架
利用操作系统的驱动程序框架,如Linux内核驱动框架,实现设备驱
动程序。这种方法可以利用操作系统的调度和资源管理功能,简化驱
动程序的开发。
设备驱动程序和中断服务机 制
2023-10-29
目录
• 设备驱动程序概述 • 设备驱动程序与操作系统的交互 • 中断服务机制概述 • 设备驱动程序和中断服务机制的
实现 • 案例分析
01
设备驱动程序概序,它负责与特定类型的硬件设 备进行交互和通信。
它充当设备和操作系统之间的接口,使操作系统能够与设备 进行通信和控制。
关键技术
掌握Windows内核编程技术,包括Windows内核结构、中断处 理机制、驱动程序开发等。
基于ARM的设备驱动程序和中断服务机制的综合应用案

ARM处理器特点
设备驱动程序和中断 服务机制的综合应用
关键技术
了解ARM处理器的特点和应用领域, 包括ARM处理器的体系结构、指令集 、性能等。
例如,开发一个基于ARM的设备驱动 程序和中断服务机制的综合应用案例 ,实现ARM处理器的设备管理和中断 处理等功能。

Linux中断处理流程

Linux中断处理流程

Linux中断处理流程1. 中断处理流程 当中断发⽣时,Linux系统会跳转到asm_do_IRQ()函数(所有中断程序的总⼊⼝函数),并且把中断号irq传进来。

根据中断号,找到中断号对应的irq_desc结构(irq_desc结构为内核中中断的描述结构,内核中有⼀个irq_desc结构的数组irq_desc_ptrs[NR_IRQS]),然后调⽤irq_desc中的handle_irq函数,即中断⼊⼝函数。

我们编写中断的驱动,即填充并注册irq_desc结构。

2. 中断处理数据结构:irq_desc Linux内核将所有的中断统⼀编号,使⽤⼀个irq_desc[NR_IRQS]的结构体数组来描述这些中断:每个数组项对应着⼀个中断源(也可能是⼀组中断源),记录中断⼊⼝函数、中断标记,并提供了中断的底层硬件访问函数(中断清除、屏蔽、使能)。

另外通过这个结构体数组项中的action,能够找到⽤户注册的中断处理函数。

struct irq_desc {unsigned int irq;irq_flow_handler_t handle_irq;struct irq_chip *chip;struct msi_desc *msi_desc;void *handler_data;void *chip_data;struct irqaction *action; /* IRQ action list */unsigned int status; /* IRQ status */unsigned int depth; /* nested irq disables */unsigned int wake_depth; /* nested wake enables */unsigned int irq_count; /* For detecting broken IRQs */unsigned long last_unhandled; /* Aging timer for unhandled count */unsigned int irqs_unhandled;spinlock_t lock;const char *name;} ____cacheline_internodealigned_in_smp;(1)handle_irq:中断的⼊⼝函数(2)chip:包含这个中断的清除、屏蔽、使能等底层函数struct irq_chip {const char *name;unsigned int (*startup)(unsigned int irq);void (*shutdown)(unsigned int irq);void (*enable)(unsigned int irq);void (*disable)(unsigned int irq);void (*ack)(unsigned int irq);void (*mask)(unsigned int irq);void (*mask_ack)(unsigned int irq);void (*unmask)(unsigned int irq);void (*eoi)(unsigned int irq);void (*end)(unsigned int irq);void (*set_affinity)(unsigned int irq,const struct cpumask *dest);int (*retrigger)(unsigned int irq);int (*set_type)(unsigned int irq, unsigned int flow_type);int (*set_wake)(unsigned int irq, unsigned int on);/* Currently used only by UML, might disappear one day.*/#ifdef CONFIG_IRQ_RELEASE_METHODvoid (*release)(unsigned int irq, void *dev_id);#endif/** For compatibility, ->typename is copied into ->name.* Will disappear.*/const char *typename;};(3)action:记录⽤户注册的中断处理函数、中断标志等内容struct irqaction {irq_handler_t handler;unsigned long flags;cpumask_t mask;const char *name;void *dev_id;struct irqaction *next;int irq;struct proc_dir_entry *dir;};3. 中断处理流程总结(1)发⽣中断后,CPU执⾏异常向量vector_irq的代码;(2)在vector_irq⾥⾯,最终会调⽤中断处理C程序总⼊⼝函数asm_do_IRQ();(3)asm_do_IRQ()根据中断号调⽤irq_des[NR_IRQS]数组中的对应数组项中的handle_irq();(4)handle_irq()会使⽤chip的成员函数来设置硬件,例如清除中断,禁⽌中断,重新开启中断等;(5)handle_irq逐个调⽤⽤户在action链表中注册的处理函数。

设备驱动程序开发与应用试卷

设备驱动程序开发与应用试卷

设备驱动程序开发与应用试卷(答案见尾页)一、选择题1. 设备驱动程序的主要功能是什么?A. 提供设备访问接口B. 管理硬件资源C. 实现操作系统与硬件设备之间的通信D. 控制设备硬件2. 在嵌入式系统中,设备驱动程序通常是以哪种形式存在的?A. 操作系统内核的一部分B. 系统调用的一部分C. 驱动程序库文件D. 可执行文件3. 下面哪个选项不是设备驱动程序开发过程中需要考虑的因素?A. 兼容性B. 性能优化C. 易用性D. 安全性4. 在设备驱动程序中,错误处理通常是如何进行的?A. 使用try-catch块B. 通过状态码判断C. 异常处理D. 错误代码返回5. 以下哪项不是设备驱动程序加载到内存后的初始化过程的一部分?A. 声明设备号B. 注册设备C. 设置I/O地址D. 初始化硬件6. 在设备驱动程序中,中断服务例程的主要作用是什么?A. 处理硬件异常B. 释放已分配的资源C. 接收来自上层设备的请求D. 控制硬件设备的工作模式7. 在Windows操作系统中,设备驱动程序通常以哪种形式提供?A. DLL(动态链接库)B. EXE(可执行文件)C. OCX(控件对象)D. SYS(系统文件)8. 在Linux操作系统中,设备驱动程序通常保存在哪个目录下?A. /libB. /usr/libC. /usr/local/libD. /opt/lib9. 在设备驱动程序开发中,为了确保兼容性,开发者通常会采取哪些措施?A. 使用标准的APIB. 尽量使用高级语言编写驱动程序C. 避免使用特定的硬件特性D. 所有选项10. 在设备驱动程序的测试过程中,哪种测试方法最适合用于功能验证?A. 单元测试B. 集成测试C. 系统测试D. 性能测试11. 在Windows操作系统中,设备驱动程序通常以什么形式存在?A. DLL文件B. EXE文件C. OCX文件D. SYS文件12. 下面哪个不是设备驱动程序开发需要考虑的问题?A. 兼容性B. 性能优化C. 可维护性D. 硬件逻辑13. 在设备驱动程序中,以下哪项不是必须的功能?A. 加载B. 卸载C. 初始化D. 重定向14. 在设备驱动程序的开发过程中,以下哪个阶段是用来验证驱动程序正确性的?A. 编码阶段B. 测试阶段C. 交叉编译D. 编译阶段15. 在设备驱动程序中,错误处理通常通过哪种机制实现?A. 异常处理B. 中断处理C. 定时器处理D. 事件处理16. 在编写设备驱动程序时,通常会使用哪种编程语言?A. CB. C++C. JavaD. Python17. 在设备驱动程序中,以下哪个是用于描述设备特性的参数?A. I/O端口地址B. 中断号C. I/O地址D. 打印屏幕18. 在设备驱动程序的开发中,以下哪个是用于测试驱动程序正确性的工具?A.调试器B.模拟器C. 反汇编器D. 驱动程序分析工具19. 在设备驱动程序中,哪种类型的代码负责处理来自操作系统的请求?A. 驱动程序核心代码B. 中断服务例程C. 驱动程序初始化代码D. 设备状态监控代码20. 对于Windows操作系统,设备驱动程序通常以什么形式提供?A. DLL文件B. EXE文件C. OCX文件D.SYS文件21. 在设备驱动程序开发中,为什么需要考虑到设备的物理特性?A. 确保设备兼容性B. 提高驱动程序稳定性C. 优化性能D. 减少资源占用22. 下面哪个函数通常用于在设备驱动程序中注册新的设备?A. OpenDevice()B. CloseDevice()C. AttachDevice()D. RegisterDevice()23. 在设备驱动程序中,中断服务例程的主要任务是什么?A. 处理来自操作系统的请求B. 监控设备状态C. 管理硬件资源D. 执行设备驱动程序的核心逻辑24. 在编写设备驱动程序时,为什么需要关注设备的数据传输速率?A. 确保数据完整性和准确性B. 提高驱动程序性能C. 优化内存使用D. 降低设备功耗25. 在Windows操作系统中,设备驱动程序的加载过程通常涉及哪些步骤?A. 加载驱动程序文件 -> 验证文件完整性 -> 初始化设备 -> 注册设备B. 初始化设备 -> 加载驱动程序文件 -> 验证文件完整性 -> 注册设备C. 验证文件完整性 -> 加载驱动程序文件 -> 初始化设备 -> 注册设备D. 加载驱动程序文件 -> 初始化设备 -> 验证文件完整性 -> 注册设备26. 在设备驱动程序中,如何处理设备故障?A. 使用错误码和异常处理机制B. 调用设备供应商提供的故障恢复程序C. 启动系统备用方案D. 重启设备27. 在设备驱动程序开发中,为什么需要考虑设备的安全性?A. 防止未授权访问B. 提高驱动程序稳定性C. 优化性能D. 降低设备功耗28. 在Windows操作系统中,设备驱动程序通常是以什么形式提供的?A. 文档B. 源代码C. 可执行文件D. 压缩包29. 下面关于设备驱动程序的描述,哪项是错误的?A. 设备驱动程序是操作系统的一部分B. 设备驱动程序需要与硬件紧密集成C. 设备驱动程序可以为多个设备提供服务D. 设备驱动程序可以通过网络进行更新30. 在设备驱动程序的开发过程中,下面哪个步骤不是必需的?A. 编写设备驱动程序的源代码B. 配置设备的硬件参数C. 测试驱动程序的兼容性D. 优化驱动程序的性能31. 在设备驱动程序中,通常会包含哪些类型的数据结构?A. 节点表B. 驱动程序状态字C. I/O请求包(IRP)D. 中断描述符表32. 在设备驱动程序的注册过程中,操作系统会执行哪些操作?A. 分配内存B. 初始化设备硬件C. 创建设备对象D. 注册设备驱动程序33. 在设备驱动程序的卸载过程中,操作系统会执行哪些操作?A. 释放设备硬件资源B. 断开设备连接C. 销毁设备对象D. 删除驱动程序模块34. 设备驱动程序与应用程序之间的交互通常是通过什么方式实现的?A. 竞争条件B. 中断服务例程C. 信号量D. 队列35. 在设备驱动程序的开发中,为什么需要考虑多线程安全?A. 避免数据竞争B. 提高系统性能C. 降低开发难度D. 增加驱动程序的复杂性36. 在嵌入式系统中,设备驱动程序通常位于什么层次?A. 应用层B. 系统层C. 物理层D. 数据链路层37. 驱动程序开发过程中,编译器需要识别哪些特定的关键字来确保代码的正确性?A. includeB. importC. staticD. void38. 下面哪个选项不是设备驱动程序加载到内存后的初始化过程的一部分?A. 设备号分配B. 设备特性读取C. 驱动程序同步D. 中断向量表设置39. 在Windows操作系统中,设备驱动程序通常以何种形式提供?A. DLL(动态链接库)B. SO(共享对象)C. DLL(动态链接库)或 SO(共享对象)D. EXE(可执行文件)40. 在Linux操作系统中,设备驱动程序的模块化设计主要通过哪种机制实现?A. 硬件抽象层(HAL)B. 虚拟文件系统(VFS)C. 内核模块(KModule)D. 设备树编译器(DTB)41. 以下哪个设备驱动程序开发工具不是用于编写和测试驱动程序的?A. 驱动程序模拟器B. 交叉编译器C. 设备树生成工具D. 性能分析工具42. 在设备驱动程序的调试过程中,哪种方法最适合排查硬件相关的问题?A. 使用打印语句B. 使用断点C. 使用逻辑分析仪D. 使用网络诊断工具43. 在设备驱动程序的更新和维护中,最重要的步骤是什么?A. 版本控制B. 安全更新C. 兼容性测试D. 回滚计划二、问答题1. 什么是设备驱动程序?它在操作系统中的作用是什么?2. 设备驱动程序通常是如何加载到内存中的?3. 设备驱动程序中的主要组成部分有哪些?4. 什么是I/O请求包(IRP)?它在设备驱动程序中如何使用?5. 设备驱动程序如何处理中断?6. 什么是同步和异步操作?它们在设备驱动程序中的应用有何不同?7. 设备驱动程序如何管理内存资源?8. 设备驱动程序如何进行错误处理和调试?参考答案选择题:1. C2. C3. D4. C5. D6. A7. A8. A9. A 10. A11. A 12. D 13. D 14. B 15. A 16. A 17. B 18. A 19. B 20. A21. A 22. D 23. B 24. A 25. A 26. A 27. A 28. C 29. A 30. D31. ABC 32. ACD 33. ABCD 34. B 35. A 36. B 37. A 38. C 39. C 40. C41. D 42. C 43. D问答题:1. 什么是设备驱动程序?它在操作系统中的作用是什么?设备驱动程序是一种特殊的软件,它允许操作系统与硬件设备进行通信。

08.山洋驱动器故障代码

08.山洋驱动器故障代码

8章8.保守8.1トラブルシューティング···································エラー! ブックマークが定義されていません。

8.2ワーニング,报警一覧·····································エラー! ブックマークが定義されていません。

1)ワーニング一覧·······································エラー! ブックマークが定義されていません。

2)报警一覧·············································エラー! ブックマークが定義されていません。

Linux 的异常处理

Linux 的异常处理
Linux 由此进入正常的运行状态,之后一段程序(用户空间的或者内核空间的)将一直 在 CPU 上执行,直到程序执行结束或发生任何 Exception。发生 Exception 时,CPU 自动进入 内核态(ARM 的 SVC 态),根据发生的 Exception 类型的不同,linux 内核将可能处理外设 IO、 切换进程、管理内存分配、提供系统服务等一系列操作。所以 Linux 的动态运行可以认为完 全是由 Exception 事件驱动的。
.endm
name:要生成的 vector_xxx 中的 xxx,比如 vector_stub irq, IRQ_MODE, 4,生成 vector_irq, 即 Exception 向量中 IRQ 对应的跳转地址。
mode:设定 CPU 模式位(CPSR 的 M[4:0]),从而可以操作对应模式的特殊寄存器。
图中显示,所有 7 种类型的 Exception 的跳转地址按顺序从基地址开始排列,被称
为 Exception 向 量 。 ARMv6 支 持 两 种 基 地 址 ( Normal:0x00000000,High vector:0xFFFF0000),具体使用哪个基地址,由 ARMv6 内部的 Control Register 的 bit13(V bit)设定。Linux 使用 High vector,需要注意的是,Exception 向量地址也是 虚拟地址(如果使用了虚拟地址机制)。
bl trace_hardirqs_off
#endif
get_thread_info tsk
#ifdef CONFIG_PREEMPT
ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
add r7, r8, #1
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一,Linux 异常处理体系结构框架:1,按键按下时。

强制的跳到异常向量处执行(中断是异常的一种)。

2,CPU 发生中断。

3,“入口函数”是一条跳转指令。

跳到某个函数:(作用)将2440 作为单片机使用时:裸机程序时②,执行中断处理函数。

③,恢复被中断的现场。

①,保存被中断处的现场(各种寄存器的值)。

LINUX 中处理中断的过程:1,写程序时先设置异常入口:发生“中断”时,就跳到0x18地址处,跳转到“HandleIRQ”是执行下面的指令:中断处理完后,要返回去继续执行之前被中断的那个程序。

保存寄存器就是保存中断前那个程序的所用到的寄存器。

然后是处理中断,最后是恢复。

linux 中:异常向量在哪里:LINUX 异常处理结构、中断处理结构:2012年2月23日11:03①,LINUX的异常向量在哪里:ARM架构的CPU的异常向量基址可以是 0x0000 0000,也可以是 0xffff0000,LINUX内核使用后者,只需要在某个寄存器里设置下,就可以将异常基址定位到这里来。

这个地址并不代表实际的内存,是虚拟地址。

当建立了虚拟地址与物理地址间的映射后,得将那些异常向量,即相当于把那些跳转指令(如:HandleSWI 等)复制拷贝到这个 0xffff0000这个地址处去。

(“那些跳转指令”是指head.S中那些跳转)。

这个过程是在trap_init这个函数里做。

trap_init函数将异常向量复制到0xffff0000处,部分代码如下:如上:将 __vectors_start, __vectors_end -__vectors_start 这段代码拷贝到 vectors来。

将 __vectors_start, __vectors_end -__vectors_start 这段代码拷贝到 vectors来。

vectors是“CONFIG_VECTORS_BASE” 是个配置项(内核的配置选项)。

在linux源码顶层目录下:vim .config, 搜索“CONFIG_VECTORS_BASE”。

我的内核配置文件这个地址是“0xffff0002”和书上的不同。

__vectors_start 在 entry-armv.S 中定义,也是些跳转指令。

可见和单片中的一样(都是跳转指令)。

A:假设发生了 vector_und (undefined)异常未定义指令后,会跳转到 vector_und 加一个偏移地址stubs_offset(b vector_und + stubs_offset)。

这个 vector_und 地址标号源代码里没有,它是一个宏:将这个宏展开:将这个宏展开:===========================================vector_stub und, UND_MODE这个宏展开替换下面的语句:.macro vector_stub, name, mode, correction=0(.macro 开始定义宏)把宏展开,上面的name就是"und"。

则下来替换后,“vector_\name”就成了“vector_und”vector_\name:(变成vector_und: )定义了一个vector_und标号。

做的事情如下。

.if \correction因为上面“correction=0”,即这里是:.if 0.所以if...endif 间的代码忽略。

sub lr, lr, #\correction.endif(这三句因为"correction=0,忽略不要")@@ Save r0, lr_<exception> (parent PC) and spsr_<exception>先保存。

@ (parent CPSR)@stmia sp, {r0, lr} @ save r0, lrmrs lr, spsrstr lr, [sp, #8] @ save spsr@@ Prepare for SVC32 mode. IRQs remain disabled.转换到管理模式。

@mrs r0, cpsreor r0, r0, #(\mode ^ SVC_MODE)msr spsr_cxsf, r0@@ the branch table must immediately follow this code这里是下一级跳转@and lr, lr, #0x0fmov r0, spldr lr, [pc, lr, lsl #2]movs pc, lr @ branch to handler in SVC mode.endm(.endm 结束宏定义).endm (.endm 结束宏定义)这里是下一级的跳转,跳转表如下:①,name是und.if \correctionsub lr, lr, #\correction.endif②,correction=0默认是0,则:则这三句不用管。

后面 __und_usr等标号中,去保存那些寄存器,作处理。

处理完后,再恢复那些寄存器,即恢复那些被中断的程序。

③,下一级跳转表:B:下面是一个实例:在 entry -armv.S 源码中的第1069行:B:下面是一个实例:在 entry -armv.S 源码中的第1069行:发生中断便跳转到这里。

这个地址标号“vector_irq”在代码中也没有。

也是一个宏来定义的:vector_stub irq, IRQ_MODE, 4 这里是一个宏,将这个宏和宏参数替换到下面的宏定义中去:“name ”为“irq ”.“correction ”为“4”。

.align 5.macro vector_stub, name, mode, correction=0.if \correction 宏替换后:.if 4vector_\name: 宏替换后:vector_irq:也是和上面的“vector_stub und, UND_MODE”一样,是用下面的宏展开:.if \correction宏替换后:.if 4sub lr, lr, #\correction宏替换后:sub lr, lr, #4.endif这里宏替换后就变成:vector_irq:.if 4sub lr, lr, #4.endif"sub lr, lr, #4"这是计算返回地址,比较裸机程序:“F:\embedded\嵌入式LINUX开发完全手册\嵌入式LINUX开发完全手册光盘\视频\ask100_example\int”下的:head.S@@ Save r0, lr_<exception> (parent PC) and spsr_<exception>转换到“管理模式”。

@ (parent CPSR)@stmia sp, {r0, lr}@ save r0, lrmrs lr, spsrstr lr, [sp, #8]@ save spsr@@ Prepare for SVC32 mode. IRQs remain disabled.@mrs r0, cpsreor r0, r0, #(\mode ^ SVC_MODE)msr spsr_cxsf, r0@@ the branch table must immediately follow this code这里是下一级跳转@and lr, lr, #0x0fmov r0, spldr lr, [pc, lr, lsl #2]movs pc, lr@ branch to handler in SVC mode.endm下一级跳转的跳转表:__irq_usr : 应该是用户态发生中断时,就跳转到“__irq_usr ”标号中去。

__irq_svc:在管理模式里发生中断时,就跳转到“__irq_svc”这个标号中去。

上面的跳转表,从名字上猜测:查看标号“__irq_usr ”:这个宏 usr_entry 应该是保存那些寄存器。

搜索“usr_entry”的宏定义如下:在这个栈(sp )中将寄存器保存进去。

接着再看:__irq_svc标号的实现,会有个:"irq_handler"也是一个宏:"irq_handler"也是一个宏:从上面的宏定义可以看到,最终会调用一个 asm_do_IRQ .就是处理函数,比较复杂的代码就用C语言实现。

总结:linux 内核中处理异常的流程,最后调用到“asm_do_IRQ()”①,异常向量:首先“trap_init”构造了“异常向量”。

②,异常向量是什么?异常向量就是将这段代码“__vectors_start”拷贝到0xffff0000“vectors”处:最后是调用:异常向量就在这里。

这“异常向量”也是某些跳转。

如:“b vector_irq + stubs_offset”因为向量已重新定位了,所以得加上“stubs_offset”偏移地址。

“vector_irq”是链接地址,要加上一个偏移地址才能正确的跳转。

③,vector_irq 做的事:它是由一个宏定义的。

做的事和单片机程序一样。

a,计算返回地址:sub lr, lr, #4b, 保存寄存器值:c,调用处理函数(如:__irq_usr若用户态发生中断,就跳转到这个标号处。

)d, 处理函数又去调用“宏”:如"__irq_usr"标号处理是“usb_entry”宏,此宏先保存环境变量诸多寄存器。

然后就调用宏“irq_handler”。

此宏的定义会调用函数“asm_do_IRQ”。

如: __irq_usr:usr_entry(这个宏也是保存些寄存器)irq_handler(从__irq_usr后调用这个函数,它也是一个宏。

)asm_do_IRQ(irq_hander这个宏是做asm_do_IRQ函数) e:恢复(调用完asm_do_IRQ函数后)==================================================二,LINUX的中断框架:内核中断框架了解“asm_do_IRQ”,理解中断处理的过程。

A,单片机下的中断处理:1,分辨是哪个中断。

2,调用处理函数(哪个中断就调用哪个处理函数)。

3,清中断。

1,上面是先读寄存器“INTOFFSET”,看是哪个中断。

2,中间是中断处理。

3,最后是清中断。

内核的也差不多。

以上单片机的3个过程,都是在 asm_do_IRQ 中实现的。

最终在“handle_irq”中实现的。

struct irq_desc *desc = irq_desc + irq;1,首先是根据传进来的 IRQ 中断号(参1),irq_desc 是一个数组。

相关文档
最新文档