014 - ARM64上的GIC-400(GICv2)

news2024/12/28 18:39:32
本章节涉及到的参考文档有三个:
  • BCM2711 ARM Peripherals.pdf
  • ARM Generic Interrupt Controller Architecture Specification.pdf (简称gic_v2)
  • CoreLink GIC-400 Generic Interrupt Controller Technical Reference Manual.pdf

1. GIC 发展历史

在早期的 ARM 系统中,比如ARM7,ARM9 都是采用单核处理器设计,比如STM32,三星的2410。基本上几个简单的寄存器就可以描述中断源的使能,关闭以及状态。

树莓派4B上默认的 legacy 中断控制器就是采用了类似的实现。当然了树莓派4B上的中断源比较多,可以采用多级串联的方式来实现。三星的2410也是采用多级串联的方式实现。

但随着Soc 越来越复杂,中断源越来越多,中断类型也越来越多,以及现在比较流行的支持虚拟化等等因素。 ARM 公司开发了 GIC (Generic Interrupt Controller) 专门来管理中断。

2. GIC 通用常识

2.1. 中断类型

  • SGI : 软件产生的中断 (Software Generated Interrupt), 软中断即软件产生的中断,用于给其他CPU核心发送中断信号。
  • PPI: 私有外设中断(Private Peripheral Interrupt), 私有的外设中断,该中断时某个指定的CPU 独有的。
  • SPI : 共享外设中断 (Shared Peripheral Interrupt), 共享的外设中断,也就是我们常说的外设中断,所有CPU都可以访问这个中断。
  • LPI: 本地特殊外设中断(Locality-specific Peripheral Interrupt), GICv3 新增的中断类型,基于消息传递的中断类型。

2.2. 中断触发方式

  • 边沿触发(edge-triggered): 当中断源产生一个上升沿或者下降沿时,触发一个中断。
  • 电平触发(level-triggered): 当中断信号产生一个高电平或者低电平时,触发一个中断。

2.3. 中断状态

  • 不活跃状态(inactive): 中断处于无效状态。
  • 等待状态(pending): 中断处理有效状态,但是等待 CPU 响应该中断。
  • 活跃(active) : CPU 相应该中断。
  • 活跃并等待状态(active and pending): CPU 正在相应该中断的同时该中断源又发送新的中断过来。

2.4. GIC-V2中断控制器

GIC -V2 有两个硬件单元组成的。

  • Distributor :分发器,对应的 Distributor Registers(GICD_) 包含了中断设置和配置
  • CPU interface : CPU接口,每个CPU内核有一个CPU接口。对应的 CPU Interface registers(GICC_) 包含了CPU 相关的特殊设置。

2.5. 中断路由

GIC-V2 最多支持 8 个CPU.

GICD_ITARGETSRn 寄存器用来配置 Distributor 可以把中断路由到 哪个CPU 上,

  • 每 8bit 表示一个中断源,每个 bit 代表能路由到的 CPU
  • 每个 bit 设置了,说明该中断源可以路由到这个 CPU 上
  • 前 32 个中断源的路由配置时硬件设置好的,权限是只读RO
  • 第 33~1019 号中断,可以有软件来配置其路由,权限是读写RW

2.6. 中断流程

GIC检测中断

GIC检测中断的流程如下:

  1. 当GIC 检测到一个中断发生时,会将该中断状态从inactive状态标记为pending状态。
  2. 对于处在penging状态的中断,分发器会确定目标 CPU, 将中断请求发给这个CPU。
  3. 对于每个 CPU, 分发器会从众多处于等待状态的中断中选择一个优先级最高的中断,发送到目标CPU 的 CPU 接口。
  4. CPU 接口会决定这个中断是否可以发送给CPU, 如果这个中断的优先级满足要求,GIC 会发送一个中断请求信号给 CPU.
  5. CPU 进入中断异常, 读取 GICC_IAR 来响应该中断(一般是由 Linux 内核的中断处理程序来读寄存器)。寄存器会返回硬件中断号(hardware interrupt ID)。对于 SGI 来说,返回源CPU 的ID (source processor ID) 。当GIC感知到软件读取了该寄存器后,根据如下情况处理。
    1. 如果该中断源处于pending 状态,则将该中断状态切换到 active 状态
    2. 如果该中断又重新产生,那么该中断状态则变成 active and pending 状态
  6. 如果该中断正在忙,正在处理其他中断, 则该中断状态其切换为 active and pending 状态,等待CPU将当前当前的中断处理结束之后,再将该中断切换到 active 状态
  7. 处理器完成中断服务,发送一个完成信号结束中断(End of Interupt,EOI) 给 GIC。该中断状态再切换到 inactive 状态。

