• 按键检测|中断检测


    一.按键检测

    1.硬件原理

    当未按下按键时,GPIO_5为低电平,按下按键GPIO_5变为高电平。

    根据引脚编号找到引脚名称

    根据引脚名称找到引脚编号

    裸机程序控制外设

    特点:读数据手册、设寄存器值

    • 找出外设有哪些相关寄存器
    • 找出外设相关寄存器如何设置

    二.中断检测

    1.通用中断控制器(GIC)

    GIC用于管理单核或多核芯片中的中断资源

    • ARM公司开发了4 个版本GIC规范 ,V1~V4
    • ARMv7-A内核搭配GIC-400使用(v2)

    2.GIC结构

    • 三类信号源:

      • 软件中断:用于多核通信,ID0~ID15
      • 私有中断:内核独有的中断,ID16~ID31
      • 共享中断:所有内核共享的中断,ID32~ID1019
    • 分发器:选择把中断信号发送到哪一个cpu接口单元

      有哪些相关寄存器?

      • 中断数量:GICD_TYPER

      • 中断清除: GICD_ ICENABLERn

      • 中断使能:GICD_ISACTIVERn

      • 中断优先级设置:GICD_IPRIORITYR

    • cpu接口单元:处理信号后,发送信号给CPU

      有哪些相关寄存器?

      • 中断优先级数量:GICC_PMR
      • 抢占优先级和子优先级设置: GICC_BPR
      • 保存中断ID:GICC_IAR
      • 通知cpu中断完成:GICC_EOIR

    2.获取GIC基地址

    方法一:查询芯片数据手册

    方法二:查询cp15协处理器

    共有16个:c0~c15。每个协处理器本身有多种含义,需逐步配置

    //设置并读协处理器
    MRC {cond} p15, , , , , 
    //设置并写协处理器
    MCR {cond} p15, , , , ,  
    
    • 1
    • 2
    • 3
    • 4
    • cond:执行条件,一般省略
    • opc1:第一层设置
    • Rn:通用寄存器
    • CRn:要设置的协处理器
    • CRm:第二层设置
    • opc2:第三层设置

    CBAR寄存器

    CRn=c15,opc1=4,CRm=c0,opc2=0

    • 查询GIC的地址
    MRC p15, 4, r1, c15, c0, 0 ;获取 GIC 基地址
    
    • 1

    把c15配置成CBAR寄存器,此时成c15的值就是GIC的基地址。

    SCTLR 寄存器

    CRn=c1,opc1=0,CRm=c0,opc2=0

    • bit13:中断向量表基地址

    • cache\mmu\分支预测…

      MRC p15, 0, , c1, c0, 0 ;读取 SCTLR 寄存器,数据保存到 Rt 中。
      MCR p15, 0, , c1, c0, 0 ;将 Rt 中的数据写到 SCTLR(c1)寄存器中。
      
      • 1
      • 2

    VBAR寄存器

    CRn=c12,opc1=0,CRm=c0,opc2=0

    • bit5~31:中断向量表偏移地址
    MRC p15, 0, , c12, c0, 0 ;读取 VBAR 寄存器,数据保存到 Rt 中。
    MCR p15, 0, , c12, c0, 0 ;将 Rt 中的数据写到 VBAR寄存器中。
    
    • 1
    • 2

    2.中断向量表

    一级查表

    自动跳转指定位置(基址+偏移)

    addrTYPEFUNCTIONMODE
    0x00Reset复位中断SVC
    0x04Undefined instructions未定义指令中断Undef
    0x08Supervisor Call软中断SYC
    0x0CPrefetch abort指令预取中止中断ABT
    0x10Data abort数据访问中止中断ABT
    0x14RESERVED未使用未使用
    0x18IRQ interruptIRQ 中断IRQ
    0x1CFIQ interruptFIQ 中断FIQ

    通过触发不同类型的中断,系统进入到相应的运行模式

    二级查表

    预先注册、回调执行

    3.中断处理流程

    中断上下文

    cpu通过内核寄存器来运行指令并进行数据的读写处理的,它在进入中断前一个时刻的具体值,称为中断上下文

    具体流程
    • 初始化irq模式栈指针

    • 进入irq模式

      • cpsr寄存器
    • 保存现场

      • 通用寄存器
      • lr
      • spsr
    • 获取中断编号

      • 读取GIC基地址
      • GICC基地址(GIC cpu interface)
      • GICC_IAR寄存器
    • 执行中断处理函数

      • 根据中断编号,回调IRQ中断服务表
    • 还原现场

      • 通用寄存器

      • lr

      • spsr

    • 返回原程序

      • 三级流水线

    cpsr寄存器
    ![2023-09-24T13:31:38.png][12]

    • bit31:负数标记位
    • bit30:零标志位
    • M[4:0]:运行模式控制位
      • 10000:User 模式
      • 10001:FIQ 模式
      • 10010:IRQ 模式
      • 10011:SVC模式
      • 10111:Abort模式
      • 11011:Undef模式
      • 11111:System模式
      • 10110:Monitor模式
      • 11010:Hyp模式
    mrs ,cpsr //读cpsr
    msr cpsr, //写cpsr
    cps #xx //写立即数到cpsr中的M[4:0]
    
    • 1
    • 2
    • 3
    GICC基地址

    4.1.3 CPU interface register ma (GIC官方手册)

    三级流水线
    • 取指令(pc)
    • 译指令
    • 执行指令
    lr = pc = 当前执行指令+8
    当前执行指令的下一条:lr-4
    
    • 1
    • 2

    3.按键中断实验

    GIC相关寄存器
    • 分发器

      • 中断数量:GICD_TYPER
      • 中断清除: GICD_ ICENABLERn
      • 中断使能:GICD_ISACTIVERn
      • 中断优先级设置:GICD_IPRIORITYR

      详见GIC官方手册

      4.3 Distributor register descriptions

    • cpu接口单元

      • 中断优先级数量:GICC_PMR
      • 抢占优先级和子优先级设置: GICC_BPR
      • 保存中断ID:GICC_IAR
      • 通知cpu中断完成:GICC_EOIR

      详见GIC官方手册

      4.4 CPU interface register descriptions

    GPIO中断相关寄存器
    • gpio中断触发类型:高/低电平、上升/下降沿

      • GPIO5_ICR1(0~15)

      • GPIO5_ICR2(16~31)

    • gpio中断屏蔽

      • GPIO5_IMR
    • gpio中断状态寄存器

      • GPIO5_ISR
    • gpio双边缘触发

      • GPIO5_EDGE_SEL

      详见芯片数据手册

      28.5 GPIO Memory Map/Register Definition

    中断服务函数表

    记录每个IRQ中断的回调函数

    • 函数指针

    • 函数参数

    中断向量表偏移位置

    C语言读写cp15协处理器

    __ASM ( code : 输出操作数列表 : 输入操作数列表 );

    • code

      • 具体操作指令(字符串表示)

      • #是把宏参数变为一个字符串

      • ##是把两个参数连接在一起

      __STRINGIFY(p##coproc) ", ->“p15”

    • 操作数

      通过%加数字引用,比如%0 引用第一个操作数,%1 引用第二个操作数

      r:将变量放入通用寄存器

    4.位置无关码和重定位

    程序执行和变量访问的两种方式:

    • pc指针+偏移地址
    • 绝对地址
    位置无关码

    没有出现绝对地址访问的代码称为位置无关码

    • 普通.text段指令
    • 局部变量

    位置无关码可以在任意合法内存运行

    位置相关码

    出现了绝对地址访问的代码称为位置相关码

    • 访问.data段:初始值非零的全局变量、静态变量

    • 访问.rodata段:字符串、具有初始值的数组

    • 访问.bss段:初始值为0的全局变量、静态变量

    • 特殊.text段指令

      汇编: ldr pc,=100000
      
      • 1
      c语言:(*(void(*)(void))0x100000)();
      
      • 1

    位置相关码必须在指定运行地址运行

    重定位

    在执行位置相关码之前,可以通过位置无关代码把位置相关码加载到位置相关代码的指定位置,如重定位.data段

  • 相关阅读:
    学js的第十六天
    m低信噪比下GPS信号的捕获算法研究,使用matlab算法进行仿真
    Web APIs——焦点事件以及小米搜索框
    跨行业人群如何通过NPDP?过来人给的四点建议!
    C++中关于树的一些定义
    repr函数输出调试信息
    架构思考(四)
    【C语言学习笔记 --- 自定义类型】
    普通人如何学好使用chatgpt
    helm简介
  • 原文地址:https://blog.csdn.net/m0_73731708/article/details/133325318