NFC CX 快速入门指南 - Windows drivers (2024)

通过

  • 项目

本指南演示如何使用 NFC 类扩展 (NFC CX) 驱动程序编写 NFC 功能驱动程序。

注意

在其实现中使用类扩展驱动程序的驱动程序称为“客户端驱动程序”。 也就是说,类扩展驱动程序的客户端。

先决条件

  • NFC 控制器的固件必须实现 NFC 论坛的 NFC 控制器接口 (NCI) 协议。
  • Visual Studio 2017 (或更高版本) 。
  • Windows SDK
  • Windows 驱动程序工具包 (WDK)

客户端驱动程序职责

NFC CX 驱动程序负责处理发送到驱动程序的 I/O 请求并创建相关的 NCI 命令数据包。 客户端驱动程序负责将这些 NCI 数据包发送到 NFC 控制器,并将 NCI 响应数据包发回 NFC CX 驱动程序。

由客户端驱动程序决定如何将 NCI 数据包发送到 NFC 控制器。 此过程因使用的硬件总线类型而异。 NFC 控制器使用的常见总线包括 I2C、SPI 和 USB。

完整的项目代码

GitHub 上提供了此示例代码的完整版本: NFC CX 客户端驱动程序示例

项目设置

  1. 在 Visual Studio 中,创建新的“用户模式驱动程序,空 (UMDF V2) ”项目。

    “文件” 菜单上,指向 “新建”,然后选择 “项目”。 在 Visual C++ 节点的 “Windows 驱动程序”下,选择“ WDF”,然后选择“ 用户模式驱动程序”、“空 (UMDF V2)

    NFC CX 快速入门指南 - Windows drivers (1)

  2. 打开 INF 文件。

    解决方案资源管理器,在“驱动程序文件”文件夹中的<“project-name>”节点下,双击“<project-name.inf>”。

  3. 在 INF 文件中,使用以下步骤删除自定义设备类:

    1. 删除以下两个部分:

      [ClassInstall32]AddReg=SampleClass_RegistryAdd[SampleClass_RegistryAdd]HKR,,,,%ClassName%HKR,,Icon,,"-10"
    2. [Strings] 部分下,删除以下行。

      ClassName="Samples" ; TODO: edit ClassName
  4. 在 INF 文件中,将驱动程序的设备类设置为 邻近感应

    1. 将 的值 Class 更改为 Proximity
    2. 将 的值 ClassGuid 更改为 {5630831C-06C9-4856-B327-F5D32586E060}
      • 这是邻近感应设备类的 GUID。
    [Version]...Class=ProximityClassGuid={5630831C-06C9-4856-B327-F5D32586E060} ; Proximity class GUID...
  5. 在 INF 文件中,添加对 NFC 类扩展的引用。 这样做可确保 Windows 驱动程序框架 (WDF) 客户端驱动程序加载时加载 NFC CX 驱动程序。

    1. 找到 <project-name>_Install 节。
    2. 添加 UmdfExtensions=NfcCx0102
    [<project-name>_Install]...UmdfExtensions=NfcCx0102
  6. 在驱动程序生成设置中,链接到 NFC 类扩展。 这样做可确保 NFC CX API 在代码编译期间可用。

    1. 在“解决方案资源管理器” 中,右键单击项目,然后选择“属性” 。 在“配置属性”中的“驱动程序设置”下,选择“NFC”。
    2. 确保 “配置” 设置为 All Configurations
    3. 确保 将“平台 ”设置为 All Platforms
    4. “NFC 类扩展的链接 ”设置为 Yes

    NFC CX 快速入门指南 - Windows drivers (2)

  7. 将名为 Driver.cpp 的文件添加到项目。

  8. DriverEntry在 中创建Driver.cpp例程。 这是驱动程序的入口点。 它的主要用途是初始化 WDF 并注册 EvtDriverDeviceAdd 回调函数。

    #include <windows.h>#include <wdf.h>#include "Device.h" // created in Step 9// The entry point for the driver.extern "C" NTSTATUS DriverEntry( _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath ){ NTSTATUS status = STATUS_SUCCESS; // Specify `DeviceContext::AddDevice` as the // `EvtDriverDeviceAdd` function for the driver. WDF_DRIVER_CONFIG driverConfig; WDF_DRIVER_CONFIG_INIT(&driverConfig, DeviceContext::AddDevice); // Initialize WDF. status = WdfDriverCreate( DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &driverConfig, WDF_NO_HANDLE); if (!NT_SUCCESS(status)) { return status; } return STATUS_SUCCESS;}
  9. 将两个名为 Device.cppDevice.h 的文件添加到项目中。

  10. Device.h中, DeviceContext 定义 类。

    #pragma once#include <windows.h>#include <wdf.h>#include <NfcCx.h>// The class that will store the driver's custom state for// a device instance.class DeviceContext{public: // Implementation of `EvtDriverDeviceAdd`. static NTSTATUS AddDevice( _In_ WDFDRIVER Driver, _Inout_ PWDFDEVICE_INIT DeviceInit);private: // Implementation of `EvtDevicePrepareHardware`. static NTSTATUS PrepareHardware( _In_ WDFDEVICE Device, _In_ WDFCMRESLIST ResourcesRaw, _In_ WDFCMRESLIST ResourcesTranslated); // Implementation of `EvtDeviceReleaseHardware`. static NTSTATUS ReleaseHardware( _In_ WDFDEVICE Device, _In_ WDFCMRESLIST ResourcesTranslated); // Implementation of `EvtDeviceD0Entry`. static NTSTATUS D0Entry( _In_ WDFDEVICE Device, _In_ WDF_POWER_DEVICE_STATE PreviousState); // Implementation of `EvtDeviceD0Exit`. static NTSTATUS D0Exit( _In_ WDFDEVICE Device, _In_ WDF_POWER_DEVICE_STATE TargetState); // Implementation of `EvtNfcCxWriteNciPacket`. static void WriteNciPacket( _In_ WDFDEVICE Device, _In_ WDFREQUEST Request);};// Define the `DeviceGetContext` function.WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DeviceContext, DeviceGetContext);
  11. Device.cpp中,开始 DeviceContext::AddDevice 函数的定义。

    #include "Device.h"NTSTATUS DeviceContext::AddDevice( _In_ WDFDRIVER Driver, _Inout_ PWDFDEVICE_INIT DeviceInit){ NTSTATUS status;
  12. 设置 NFC CX 设备配置。 设备配置包括提供 EvtNfcCxWriteNciPacket 回调函数。 此回调从 NFC CX 驱动程序接收 NCI 数据包,客户端驱动程序应将其转发到 NFC 控制器。

     // Create the NfcCx config. NFC_CX_CLIENT_CONFIG nfcCxConfig; NFC_CX_CLIENT_CONFIG_INIT(&nfcCxConfig, NFC_CX_TRANSPORT_CUSTOM); nfcCxConfig.EvtNfcCxWriteNciPacket = WriteNciPacket; nfcCxConfig.DriverFlags = NFC_CX_DRIVER_ENABLE_EEPROM_WRITE_PROTECTION; // Set the NfcCx config. status = NfcCxDeviceInitConfig(DeviceInit, &nfcCxConfig); if (!NT_SUCCESS(status)) { return status; }
  13. 注册客户端驱动程序所需的 PnP 电源回调

    典型的客户端驱动程序可能需要 EvtDevicePrepareHardwareEvtDeviceReleaseHardwareEvtDeviceD0EntryEvtDeviceD0Exit 函数。 要求可能因客户端驱动程序处理电源管理的方式而异。

     // Create the PnP power callbacks configuration. WDF_PNPPOWER_EVENT_CALLBACKS pnpCallbacks; WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpCallbacks); pnpCallbacks.EvtDevicePrepareHardware = PrepareHardware; pnpCallbacks.EvtDeviceReleaseHardware = ReleaseHardware; pnpCallbacks.EvtDeviceD0Entry = D0Entry; pnpCallbacks.EvtDeviceD0Exit = D0Exit; // Set the PnP power callbacks. WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpCallbacks);
  14. WdfDeviceCreate调用 函数以创建 WDFDEVICE 对象。

     // Create WDF object attributes for the WDFDEVICE object. WDF_OBJECT_ATTRIBUTES deviceAttributes; WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DeviceContext); // Create the device. WDFDEVICE device; status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device); if (!NT_SUCCESS(status)) { return status; }
  15. 调用 NfcCxDeviceInitialize 函数。

    应在创建 对象后 WDFDEVICE 调用此函数,以允许 NFC CX 驱动程序完成设备实例的初始化。

     // Let NFC CX finish initializing the device instance. status = NfcCxDeviceInitialize(device); if (!NT_SUCCESS(status)) { return status; }
  16. 调用 NfcCxSetRfDiscoveryConfig 以指定 NFC 控制器支持的 NFC 技术和协议。

     // Create the RF config. (Enable everything.) NFC_CX_RF_DISCOVERY_CONFIG discoveryConfig; NFC_CX_RF_DISCOVERY_CONFIG_INIT(&discoveryConfig); discoveryConfig.PollConfig = NFC_CX_POLL_NFC_A | NFC_CX_POLL_NFC_B | NFC_CX_POLL_NFC_F_212 | NFC_CX_POLL_NFC_F_424 | NFC_CX_POLL_NFC_15693 | NFC_CX_POLL_NFC_ACTIVE | NFC_CX_POLL_NFC_A_KOVIO; discoveryConfig.NfcIPMode = NFC_CX_NFCIP_NFC_A | NFC_CX_NFCIP_NFC_F_212 | NFC_CX_NFCIP_NFC_F_424 | NFC_CX_NFCIP_NFC_ACTIVE | NFC_CX_NFCIP_NFC_ACTIVE_A | NFC_CX_NFCIP_NFC_ACTIVE_F_212 | NFC_CX_NFCIP_NFC_ACTIVE_F_424; discoveryConfig.NfcIPTgtMode = NFC_CX_NFCIP_TGT_NFC_A | NFC_CX_NFCIP_TGT_NFC_F | NFC_CX_NFCIP_TGT_NFC_ACTIVE_A | NFC_CX_NFCIP_TGT_NFC_ACTIVE_F; discoveryConfig.NfcCEMode = NFC_CX_CE_NFC_A | NFC_CX_CE_NFC_B | NFC_CX_CE_NFC_F; // Set the RF config. status = NfcCxSetRfDiscoveryConfig(device, &discoveryConfig); if (!NT_SUCCESS(status)) { return status; }
  17. DeviceContext::AddDevice结束函数。

     return STATUS_SUCCESS;}
  18. PrepareHardware实现 和 ReleaseHardware 回调函数。

    这两个函数用于初始化和取消初始化分配给 NFC 控制器设备实例的硬件资源。 其实现取决于设备连接到 (的总线类型,例如 I2C、SPI 和 USB) 。

    NTSTATUS DeviceContext::PrepareHardware( _In_ WDFDEVICE Device, _In_ WDFCMRESLIST ResourcesRaw, _In_ WDFCMRESLIST ResourcesTranslated){ // FIX ME: Initialize hardware resources. return STATUS_SUCCESS;}NTSTATUS DeviceContext::ReleaseHardware( _In_ WDFDEVICE Device, _In_ WDFCMRESLIST ResourcesTranslated){ // FIX ME: Uninitialize hardware resources. return STATUS_SUCCESS;}
  19. NfcCxHardwareEvent使用 HostActionStartHostActionStop 调用 函数,以在适当的时间启动和停止 NCI 状态机。

    某些驱动程序在 D0EntryD0Exit PnP 电源回调期间执行此操作。 不过,这可能因客户端驱动程序处理电源管理的方式而异。

    // Device exiting low power state (or is booting up).NTSTATUS DeviceContext::D0Entry( _In_ WDFDEVICE Device, _In_ WDF_POWER_DEVICE_STATE PreviousState){ (void)PreviousState; NTSTATUS status; // Invoke the HostActionStart event, so that the NFC CX initializes // the NFC Controller. NFC_CX_HARDWARE_EVENT eventArgs = {}; eventArgs.HostAction = HostActionStart; status = NfcCxHardwareEvent(Device, &eventArgs); if (!NT_SUCCESS(status)) { return status; } return STATUS_SUCCESS;}// Device entering low power state.NTSTATUS DeviceContext::D0Exit( _In_ WDFDEVICE Device, _In_ WDF_POWER_DEVICE_STATE TargetState){ (void)TargetState; NTSTATUS status; // Trigger the HostActionStop event, so that the NFC CX // uninitializes the NFC Controller. NFC_CX_HARDWARE_EVENT eventArgs = {}; eventArgs.HostAction = HostActionStop; status = NfcCxHardwareEvent(Device, &eventArgs); if (!NT_SUCCESS(status)) { return status; } return STATUS_SUCCESS;}
  20. 实现 WriteNciPacket 函数。

    当有要发送到 NFC 控制器的 NCI 数据包时,NFC CX 会调用此回调。

    void DeviceContext::WriteNciPacket( _In_ WDFDEVICE Device, _In_ WDFREQUEST Request){ NTSTATUS status; // Get the NCI packet as a raw byte buffer. void* nciPacket; size_t nciPacketLength; status = WdfRequestRetrieveInputBuffer(Request, 0, &nciPacket, &nciPacketLength); if (!NT_SUCCESS(status)) { WdfRequestComplete(Request, status); return; } // FIX ME: Use the NCI packet in some way. // FIX ME: Call `WdfRequestComplete` on `Request` with failure // or success `NTSTATUS` code.};
  21. NfcCxNciReadNotification当 NFC 控制器具有应发送到 NFC CX 的 NCI 数据包时,调用 函数。 这通常在硬件事件回调中完成。

    例如:

    • GPIO 中断事件回调。 (I2C 和 SPI)
    • USB 连续读卡器回调。

日志记录

请考虑将日志记录添加到客户端驱动程序,使其更易于调试。 ETW 跟踪WPP 跟踪都是不错的选择。

反馈

此页面是否有帮助?

提供产品反馈|

NFC CX 快速入门指南 - Windows drivers (2024)
Top Articles
Baked Ziti Recipe (VIDEO)
Best & Easy Authentic Italian Baked Ziti Recipe - Mortadella Head
Funny Roblox Id Codes 2023
Golden Abyss - Chapter 5 - Lunar_Angel
Www.paystubportal.com/7-11 Login
Joi Databas
DPhil Research - List of thesis titles
Shs Games 1V1 Lol
Evil Dead Rise Showtimes Near Massena Movieplex
Steamy Afternoon With Handsome Fernando
Which aspects are important in sales |#1 Prospection
Detroit Lions 50 50
18443168434
Zürich Stadion Letzigrund detailed interactive seating plan with seat & row numbers | Sitzplan Saalplan with Sitzplatz & Reihen Nummerierung
Grace Caroline Deepfake
978-0137606801
Nwi Arrests Lake County
Justified Official Series Trailer
London Ups Store
Committees Of Correspondence | Encyclopedia.com
Pizza Hut In Dinuba
Jinx Chapter 24: Release Date, Spoilers & Where To Read - OtakuKart
How Much You Should Be Tipping For Beauty Services - American Beauty Institute
Free Online Games on CrazyGames | Play Now!
Sizewise Stat Login
VERHUURD: Barentszstraat 12 in 'S-Gravenhage 2518 XG: Woonhuis.
Jet Ski Rental Conneaut Lake Pa
Unforeseen Drama: The Tower of Terror’s Mysterious Closure at Walt Disney World
Ups Print Store Near Me
C&T Wok Menu - Morrisville, NC Restaurant
How Taraswrld Leaks Exposed the Dark Side of TikTok Fame
Dashboard Unt
Access a Shared Resource | Computing for Arts + Sciences
Speechwire Login
Restored Republic
3473372961
Craigslist Gigs Norfolk
Litter-Robot 3 Pinch Contact & DFI Kit
Moxfield Deck Builder
Senior Houses For Sale Near Me
Whitehall Preparatory And Fitness Academy Calendar
Trivago Myrtle Beach Hotels
Anya Banerjee Feet
Three V Plymouth
FREE - Divitarot.com - Tarot Denis Lapierre - Free divinatory tarot - Your divinatory tarot - Your future according to the cards! - Official website of Denis Lapierre - LIVE TAROT - Online Free Tarot cards reading - TAROT - Your free online latin tarot re
Poe Self Chill
Senior Houses For Sale Near Me
Funkin' on the Heights
Vci Classified Paducah
Www Pig11 Net
Ty Glass Sentenced
Latest Posts
Article information

Author: Mr. See Jast

Last Updated:

Views: 5335

Rating: 4.4 / 5 (55 voted)

Reviews: 86% of readers found this page helpful

Author information

Name: Mr. See Jast

Birthday: 1999-07-30

Address: 8409 Megan Mountain, New Mathew, MT 44997-8193

Phone: +5023589614038

Job: Chief Executive

Hobby: Leather crafting, Flag Football, Candle making, Flying, Poi, Gunsmithing, Swimming

Introduction: My name is Mr. See Jast, I am a open, jolly, gorgeous, courageous, inexpensive, friendly, homely person who loves writing and wants to share my knowledge and understanding with you.