当然,实际情况可能更复杂。

3.2.4 Interrupt handling state machine, ARM Generic Interrupt Controller Architecture Specification.pdf

GIC中断时序图

GIC 支持中断优先级抢占功能。一个高优先级的中断可以抢占一个处于 active 状态的低优先级中断,即 GIC 的分发器会先找出并记录当前优先级最高并且处于 peding 的中断,然后抢占当前的中断服务,转而先处理高优先级中断,上述内容是从 GIC 角度分析的。总之,GIC 的分发器总会把 pending 状态中优先级最高的中断请求发送给 CPU。

从 Linxu 内核角度分析,如果在低优先级的中断处理程序中发生了 GIC 抢占,虽然 GIC 会发送高优先级中断请求给 CPU, 但是CPU处于关中断的状态,需要等到CPU开中断时才会响应高优先级中断。这一点需要注意。

B1. Interrupt signaling in the GIC-400 with physical interrupts only, CoreLink GIC-400 Generic Interrupt Controller Technical Reference Manual.pdf

假设中断N和中断M 都是 SPI 类型的外设中断且通过快速中断请求(Fast Interrupt Request, FIR) 来处理,高电平触发,N的优先级比M的高,它们的目标CPU 相同。

  • T1时刻,GIC 的分发器检测到中断M的电平变化。
  • T2时刻,分发器设置中断 M 的状态为 pending.
  • T17 时刻,CPU接口会拉低 nFIQCPU[n] 信号来向 CPU 报告中断请求。分发器需要这些时间来计算哪个是 pending状态下的优先级最高的中断。
  • T42时刻,分发器检测到另外一个更高优先级更高的中断 N.
  • T43时刻,分发器用中断 N 来替换中断 M, 作为当前pengding 状态下最高的中断,并设置中断 N 处于 pending 状态。
  • T58时刻,经过 tph个时钟周期之后,CPU 接口拉低 nFIQCPU[n] 信号来通知 CPU。nFIQCPU[n] 信号在T17时刻已经被拉低。 CPU接口会更新 GICC_IAR的 ID 字段,该字段的值变成中断 N 的硬件中断号。
  • T61 时刻,CPU (Linux 内核的中断服务程序) 读取GICC_IAR, 即软件响应了中断 N, 这时分发器把中断 N 的状态从 pending 状态切换为 active and pending 状态。
  • T61-T131 时刻,Linux 内核处理中断 N 的中断服务程序。
    • T64时刻,在中断 N 被 Linux 内核响应后的 3个时钟周期内,CPU接口完成对 nFIQCPU[n] 信号的复位,即拉高 nFIQCPU[n]信号。
    • T126时刻,外设也复位了中断 N。
    • T128时刻,退出了中断 N 的 Pending 状态。
  • T131时刻,处理器(Linux内核中断服务程序)把中断 N 的硬件ID 写入 GICC_EOIR来完成中断 N 的全部处理过程。
  • T146 时刻,在向GICC_EOIR 写入中断N 硬件 ID 后的 tph 个时钟周期后,分发器会选择下一个优先级最高的中断,即中断M, 发送中断请求给 CPU 接口。CPU接口拉低 nFIQCPU[n] 信号来向 CPU 报告中断 M 的请求。 CPU接口会更新 GICC_IAR的 ID 字段,该字段的值变成中断 M 的硬件中断号。
  • T211 时刻,CPU(Linux 内核中断服务程序)读取GICC_IAR 来响应该中断,分发器设置中断M的状态为 active and pending 状态。
  • T214时刻,在 CPU 响应中断后的3个时钟周期内,CPU 接口拉高 nFIQCPU[n] 信号来完成复位动作。

2.7. GIC-v2 寄存器

不考虑虚拟化的话,GIC 的寄存器可以分为两组:

  • D: 表示 Distributor 相关的寄存器, 以 ”GICD_“ 打头的寄存器
  • C: 表示 CPU interface 相关的寄存器,以 ”GICC_“ 打头的寄存器

