正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-15-GPIO中断控制实验

news2024/11/17 3:23:44

前言:

本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM(MX6U)裸机篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。

引用:

正点原子IMX6U仓库 (GuangzhouXingyi) - Gitee.com

《【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.5.2.pdf》

正点原子资料下载中心 — 正点原子资料下载中心 1.0.0 文档

正文:

本文是 “正点原子[第二期]Linux之ARM(MX6U)裸机篇--第15.1, 15.2,15.3 讲” 的读书笔记。第15讲主要是介绍I.MX6U处理器GPIO中断控制实验。本节将参考正点原子的视频教程第15讲和配套的正点原子开发指南文档进行学习。

0. 概述

中断系统是一个处理器的重要的组成部分,中断系统极大的提高了CPU的执行效率,在学习STM32的时候就经常用到中断。本章就是通过与STM32的对比来学习一下 Cortex-A7(I.MX6U)中断系统和Cortex-M(STM32)中断系统的异同,同时,本章会将I.MX6U的一个IO作为输入中断,借此来讲解如何对I.MX6U的中断系统进行编程。

1. Conrtex-A7 中断系统详解

1.1 STM32中断系统回顾

STM32的中断系统主要有以下几个关键点:

  1. 中断向量表。
  2. NVIC(内嵌向量中断控制器,Nested Vector Interrupt Controller)。
  3. 中断使能。
  4. 中断服务函数。
1. 中断向量表

中断向量表是一个表,这个表里面存放的是中断向量。中断服务程序的入口地址或存放中断服务程序的首地址称为中断向量表,因此中断向量表是一些列中断服务程序入口地址组成的表。这些中断服务程序(函数)在中断向量表中的位置是由半导体厂商定好的,当某个中断被触发以后就会自动跳转到中断向量表中对应的中断服务程序(函数)入口地址处。中断向量表在整个程序的组前面,比如 STM32F103 的中断向量表如下所示:

上图示例代码就是 STM32F103 的中断向量表,中断向量表都是链接到代码的最前面,比如一般ARM处理器都是从 0x00000000 开始执行指令的,那么中断向量表就是从 0x0000_0000 开始存放的。示例代码中的第一行 “__initial_sp” 就是第一条中断向量,存放的是栈顶指针,接下来第2行复位中断函数 Reset_Handler 的入口地址,依次类推,知道第27行的最后一个中断服务函数 DMA2_Channel4_5_IRQHandler 的入口地址,这样 STM32F103的中断向量表就建好了。

我们说ARM处理器都是从地址 0x0000_0000 开始运行的,但是我们学习STM32的时候代码是下载到 0x80_0000 开始的存储区中。因此中断向量表是存放到 0x80_0000 地址处的,而不是 0x0000_0000 ,这样不就出错了么?为了解决这个问题,Cortex-M 架构引入了一个新的概念-中断向量表偏移,通过中断向量表偏移就可以将中断向量表存放到任意地址处,中断向量表偏移配置在函数 SystemInit 中完成,通过向 SCB_VTOR 寄存器写入新的中断向量表首地址即可,代码如下所示:

第8行和第10行就是设置中断向量表偏移,第八行是将中断向量表设置到 RAM 中,第10行是将中断向量表设置到 ROM 中,也就是地址 0x80_0000 处。第10行用到了 FLAS_BASSE 和 VEC_TAB_OFFSET ,这两个都是宏,定义如下所示:

#define FLASH_BASE                ((uint32_t)0x08000000)

#define VECT_TAB_OFFSET      0x0 

第10行的代码就是:SCB->VTOR = 0x0800_0000,中断向量表偏移设置完成。通过上面的讲解我们了解了STM32中断有关的概念:中断向量表和中断偏移,那么这跟  I.MX6U 有什么关系呢?因为I.MX6U 使用的是 Cortex-A7 内核也有中断向量表和中断向量表偏移,而且其含义和 STM32 是一模一样的!指示用到的寄存器不同而已,概念完全相同。

2. NVIC(内嵌向量中断控制器)

