WDF驱动开发-PNP和电源管理(二)

下面是一种比较典型的 PnP 和电源管理方案,WDF框架在这些情况下调用驱动程序的事件回调函数:

  • 用户插入设备
  • 用户拔出设备
  • 设备进入低功耗状态
  • 设备回到工作状态
  • PnP 管理器重新分发系统资源

这些几乎是所有的和PNP、电源管理相关的场景了,它们分别诠释了设备在各种情况下比较典型的用户场景,接下来会依次分析这些场景下WDF框架的行为。

用户插入设备

在以下方案中,设备节点包括 KMDF 总线驱动程序和支持 PnP 设备的一个或多个 KMDF 函数或Filter驱动程序。

当用户在系统运行时将设备插入总线时,设备的总线驱动程序和框架将执行以下任务:

  • 设备的总线驱动程序检测设备并调用 WdfChildListAddOrUpdateChildDescriptionAsPresent (此过程称为“动态枚举”);
  • 框架调用总线驱动程序的 EvtChildListCreateDevice 回调函数,因此总线驱动程序可以调用 WdfDeviceCreate 为物理设备创建框架设备对象 (PDO) ;
  • 框架调用总线驱动程序的 EvtDeviceResourcesQuery 和 EvtDeviceResourceRequirementsQuery 回调函数来确定设备所需的系统硬件资源;

接下来,PnP 管理器确定哪些其他驱动程序 (功能驱动程序和Filter驱动程序) 设备所需的。 如果尚未加载这些驱动程序,PnP 管理器将加载它们并调用其 DriverEntry 例程。 对于每个函数或Filter驱动程序,将执行以下操作:

1. 框架调用每个附加驱动程序的 EvtDriverDeviceAdd 回调函数,以便驱动程序可以调用 WdfDeviceCreate 来创建表示驱动程序设备的框架设备对象。 功能驱动程序 (FDO) 创建功能设备对象,Filter驱动程序 (Filter DO) 创建Filter设备对象。

2. 框架调用每个函数和Filter驱动程序的 EvtDeviceFilterRemoveResourceRequirements 回调函数,然后调用每个驱动程序的 EvtDeviceFilterAddResourceRequirements 回调函数。 在设备启动之前,框架立即调用 EvtDeviceRemoveAddedResources 回调函数。 这三个回调函数允许Filter和功能驱动程序在 PnP 管理器将资源分配给设备之前修改设备所需的硬件资源列表。 

3. 框架确保设备已达到其工作 (D0) 电源状态。

4. 对于支持设备的每个函数和Filter驱动程序,框架依次执行以下操作,一次一个驱动程序,从驱动程序堆栈中最低的驱动程序开始:

  • 框架 (调用驱动程序的 EvtDevicePrepareHardware 回调函数(如果该函数存在) ),并传递 PnP 管理器分配给设备的硬件资源列表;
  • 框架调用驱动程序的 EvtDeviceD0Entry 回调函数 (如果它存在于) ;
  • 框架 调用驱动程序的 EvtInterruptEnable 回调函数(如果每个中断存在),然后调用驱动程序的 EvtDeviceD0EntryPostInterruptsEnabled 回调函数 (如果存在) ,则调用该驱动程序的 EvtDeviceD0EntryPostEnabled 回调函数。
  • 如果硬件和驱动程序支持 DMA,框架将调用驱动程序的 EvtDmaEnablerFill、 EvtDmaEnablerEnable 和 EvtDmaEnablerSelfManagedIoStart 回调函数 (如果它们存在) 创建的每个 DMA 通道
  • 框架调用驱动程序的 EvtChildListScanForChildren 回调函数 (如果该函数存在于) ;
  • 框架启动设备的所有电源托管 I/O 队列;
  • 如果驱动程序使用自托管 I/O,框架将调用驱动程序的 EvtDeviceSelfManagedIoInit 回调函数;
用户拔出设备

当系统运行时,用户可以通过以下两种方式之一删除设备:有 条不紊地删除设备,这意味着用户通知系统设备即将 (删除,例如使用拔出或弹出硬件程序) ;或 意外删除,这意味着用户在不通知系统的情况下拔下设备。 如果总线支持意外删除 (例如 USB) ,则设备的驱动程序必须能够处理设备的突然消失。

有序删除

