windows USB 设备驱动开发-开发Type C接口的驱动程序(三)

news2024/11/26 14:51:14
 编写 USB Type C 端口控制器驱动程序

如果 USB Type-C 硬件实现 USB Type-C 或电源传送 (PD) 物理层,但未实现供电所需的状态机,则需要编写 USB Type-C 端口控制器驱动程序。

在 Windows 10 版本 1703 中,USB Type-C 体系结构已得到改进,以支持实现 USB Type-C 或电源交付  物理层,但没有相应的 PD 策略引擎或协议层实现的硬件设计。 对于这些设计,Windows 10版本 1703 通过名为“USB 连接器管理器Type-C 端口控制器接口类扩展”的新类扩展 (UcmTcpciCx) 提供基于软件的 PD 策略引擎和设备策略管理器。 由 IHV 或 OEM/ODM 编写的客户端驱动程序与 UcmTcpciCx 通信,以提供有关 UcmTcpciCx 中 PD 策略引擎和设备策略管理器正常运行所需的硬件事件的信息。 

UcmTcpciCx 类扩展本身是 UcmCx 的客户端驱动程序。 有关电力合同、数据角色的策略决策在 UcmCx 中做出,并转发到 UcmTcpciCx。 UcmTcpciCx 使用 UcmTcpciCx 客户端驱动程序提供的端口控制器接口实现这些策略并管理 Type-C 和 PD 状态机。

准备阶段
  • 根据硬件还是固件实现 PD 状态机确定需要写入的驱动程序类型;
  • 在目标计算机上安装 (家庭版、专业版、企业版和教育版) 桌面版的Windows 10,或使用 USB Type-C 连接器Windows 10 移动版;
  • 在开发 计算机上安装最新的 Windows 驱动程序工具包 (WDK) 。 该工具包具有用于编写客户端驱动程序所需的头文件和库,具体而言,你需要:库 (UcmTcpciCxStub.lib) 。 库转换客户端驱动程序发出的调用,并将其传递到类扩展;头文件 UcmTcpciCx.h;

客户端驱动程序在内核模式下运行,并绑定到 KMDF 1.15 库。

  • 确定客户端驱动程序是否支持警报;
  • 端口控制器不需要符合 TCPCI。 接口捕获任何 Type-C 端口控制器的功能。 为不符合 TCPCI 的硬件编写 UcmTcpciCx 客户端驱动程序涉及将 TCPCI 规范中的寄存器和命令的含义映射到硬件的含义;
  • 大多数 TCPCI 控制器都连接了 I 2C。 客户端驱动程序使用串行外围总线 (SPB) 连接资源和中断线路来与硬件通信。 驱动程序使用 SPB 框架扩展 (SpbCx) 编程接口;
UcmTcpci 类扩展的行为
  • 作为状态机执行的一部分,UcmTcpciCx 将 IOCTL 请求发送到端口控制器。 例如,在 PD 消息传送中,它会发送IOCTL_UCMTCPCI_PORT_CONTROLLER_SET_TRANSMIT_BUFFER请求来设置传输缓冲区。 该请求 (TRANSMIT_BUFFER) 将移交给客户端驱动程序。 然后,驱动程序使用类扩展提供的详细信息设置传输缓冲区;
  • UcmTcpciCx 实现有关电力合同、数据角色等的策略;
客户端驱动程序的预期行为

UcmTcpciCx 的客户端驱动程序应:

  • 成为电源策略所有者。 UcmTcpciCx 不参与端口控制器的电源管理;
  • 将从 UcmTcpciCx 接收的请求转换为硬件读取或写入命令。 命令必须是异步的,因为 DPM 无法阻止等待硬件传输完成;
  • 提供包含框架请求对象的框架队列对象。 对于 UcmTcpci 类扩展要发送到客户端驱动程序的每个请求,扩展会在驱动程序的队列对象中添加一个请求对象。 驱动程序处理完请求后,将调用 WdfRequestComplete。 客户端驱动程序负责及时完成请求;
  • 发现并报告端口控制器的功能。 这些功能包括端口控制器可以在 中运行的角色等信息,例如仅限源、仅限接收器、DRP。 但是,连接器的其他功能和整个系统的注释,DPM 需要知道才能正确实现 USB Type-C 和 PD 策略。 例如,DPM 需要知道系统/连接器的源功能才能将其播发到端口伙伴;
