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

 编写 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.mzph.cn/bicheng/48613.shtml

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

相关文章

pytorch学习(十)优化函数

优化函数主要有,SGD, Adam,RMSProp这三种,并且有lr学习率,momentum动量,betas等参数需要设置。 通过这篇文章,可以学到pytorch中的优化函数的使用。 1.代码 代码参考《python深度学习-基于pytorch》&…

Java里的引用详解

1.体验方法引用 方法引用的出现原因 在使用Lambda表达式的时候,我们实际上传递进去的代码就是一种解决方案:拿参数做操作 那么考虑一种情况:如果我们在Lambda中所指定的操作方案,已经有地方存在相同方案,那是否还有必要…

2024最新教程,在docker中安装kali,并配置ssh连接

docker的基本使用:搭建高效攻防靶场vulfocus与Docker仓库管理实战:从听说到入门 拉取kali官方镜像 docker pull kalilinux/kali-rolling 启动一个kali镜像,将容器中的22端口映射到主机100端口,方便ssh直接连接 docker run -it…

Java 集合框架:Java 中的优先级队列 PriorityQueue 的实现

大家好,我是栗筝i,这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 018 篇文章,在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验,并希望进…

用不同的url头利用Python访问一个网站,把返回的东西保存为txt文件

这个需要调用requests模块(相当于c的头文件) import requests 还需要一个User-Agent头(这个意思就是告诉python用的什么系统和浏览器) Google Chrome(Windows): Mozilla/5.0 (Windows NT 10.0; Win64; x64…

【Git命令】git rebase之合并提交记录

使用场景 在本地提交了两个commit,但是发现根本没有没必要分为两次,需要想办法把两次提交合并成一个提交;这个时候可以使用如下命令启动交互式变基会话: git rebase -i HEAD~N这里 N 是你想要重新调整的最近的提交数。 如下在本地…

vscode配置django环境并创建django项目(全图文操作)

文章目录 创建项目工作路径下载python插件:创建虚拟环境选择虚拟环境在虚拟环境中安装Django创建Django项目 创建项目工作路径 下载python插件: 创建虚拟环境 >python:create 于是会多出一个.venv的目录 选择虚拟环境 在虚拟环境中安装Django …

MySQL 数据库 day 7.16

ok了家人们今天继续记录一下数据库,看看今天学了什么。 一.事物概述 1.1 环境准备 -- 账户表 create table account( id int primary key auto_increment, name varchar(20), money double );insert into account values (null,张三,1000); insert into account values (n…

解决Linux桌面初始化问题

问题 启动vnc桌面,提示问题 定位 从[t]csh手册 可以看到,其初始化流程 经定位,是.cshrc的这段代码存在,导致桌面初始化异常。 [wanlin.wangicinfra-cn-172-16-0-115 ~]$ cat .cshrc ...部分省略... # Environment for anac…

Unity UGUI 之 Canvas Scaler

本文仅作学习笔记与交流,不作任何商业用途 本文包括但不限于unity官方手册,唐老狮,麦扣教程知识,引用会标记,如有不足还请斧正 1.什么是Canvas Scaler Unity - 手册:Canvas Scaler 重点:虽然叫…

【springboot】中使用--WebMvcConfigurer

WebMvcConfigurer 一、页面跳转控制器step1:创建视图,resources/templates/index.htmlstep2:创建SpringMVC配置类step3:测试功能 二、数据格式化step1:创建 DeviceInfo 数据类step2:自定义 Formatterstep3: 登记自定义的 DeviceFormatterstep4: 新建 Con…

Flutter中GetX的用法(超详细使用指南之路由依赖管理篇)

目录 1.前言 2.GetX 依赖管理概述 1.GetX 依赖管理的基本概念 2.与其他依赖管理工具的比较 3. 基础依赖注入 1.Get.put 2.Get.lazyPut 3.Get.putAsync 4.高级依赖注入 1.使用Get.create 2.依赖生命周期管理 5. 参考资料 1.前言 今天这篇博客主要介绍Getx的三大功能…

java基于ssm+vue 药品网购平台

1用户前台功能模块 1.1前台首页 前台首页详情页面:首页、药品信息、疫情常识、保健品推荐、个人中心、后台管理、购物车等操作。程序效果图如下图1所示: 前台页面等内容,如图1所示。 1.2个人中心 在前台页面查看个人中心用户注册、登录&am…

【proteus经典实战】LCD滚动显示汉字

一、简介 Proteus是一款功能丰富的电子设计和仿真软件,它允许用户设计电路图、进行PCB布局,并在虚拟环境中测试电路功能。这款软件广泛应用于教育和产品原型设计,特别适合于快速原型制作和电路设计教育。Proteus的3D可视化功能使得设计更加直…

多任务高斯过程数学原理和Pytorch实现示例

高斯过程其在回归任务中的应用我们都很熟悉了,但是我们一般介绍的都是针对单个任务的,也就是单个输出。本文我们将讨论扩展到多任务gp,强调它们的好处和实际实现。 本文将介绍如何通过共区域化的内在模型(ICM)和共区域化的线性模型(LMC)&…

【Linux知识点汇总】07 Linux系统防火墙相关命令,关闭和开启防火墙、开放端口号

​完整系列文章目录 【Linux知识点汇总】 心血来潮突然想起之前写过的系列文章【Linux知识点汇总】还未完结,那么今天就继续吧 说明:这个系列的内容,在系列【Linux服务器Java环境搭建】中会经常用到,大家可以自行查找相关命令 一、…

Docker搭建本地私有仓库

目录 1.下载运行registry 镜像 2.添加私有镜像仓库地址 3.为镜像添加标签 4.上传到私有仓库 5.查看私有仓库的所有镜像 6.测试私有仓库下载 1.下载运行registry 镜像 docker pull registry docker run -d -v /data/registry:/var/lib/registry -p 5000:5000 --restartal…

PostgreSQL使用(二)——插入、更新、删除数据

说明:本文介绍PostgreSQL的DML语言; 插入数据 -- 1.全字段插入,字段名可以省略 insert into tb_student values (1, 张三, 1990-01-01, 88.88);-- 2.部分字段插入,字段名必须写全 insert into tb_student (id, name) values (2,…

vue3【详解】跨组件通信 -- 依赖注入 provide inject

用于解决跨组件&#xff08;父组件与所有后代&#xff09;数据通信 提供数据 provide 传出数据的组件 &#xff08;通常为父辈组件&#xff09;提供数据 <script setup> import { provide } from vueprovide(/* 注入名 */ message, /* 值 */ hello!) </script>pro…

pycharm中运行.sh文件

最近在跑一个项目代码&#xff0c;里面要运行.sh文件。于是配置了下如何在pycharm中正常运行.sh文件。 首先安装好git&#xff0c;然后 File—>Settings—>Tools—>Terminal—>Shell path&#xff0c;将cmd.exe改成刚刚下载的git的路径&#xff0c;注意选择的是s…