用户通过使用系统的拔出或弹出硬件程序、通过使用设备管理器禁用设备或推送可弹出设备的弹出按钮来请求删除。 框架允许删除或禁用设备,除非驱动程序具有:

  • 名为 WdfDeviceSetSpecialFileSupport ,并在设备上打开一个特殊文件;
  • 名为 WdfDeviceSetStaticStopRemove;
  • 提供了 EvtDeviceQueryRemove 回调函数,并且回调函数已否决删除;

对于支持该设备的每个函数和Filter驱动程序,框架从驱动程序堆栈中最高的驱动程序开始,按顺序一次执行一个驱动程序的以下操作:

  • 如果驱动程序使用自托管 I/O,框架将调用驱动程序的 EvtDeviceSelfManagedIoSuspend 回调函数;
  • 框架会停止驱动程序的所有电源托管 I/O 队列;
  • 如果硬件和驱动程序支持 DMA,框架将驱动程序的 EvtDmaEnablerSelfManagedIoStop、 EvtDmaEnablerFlush 和 EvtDmaEnablerDisable 回调 函数 (如果它们存在) 创建的每个 DMA 通道;
  • 框架 (调用驱动程序的 EvtDeviceD0ExitPreInterruptsDisabled 回调函数(如果存在) ),然后调用驱动程序的 EvtInterruptDisable 回调函数 (如果存在每个中断) ,则驱动程序可以禁用设备中断;
  • 框架 调用驱动程序的 EvtDeviceD0Exit 回调函数(如果存在) ;
  • 框架调用驱动程序的 EvtDeviceReleaseHardware 回调函数 (如果它存在) ,则向其传递 PnP 管理器分配给设备的硬件资源列表;
  • 如果驱动程序使用自托管 I/O,框架将调用驱动程序的 EvtDeviceSelfManagedIoFlush 回调函数;
  • 如果驱动程序使用自托管 I/O,框架将调用驱动程序的 EvtDeviceSelfManagedIoCleanup 回调函数;

总线驱动程序是堆栈中最后调用的驱动程序。 当框架调用总线驱动程序的 EvtDeviceD0Exit 回调函数时,回调函数将设备的电源状态 (总线) 的子设备设置为 D3。 总线驱动程序可以通过调用 WdfDeviceInitSetReleaseHardwareOrderOnFailure 来控制框架何时调用其 EvtDeviceReleaseHardware 回调函数。

意外删除

用户意外拔下设备。 设备总线的总线驱动程序发现设备缺失,并调用 WdfChildListUpdateChildDescriptionAsMissing。

对于支持该设备的每个函数和Filter驱动程序,框架从驱动程序堆栈中最高的驱动程序开始,按顺序一次执行一个驱动程序的以下操作:

1. 框架调用驱动程序的 EvtDeviceSurpriseRemoval 回调函数 ((如果存在) )。

2. 如果设备处于工作状态 (D0) 拔出设备时的状态:

  • 框架会停止驱动程序的所有电源托管 I/O 队列;
  • 如果驱动程序使用自托管 I/O,框架将调用驱动程序的 EvtDeviceSelfManagedIoSuspend 回调函数;
  • 如果硬件和驱动程序支持 DMA,框架将驱动程序的 EvtDmaEnablerSelfManagedIoStop、 EvtDmaEnablerFlush 和 EvtDmaEnablerDisable 回调 函数 (如果它们存在) 创建的每个 DMA 通道;
  • 框架调用驱动程序的 EvtDeviceD0ExitPreInterruptsDisabled 和 EvtInterruptDisable 回调函数 (如果它们存在) ,以便驱动程序可以禁用设备中断;
  • 框架 调用驱动程序的 EvtDeviceD0Exit 回调函数(如果存在) ;

3. 框架调用驱动程序的 EvtDeviceReleaseHardware 回调函数 (如果它存在) ,将 PnP 管理器分配给设备的硬件资源列表传递。
4. 如果驱动程序使用自托管 I/O,框架将调用驱动程序的 EvtDeviceSelfManagedIoFlush 回调函数。
5. 如果驱动程序使用自托管 I/O,框架将调用驱动程序的 EvtDeviceSelfManagedIoCleanup 回调函数。
请注意,设备随时可能会意外删除。 因此,框架可能会在前面步骤中显示的时间调用驱动程序的 EvtDeviceSurpriseRemoval 回调函数。 例如,如果用户在设备进入低功耗状态时意外拔下电源,框架可能会在调用 EvtDeviceReleaseHardware 回调函数后调用 EvtDeviceSurpriseRemoval 回调函数。 不得以假定在特定序列中调用 EvtDeviceSurpriseRemoval 回调函数和其他回调函数的方式编写代码。