中断系统得有个管理结构,对于 STM32 这种 Cortex-M 内核的单片机来说这个管理机构叫做 NVIC,全程叫做 Nested Vector Interrupt Controller。关于 NVIC 本教程不做详细的讲解,既然 Corex-M 内核有个中断系统的管理结构--NVIC,那么 I.MX6U 所使用的 Corex-A7 内核是不是也应该有一个中断管理机构?答案是肯定的,不过 Cortex-A7 内核的中断管理机构不叫做 NVIC ,而是叫做 GIC,全程是 Geneal Interrupt Controller ,后面我们会详细的讲解 Cortex-A7 内核的 GIC。

3. 中断使能

要使用某个外设的中断,肯定要先使能这个外设的中断,以 STM32F103 的 PE2 这个IO为例,假如我们要使用 PE2 的输入中断肯定要使用下面的代码来使能对应的中断:

NVIC_InitStructure.NVIC_IRQChannel = EXIT2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2

NVIC_InitStructure.NVIC_IRQChannelSubPriority = x002;             //子优先级2

NVIC_InitStructure.NVIC_IRQChannelCmd = ENALBE;                 //使能外部中断通道

NVIC_Init(&NVIC_InitStructure);

上述代码就是使能 PE2 对应的 EXIT2 中断,同理,如果要使用 I.MX6U 的某个中断的话也需要使能其对应的中断。

4. 中断服务函数

我们使用中断的目的就是为了使用中断服务函数,当中断发生以后中断服务函数就会被调用,我们要处理的工作就可以放到中断服务函数中去完成。同样以 STM32F103 的 PE2 为例,其中断服务函数如下图所示:

/* 外部中断2 服务程序 */

void EXIT2_IRQHandler(void)

{

        /* 中断处理代码 */

}

当PE2引脚的中断触发以后就会调用其对应的中断服务函数 EXIT2_IRQHandler,我么可以在函数 EXIT2_IRQHandler 中提那家中断处理代码。同理,I.MX6U 也有中断服务函数,当某个外设发生中断以后就会调用其对应的中断服务函数。

通过对 STM32 中断系统的回顾,我们知道了 Cortex-M 内核的中断处理过程,那么 Cortex-A7 内核的中断处理过程是否是一样的,有什么异同呢?接下来我们就带着这样的疑问来学习 Cortex-A7 内核的中断处理系统。

1.2 Cortex-A7 中断系统简介

 跟STM32一样,Cortex-A7 内核也有中断向量表,中断向量表也是在代码的最前面。Cortex-A7 内核有8个异常中断,这8个异常中断的中断向量表如下表所示:

向量地址中断类型中断模式
0x00复位中断(Reset)特权模式(SVC)
0x04未定义指令中断(Undefined Instruction)未定义指令终止模式(Undef)
0x08软中断(Software Interrupt, SWI)特权模式(SVC)
0x0C指令预取中止中断(Prefetch Abort)中止模式
0x10数据访问中止 (Data Abort)中止模式
0x14未使用(Note Used)未使用
0x18IRQ中断(IRQ Interrupt)外部中断模式(IRQ)
0x1CFIRQ中断(FIRQ Interrupt)快速中断模式(FIRQ)

中断向量表里都是中断服务函数的入口地址,因此一款新芯片有什么中断都是可以从中断向量表看出来的。从上表中可以看出,Cortex-A7 内核一共有 8 个中断,而且还有一个中断向量未使用,实际只有7个中断。和“示例代码 17.1.1.1”中的 STM32F103 中断向量表比起来少了很多!难道一个能跑 Linux 的芯片只有这7个中断?明显是不可能的!那类似 STM32 中的 EXIT9-5_IRQHandler, TIM2_IRQHandler 这样的中断向量在哪里?I2C, SPI,定时器等等的中断怎么处理呢?

