当前位置:网站首页>I.MX6U-ALPHA开发板(GPIO中断实验)
I.MX6U-ALPHA开发板(GPIO中断实验)
2022-07-26 04:08:00 【*﹏ℳ๓无情*】
一、回顾STM32中断系统
1、STM32中断向量表
ARM芯片从0X00000000开始运行,执行指令。在程序开始的地方存放着中断向量表。中断向量表主要功能是描述中断对应的中断服务函数。
对于STM32来说代码最开始的地址存放堆栈栈顶指针。
2、中断向量偏移
一般ARM从0X000000000地址开始运行,对于STM32我们设置连接首地址为0X8000000。
如果代码一定要从0X8000000开始运行,那么需要告诉一下soc内核。也就是设置中断向量偏移。设置SCB的VTOR寄存器为新的中断向量表起始地址即可。
3、NVIC中断控制器。
NVIC就是中断管理机构。使能和关闭指定的中断、设置中断优先级。
4、中断服务函数的编写
中断服务函数就是中断要做的事情。
二、Cortex-A7中断系统
1、Cortex-A中断向量表
Cortex-A中断向量表有8个中断,其中重点关注IRQ。Cortex-A的中断向量表需要用户自己去定义。
2、中断向量偏移
我们的裸机历程都是从0X87800000开始的,因此要设置中断向量偏移。
3、GIC中断控制器。
同NVIC一样,GIC用于管理Cortex-A的中断。GIC提供了开关中断,设置中断优先级。
4、IMX6U中断号
为了区分不同的中断,引入了中断号。ID0ID15是给SGI,ID16ID31是给PPI。剩下的ID32~1019给SPI,也就是按键中断、串口中断。。。。
6ULL支持128个中断。
4、中断服务函数的编写
一个是IRQ中断服务函数的编写,另一个就是在IRQ中断服务函数里面去查找并运行的具体的外设中断服务函数,
三、GIC中断控制器
四、中断实验编写
1、编写按键中断例程。
KEY0使用UART1_CTS这个IO。编写UART1_CTS的中断代码。
2、修改start.S
添加中断向量表,编写复位中断服务函数和IRQ中断服务函数。
编写复位中断服务函数,内容如下:
①、关闭I,D Cache和MMU。
②、设置处理器9中工作模式下对应的SP指针。要使用中断那么必须设置IRQ模式下的SP指针。索性直接设置所有模式下的SP指针。
③、清除bss段。
④、跳到C函数,也就是main函数
3、CP15协处理器
MRC: 将 CP15 协处理器中的寄存器数据读到 ARM 寄存器中。
MRC 就是读 CP15 寄存器, MCR 就是写 CP15 寄存器, MCR 指令格式如下:
MCR{cond} p15, , , , ,
MRC p15, 0, r0, c0,c0,0
现在要关闭I,D ache和MMU,打开Cortex-A7参考手册到105页,找到SCTLR寄存器。也就是系统控制寄存器,此寄存器bit0用于打开和关闭MMU,bit1控制对齐,bit2控制D Cache的打开和关闭。Bit11用于控制分支预测。Bit12用于控制I Cache。
中断向量偏移设置
将新的中断向量表首地址写入到CP15协处理器的VBAR寄存器。
MCR{cond} p15, , , , ,
MRC p15,0,r0,c12,c0,0 //
MCR p15,0,r0,c12,c0,0
IRQ中断服务函数
mrc p15, 4, r1, c15, c0, 0 读取CP15的CBAR寄存器。CBAR寄存器保存了GIC控制器的寄存器组首地址。GIC寄存器组偏移0x10000x1fff为GIC的分发器。0x20000x3fff为CPU接口端。意味我们可以访问GIC控制器了!
代码中,R1寄存器吧保存着GIC控制器的CPU接口端基地址。读取CPU接口段的GICC_IAR寄存器的值保存到R0寄存器里面。可以从GICC_IAR的bit9~0读取中断ID,我们读取中断ID的目的就是为了得到对应的中断处理函数。
system_irqhandler就是具体的中断处理函数,此函数有一个参数,为GICC_IAR寄存器的值。
system_irqhandler处理完具体的中断以后,需要将对应的中断ID值写入到GICC_EOIR寄存器里面。
.global _start /* 全局标号 */
/*
* 描述: _start函数,首先是中断向量表的创建
* 参考文档:ARM Cortex-A(armV7)编程手册V4.0.pdf P42,3 ARM Processor Modes and Registers(ARM处理器模型和寄存器)
* ARM Cortex-A(armV7)编程手册V4.0.pdf P165 11.1.1 Exception priorities(异常)
*/
_start:
ldr pc, =Reset_Handler /* 复位中断 */
ldr pc, =Undefined_Handler /* 未定义中断 */
ldr pc, =SVC_Handler /* SVC(Supervisor)中断 */
ldr pc, =PrefAbort_Handler /* 预取终止中断 */
ldr pc, =DataAbort_Handler /* 数据终止中断 */
ldr pc, =NotUsed_Handler /* 未使用中断 */
ldr pc, =IRQ_Handler /* IRQ中断 */
ldr pc, =FIQ_Handler /* FIQ(快速中断)未定义中断 */
/* 复位中断 */
Reset_Handler:
cpsid i /* 关闭全局中断 */
/* 关闭I,DCache和MMU
* 采取读-改-写的方式。
*/
mrc p15, 0, r0, c1, c0, 0 /* 读取CP15的C1寄存器到R0中 */
bic r0, r0, #(0x1 << 12) /* 清除C1寄存器的bit12位(I位),关闭I Cache */
bic r0, r0, #(0x1 << 2) /* 清除C1寄存器的bit2(C位),关闭D Cache */
bic r0, r0, #0x2 /* 清除C1寄存器的bit1(A位),关闭对齐 */
bic r0, r0, #(0x1 << 11) /* 清除C1寄存器的bit11(Z位),关闭分支预测 */
bic r0, r0, #0x1 /* 清除C1寄存器的bit0(M位),关闭MMU */
mcr p15, 0, r0, c1, c0, 0 /* 将r0寄存器中的值写入到CP15的C1寄存器中 */
#if 0
/* 汇编版本设置中断向量表偏移 */
ldr r0, =0X87800000
dsb
isb
mcr p15, 0, r0, c12, c0, 0
dsb
isb
#endif
/* 设置各个模式下的栈指针,
* 注意:IMX6UL的堆栈是向下增长的!
* 堆栈指针地址一定要是4字节地址对齐的!!!
* DDR范围:0X80000000~0X9FFFFFFF
*/
/* 进入IRQ模式 */
mrs r0, cpsr
bic r0, r0, #0x1f /* 将r0寄存器中的低5位清零,也就是cpsr的M0~M4 */
orr r0, r0, #0x12 /* r0或上0x13,表示使用IRQ模式 */
msr cpsr, r0 /* 将r0 的数据写入到cpsr_c中 */
ldr sp, =0x80600000 /* 设置IRQ模式下的栈首地址为0X80600000,大小为2MB */
/* 进入SYS模式 */
mrs r0, cpsr
bic r0, r0, #0x1f /* 将r0寄存器中的低5位清零,也就是cpsr的M0~M4 */
orr r0, r0, #0x1f /* r0或上0x13,表示使用SYS模式 */
msr cpsr, r0 /* 将r0 的数据写入到cpsr_c中 */
ldr sp, =0x80400000 /* 设置SYS模式下的栈首地址为0X80400000,大小为2MB */
/* 进入SVC模式 */
mrs r0, cpsr
bic r0, r0, #0x1f /* 将r0寄存器中的低5位清零,也就是cpsr的M0~M4 */
orr r0, r0, #0x13 /* r0或上0x13,表示使用SVC模式 */
msr cpsr, r0 /* 将r0 的数据写入到cpsr_c中 */
ldr sp, =0X80200000 /* 设置SVC模式下的栈首地址为0X80200000,大小为2MB */
cpsie i /* 打开全局中断 */
#if 0
/* 使能IRQ中断 */
mrs r0, cpsr /* 读取cpsr寄存器值到r0中 */
bic r0, r0, #0x80 /* 将r0寄存器中bit7清零,也就是CPSR中的I位清零,表示允许IRQ中断 */
msr cpsr, r0 /* 将r0重新写入到cpsr中 */
#endif
b main /* 跳转到main函数 */
/* 未定义中断 */
Undefined_Handler:
ldr r0, =Undefined_Handler
bx r0
/* SVC中断 */
SVC_Handler:
ldr r0, =SVC_Handler
bx r0
/* 预取终止中断 */
PrefAbort_Handler:
ldr r0, =PrefAbort_Handler
bx r0
/* 数据终止中断 */
DataAbort_Handler:
ldr r0, =DataAbort_Handler
bx r0
/* 未使用的中断 */
NotUsed_Handler:
ldr r0, =NotUsed_Handler
bx r0
/* IRQ中断!重点!!!!! */
IRQ_Handler:
push {lr} /* 保存lr地址 */
push {r0-r3, r12} /* 保存r0-r3,r12寄存器 */
mrs r0, spsr /* 读取spsr寄存器 */
push {r0} /* 保存spsr寄存器 */
mrc p15, 4, r1, c15, c0, 0 /* 从CP15的C0寄存器内的值到R1寄存器中
* 参考文档ARM Cortex-A(armV7)编程手册V4.0.pdf P49
* Cortex-A7 Technical ReferenceManua.pdf P68 P138
*/
add r1, r1, #0X2000 /* GIC基地址加0X2000,也就是GIC的CPU接口端基地址 */
ldr r0, [r1, #0XC] /* GIC的CPU接口端基地址加0X0C就是GICC_IAR寄存器,
* GICC_IAR寄存器保存这当前发生中断的中断号,我们要根据
* 这个中断号来绝对调用哪个中断服务函数
*/
push {r0, r1} /* 保存r0,r1 */
cps #0x13 /* 进入SVC模式,允许其他中断再次进去 */
push {lr} /* 保存SVC模式的lr寄存器 */
ldr r2, =system_irqhandler /* 加载C语言中断处理函数到r2寄存器中*/
blx r2 /* 运行C语言中断处理函数,带有一个参数,保存在R0寄存器中 */
pop {lr} /* 执行完C语言中断服务函数,lr出栈 */
cps #0x12 /* 进入IRQ模式 */
pop {r0, r1}
str r0, [r1, #0X10] /* 中断执行完成,写EOIR */
pop {r0}
msr spsr_cxsf, r0 /* 恢复spsr */
pop {r0-r3, r12} /* r0-r3,r12出栈 */
pop {lr} /* lr出栈 */
subs pc, lr, #4 /* 将lr-4赋给pc */
/* FIQ中断 */
FIQ_Handler:
ldr r0, =FIQ_Handler
bx r0
边栏推荐
- [MCU simulation project] external interrupt 0 controls 8 LED flashes
- Maximum average value of continuous interval
- redux
- 1311_ Hardware design_ Summary of ICT concept, application, advantages and disadvantages
- PHP object conversion array
- 【第019问 Unity中对SpherecastCommand的理解?】
- Retail chain store cashier system source code management commodity classification function logic sharing
- Inventory the concept, classification and characteristics of cloud computing
- PHP implements the algorithm of adding from 1 to 100
- 荐书丨《教育心理学》:送给明日教师的一本书~
猜你喜欢

Seat / safety configuration upgrade is the administrative experience of the new Volvo S90 in place

1311_ Hardware design_ Summary of ICT concept, application, advantages and disadvantages

零售连锁门店收银系统源码管理商品分类的功能逻辑分享

如何构建面向海量数据、高实时要求的企业级OLAP数据引擎?

Verilog implementation of key dithering elimination

Can't the container run? The Internet doesn't have to carry the blame

【读书笔记->数据分析】01 数据分析导论

《opencv学习笔记》-- 霍夫变换

资深报表开发经验总结:明白这一点,没有做不好的报表

Worked overtime for a week to develop a reporting system. This low code free it reporting artifact is very easy to use
随机推荐
荐书丨《教育心理学》:送给明日教师的一本书~
JS get some attributes of the object
php 实现从1累加到100的算法
按键消抖的Verilog实现
How mantium uses deepspeed to implement low latency gpt-j reasoning on Amazon sagemaker
CPU and GPU are out of date, and the era of NPU and APU begins
Wechat applet to realize music player (4) (use pubsubjs to realize inter page communication)
Dracoo Master天龙卡牌大师
[Reading Notes - > data analysis] Introduction to BDA textbook data analysis
加班一周开发了报表系统,这个低代码免费IT报表神器太好用了
Dynamic planning for stair climbing
Constructing verb sources for relation extraction
The PHP Eval () function can run a string as PHP code
在 Istio 服务网格内连接外部 MySQL 数据库
1311_ Hardware design_ Summary of ICT concept, application, advantages and disadvantages
General test case writing specification
LeetCode:1184. 公交站间的距离————简单
【云原生】谈谈老牌消息中间件ActiveMQ的理解
firewall 命令简单操作
[in depth study of 4g/5g/6g topic-42]: urllc-13 - in depth interpretation of 3GPP urllc related protocols, specifications and technical principles -7-low delay technology-1-subcarrier spacing expansio