此外,框架不会将设备的 EvtDeviceSurpriseRemoval 回调函数与该设备前面步骤中列出的任何回调函数同步。 因此, EvtDeviceSurpriseRemoval 回调函数可能会运行,而前面列出的另一个回调函数也在运行。

设备进入低功耗状态

如果发生以下情况之一,设备将使其工作 (D0) 状态,并进入低功耗状态:

  • 设备 处于空闲状态 访问,并且能够在系统保持工作 (S0) 状态时进入低功耗空闲状态;
  • 系统的电源状态已从其工作 (S0) 状态更改为低功耗状态。 驱动程序可以调用 WdfDeviceGetSystemPowerAction 来确定系统电源状态更改的原因;

对于支持该设备的每个函数和筛选器驱动程序,框架从驱动程序堆栈中最高的驱动程序开始,按顺序一次执行一个驱动程序的以下操作:

  • 如果驱动程序使用自托管 I/O,框架将调用驱动程序的 EvtDeviceSelfManagedIoSuspend 回调函数;
  • 框架会停止驱动程序的所有电源托管 I/O 队列,并调用其 EvtIoStop 回调函数 (如果它们存在) ;
  • 如果驱动程序是设备的电源策略所有者,框架将调用其 EvtDeviceArmWakeFromS0、 EvtDeviceArmWakeFromSx 或 EvtDeviceArmWakeFromSxWithReason 回调函数;
  • 如果硬件和驱动程序支持 DMA,框架会调用驱动程序的 EvtDmaEnablerSelfManagedIoStop、 EvtDmaEnablerFlush 和 EvtDmaEnablerDisable 回调 函数 (如果它们存在) 创建的每个 DMA 通道;
  • 框架 调用驱动程序的 EvtDeviceD0ExitPreInterruptsDisabled 回调函数(如果存在) ,然后调用驱动程序的 EvtInterruptDisable 回调函数 (如果存在每个中断) ,以便驱动程序可以禁用设备中断;
  • 框架 调用驱动程序的 EvtDeviceD0Exit 回调函数(如果存在) ;

总线驱动程序是堆栈中最后调用的驱动程序。 当框架调用总线驱动程序的 EvtDeviceD0Exit 回调函数时,回调函数将设备的电源状态 (总线) 的子设备设置为低功耗状态。 框架指定 D3 低功耗状态,除非电源策略所有者指定了不同的低功耗状态。

注意:总线驱动程序用于设置子设备的电源状态的方法特定于总线。 例如,PCI 总线电源管理规范定义 16 位电源管理控制/状态寄存器 (PMCSR) 。 最低两位 (“PowerState”) 都决定设备的当前电源状态,并用于将设备设置为新的电源状态。 pci.sys当 PDO 收到IRP_MN_SET_POWER/D3 时,它会读取 PMCSR,将 PowerState 位更改为 11b (功率级别 D3) ,并写回 PMCSR。

设备回到工作状态

如果发生以下情况之一,处于低功耗状态的设备将返回到其工作状态:

  • 设备检测到外部事件并在其总线上触发唤醒信号。 检测唤醒信号的总线驱动程序调用 WdfDeviceIndicateWakeStatus。 因此,框架调用总线驱动程序的 EvtDeviceDisableWakeAtBus 回调函数;
  • 设备处于空闲状态,驱动程序调用 WdfDeviceStopIdle;
  • 系统的电源状态已从低功率状态更改为其工作 (S0) 状态;

在上述每种情况下,框架都会调用总线驱动程序的 EvtDeviceD0Entry 回调函数,然后将设备 (总线) 的子设备还原到其工作 (D0) 状态。