功能存储

除了与客户端驱动程序相关的功能外,其他信息还来自称为 “功能存储”的系统全局位置。 此系统全局功能存储存储在 ACPI 中。 它是对系统及其每个 USB Type-C 连接器的功能的静态说明,DPM 使用这些连接器来确定要实现的策略。

通过将系统功能的说明与端口控制器的客户端驱动程序分离,该设计允许在功能不同的不同系统上使用驱动程序。 UcmCx(而不是 UcmTcpciCx)与功能存储接口。 UcmTcpciCx (或其客户端驱动程序) 不与功能存储交互。

如果适用,功能存储中的信息将替代直接来自端口控制器客户端驱动程序的信息。 例如,端口控制器能够仅执行接收器操作,客户端驱动程序会报告该信息。 但是,系统其余部分可能未正确配置为仅接收器操作。 在这种情况下,系统制造商可以报告连接器能够在功能存储中执行仅限源的操作。 功能存储中的设置优先于驱动程序报告的信息:

  • 使用与警报相关的所有相关数据通知 UcmTcpciCx;
  • 可选。 在进入/退出备用模式后执行一些额外的处理。 类扩展通过 IOCTL 请求通知驱动程序有关这些状态的信息;
向 UcmTcpciCx 注册客户端驱动程序

1.在EVT_WDF_DRIVER_DEVICE_ADD实现中,调用 UcmTcpciDeviceInitInitialize 以初始化WDFDEVICE_INIT不透明结构。 调用将客户端驱动程序与框架相关联;

2.(WDFDEVICE) 创建框架设备对象后,调用 UcmTcpciDeviceInitialize 以向 UcmTcpciCx 注册客户端 diver;

初始化到端口控制器硬件的 I2C 通信通道

在EVT_WDF_DEVICE_PREPARE_HARDWARE实现中,读取硬件资源以打开信道。 这是检索 PD 功能并获取有关警报的通知所必需的。

大多数 TCPCI 控制器都连接了 I 2C。 在参考示例中,客户端驱动程序使用 SPB 框架扩展 (SpbCx) 编程接口打开 I2 通道。

客户端驱动程序通过调用 WdfCmResourceListGetDescriptor 枚举硬件资源。

警报作为中断接收。 因此,驱动程序会创建一个框架中断对象,并注册处理警报的 ISR。 ISR 执行硬件读取和写入操作,这些操作会阻止,直到硬件访问完成。 由于在 DIRQL 中无法接受等待,因此驱动程序在 PASSIVE_LEVEL 执行 ISR。

初始化端口控制器的 Type-C 和 PD 功能

在EVT_WDF_DEVICE_D0_EXIT实现中,

  1. 与端口控制器硬件通信,并通过读取各种寄存器来检索设备标识和功能;
  2. 使用检索到的信息初始化UCMTCPCI_PORT_CONTROLLER_IDENTIFICATION和UCMTCPCI_PORT_CONTROLLER_CAPABILITIES;
  3. 通过将初始化的结构传递给UCMTCPCI_PORT_CONTROLLER_CONFIG_INIT,使用上述信息初始化UCMTCPCI_PORT_CONTROLLER_CONFIG结构;
  4. 调用 UcmTcpciPortControllerCreate 以创建端口控制器对象并检索 UCMTCPCIPORTCONTROLLER 句柄;