Chapter 4.1 Distributor register map, ARM Generic Interrupt Controller Architecture Specification.pdf

Chapter 4.1 CPU interface register map, ARM Generic Interrupt Controller Architecture Specification.pdf

GIC-V2寄存器有个特点:名称以n 结束的寄存器会有 n个。比如 GICD_ISENABLERn寄存器就有 n 个GICD_ISENABLER 寄存器。

第一种:一个bit表示一个中断号类型的寄存器

GICD_ISENABLERn寄存器是用来使能某个中断号的,并且是按照中断号来描述的。

Chapter 4.1 Distributor register map, ARM Generic Interrupt Controller Architecture Specification.pdf

此寄存器的偏移量是 0x100~0x17c。 总共有n = (0x17c-0x100)/4 = 31 个寄存器。分别是 GICD_ISENABLER0 到 GICD_ISENABLER31。

对于中断号 m 来说,我们需要计算中断m对应的是哪个寄存器,也就是说我们要计算偏移多少。

Chapter 4.3.5 Interrupt Set-Enable Registers, GICD_ISENABLERn, ARM Generic Interrupt Controller Architecture Specification.pdf

GICD_ISENABLERn寄存器中每bit表示一个中断源。所以 n=m/32。 那么对于中断号 m 的GICD_ISENABLERn寄存器的地址就是 (0x100+4n)。

假设 m = 50, 即50号中断。 n = 50/32=1。 即GICD_ISENABLER1,偏移地址是(0x100+4*1)

第二种:8bits表示一个中断源类型的寄存器

GICD_ITARGETsRn 寄存器 使用 8位表示一个中断源所能路由的目标CPU有哪些。

Chapter 4.3.5 Interrupt Set-Enable Registers, GICD_ISENABLERn, ARM Generic Interrupt Controller Architecture Specification.pdf

  • 前32个中断的Target reg 是固定的,只读。
  • 后面的32~1019个中断的 Target 是软件可以设置的。

Chapter 4.3.12 Interrupt Processor Targets Register, GICD_ITARGETSRn, ARM Generic Interrupt Controller Architecture Specification.pdf

Chapter 4.3.12 Interrupt Processor Targets Register, GICD_ITARGETSRn, ARM Generic Interrupt Controller Architecture Specification.pdf

对于中断 m来说,这个寄存器 n的计算公式变成了 n =m/4。这里是取整计算。 寄存器的偏移量等于(0x800+4n)。

假设 m =50, 即50号中断。 n=50/4=12。 即GICD_ITARGETSR12。寄存器的偏移量是 0x800 +4*12 = 0x830。

3. 树莓派4B 上的 GIC-400

树莓派4B上集成了 GIC-V2架构的GIC-400。 GIC-400 上的具体中断号的分配和Soc 芯片的实现相关。

6.3 GIC-400 interrupt controller, BCM2711 ARM Peripherals.pdf

树莓派上的GIC-400分配有5种情况:

  • ARM Core 中断组:所有的PPI的中断组以及部分 SPI 寄存器组,包括ARM 核心上的通用寄存器,例如,PNS(non-secure physical)定时器的中断号就是30
    • Core n PS(Secure Physical) 定时器中断,PPI
    • Core n PNS(Non-Secure Physical) 定时器中断,PPI
    • Core n HP(Hypervisor) 定时器中断,PPI
    • Core n V(Virtual) 定时器中断,PPI
    • Core n PMU(Performance Monitoring Unit) 中断,SPI

  • ARM local 的中断,这部分都是SPI中断,例如, 16个 ARM 邮箱中断号为 32~47, CPU 内核0 上的 PMU 中断号是48
  • ARMC 外设中断组,CPU和GPU都可以访问的中断。这部分都是SPI中断。他们对应的中断号为64~79,比如常见的软件中断
  • VC(VideoCore)外设中断组,对应的中断号为96~159。这部分都是SPI中断。比如树莓派4B的 system timer 0 的中断号是96。相应的中断寄存器也是在 ARMC 寄存器组里。
  • 与PCIe相关的中断,对应中断号为 160~216。这部分都是SPI中断,