对于支持设备的每个函数和Filter驱动程序,框架依次执行以下操作,一次一个驱动程序,从驱动程序堆栈中最低的驱动程序开始:

  • 框架调用驱动程序的 EvtDeviceD0Entry 回调函数 (如果它存在于) 。
  • 框架 调用驱动程序的 EvtInterruptEnable 回调函数(如果每个中断存在) ,然后调用驱动程序的 EvtDeviceD0EntryPostInterruptsEnabled 回调函数 (如果它存在) ,则调用该驱动程序的 EvtDeviceD0EntryPostEnabled 回调函数) 。
  • 如果硬件和驱动程序支持 DMA,框架将调用驱动程序的 EvtDmaEnablerFill、 EvtDmaEnablerEnable 和 EvtDmaEnablerSelfManagedIoStart 回调函数 (如果它们对于创建的每个 DMA 通道存在) ;
  • 如果驱动程序是设备的电源策略所有者,框架将调用其 EvtDeviceDisarmWakeFromS0 或 EvtDeviceDisarmWakeFromSx 回调函数';
  • 框架调用驱动程序的 EvtChildListScanForChildren 回调函数 (如果它存在于) ;
  • 框架会重启驱动程序的所有电源托管 I/O 队列,并在必要时 (调用其 EvtIoResume 回调函数) ;
  • 如果驱动程序使用自托管 I/O,框架将调用驱动程序的 EvtDeviceSelfManagedIoRestart 回调函数;
PnP 管理器重新分发系统资源

如果用户将设备添加到系统,并且设备需要 PnP 管理器已分配给另一个设备的系统资源,则 PnP 管理器会尝试重新分配资源。

在此过程中,PnP 管理器会停止设备并将其从工作 (D0) 状态中取出。 然后,它将新资源列表传递给设备,以便它们可以使用新资源重启。

重新分发资源时,如果设备的驱动程序之一具有:PnP 管理器不会更改设备的资源分配:

  • 名为 WdfDeviceSetSpecialFileSupport ,并在设备上打开一个特殊文件;
  • 名为 WdfDeviceSetStaticStopRemove;
  • 提供了一个 EvtDeviceQueryStop 回调函数,并且回调函数已否决了重新分配;
Power-Down序列

对于支持要停止的设备的每个函数和筛选器驱动程序,框架从驱动程序堆栈中最高的驱动程序开始,按顺序一次执行一个驱动程序的以下操作:

  • 如果驱动程序使用自托管 I/O,框架将调用驱动程序的 EvtDeviceSelfManagedIoSuspend 回调函数;
  • 框架停止设备的所有电源托管 I/O 队列;
  • 如果硬件和驱动程序支持 DMA,框架会针对创建的每个 DMA 通道调用驱动程序的 EvtDmaEnablerSelfManagedIoStop、 EvtDmaEnablerFlush 和 EvtDmaEnablerDisable 回调 函数;
  • 调用驱动程序的 EvtDeviceD0ExitPreInterruptsDisabled 和 EvtInterruptDisable 回调函数 (如果它们存在) ,以便驱动程序可以禁用设备中断;
  • 框架调用驱动程序的 EvtDeviceD0Exit 回调函数(如果存在) ;
  • 框架调用驱动程序的 EvtDeviceReleaseHardware 回调函数(如果该函数存在) ,传递 PnP 管理器分配给设备的硬件资源列表;

总线驱动程序是堆栈中最低的驱动程序,最后调用。 当框架调用总线驱动程序的 EvtDeviceD0Exit 回调函数时,它将句柄传递给表示设备的 PDO 的框架设备对象和 WdfPowerDeviceD3Final 的 TargetState 值。 总线驱动程序可以通过调用 WdfDeviceInitSetReleaseHardwareOrderOnFailure 来控制框架何时调用其 EvtDeviceReleaseHardware 回调函数。

Power-Up序列

第一个调用的驱动程序是总线驱动程序。 当框架调用总线驱动程序的 EvtDeviceD0Entry 回调函数时,回调函数会将设备 (总线) 的子设备还原到其工作 (D0) 状态。

