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
Euphoria : disponible sur quelles plateformes de streaming ? - Editions Oreilly
Las Vegas Optic Nm
Is Paige Vanzant Related To Ronnie Van Zant
Durr Burger Inflatable
Truist Bank Near Here
Sound Of Freedom Showtimes Near Governor's Crossing Stadium 14
Form V/Legends
Recent Obituaries Patriot Ledger
Hawkeye 2021 123Movies
Fusion
Free VIN Decoder Online | Decode any VIN
Computer Repair Tryon North Carolina
Bluegabe Girlfriend
Kent And Pelczar Obituaries
Victoria Secret Comenity Easy Pay
Locate Td Bank Near Me
1Win - инновационное онлайн-казино и букмекерская контора
Cbs Trade Value Chart Fantasy Football
Craigslist Edmond Oklahoma
Urban Airship Expands its Mobile Platform to Transform Customer Communications
How To Cancel Goodnotes Subscription
Red Devil 9664D Snowblower Manual
The best TV and film to watch this week - A Very Royal Scandal to Tulsa King
Buy Swap Sell Dirt Late Model
Nurse Logic 2.0 Testing And Remediation Advanced Test
Form F-1 - Registration statement for certain foreign private issuers
Stihl Dealer Albuquerque
Aspenx2 Newburyport
Devotion Showtimes Near Regency Buenaventura 6
Jayme's Upscale Resale Abilene Photos
Unity Webgl Car Tag
Himekishi Ga Classmate Raw
Sinfuldeed Leaked
Craftsman Yt3000 Oil Capacity
Elijah Streams Videos
Barbie Showtimes Near Lucas Cinemas Albertville
Indiana Jones 5 Showtimes Near Jamaica Multiplex Cinemas
2487872771
Rogers Centre is getting a $300M reno. Here's what the Blue Jays ballpark will look like | CBC News
Synchrony Manage Account
Otter Bustr
2700 Yen To Usd
Rs3 Bis Perks
Craigslist Pets Plattsburgh Ny
Sun Tracker Pontoon Wiring Diagram
Courses In Touch
Craigslist Rooms For Rent In San Fernando Valley
303-615-0055
Canonnier Beachcomber Golf Resort & Spa (Pointe aux Canonniers): Alle Infos zum Hotel
Autozone Battery Hold Down
Skybird_06
Cool Math Games Bucketball
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.