设置框架队列对象以接收来自 UcmTcpciCx 的请求
  • 在EVT_WDF_DEVICE_D0_EXIT实现中,通过调用 WdfIoQueueCreate 创建框架队列对象。 在该调用中,需要注册回调实现,以处理 UcmTpciCx 发送的 IOCTL 请求。 客户端驱动程序可以使用电源管理的队列。在执行 Type-C 和 PD 状态机期间,UcmTpciCx 会向客户端驱动程序发送命令以执行。 UcmTcpciCx 保证在任何给定时间最多有一个未完成的端口控制器请求;
  • 调用 UcmTcpciPortControllerSetHardwareRequestQueue 以向 UcmTpciCx 注册新的框架队列对象。 调用成功后,当需要驱动程序的操作时,UcmTcpciCx 会将框架队列对象 (WDFREQUEST) 在此队列中;
  • 实现 EvtIoDeviceControl 回调函数来处理这些 IOCTL;

  • 调用 UcmTcpciPortControllerStart 以指示 UcmTcpciCx 启动端口控制器。 UcmTcpciCx 假定控制 USB Type-C 和电源传送。 启动端口控制器后,UcmTcpciCx 可能会开始将请求放入硬件请求队列;
处理来自端口控制器硬件的警报

客户端驱动程序必须处理从端口控制器硬件收到的警报 (或事件) ,并使用与事件相关的数据将它们发送到 UcmTcpciCx。

发生硬件警报时,端口控制器硬件会将 ALERT 引脚推高。 这会导致调用在步骤 2中注册的客户端驱动程序的 ISR 。 例程在PASSIVE_LEVEL为硬件中断提供服务。 例程确定中断是否是来自端口控制器硬件的警报;如果是这样,它将完成警报的处理,并通过调用 UcmTcpciPortControllerAlert 通知 UcmTcpciCx。

在调用 UcmTcpciPortControllerAlert 之前,客户端负责在UCMTCPCI_PORT_CONTROLLER_ALERT_DATA结构中包含与警报相关的所有相关数据。 客户端提供所有处于活动状态的警报的数组,因为硬件可能会同时断言多个警报。

下面是在抄送状态中报告更改的任务流示例:

  • 客户端收到硬件警报;
  • 客户端读取 ALERT 寄存器并确定处于活动状态的警报类型;
  • 客户端读取 CC STATUS 寄存器,并在 UCMTCPCI_PORT_CONTROLLER_ALERT_DATA 中描述抄送状态寄存器的内容。 驱动程序将 AlertType 成员设置为 UcmTcpciPortControllerAlertCCStatus 和 register 的 CCStatus 成员;
  • 客户端调用 UcmPortControllerAlert 将阵列硬件警报发送到 UcmTcpciCx;
  • 客户端清除警报 (在客户端检索警报信息后随时可能发生这种情况);
处理从 UcmTcpciCx 接收的请求

作为状态机执行的一部分,UcmTcpciCx 需要将请求发送到端口控制器。 例如,它需要设置TRANSMIT_BUFFER。 此请求将移交给客户端驱动程序。 驱动程序使用 UcmTcpciCx 提供的详细信息设置传输缓冲区。 其中大多数请求转换为客户端驱动程序读取或写入的硬件。 命令必须是异步的,因为 DPM 无法阻止等待硬件传输完成。

UcmTcpciCx 将命令作为 I/O 控制代码发送,描述客户端驱动程序所需的 get/set 操作。 在客户端驱动程序的队列设置中,驱动程序向 UcmTcpciCx 注册了其队列。 UcmTcpciCx 开始将框架请求对象放置在它需要从驱动程序进行操作的队列中。 I/O 控制代码列在步骤 4 的表中。

客户端驱动程序负责及时完成请求。客户端驱动程序在完成请求的操作后,对具有完成状态的框架请求对象调用 WdfRequestComplete。