对于支持该设备的每个函数和筛选器驱动程序,框架按顺序一次执行一个驱动程序,从驱动程序堆栈中最低的驱动程序开始:

  • 框架调用驱动程序的 EvtDevicePrepareHardware 回调函数(如果存在) ,并将 PnP 管理器分配给设备的硬件资源列表传递;
  • 框架调用驱动程序的 EvtDeviceD0Entry 回调函数 (如果存在) ;
  • 框架调用驱动程序的 EvtInterruptEnable 和 EvtDeviceD0EntryPostInterruptsEnabled 回调函数 (如果它们存在) ,以便驱动程序可以启用设备中断;
  • 如果硬件和驱动程序支持 DMA,框架会针对创建的每个 DMA 通道调用驱动程序的 EvtDmaEnablerFill、 EvtDmaEnablerEnable 和 EvtDmaEnablerSelfManagedIoStart 回调函数;
  • 框架调用驱动程序的 EvtChildListScanForChildren 回调函数 (如果存在) ;
  • 框架重启设备的所有电源托管 I/O 队列;
  • 如果驱动程序使用自我管理的 I/O,框架将调用驱动程序的 EvtDeviceSelfManagedIoRestart 回调函数;

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

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

相关文章

达梦8 网络中断对系统的影响

测试环境:三节点实时主从 版本:--03134283938-20221019-172201-20018 测试1 系统没有启动确认监视器 关闭节点3网卡 登录节点1检查主库状态 显示向节点2发送归档成功,但无法收到节点3的消息,节点1挂起 日志报错如下&#xf…

易于上手的requests

Python中的requests库主要用于发送HTTP请求并获取响应结果。在现代网络编程中,HTTP请求是构建客户端与服务器之间通信的基础。Python作为一种高级编程语言,其丰富的库支持使得它在网络数据处理领域尤为突出。其中,requests库以其简洁、易用的…

力扣560. 和为 K 的子数组

Problem: 560. 和为 K 的子数组 文章目录 题目描述思路复杂度Code 题目描述 思路 1.初始化一个哈希表preSum,用于记录前缀和及其出现次数,ans记录和为k的子数组数量、sum_i记录当前前缀和; 2.将前缀和为 0 的情况存入哈希表,表示前缀和为 0 出…

【Python】认识 Python

一、计算机基础概念 1、什么是计算机 很多老一辈的人,管下面这个叫做计算机。然而,它只是 “计算器”,和计算机是有很大区别的。 现在我们所说的计算机,不光能进行算术运算,还能进行逻辑判断、数据存储、网络通信等…

遇到no module named ‘pyLDAvis.sklearn‘的解决办法

在NLP学习中,常常用到LDA主题模型对文本进行分类,可视化经常用到的代码有 import pyLDAvis import pyLDAvis.sklearnpanel pyLDAvis.sklearn.prepare(lda, tf_idf, tf_idf_vectorizer) pyLDAvis.save_html(panel, lda_visualization.html) pyLDAvis.di…

HTML静态网页成品作业(HTML+CSS)—— 节日母亲节介绍网页(5个页面)

🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有5个页面。 二、作品演示 三、代…

骑砍2霸主MOD开发(12)-游戏实例GameEntity

一.GameEntity游戏实例 <1.通用GameEntity,梯子,椅子,攻城云梯,战车等定义为GameEntity,一个GameEntity由若干GameEntityComponets组成,例如攻城云梯的轮子是一个独立Component,支架是一个独立Component, GameEntity GameEntityComponent1 GameEntityComponent2 GameEntit…

前端开发之WebSocket通信

WebSocket WebSocket是一种在单个TCP连接上进行全双工通信&#xff08;双向同时通信&#xff09;的协议&#xff0c;它允许服务器和客户端之间自由地交换数据&#xff0c;无需反复建立连接。其特点包括&#xff1a; 双向通信&#xff1a;实时性强&#xff0c;支持服务器向客户…

移动端前端开发遇到过的Andorid和IOS的差异记录

移动端前端开发遇到过的安卓和苹果的差异记录 1. 引入外部资源&#xff0c;最好用https2. IOS时间戳获取NaN问题3. 金额三位分节显示方式4. .webp图片支持问题 1. 引入外部资源&#xff0c;最好用https ios处于安全性的考虑&#xff0c;不大支持http引入外部资源&#xff0c;所…

【kubernetes】探索k8s集群的配置资源(secret和configma)

目录 一、Secret 1.1Secret 有四种类型 1.2Pod 有 3 种方式来使用 secret 1.3应用场景&#xff1a;凭据 1.4创建 Secret 1.4.1用kubectl create secret命令创建Secret 1.4.2内容用 base64 编码&#xff0c;创建Secret 1.4.2.1Base64编码 1.4.2.2创建YAML文件 1.4.2.3…

