当前位置:网站首页>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
边栏推荐
- Find my technology | the Internet of things asset tracking market has reached US $6.6 billion, and find my helps the market develop
- Web测试方法大全
- UFS Clk Gate介绍
- LeetCode:1184. 公交站间的距离————简单
- Pits encountered by sdl2 OpenGL
- `Oi problem solving ` ` leetcode '2040. The k-th minor product of two ordered arrays
- php 实现从1累加到100的算法
- JS get some attributes of the object
- Sentinel fusing and current limiting
- [SVN] please execute the 'cleanup' command appears all the time. The solution is that there is no response after cleanup
猜你喜欢

Communication protocol and message format between microservices

第十八章:2位a~b进制中均位奇观探索,指定整数的 3x+1 转化过程,指定区间验证角谷猜想,探求4份黑洞数,验证3位黑洞数
![[project chapter - how to write and map the business model? (3000 word graphic summary suggestions)] project plan of innovation and entrepreneurship competition and application form of national Entrep](/img/e8/b115b85e2e0547545e85b2058a9bb0.png)
[project chapter - how to write and map the business model? (3000 word graphic summary suggestions)] project plan of innovation and entrepreneurship competition and application form of national Entrep

1311_硬件设计_ICT概念、应用以及优缺点学习小结

Introduction to UFS CLK gate

Helloworld案例分析

Advanced content of MySQL -- three MySQL logs that must be understood binlog, redo log and undo log

Opencv learning notes -- Hough transform

(翻译)网站流程图和用户流程图的使用时机

Go plus security: an indispensable security ecological infrastructure for build Web3
随机推荐
2.9.4 Ext JS的布尔对象类型处理及便捷方法
Basic principles of iptables
Connect external MySQL databases in istio Service Grid
【读书笔记->数据分析】BDA教材《数据分析》书籍介绍
sorting and searching 二分查找法
Web测试方法大全
雅迪高端之后开始变慢
Dracoo master
STM32 state machine programming example - full automatic washing machine (Part 2)
构建关系抽取的动词源
[SVN] please execute the 'cleanup' command appears all the time. The solution is that there is no response after cleanup
How to build an enterprise level OLAP data engine for massive data and high real-time requirements?
Educational Codeforces Round 132 (Rated for Div. 2) E. XOR Tree
2022杭电多校 Bowcraft
Acwing第 61 场周赛【完结】
[cloud native kubernetes] how to use configmap under kubernetes cluster
Summary of senior report development experience: understand this and do not make bad reports
Leetcode: 102. Sequence traversal of binary tree
[unity3d shader] character projection and reflection
加班一周开发了报表系统,这个低代码免费IT报表神器太好用了