• 按键中断控制实验


    1 CPU和外设之间的数据传送方式(即I/O控制方式),通常有以下三种:

    1.0 程序控制方式

    实现简单,以轮询的方式,让CPU不停检查I/O模块的状态,但是容易造成CPU浪费,与I/O相比CPU的速度明显快很多,但是由于I/O没有执行完操作,CPU只能等待I/O执行完成,在这期间CPU不停询问I/O模块的状态,而不去做其他事;在这种状态下I/O模块和CPU是串行状态;
    在这里插入图片描述

    1.1 中断控制方式

    在CPU给I/O发送命令后,I/O模块开始执行相应的操作,而CPU可以去做其他事,当I/O模块执行完会主动发送一个中断信号,这个中断信号会让CPU暂时停下之前做的事,先来处理这个中断事件,处理完中断再继续之前没做完的事情;
    这样CPU不用一直询问I/O的状态,而是让I/O模在准备好后主动通知CPU;这样状态下CPU和I/O模块是并行状态;这样虽然比程序直接控制整体系统的运行性能更高,减少了CPU在轮询时等待的时间,但是这样处理在执行中断的过程仍然会占用大量CPU时间,因为每个字都需要CPU进行传递,而为了解决引入了DMA方式;
    在这里插入图片描述

    1.2 DMA方式(直接存取方式)

    直接存储器存取方式: 主要用于快速设备和主存储器成批数据的场合。在这种应用中, 处理问题的出发点集中到两点: 一是不能丢失快速设备提供出来的数据, 二是进一步减少快速设备入出操作过程中对CPU的打扰。这能够经过把这批数据的传输过程交由一块专用的接口卡( DMA接口) 来控制, 让DMA卡代替CPU控制在快速设备与主存储器之间直接传输数据, 此时每传输一个数据只需一个总线周期即可。多共同使用总线角度看, DMA和CPU成为竞争对手关系。当完成一批数据传输之后, 快速设备还是要向CPU发一次中断请求, 报告本次传输结束的同时, ”请示”下一步的操作要求。
    在这里插入图片描述

    2 中断的定义

    程序运行中,出现了某种紧急事件,CPU必须中止现行程序,转去处理此紧急事件(执行中断服务程序),并且在处理完毕后再返回运行程序的过程。

    3 中断的产生和传输

    中断的产生和传输过程如图:

    在这里插入图片描述

    4 实例1 Exynos 4412 (查找流程)

    4.0整体操作过程简述

    步骤操作
    1确定触发中断的外部设备,然后查看电路图,确定相应引脚
    2查看芯片手册,找出引脚对应的配置寄存器,将控制方式设置为中断控制方式
    3查看芯片手册,查看关于GPIO的Register Description,找到找到中断配置寄存器,将外部中断触发方式设置下降沿触发
    4查看芯片手册,查看关于GPIO的Register Description,找到外部中断屏蔽(掩码)寄存器,将外部中断使能
    5查看芯片手册,查看关于Interrupt Controller的Register Description,找到分配控制寄存器,使能GIC让其能监控外部设备的中断信号,并且将挂起的中断转发给CPU
    6查看芯片手册,查看GIC Interrupt对应的表,得到中断ID,及其中断类型和中断类型号
    7查看芯片手册,查看关于Interrupt Controller的Register Description,找到中断设置使能寄存器,中断类型号选择使用哪个寄存器,同时根据中断ID号配置相应寄存器
    8查看芯片手册,查看关于Interrupt Controller的Register Description,找到处理目标寄存器,根据中断类型号选择使用哪个寄存器,同时根据中断类型号和中断ID配置相应寄存器从而指定处理对应中断的ID号
    9
    10查看芯片手册,关于查看关于Interrupt Controller的Register Description,找到中断确认寄存器,CPU向中断控制器中获取对应的中断ID
    11查看芯片手册,查看关于GPIO的Register Description。找到外部中断挂起寄存器,清除GPX1_2的中断挂起状态
    12查看芯片手册,查看关于Interrupt Controller的Register Description,找到结束中断寄存器,设置中断ID,让CPU通知中断控制器该中断ID代表的中断已经执行完毕

    4.1查看电路图,确定引脚

    在这里插入图片描述

    在这里插入图片描述
    得到信息:K3=>应SIM_DET=>XEINT10=>GPX1_2即引脚GPX1_2,外部中断XEINT_10

    4. 2 设置外部设备对应引脚的配置寄存器(中断控制)

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    因为K3对应的引脚时GPX1_2所以
    将引脚配置寄存器寄存器GPX1CON[2]设置为WAKEUP_INT1[2]
    
    • 1
    • 2

    4.3 设置外部中断配置寄存器

    4.3.0找到关于GPIO的Register Description,对应一个框图,对寄存器有个简单描述

    在这里插入图片描述

    4.3.1 上图可以看到一共有4个外部中断配置寄存器,外部中断配置寄存器和引脚对应关系如下图

    外部中断配置寄存器名称对应引脚
    EXT_INT40_CONGPX0
    EXT_INT41_CONGPX1
    EXT_INT42_CONGPX2
    EXT_INT43_CONGPX3

    **这里的“X”不单单指"X",同时可以指代"A",“B”…

    4.3.2 配置EXT_INT41_CON

    在这里插入图片描述
    在这里插入图片描述
    将EXT_INT41_CON[2]设置为Tiggers Falling edge
    即将GPX1_2外部中断的触发方式设置为下降沿触发

    4.4设置外部中断(掩码)屏蔽寄存器

    4.4.0 找到关于GPIO的Register Description,对应一个框图,对寄存器有个简单描述

    在这里插入图片描述

    4.4.1 上图可以看到一共有4个外部中断屏蔽寄存器,外部中断屏蔽寄存器和引脚对应关系如下图

    外部中断屏蔽寄存器名称对应引脚
    EXT_INT40_MASKGPX0
    EXT_INT41_MASKGPX1
    EXT_INT42_MASKGPX2
    EXT_INT43_MASKGPX3

    **这里的“X”不单单指"X",同时可以指代"A",“B”…

    4.4.2设置EXT_INT40_MASK

    在这里插入图片描述
    将EXT_INT40_MASK[2]设置为Enables Interrput
    即让GPX1_2中断使能;

    4.5设置(中断)分配控制寄存器

    4.5.0 找到Interrupt Controller的Register Description

    在这里插入图片描述

    4.5.1 设置ICDDCR

    在这里插入图片描述
    将GIC使能,让他能监控外部设备的中断信号,并且将挂起的中断转发给CPU

    4.6查找中断ID

    4.6.0 在wps目录搜索框中搜索GIC Interrupt,出现GIC的ID和中断的对应关系图如下

    在这里插入图片描述

    4.6.1 通过之前的电路图得到GPX1_2对应XEINT10

    得到信息为:GPX1_2触发的中断为EINT[10],同时是一个外部中断;通过对应信息对比GIC Interrupt Table
    在这里插入图片描述
    在这里插入图片描述
    得到中断ID号为58,中断类型SPI,中断号类型号为26

    4.7 设置中断设置使能寄存器

    4.7.0 通过Interrupt controller的Register Description找到对应的寄存器

    在这里插入图片描述

    4.7.1 通过中断类型及其类型号选择使用哪个寄存器

    之前得到中断类型号为SPI,同时中断类型号为26 于是我们选用ICDISER1寄存器
    在这里插入图片描述

    4.7.2 通过中断ID号配置ICDISER1寄存器

    在这里插入图片描述
    即将ICDISER1的26位设置为Enables the corresponding interrupt。

    4.8 设置处理目标寄存器

    4.8.0 通过于Interrupt Controller的Register Description,找到处理目标寄存器ICDIPTR14_CPU0

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    跟据上面的图不难理解
    (1)每8位代表一个中断的设置,每个寄存器32位。即每个寄存器可以指定4个中断的设置;
    (2)每8位设置一个中断,设置的是什么?设置的是指定处理该中断的CPU;
    (3)INTID即中断ID
    (4)SPI代表一种中断类型

    如果CDIPTR14_CPU0=0x1<<16;代表将处理GPX1_2产生的中断的CPU为CPU0;

    4.9 设置CPU接口控制寄存器

    4.9.0 查看芯片手册Interrupt controller的Register Description,找到中断确认寄存器

    在这里插入图片描述

    4.9.1 设置CPU接口控制寄存器

    在这里插入图片描述
    使能即可开启CPU和中断控制器之间的开关

    4.10 获取中断确认寄存器中的中断ID

    4.10.0 查看芯片手册Interrupt controller的Register Description,找到中断确认寄存器

    在这里插入图片描述

    4.10.1 设置ICCIAR_CPU0

    在这里插入图片描述
    (1)之前在目标处理寄存器中已经设置了GIC会将中断信号转发给CPU0,所以这里选择ICCIAR_CPU0;
    (2)从该寄存器中可以看出位对于SPI类型的中断,0~9位代表中断ID,而其他位没什么用

    4.11 设置外部中断挂起寄存器

    4.11.0 查看关于GPIO的Register Description,找到外部中断挂起寄存器

    在这里插入图片描述
    这里有4个外部中断挂起寄存器,而选择EXT_INT41_PEND的原因时GPX1_2是GPX1中的一个引脚

    4.11.1 设置EXT_INT41_PEND

    在这里插入图片描述
    将EX_INT41_PEND[2=Interrupt Occurs;代表中断已经发生;而Not Occurs意味着中断还没有发生;
    而表示中断已经发生的话会将该挂起的中断清除;
    因为入中断控制器后,会将相应的挂起并将信号发给CPU,挂起状态需要手动清除,否则会不断将信号发送给CPU

    4.12 设置结束中断寄存器

    4.12.0 查看芯片手册,关于Interrupt Controller的Register Description,找到结束中断寄存器

    在这里插入图片描述
    同样选择ICCEOIR_CPU0,因为之前都是用的CPU0

    4.12.1 设置结束中断寄存器

    在这里插入图片描述
    对于SPI类型的中断设置0~9位即可,设置为中断代表的中断ID;
    作用是让CPU通知中断控制器,中断已经执行完成;

    4.13 关于上述操作的代码(伪代码)

    汇编部分;

    .global _start
    _start:
    .text
    	ldr pc,_rest		   @0x00	Rest
    	ldr pc,_undef_oder	   @0x04	Undefine Instruction
    	ldr pc,_swi_handler    @0x08	Supervisor call(svc)
    	ldr pc,_pref_abort	   @0x0c	Prefetch Abort
    	ldr pc,_data_abort	   @0x10	Data Abort
    	NOP					   @0x14	Not used
    	ldr pc,_irq			   @0x18	IRQ(interrupt)
    	ldr pc,_fiq			   @0x1c	FIQ(fast interrupt)
    _fiq:
    _rest:
     	.word rest		@//定义一个标签main,放在_main:标签下,并且main这个标签占4个字节 ,即_main对应代表4个字节的一个标签
    _undef_oder:
    _swi_handler:
    _pref_abort:
    _data_abort:
    _irq:
    	.word irq
    rest:
    	ldr sp,=stack_base		@//指定栈指针指向栈底部,也就是sp寄存器保存栈地地址,堆栈初始化;这一步不能在user模式下执行,一般在复位后执行
    
    	NOP						@//其他初始化操作
    
    	ldr pc,main				@//跳转到main函数入口
    irq:
    	sub lr,lr,#4		   @//恢复转跳地址
    
    	stmfd sp!,{r0-r12,lr}  @//保护现场,入栈
    
    	ldr	pc,do_IRQ		   @//跳转到中断执行函数,这部分用C语言写在后面
    
    	ldmfd sp!,{r0-r12,pc}^ @//恢复现场,出栈
    main:
    
    	msr cpsr,#0xD0			@//从管理模式切换到User模式
    	NOP						@//空指令
    	NOP
    	
    .data
    buf:						@//切换到数据段
    	.space 200				@//开辟200字节空间
    stack_base:					@//栈底位置
    
    .end  
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    C语言部分

    #include "exynos_4412.h"
    
    #define LED2_ON GPX2.DAT |= (1 << 7)
    #define LED2_OFF GPX2.DAT &= (~(1 << 7))
    #define LED3_ON GPX1.DAT |= (1 << 0)
    #define LED3_OFF GPX1.DAT &= (~(1 << 0))
    
    int flag = 0;
    
    void delay(unsigned int i)
    {
    	while(i--);
    }
    
    void do_IRQ()
    {
    	unsigned int interrupt_id = 0;
    	interrupt_id = CPU0.ICCIAR & 0x3FF;  //获得中断id
    	switch(interrupt_id)  //选择执行相应的外设中断
    	{
    		case 0:
    			break;
    		case 1:
    			break;
    			// ... ...
    		case 58:
    			flag++;
    			printf("%d\n", flag);
    			if(flag%2 == 1)
    				LED2_ON;
    			else
    				LED2_OFF;
    			/* 取消挂起状态,相应位置1 */
    			EXT_INT41_PEND = (1 << 2);   
    
    			/* 通知中断控制器CPU已经执行完中断 */
    			CPU0.ICCEOIR = CPU0.ICCEOIR & (~0x3FF) | 58;
    			break;
    			// ... ...
    		case 159:
    			break;
    		default:
    			break;
    	}
    }
    
    void key3_init()
    {
    	//外设中断配置
    	/* 配置key2引脚为中断模式 */
    	GPX1.CON |= (0xF << 8);
    
    	/* 配置中断触发方式,下降沿触发 */
    	EXT_INT41_CON = EXT_INT41_CON & (~(0x7)) | (0x2 << 8); 
    
    	/* 打开外设中断开关 */
    	EXT_INT41_MASK &= (~(1 << 2));
    
    	//中断处理器配置
    	/* 打开外设与中断处理器之间的通道开关 */
    	ICDDCR |= 1;
    
    	/* 打开对应外设通道中断开关 */
    	ICDISER.ICDISER1 |= (1 << 26);
    
    	/* 选择对应CPU处理中断 CPU0 */
    	ICDIPTR.ICDIPTR14 = ICDIPTR.ICDIPTR14 & (~(0xFF << 16)) | (0x01 << 16);
    
    	/* 打开中断处理器与CPU之间的通道开关 */
    	CPU0.ICCICR |= 1;
    	
    }
    
    int main()
    {
    	/* 配置LED2、LED3的引脚为输出模式 */
    	GPX2.CON |= (0x1 << 28);
    	GPX1.CON |= (0x1 << 0);
    	
    	key3_init();
    
    	while(1)
    	{
    		LED3_ON;
    		delay(1000000);
    		LED3_OFF;
    		delay(1000000);
    	}
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91

    实验现象 LED3不停闪烁,如果按K3,LED2会亮

    4.14 相关寄存器详细描述

    4.14.0 寄存器分类

    在这里插入图片描述

    4.14.1寄存器功能描述

    寄存器名称寄存器名称功能
    GPXn_CON引脚配置寄存器选择引脚功能这里是
    EXT_INT4n_CON外部中断配置寄存器设置外部中断的触发方式
    EXT_INT4n_MASK外部中断屏蔽寄存器打开外部中断开关
    EXT_INT4n_PEND外部中断挂起寄存器取消挂起的中断
    ICDDCR中断分配控制寄存器打开外部中断和中断控制器之间的总通道
    ICDISERn中断设置使能寄存器打开具体的某个外部中断和控制器之间的通道
    ICDIPTR14_CPU0处理目标设置寄存器选择对应CPU处理中断选择由哪个CPU处理该中断
    ICCICR_CPUnCPU接口控制寄存器打开CPU和中断控制器之间的通道
    ICCIAR_CPU0中断确认寄存器获取中断ID
    ICCEOIR_CPU0结束中断寄存器让CPU通知中断控制器中断已经执行完毕
    4.14.2 寄存器关系视图

    在这里插入图片描述

  • 相关阅读:
    串口通信及串口转蓝牙相关知识
    Matlab之数组、包含分配给类别的值函数categorical
    高级数据结构:最小生成树及普里姆算法
    git 时忽略某个文件或文件夹
    CSS复习笔记
    Spring高手之路11——BeanDefinition解密:构建和管理Spring Beans的基石
    b和B的区别?大B与小b的区别(Bps与bps)以及b、B、KB、MB、TB、PB、EB的换算
    【最强最全车牌识别算法】支持13种中文车牌识别的云端API部署(可直接获取源码使用)
    Springboot毕设项目超市综合管理系统xcnk7(java+VUE+Mybatis+Maven+Mysql)
    LED制造企业元亨光电牵手盘古信息,开启数字化转型新篇章
  • 原文地址:https://blog.csdn.net/hpx12345678/article/details/126601069