《计算机网络》

计算题【33】 题目:假设一个有噪声信道的带宽为3KHz,信噪比为30dB,则该信道的最大数据传输速率是多少? C = W log2(1+S/N)(bit/s)=3000Hz* log2(1+30)= 29.9kbps 题目:一个网络中,设定的IP地址范围是:172.88.32.1至172.88.32.254,试确定其合适的子网掩码。 分析第…

「前端+鸿蒙」鸿蒙应用开发预览模拟器运行

在鸿蒙应用开发中&#xff0c;预览和模拟器运行是开发流程中的重要环节&#xff0c;它们允许开发者在不使用实体设备的情况下测试应用的界面和功能。以下是如何使用华为DevEco Studio进行预览和在模拟器上运行鸿蒙应用的详细步骤&#xff0c;以及相应的示例代码。 快速体验-预览…

277 基于MATLAB GUI火灾检测系统

基于MATLAB GUI火灾检测系统&#xff0c;可以实现图片和视频的火苗检测。火焰识别的三个特征&#xff1a;1个颜色特征&#xff0c;2个几何特征颜色特征&#xff1a;HSV颜色空间下&#xff0c;对三个通道值进行阈值滤波&#xff0c;几何特征1&#xff1a;长宽比&#xff0c;几何…

用 Python 撸一个 Web 服务器-第3章:使用 MVC 构建程序

Todo List 程序介绍 我们将要编写的 Todo List 程序包含四个页面&#xff0c;分别是注册页面、登录页面、首页、编辑页面。以下分别为四个页面的截图。 注册页面&#xff1a; 注册 登录页面&#xff1a; 登录 首页&#xff1a; 首页 编辑页面&#xff1a; 编辑 程序页面非…

程序员搞副业一些会用到的工具

微信号采集(爬虫)技术的选型 那么&#xff0c;我们应该使用什么技术来从庞大的网页内容中自动筛选和提取微信号呢&#xff1f;答案就是&#xff1a;数据采集技术&#xff0c;也就是爬虫技术。 然而&#xff0c;数据采集技术种类繁多&#xff0c;我们具体应该采用哪一个呢&…

【Linux】—— 线程控制的基本介绍

目录 &#xff08;一&#xff09;POSIX线程库 &#xff08;二&#xff09;创建线程 2.1 线程ID及进程地址空间布局 &#xff08;三&#xff09;线程终止 &#xff08;四&#xff09;分离线程 &#xff08;一&#xff09;POSIX线程库 POSIX线程库&#xff08;POSIX Thread…

Node.js后端构建指南:MongoDB与Express的集成

安装express 安装 Express 并将其保存到依赖列表中&#xff1a; $ cnpm install express --save 以上命令会将 Express 框架安装在当前目录的 node_modules 目录中&#xff0c; node_modules 目录下会自动创建 express 目录。以下几个重要的模块是需要与 express 框架一起安…

nss刷题(4)

1、[SWPUCTF 2021 新生赛]easyrce <?php error_reporting(0); highlight_file(__FILE__); if(isset($_GET[url])) { eval($_GET[url]); } ?> if(isset($_GET[url])) isset函数用来检测url变量是否存在&#xff1b;$_GET函数获取变量数据 eval($_GET[url]); eval函数用…

【GIS矢量切片】tippecanoe在Windows和CentOS中的安装

组件安装记录 背景介绍Windows下安装1、下载工具2、存放安装包3、进入DOS终端4、在终端执行命令5、下载程序6、放置源码7、修改配置信息8、编译9、测试10、参数说明瓦片输出瓦片描述和权属信息输入文件和图层名输入文件的并行处理输入文件的投影缩放级别瓦片分辨率CentOS 7安装…

尝试用 GPT-4o 写 2024高考语文作文

文章目录 新课标I卷科技进步与问题的演变 新课标II卷抵达未知之境&#xff1a;探索与成长的旅程 全国甲卷坦诚交流&#xff1a;构建真正相遇的桥梁 北京卷历久弥新 天津卷定义与自定义&#xff1a;在世界的缤纷中前行 上海卷认可度的思考与反思 新课标I卷 阅读下面的材料&#…