ARM之中断

中断的基本概念

在4412板中,中断属于异常的一种,也是在发生状况的时候去跳转,它通过GIC来对中断进行管理,他有下面四个状态
(1)未激活(Inactive),中断尚未激活或未挂起;
(2)未决(Pending),中断已经由硬件或者软件产生,正等待目标cup响应
(3)激活(Active),CPU已经应答(Acknowledge)来自GIC的
(4)激活并挂起(Active&Pending),CPU正在处理该中断

中断类型
(1)软件生成的中断(SGls):是通过向软件生成中断寄存器写入SGI中断号生成的。SGl一般被用作核间中断,用于核间通信
(2)私有外设中断(PPI),由一个单独的处理器私有的外设生成

GIC的工作原理

ARM之中断_第1张图片

它可以分为左侧和右侧,左侧主要是分配器,用来接收信号,还有外围电路等中断信息,右侧的CPU接口是用来处理中断的私有通道,接受来自分配器分配好的最高优先级中断

GIC的配置

ARM之中断_第2张图片
大概解释一下这个图,我们需要做的就是按照这个表来配置和完成中断

  1. 进入管理模式
  2. 初始化:设置异常向量表基地址,切换到irq模式,初始化irq栈,初始化use模式栈
  3. 初始化中断源,设置gpio口为中断模式,初始化中断方式,设置gpio使能中断
  4. 初始化GIC
  5. 判断是否发生中断,否的话一直检查,是的话进入下一步
  6. 开启中断向量表
  7. 中断处理函数(取中断号,处理中断,清除中断,通知GIC来完成中断)

初始化中断注册函数

typedef void(* handler_t)(void);  //定义一个指针函数
//建立一个函数指针数组,通过获取的中断号,作为index,寻找对应中断号的执行程序
handler_t isr[160];
//GIC的初始化
//全局使能中断ICDDIR,使能改中断,选择CPU ICDIPTR,使能分发 设置屏蔽优先级*/

ARM之中断_第3张图片

 //全局使能GIC 与CPU0转发中断接口
    ICCICR_CPU0 = 0x1;

ARM之中断_第4张图片

  //ICCPMR_CPUnCPU响应阈值寄存器,超过阈值才能响应,配为0XFF
    ICCPMR_CPU0 = 0xff;

ARM之中断_第5张图片

//全局使能GIC监控中断信号,并转发给CPU内核
    ICDDCR = 0x1;

ARM之中断_第6张图片
设计优先级位域参考表
ARM之中断_第7张图片

   /*设置中断号为irqnum的优先级*/
        ICDIPR_CPU0[irqnum/4] &= ~(0xff << ((irqnum%4)*8));
        ICDIPR_CPU0[irqnum/4] |= level << ((irqnum%4)*8);
        //设置中断号为irqnum的中断只转发给CPU0
        ICDIPTR_CPU0[irqnum/4] &= ~(0xff << ((irqnum%4)*8));
        ICDIPTR_CPU0[irqnum/4] |= 0x1 << ((irqnum%4)*8);
        //全局使能中断号irqnum的中断响应
        ICDISER_CPU0[irqnum/32] |= 0x1 << (irqnum%32); 

下来我没需要将cpsr寄存器中的中的i位置1,来开启中断,所以我们需要一些内敛汇编

  isr[irqnum] = handler;

    /*使用汇编,将CPSR的I位置1,打开中断总开关*/  

    __asm__ __volatile__(
            "mrs r0, cpsr\n"
            "bic r0, #0x80\n"
            "msr cpsr, r0\n"
            :
            :
            :"r0"
    );
}

这样就完成了一个最简单中断的环境

你可能感兴趣的:(ARM,ARM,中断)