这个就是 Cortex-A 和 Cortex-M 在中断向量表这一块的区别,对于 Cortex-M 内核来说,中断向量表列举出了一款芯片所有的中断向量,包括芯片外设的所有中断。对于 Cortex-A 内核来说并没有这么做,在上表中有个 IRQ 中断,Cortex-A 内核CPU的所有外部中断都属于这个 IRQ 中断,当任意一个外设中断发生的时候都会触发 IRQ 中断。在IRQ中断服务函数中就可以读取指定的寄存器来判断发生的具体事什么中断,进而根据具体的中断做出相应的处理。这些外部中断和IRQ的关系如下图所示:

在图 17.1.2.1 中,,左侧的 Softwre0_IRQn~PMU_IRQ2_IRQ 这些都是 I.MX6U 的中断,它们都属于 IRQ 中断。当图 17.1.2.1左侧这些中断中任意一个发生的时候 IRQ 中断都会被触发,所以我们需要在 IRQ 中断服务函数中判断究竟是左侧的哪个中断发生了,然后在坐车具体的处理。

在表 17.1.2.1 中一共有7个中断,简单介绍一下这7个中断:

  1. 复位中断(Reset),CPU复位以后就会进入复位中断,我们可以在复位中断服务函数里面做一些初始化工作,比如初始化SP指针,DDR等等。
  2. 未定义指令中断(Undefined Instruction),如果指令不能识别的话就会产生此中断。
  3. 软中断(Software Interrupt,SWI),由SWI指令引起的中断,Linux系统调用会用 SWI 指令来一起软中断,通过软中断来陷入到内核空间。
  4. 指令预取中止中断(Prefetch Abort),预取指令出错的时候会产生此中断。
  5. 数据访问中止中断(Data Abort),访问数据出错的时候会产生此中断
  6. IRQ中断(IRQ Interrupt),外部中断,前面已经说过了,芯片内部的外设中断都会引起此中断的发生。
  7. FIQ中断(FIQ Interrupt),快速中断,如果需要快速处理中断的话就可以使用此中断。

在上面的7个中断中,我们常用的就是复位中断和IRQ中断,所以我们需要编写这两个中断的中断服务函数,稍后我们会讲解如何编写对应的中断服务函数。首先我们要将表 17.1.2.1 的内容来创建中断向量表,中断向量表处于程序最开始的地方,比如我们前面例程 Start.S 的文件最前面,中断向量表如下:

                                         示例代码 17.1.1.1 Cortex-A7 向量表模板

.global _start

_start:

        ldr pc, =Reset_Handler                /*复位中断*/

        ldr pc, =Undefined_Handler        /*未定义指令中断*/

        ldr pc, =SVC_Handler                 /*SVC(SuperVisor)中断*/

        ldr pc, =PrefAbort_Handler         /*预取中止中断*/

        ldr pr, =DataAbort_Handler         /*数据中止中断*/

        ldr pc, =NotUsed_Hanlder          /*未使用中断*/

        ldr pc, =IRQ_Handler                 /*IRQ中断*/

        ldr pc, =FIQ_Handler                  /*FIQ(快速中断)*/

/* 复位中断 */

Reset_Handler:

        /*复位中断具体处理过程*/

/*未定义中断*/

Undefined_Handler:

        ldr r0, =Undefined_Handler

        bx r0

/*SVC中断*/

SVC_Handler:

        ldr r0, =SVC_Handler
        bx r0

/*预取中止中断*/

PrefAbort_Handler:

        ldr r0, =PerfAbort_Handler

        bx r0

/*数据中止中断*/

DataAbort_Handler:

        ldr r0, =DataAbort_Handler

        bx r0


/*未使用的中断*/

NotUsed_Handler:

        ldr r0, =NotUserd_Handler

        bx r0


/* IRQ中断!重点!!!!*/

IRQ_Handler:

        /*IRQ中断具体处理过程*/

/*FIQ中断*/
FIQ_Handler:

        ldr r0, =FIQ_Handler

        bx r0

第4到11行时中断向量表,当指定的中断发生以后就会调用对应的中断服务函数,比如复位中断发生以后会执行第4行的代码,也就是调用 Reset_Handler,函数 Reset_Handler 就是复位中断的中断服务函数,其它中断同理。