客户端驱动程序可能需要向另一个驱动程序发送 I/O 请求才能执行硬件操作。 例如,在示例中,驱动程序将 SPB 请求发送到连接 I2C 的端口控制器。 在这种情况下,驱动程序无法转发从 UcmTcpciCx 收到的框架请求对象,因为请求对象在 WDM IRP 中可能没有正确数量的堆栈位置。 客户端驱动程序必须创建另一个框架请求对象,并将其转发到另一个驱动程序。 客户端驱动程序可以在初始化期间预先分配所需的请求对象,而不是在每次从 UcmTcpciCx 获取请求时创建一个请求对象。 这是可能的,因为 UcmTcpciCx 保证在任何给定时间只有一个未完成的请求。

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

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

相关文章

云监控(华为) | 实训学习day5(10)

Gaussdb安装和连接idea GaussDB的安装 首先关闭防火墙 systemctl disable firewalld.service 永久关闭防火墙(发生在下次启动) systemctl stop firewalld.service 关闭本次防火墙 查看防火墙状态systemctl status firewalld.service 查询的状态是Dead表…

【算法】百钱买百鸡问题算法详解及多语言实现

问题描述 百钱买百鸡问题是一个经典的数学问题,题目要求用100文钱买100只鸡,公鸡5文钱一只,母鸡3文钱一只,小鸡3只一文钱,问公鸡、母鸡、小鸡各买多少只? 目录 问题描述​编辑 解决方案 Python实现 Ja…

选择Maya进行3D动画制作与渲染的理由

如果你对3D动画充满热情并追求成为专业3D动画师的梦想,你一定听说过Maya——近年来3D动画的行业标准。Maya被3D艺术家广泛使用,你是否想知道为什么Maya总是他们的首选?下面一起来了解下。 一、什么是Maya? 由Autodesk开发的Maya是…

wxid转微信号

7.21由于微信的再一次调整,能够转出微信号的接口已经和谐,根据客户要求琢磨了几个小时 发现新的接口也是可以批量转换的

springcolud学习06Hystrix

Hystrix Hystrix是Netflix开发的一个用于处理分布式系统中延迟和容错问题的库。它主要用于防止分布式系统中的雪崩效应,通过在服务之间添加延迟容错和故障处理机制来增强系统的弹性。 服务熔断 类似于电路中的断路器,当失败率超过阈值时,Hystrix 可以自动地开启断路器,停…

c++习题12-开关灯

目录 一,题目 二,思路 三,代码 一,题目 用例输入 1 10 10 用例输出 1 1,4,9 二,思路 创建可以存放路灯亮灭情况的数组,路灯的编号从1开始,因此在使用for循环去初始化数组时&#xff…

初识模板【C++】

P. S.:以下代码均在VS2022环境下测试,不代表所有编译器均可通过。 P. S.:测试代码均未展示头文件stdio.h的声明,使用时请自行添加。 博主主页:LiUEEEEE                        …

编写小程序用什么软件

编写小程序时,可以使用多种软件或工具,这些工具通常提供了丰富的开发功能和组件,方便开发者进行小程序的创建、开发和调试。以下是一些常用的编写小程序的软件和工具: DIY官网可视化工具 可视化拖拽开发神器|无须编程 零代码基础…

HashMap原理详解,HashMap源码解析

HashMap是一个数组链表和红黑树的结合体 HashMap的第一层表现是数组,HashMap默认创建一个长度为十六的数组来储存数据,但不同的是,它并非是先放在第0个索引,然后第一个索引那么放置,而是通过key获取对应的32位hash值&a…

OAuth2.0 or Spring Session or 单点登录流程

1.社交登录 2.微博社交登录 第三方登录 1.登录微博 2.点击网站接入 3.填写完信息,到这里,写入成功回调 和 失败回调 是重定向,所以可以写本地的地址 3.认证 分布式Session spring-session 域名不一样 发的 jSessionId 就不同&#xff0c…

uniapp,vue3上传图片组件封装