这些中断是如何映射到GIC-400 中的呢?

ARMC 外设中断组中每个中断定义如下

Chapter 6.2.3 ARMC interrupt, BCM2711 ARM Peripherals.pdf

GIC-400 分配的 ARMC peripheral IRQs 的 中断号是从 64-79,直接映射过去即可,比如 Timer 在ARMC中断组的id是0 ,那么映射到GIC-400就是64。 Software Interrupt 7 在ARMC组的id是15, 那么映射到GIC-400就是79。

另外,ARMC 中断组的寄存器 IRQn_PENDING2 每个bit 表示一个中断。

Chapter 6.5.3 ARMC, BCM2711 ARM Peripherals.pdf

VC(VideoCore) 外设中断组详细中断号如下

Chapter 6.2.4. VideoCore interrupts, BCM2711 ARM Peripherals.pdf

GIC-400 分配的 VC(VideoCore) peripheral IRQs 的 中断号是从 96-159, 那么System Timer 1 映射到 GIC-400,中断号就是97。

另外,VC 中断组的寄存器IRQn_PENDING0, IRQn_PENDING1 每个bit 表示一个中断。总共64个。

Chapter 6.5.3 ARMC, BCM2711 ARM Peripherals.pdf

PCIe 的中断组详细的中断号如下

Chapter 6.2.5. ETH_PCIe interrupts, BCM2711 ARM Peripherals.pdf

4. 访问树莓派上 GIC-400 寄存器

树莓派4B有两种地址模式

  • 高地址模式,此模式下GIC-400的基地址是0x4C0040000
  • 低地址模式, 此模式下GIC-400的基地址是0xFF840000

一般我们使用低地址模式(enable low peripheral),对应的基地址是0x0 FF84 0000。

Chapter 6.5.1 GIC-400, BCM2711 ARM Peripherals.pdf

然后,我们需要继续查看 GIC-V2的手册来确定 Distributor 和 CPU interface 的偏移量。

3.2 GIC-400 register map, CoreLink GIC-400 Generic Interrupt Controller Technical Reference Manual.pdf

从上图可以知道, Distributor 和CPU interface 的基地址分别是 0x1000和0x2000。

