Zynq7000系列学习笔记

本文介绍分发器(Distributor)CPU接口 (CPU Interface)的功能与协作,并提供C语言案例辅助理解。

总结来说,分发器设置中断使能和中断优先级,并将该中断信号发送给CPU,CPU设置可接受的最低优先级,进行中断处理和完成中断通知。

一、分发器和CPU接口的功能

 

分发器Distributor

CPU 接口 (CPU Interface)

基地址

0xF8F01000

0xF8F00100

功能

全局中断管理

CPU 核心的中断交互

管理对象

所有中断源 (SPI, PPI, SGI)

连接到单个 CPU 核心的中断

具体使用

中断使能/禁用、优先级配置、路由到 CPU

中断确认、优先级屏蔽、中断完成通知

可见性

全局唯一(CPU共享)

每个CPU私有

二、工作原理与交互流程 (中断生命周期)

  1. 中断触发(外设 → 分发器)
  • 外设中断源(如 GPIO / UART / Timer)触发中断信号。
  • 分发器接收:
    • 中断信号到达分发器(0xF8F01000
    • 分发器检查该中断是否 已使能(GICD_ISENABLERn
    • 分发器读取该中断的 优先级(GICD_IPRIORITYRn
    • 分发器根据配置决定是否 转发 给目标 CPU
  1. 中断分发(分发器 → CPU 接口)
  • 路由决策:
    • 分发器检查目标 CPU 接口的状态(是否使能接收中断)
    • 比较 中断优先级 与目标 CPU 当前的 运行优先级(通过 CPU 接口的 GICC_PMR 获取)
    • 若中断优先级 > CPU 当前优先级,分发器将其挂起到目标 CPU 的待处理队列。
  • 信号通知:
    • 分发器通过硬件信号线通知目标 CPU 的 CPU 接口:有高优先级中断等待处理。
  1. CPU 响应 (CPU 接口 → CPU 核心)
  • 中断通知:
    • CPU 接口 (0xF8F00100)收到分发器通知。
    • CPU 接口向 CPU 核心 发送 IRQ/FIQ 中断请求。
  • CPU 核心响应:
    • CPU 核心暂停当前程序,跳转到 中断向量表 入口。
    • 执行中断服务程序 (ISR) 的 入口代码。
  1. 中断处理 (ISR 与 CPU 接口交互)
  • 中断确认:
    • ISR 通过 CPU 接口的 Interrupt Acknowledge Register(GICC_IAR)读取 中断号(INTID)
    • 读取 GICC_IAR 的行为告知 GIC:“CPU 已开始处理此中断”
    • GIC 自动将该中断状态从 Pending 改为 Active
  • 服务中断:
    • ISR 根据 INTID 执行具体的中断服务逻辑(如读取 UART 数据)
  • 中断完成:
    • ISR 结束时,向 CPU 接口的 End of Interrupt Register(GICC_EOIR)写入之前读到的 INTID。
    • 写入 GICC_EOIR 告知 GIC:“此中断处理已完成”
    • GIC 将该中断状态从 Active 改为 Inactive,并允许分发器再次发送此中断(若再次触发)
  1. 中断优先级与抢占
  • 分发器 根据全局中断优先级决定哪些中断可发送给 CPU。
  • CPU 接口 的 GICC_PMR 设置 CPU 可接受的最低优先级(低于此值的中断被屏蔽)
  • 若高优先级中断到达,且当前中断优先级较低,CPU 接口可触发 中断抢占(暂停当前 ISR,转去处理更高优先级中断)。

三、软件编程详细案例

  1. 分发器初始化代码详解
    1. 全局使能分发器
*(volatile uint32_t *)(GIC_DIST_BASE + 0x000) = 0x1; // GICD_CTLR
  • 作用:启用整个中断分发系统,是整个 GIC 系统的总开关
  • 寄存器:GICD_CTLR(Distributor Control Register)
  • 地址计算:基地址0xF8F01000+偏移量0x000
  • 位设置:
    • Bit 0 = 1:使能中断转发到 CPU 接口
    • Bit 1 = 0:禁用安全扩展
    1. 配置中断优先级
*(volatile uint32_t *)(GIC_DIST_BASE + 0x400 + (84 * 4/4)) = 0xA0;
// GICD_IPRIORITYR[21]
  • 作用:设置中断号84的优先级(优先级范围0~255,0最高)
  • 寄存器:GICD_IPRIORITYRn(Interrupt Priority Registers)
  • 地址计算:
    • 优先级寄存器组基偏移:0x400
    • 中断号 84 的偏移:84 * 1(因为每个中断占 1 字节)
    • 实际地址:0xF8F01000 + 0x400 + 84 = 0xF8F01454
    • Zynq-7000 中:0-31是私有中断(PPI)和软件中断(SGI);32-95是共享外设中断(SPI)
    1. 路由到 CPU0
*(volatile uint32_t *)(GIC_DIST_BASE + 0x800 + (84 * 4/4)) = 0x01;
// GICD_ITARGETSR[21]
  • 作用:指定中断84发送到 CPU0
  • 寄存器:GICD_ITARGETSRn(Interrupt Processor Targets Registers)
  • 地址计算:0xF8F01000 + 0x800 + 84 = 0xF8F01854
  • 位掩码:0x01表示 CPU0
    • Bit 0 = 1:路由到 CPU0
    • Bit 1 = 0:不路由到 CPU1
  • 注:在双核系统中,必须明确指定中断发送到哪个核心。
  • 注:PPI/SGI 不能配置路由,只有 SPI(32+)可配置
    1. 使能中断号 84
*(volatile uint32_t *)(GIC_DIST_BASE + 0x100 + (84 / 32)*4) |= (1 << (84 % 32));
// GICD_ISENABLER
  • 作用:启用特定中断源
  • 寄存器:GICD_ISENABLERn(Interrupt Set-Enable Registers)
  • 地址计算:
    • 使能寄存器组基偏移:0x100
    • 寄存器索引:84 / 32 = 2(第3个寄存器,管理中断64-95)
    • 位位置:84 % 32 = 20
    • 实际地址:0xF8F01000 + 0x100 + 2*4 = 0xF8F01008
  1. CPU 接口初始化代码详解
    1. 设置优先级屏蔽阈值
*(volatile uint32_t *)(GIC_CPU_BASE + 0x0004) = 0xA0; // GICC_PMR
  • 作用:定义 CPU 处理中断的最低优先级
  • 寄存器:GICC_PMR(Priority Mask Register)
  • 地址:0xF8F00100 + 0x0004 = 0xF8F00104
  • 值说明:0xA0(160)表示:
    • 优先级高于 160 的中断被屏蔽
    • 优先级低于 160 的中断可被处理
    • 防止低优先级中断打断高优先级任务
    1. 使能 CPU 接口
*(volatile uint32_t *)(GIC_CPU_BASE + 0x0000) = 0x1; // GICC_CTLR
  • 作用:启用 CPU 与 GIC 的交互通道
  • 寄存器:GICC_CTLR(CPU Interface Control Register)
  • 地址:0xF8F00100 + 0x0000 = 0xF8F00100
  • 位设置:
    • Bit 0 = 1:使能中断信号到 CPU
    • Bit 1 = 0:禁用 FIQ(通常用 IRQ)
    • Bit 2 = 0:禁用 ACK 特殊处理
  • 注:不使能CPU接口,即使分发器发送中断,CPU 也不会响应
  1. 中断服务程序 (ISR)
    1. 读取中断号
uint32_t intid = *(volatile uint32_t *)(GIC_CPU_BASE + 0x000C); // GICC_IAR
  • 作用:获取当前中断 ID 并确认接收
  • 寄存器:GICC_IAR(Interrupt Acknowledge Register)
  • 地址:0xF8F00100 + 0x000C = 0xF8F0010C
  • 读取操作的意义:
    • 获取中断号(低 10 位)
    • 通知 GIC "CPU 已开始处理此中断"
  • 状态转换:GIC 将中断状态从 Pending 改为 Active
  • 注:必须读取此寄存器后才能安全处理中断
  • 注:返回值可能包含其他信息(如 CPU 号),通常 intid & 0x3FF提取 ID
    1. 执行中断处理
handle_irq(intid);  // 用户定义的中断处理函数
  • 应避免阻塞其他中断
  • 不能调用可能阻塞的函数
  • 清除外设中断标志
    1. 通知中断处理完成
*(volatile uint32_t *)(GIC_CPU_BASE + 0x0010) = intid; // GICC_EOIR
  • 作用:告知 GIC 中断处理已完成
  • 寄存器:GICC_EOIR(End of Interrupt Register)
  • 地址:0xF8F00100 + 0x0010 = 0xF8F00110
  • 注:必须写入从GICC_IAR读取的原始值
  • 必须在中断处理完成后立即执行
  • 此时中断状态从Active转换为Inactive,才能允许相同的中断再次触发

ARM 通用中断控制器GIC(Generic Interrupt Controller)的更多相关文章

  1. x86架构中的外部中断结构-Part 1:中断控制器的演化

    本文主要讲解了x86体系架构从外部设备接受中断的过程,本文是系列文章的第一部分,试图回答以下问题: 什么是PIC以及它的用途是什么? 什么是APIC以及它的用途是什么?LAPIC和I/O APIC的目 ...

  2. 【原创】Linux中断子系统(一)-中断控制器及驱动分析

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  3. 10.1 Nested vectored interrupt controller (NVIC) 嵌套矢量中断控制器

    特点 60个可屏蔽中断通道(不包含16个Cortex™-M3的中断线): 16个可编程的优先等级(使用了4位中断优先级): 低延迟的异常和中断处理: 电源管理控制: 系统控制寄存器的实现: 1. 中断 ...

  4. LPC2478中断控制器以及串口详解

    LPC2478的中断系统 LPC2478使用的是ARM PrimeCell向量中断控制器,一共支持32个中断向量,处于AHB空间便于系统快速访问,在中断向量的硬件优先级上还有一层可以用户自己设计的软件 ...

  5. s3c2440中断控制器操作

    一.ARM中断体系结构 arm有7中异常工作模式 用户模式.快中断模式.管理模式.数据访问终止模式.中断模式.系统模式.未定义指令终止模式. 几种模式有什么不同呢, 1.不同的寄存器 2.不同的权限 ...

  6. 【DSP开发】C6678的中断控制器

    分两层,一层是每个core内部的中断控制器,这个叫interrupt controller,简写intc:一层是整个芯片的,属于芯片级的,在每个core的外面,这个叫chip-level interr ...

  7. ARM9的中断控制器

    简要复习一下ARM9中断控制器的控制过程: 1.首先能识别触发的中断(对应中断源必须打开,然后查询当前中断状态寄存器),硬件会操控PC跳到中断向量入口(IRQ_HANDLE,硬件控制的只要是IRQ中断 ...

  8. Linux中断子系统:级联中断控制器驱动

    Linux中断子系统 Linux中断子系统是个很大的话题,如下面的思维导图所示,包含硬件.驱动.中断上半部.中断下半部等等.本文着眼于中断控制器(PIC),特别是级联中断控制器驱动部分,对驱动的设计和 ...

  9. 微机原理与系统设计笔记7 |常用芯片接口技术、中断系统与可编程中断控制器8259A

    打算整理汇编语言与接口微机这方面的学习记录.本部分介绍常用芯片接口技术.中断系统与可编程中断控制器8259A. 参考资料 西电<微机原理与系统设计>周佳社 西交<微机原理与接口技术& ...

  10. 关于ck中断控制器

    一.中断控制器 中断控制器模块包括 其使能寄存器,状态寄存器等. 中断使能寄存器为32bit,每一个bit 对应一个中断源,具体对应到硬件上线的连接 二.cpu怎样调用到中断 (1). 前置工作 首先 ...

随机推荐

  1. Spring扩展接口-ApplicationContextInitializer

    .markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...

  2. Kubernets初窥门径 (NameSpace、Pod、Label、Deployment、Service)

    1.Namespace Namespace是Kubernetes系统中一种非常重要的资源,它的主要作用是用来实现多套系统的资源隔离或者多租户的资源隔离. 默认情况下,Kubernetes集群中的所有P ...

  3. 关于vue关闭页面时去除定时器失效问题解决

    1.先去除页面缓存,这个在路由部分 2.

  4. Golang协程和线程区别

    一.进程.线程.协程介绍 进程:系统中所有的应用程序都是以进程(process)的方式运行,是系统进行资源分配和调度的基本单位,每个进程都有自己的独立的地址空间,使得进程之间的地址空间相互隔离. 线程 ...

  5. kubernetes获取Pod内容器信息

    一.简单说明 在实际的业务需求中,我们可能需要在写yaml文件的时候,可以在Pod的container内获取Pod的spec,metadata等信息,包含:node的名称,pod的名称,pod的nam ...

  6. LogStash介绍及二进制安装

    概述 官方文档:https://www.elastic.co/guide/en/logstash/7.17/introduction.html Logstash 是一款开源数据收集引擎,具备实时流水线 ...

  7. 「CF798E」 Mike and code of a permutation

    \(O(n^2)\)做法 让第\(i\)个点向\(p_j(p_j>p_i)\)的点连边 首先\(i\)肯定能连向\(a_i\),若当\(a_i==-1\),那么当前所有没打过标记的点向\(i\) ...

  8. Hack 说明

    在今天的模拟赛中,部分同学由于对出现某个数在模 \(1000000007\) 意义下为 \(0\) 的情况不规范被 Hack. Hack 原理:开始时有 \(2\) 个 \(1\),先都加到 \(10 ...

  9. Docker + CentOS 部署 Zookeeper 集群 + Kubernetes Operator 自动化运维方案

    环境说明 主机 IP 主机名 节点角色 数据目录 Kubernetes 节点标签 192.168.10.100 zk1 Master /opt/zookeeper/data zk-cluster=tr ...

  10. Python全栈应用开发利器Dash 3.x新版本介绍(4)

    更多Dash应用开发干货知识.案例,欢迎关注"玩转Dash"微信公众号 大家好我是费老师,在前几期文章中,我们针对Python生态中强大且灵活的全栈应用开发框架Dash,介绍了其3 ...