首先创建一个 components 文件在里面进行组件的创建 下面是 vip组件的封装 也就是图片上传组件 只是我的命名是随便起的 <template><!--图片 --><view class"up-page"><!--图片--><view class"show-box" v-for"(item,ind…

STM32的串口(RS485)数据收发

一、前言 我们的单片机串口一般常用RS232、RS485、TTL这几种通讯方式&#xff0c;日常调试可能RS232、TTL比较多&#xff0c;真正和其它厂家数据交互的时候&#xff0c;还是RS485用的比较多&#xff0c;因为它是差分信号等电气属性&#xff0c;所以比较稳定&#xff0c;传输距…

Matlab演示三维坐标系旋转

function showTwo3DCoordinateSystemsWithAngleDifference() clear all close all % 第一个三维坐标系 origin1 [0 0 0]; x_axis1 [1 0 0]; y_axis1 [0 1 0]; z_axis1 [0 0 1];% 绕 x 轴旋转 30 度的旋转矩阵 theta_x 30 * pi / 180; rotation_matrix_x [1 0 0; 0 cos(th…

SpringBoot使用本地缓存——Caffeine

SpringBoot使用本地缓存——Caffeine 缓存&#xff0c;想必大家都用过&#xff0c;将常用的数据存储在缓存上能在一定程度上提升数据存取的速度。这正是局部性原理的应用。之前用的缓存大多是分布式的&#xff0c;比如Redis。使用Redis作为缓存虽然是大多数系统的选择&#xf…

基于重要抽样的主动学习不平衡分类方法ALIS

这篇论文讨论了数据分布不平衡对分类器性能造成的影响,并提出了一种新的有效解决方案 - 主动学习框架ALIS。 1、数据分布不平衡会影响分类器的学习性能。现有的方法主要集中在过采样少数类或欠采样多数类,但往往只采用单一的采样技术,无法有效解决严重的类别不平衡问题。 2、论…

【Datawhale AI 夏令营】CV图像竞赛——Deepfake攻防

【Datawhale AI 夏令营】CV图像竞赛——Deepfake攻防 从零入门CV图像竞赛(Deepfake攻防) 是 Datawhale 2024 年 AI 夏令营第二期 的学习活动&#xff08;“CV图像”方向&#xff09;&#xff0c;基于蚂蚁集团举办的“外滩大会-全球Deepfake攻防挑战赛”开展的实践学习 ​ 这几天…

Mysql深入讲解(索引、事务、锁机制)

一、MySQL索引 1、何为索引&#xff1f; MySQL中的索引是一种数据结构&#xff0c;用于加快对数据库表中数据的查询速度【查询速度提升】。它类似于书本目录&#xff0c;使得用户可以根据特定字段快速定位到所需的数据行&#xff0c;而无需扫描整个表。 2、索引分类 Hash索…

C 语言回调函数

回调函数的概念 您的理解是正确的。pFunCallBack 是一种函数指针类型&#xff0c;它定义了函数的签名&#xff08;即函数的参数类型和返回类型&#xff09;。当我们说 pFunCallBack pFun&#xff0c;我们是在声明一个变量 pFun&#xff0c;其类型是 pFunCallBack —— 即一个函…

【D3.js in Action 3 精译_018】2.4 向选择集添加元素

当前内容所在位置 第一部分 D3.js 基础知识 第一章 D3.js 简介&#xff08;已完结&#xff09; 1.1 何为 D3.js&#xff1f;1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践&#xff08;上&#xff09;1.3 数据可视化最佳实践&#xff08;下&#xff09;1.4 本章小结 第二章…

RNN循环递归网络讲解与不掉包python实现

1.算法简介 参考论文&#xff1a;Elman J L. Finding structure in time[J]. Cognitive science, 1990, 14(2): 179-211.&#xff0c;谷歌被引次数超16000! 说到循环递归结构就不得不提到其鼻祖RNN网络。首先我们先对RNN有个初步的概念&#xff1a;想象一下&#xff0c;你正在…