最后,在查看对应的寄存器的偏移量。寄存器的偏移量可以参考[[014 - GIC-400#2.5. GIC-v2 寄存器]]

我们继续使用中断 m 来举例, 假设通过[[014 - GIC-400#3. 树莓派4B 上的 GIC-400]]c 参考到中断M的中断号是 50。

我们来计算下,中断 m 对应的 GICD_ISENABLER1 和 GICD_ITARGETSR12 在树莓派4B设置为低地址模式下的访问地址。

GICD_ISENABLER1 的访问地址 = GIC-400 的基地址+ GIC-400 的 Distributor的偏移量+ 指定寄存器的偏移量 = 0x FF84 0000 + 0x100 + (0x100+4*1) = 0x FF84 0204

GICD_ITARGETSR12 的访问地址 = GIC-400 的基地址+ GIC-400 的 Distributor 的偏移量+ 指定寄存器的偏移量 = 0xFF84 0000 + 0x100 +(0x800+4*\12) = 0xFF84 093C

这些地址的来源总结下:

  • GIC-400 的基地址: 来自树莓派的手册,Chapter 6.5.1 GIC-400, BCM2711 ARM Peripherals.pdf
  • GIC-400 的 Distributor/CPU 的偏移量 : 来自 gic -v2, 3.2 GIC-400 register map, CoreLink GIC-400 Generic Interrupt Controller Technical Reference Manual.pdf
  • GIC-400 的 指定寄存器的偏移量 : 来自 gic -v2, 4.3 Distributor register descriptions, ARM Generic Interrupt Controller Architecture Specification 以及 4.4 CPU interface register descriptions, ARM Generic Interrupt Controller Architecture Specification.pdf

“GICC_” 打头的寄存器也可以这样计算访问地址。

5. GIC-400 中断处理流程

5.1. GIC-400 初始化

  1. 设置Distributor 和 CPU interface 寄存器组的基地址
  2. 读取 GICD_TYPER寄存器,计算当前GIC 最大支持多少个中断源
  3. 初始化 Distributor
    1. Disable Distributor
    2. 设置SPI 中断的路由
    3. 设置SPI 中断的触发类型,例如 level触发
    4. Disactive and disable 所有的中断源
    5. Enable distributor

  1. 初始化 CPU interface
    1. 设置 GIC_CPU_PRIMASK, 设置中断优先级mask level
    2. Enable CPU interface

5.2. 注册中断

  1. 初始化外设
  2. 查找该外设的中断在 GIC-400 的中断号,例如 PNS timer 的中断号为30
  3. 设置 GIC_DIST_ENABLE_SET 寄存器enable 这个中断号
  4. 打开设备相关的中断,例如树莓派上的 generic timer, 需要打开ARM_LOCAL 寄存器组的 TIMER_CNTRL0 寄存器种相关的 enable 位
  5. 打开 CPU 的 PSTAE 中 I 位(PSTATE.I)

5.3. 中断响应

  1. 中断发生
  2. 异常向量表
  3. 跳转到GIC中断函数里,gic_handle_irq()
  4. 读取GIC_IAR 寄存器,获取中断号
  5. 根据中断号来进行相应中断处理,例如读取的中断号为30,说明是 PNS 的 generic timer,然后跳转到generic timer 的处理函数里。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1113348.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

睿趣科技:抖音小店新手运营攻略

随着短视频平台的兴起,抖音已经成为了一个炙手可热的营销工具。越来越多的商家选择在抖音上开设小店,以此来拓展自己的业务。那么,作为新手,如何运营好自己的抖音小店呢?本文将为您提供一些实用的建议。 首先,要明确自…

python实现图片与视频转换:将视频保存为图片,将批量图片保存为视频

1、将视频保存为图片 1.1 完整代码 # -*- coding: utf-8 -*- import cv2 import os cap cv2.VideoCapture(TestFiles/2.mp4) index 0 prop cv2.CAP_PROP_FRAME_COUNT total int(cap.get(prop)) # 获取视频总帧数 while(cap.isOpened()):# ret返回布尔值ret, frame cap.r…

竹云荣膺2023十大数字化转型创新企业

10月14日上午,“2023DTWORLD国际数字科技领袖峰会/ IDI Award 数创奖颁奖盛典”在深圳会展中心(福田)2号馆成功举办。本届峰会由深圳市科学技术协会等相关政府部门指导,由深圳市科技交流服务中心、深圳市人工智能行业协会、湾盟产…

医疗终端札记

文章目录 一、打印Windows 下打印 PDF打印 Word转换格式 一、打印 Windows 下打印 PDF 从 Windows 命令行打印 PDF AcroRd32.exe /t "C:\Path\To\Your\File.pdf" "PrinterName" # 其中,“C:\Path\To\Your\File.pdf”是您要打印的PDF文件的完…

嵌入式软件开发笔试面试

C语言部分: 1.gcc的四步编译过程 1.预处理 展开头文件,删除注释、空行等无用内容,替换宏定义。 gcc -E hello.c -o hello.i 2.编译 检查语法错误,如果有错则报错,没有错误则生成汇编文件。 gcc -S hello.i -o h…

在线录音工具分享,总有一款适合你!

“有人知道怎么在线录音吗?在网页上播放了一首民谣,觉得旋律很好听,但是不能下载,就想用录音的方式记录下来,可是完全不会操作,真的很急!有没有好心人教教我,谢谢!” 随…

衍射:经典波动行为

一、说明 在本页中,我将尝试引导您了解光背后的基础知识。光是粒子还是波? 衍射是与光传播偏差相关的现象的通用名称,与几何光学预测的偏差(即光的直线传播)有关,它揭示了光的性质波而不是微粒物质。 图1&a…

为T507-H开发板配置Samba服务,实现跨系统的文件共享——飞凌嵌入式

作为一款经典的国产芯,全志T507-H芯片被广泛应用于车载电子、电力、医疗、工业控制、物联网、智能终端等诸多领域当中,而在各种复杂的嵌入式Linux应用场景当中,“打通ARM板卡与Windows设备间的壁垒以实现跨平台的文件共享”是一项不能被忽视的…

IStoreOS结合内网穿透软件Cpolar实现公网远程访问

文章目录 前言1. ssh局域网登陆iStoreOS系统2. 安装Cpolar内 网穿透软件3. 测试公网远程链接4. 公网使用固定http地址远程访问iStoreOS webui界面 前言 iStoreOS系统是基于OpenWrt定制的软路由系统,提供了如轻nas,云盘,文件共享等众多网络服务…

21款奔驰EQC350升级原厂360全景影像 感受上帝视野

您是否经历过这种场面呢? 停车位,狭窄障碍停车困难 避免盲区,倒车盲区危及生命安全 狭窄路段,无法判断是否安全通过 视角盲区,小孩站在视野盲区看不到,Xjh15863 360度无缝3D全车可见,解决各…

最新《中国环境统计年鉴》2001-2022年-EXCEL面板数据

数据简介:本数据汇集全国31个省、直辖市环境方面的面板数据,涵盖自然状况、水环境、海洋环境、大气环境、固体废物、自然生态、土地利用、林业、自然灾害及突发事件、环境投资、城市环境、农村环境等11个一级指标,数百个二级、三级指标。通过…

照片后期编辑工具Lightroom Classic 2024 mac中文新增功能

Lightroom Classic 2024(lrC2024)是专为摄影爱好者和专业摄影师设计的软件,它提供了全面的照片编辑工具,可以精准调整照片的色彩、对比度和曝光等参数,以便定制后期处理效果。 在lrC2024中,用户体验得到了提…

【Mysql】Mysql中的B+树索引(六)

概述 从上一章节我们了解到InnoDB 的数据页都是由7个部分组成,然后各个数据页之间可以组成一个双向链表 ,而每个数据页中的记录会按照主键值从小到大的顺序组成一个单向链表 ,每个数据页都会为存储在它里边儿的记录生成一个页目录 &#xff…

随着Telegram的崛起,这些特性和运营方法你得知道~

截止至2023年6月,Telegram已成为除了WhatsApp之外全球苹果应用商店中用户下载量最多的社交网络应用,这个新兴的社媒平台正在逐渐扩大它的影响力。Telegram的崛起也意味着出现了新的商机,要怎么把握这个热门社媒来进行营销也成了各出海企业最关…

MapGIS 10.6 Pro新品发布!加速地理信息领域核心技术国产替代

10月18日,国产GIS软件厂商中地数码在深圳举办“时空筑基智绘九州”新品发布会,正式推出新一代全空间智能GIS升级之作——MapGIS 10.6 Pro。来自全国各地的地理信息产业专家学者汇聚一堂,共话地信科技自立自强,助推产业高质量发展。…

Steam中如何设置HTTP服务器防封

要在 Steam 中设置HTTP服务器,请按照以下步骤操作: 1、打开 Steam 客户端。 2、点击“设置”(即齿轮图标),然后选择“网络”。 3、在“网络”页面中,找到“HTTP服务器”部分。 4、首先,将“使…

抖音招聘直播报白是通过直播方式展现职位信息适用于企业和人力资源公司

首先,视频展示职位能够给求职者更直观的感受,让他们更好地了解岗位的详情和要求。其次,抖音的短视频流量能够让岗位信息覆盖更广泛的人群,增加招聘信息的曝光度。此外,抖音招聘的成本也较低,相比传统的人工…

智荟雄安,创想未来 | 竹云董事长受邀出席雄安新区2023软件和信息技术服务业创新发展论坛并作主题演讲

10月18日,以“智荟雄安 创想未来”为主题的雄安新区2023软件和信息技术服务业创新发展论坛在雄安新区国际酒店会议中心召开。河北省委常委,雄安新区党工委书记、管委会主任张国华出席活动。 中国科学院院士朱鲁华现场致辞,中国工程院院士邬贺…

AC修炼计划(AtCoder Regular Contest 167)

传送门:AtCoder Regular Contest 167 - AtCoder 再次感谢樱雪喵大佬的题解,讲的很详细,Orz。 大佬的博客链接如下:Atcoder Regular Contest 167 - 樱雪喵 - 博客园 (cnblogs.com) 第一题很签到,就省略掉了。 第二题…

函数设计心得:尽量避免布尔型参数

通常来说,我认为在设计一个函数原型的时候,应该尽量避免使用布尔类型的参数,除非函数名称能十分清楚的将这个参数的意思表达出来。 我并没有想教你做事,但是请听我细说 先举两个正面的例子,有一个 API 函数 EnableWi…