第14到50行就是对应的中断服务函数,中断服务函数都是用汇编编写的,我们实际需要编写的只有复位中断服务函数 Reset_Handler 和 IRQ中断服务函数  IRQ_Handler,其它的中断本教程没有用到,所以是死循环。在编写复位(Reset)中断服务函数和IRQ中断服务函数之前我们还需要了解一些其他的知识,否则的话就没法编写。

1.3 GIC 控制器简介

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

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

相关文章

Failed to build flash-attn:ERROR: Could not build wheels for flash-attn

安装 FlashAttention 的时候遇到报错: Failed to build flash-attn ERROR: Could not build wheels for flash-attn, which is required to install pyproject.toml-based projects可能是安装的版本与环境存在冲突吧,我的环境是: python 3.1…

域控安全 ----> Ntds.dit文件抓取

大家还记得内网渗透的初衷吗??? 找到域馆,拿下域控!! 拿下了域控就是拿下了整个域!! 但是大家知道拿下域环境之后应该怎么操作吗(灵魂拷问)??? …

【WEEK11】 【DAY3】员工管理系统第四部分【中文版】

2024.5.8 Wednesday 接上文【WEEK11】 【DAY2】员工管理系统第三部分【中文版】 目录 10.5.展示员工列表10.5.1.修改dashboard.html10.5.2.新建EmployeeController.java10.5.3.新建emp文件夹,将list.html移动至该文件夹10.5.4.重启并检查10.5.5.提取公共页面&#x…

钉钉开放平台创建企业内部H5微应用或者小程序

前言: 在当今企业数字化转型的浪潮中,创建企业内部H5微应用或小程序已成为提升工作效率和促进内部沟通的重要举措。发话不多说本文将介绍如何利用钉钉平台快速创建这些应用,让企业内部的工作更加便捷高效。 步骤 1.在浏览器打开链接…

旧物回收小程序开发:打造绿色生活,共筑美好未来

随着环保意识的逐渐增强,我们越来越意识到旧物回收的重要性。为了响应这一趋势,我们精心研发了一款旧物回收小程序,旨在通过科技的力量,让每个人都能够轻松参与到旧物回收的行动中来,共同为地球环保贡献一份力量。 一…

【C++】Visual Studio 2019 给 C++ 文件添加头部注释说明

使用代码片段管理器&#xff0c;添加快捷插入代码文件说明 1. 效果 2. header.snippet 新建 header.snippet 文件&#xff0c;存放到某个文件夹 内容&#xff0c;自行更新 快捷名称&#xff0c;修改 Header 里面内容注释内容&#xff0c;修改 Code 里面内容 <?xml ver…

利用函数视图实现精细化管控:DolphinDB 非标权限管理指南

1. 前言 DolphinDB 提供的用户权限管理功能管控的最小粒度是表级别&#xff0c;无法设置小于表粒度的数据访问权限管控&#xff0c;如限制用户仅能访问表中某些行或某些列的数据。为了满足客户更精细的权限管控需求&#xff0c;我们编写了本教程。 2. 概述 函数视图是封装了…

vue打包报错:CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

前言&#xff1a; vue项目&#xff0c;打包报错&#xff1a;CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 报错现象&#xff1a; 报错原因&#xff1a; 这个错误是由Node.js在尝试分配内存时因为系统的可用内存不足而发生的。"JavaScript heap…

远动屏柜作用

远动屏柜作用 远动屏柜是电力系统中的重要设备&#xff0c;主要用于实现远方监控和遥控功能&#xff0c;确保电力系统的安全运行。它主要由远动装置、通讯管理机、交换机、调制解调器、GPS对时装置、数字通道防雷器、模拟通道防雷器、插线板、空气开关、屏柜及附件等组成。 远…

英语学习笔记7——Are you a teacher?

Are you a teacher? 你是教师吗&#xff1f; 词汇 Vocabulary name /neɪm/ n. 名字&#xff0c;名声 英文名字构成&#xff1a; 名 字 姓      given name family name  也叫做&#xff1a;first name last name      例&#xff1a;Yanyan Gao 例句&#xff1…

【prometheus】Pushgateway安装和使用

目录 一、Pushgateway概述 1.1 Pushgateway简介 1.2 Pushgateway优点 1.3 pushgateway缺点 二、测试环境 三、安装测试 3.1 pushgateway安装 3.2 prometheus添加pushgateway 3.3 推送指定的数据格式到pushgateway 1.添加单条数据 2.添加复杂数据 3.SDk-prometheus-…

CISCN 2023 初赛

Web unzip 文件上传页面 upload.php页面源码显示了出来 <?php error_reporting(0); highlight_file(__FILE__);$finfo finfo_open(FILEINFO_MIME_TYPE); if (finfo_file($finfo, $_FILES["file"]["tmp_name"]) application/zip){exec(cd /tmp &am…

致力于双碳减排服务——安科瑞推出碳电表

1. 概述 全球首个“碳关税”——欧盟碳边境调节机制于2023年10月启动试运行。自此&#xff0c;首批纳入欧盟碳边境调节机制的6个行业相关产品在出口至欧盟国家时需提供碳排放数据&#xff0c;这会倒逼国内制造业企业加快开展产品碳足迹核查的步伐。以钢铁行业为例&#xff0c;…

进口家装水管十大品牌哪家好,弗锐德为您推荐进口家装水管领先十大品牌

水管作为家装隐蔽工程之一&#xff0c;选对一款优质的水管是至关重要的&#xff0c;毕竟好的水管能够保证家庭后续几十年的用水安全和健康。今天&#xff0c;小编就和大家说说进口家装水管十大品牌哪家好&#xff1f; 目前国内进口家装水管具有知名度和消费者认可的品牌有&…

Linux网络编程(三)IO复用三 epoll系统调用

三、epoll系统调用 epoll是Linux特有的I/O复用函数。它在实现和使用上与select、poll有很大差异。 epoll使用一组函数来完成任务&#xff0c;而不是单个函数epoll把用户关心的文件描述符上的事件放在内核里的一个事件表中&#xff0c;从而无须像select和poll那样每次调用都要…

JS笔试手撕题

数据劫持 Vue2的Object.defineProperty() Vue2的响应式是通过Object.defineProperty()拦截数据&#xff0c;将数据转换成getter/setter的形式&#xff0c;在访问数据的时候调用getter函数&#xff0c;在修改数据的时候调用setter函数。然后利用发布-订阅模式&#xff0c;在数…

计算机专业,求你别再玩了,我都替你们着急

明确学习目标和方向&#xff1a;确定自己希望在计算机领域的哪个方向深入发展&#xff0c;如前端开发、后端开发、数据库管理、人工智能等。根据目标方向&#xff0c;制定详细的学习计划&#xff0c;确保所学知识与未来职业方向相匹配。 【PDF学习资料文末获取】 扎实基础知识…

effective python学习笔记_推导与生成

用推导取代map和filter 序列推导可取代map和filter&#xff0c;优越性有&#xff1a;1可读性强2不需要map的函数 控制推导逻辑的子表达式不要超过2个 即推导的for层数最多建议两层&#xff0c;多了可读性会下降&#xff0c;反而用for循环会清晰 一层for内可连接多个if&…

为什么要使用大模型

随着OpenAI引领的超大模型风潮&#xff0c;大模型的发展日新月异&#xff0c;如同雨后春笋般茁壮成长。在现今的科技舞台上&#xff0c;每周&#xff0c;甚至每一天&#xff0c;我们都能见证到一个全新模型的开源&#xff0c;这些模型的创新性和实用性不断超越前作&#xff0c;…

激光雷达技术:科技之眼,照亮前行

在科技与人文关怀的交响乐章中&#xff0c;一项名为“蝙蝠避障”使用了激光雷达技术原理及应用的创新成果&#xff0c;正悄然改变着视障朋友们的生活方式&#xff0c;为他们的日常出行铺设了一条充满希望的光明之路。今天&#xff0c;让我们一起深入探讨这项技术如何成为盲人出…