驱动程序初始化

驱动程序初始化是用户模式驱动程序功能的更复杂阶段之一。 它涉及示例驱动程序中大多数(如果不是全部)的组件。

ACPI 配置和初始化

模块 类/接口
SpbAccelerometer.asl 空值

示例驱动程序设计为将传感器永久连接到 I2C 总线。 它不支持即插即用,而是支持 高级配置和电源接口 (ACPI) 。

ACPI Windows控制设备的配置和电源管理。 ACPI 规范具有表的定义,这些表Windows连接到系统板的设备和外围设备的链接。 DSDT (表) 介绍了连接到系统的外围设备(包括传感器)。 它以二进制格式存储,称为 ACPI 计算机语言 (AML) 。 有关 DSDT 表的详细信息,请参阅 ACPI 系统说明表主题。 (请注意,某些系统还使用 SSDT (辅助) 表来描述外围设备。)

若要在 SoC 设备上Windows传感器设备和驱动程序,需使用相应的节点更新 DSDT 表。 此节点包含有关示例设备的控制器和连接器的信息。 下面是驱动程序Windows驱动程序使用节点中数据的原因:

  1. PnP 即插即用 (管理器) 从 ACPI 驱动程序获取设备连接信息。
  2. 然后,PnP 管理器创建一个连接 ID 来表示总线连接。
  3. PnP 管理器将连接 ID 作为硬件资源传递给示例驱动程序。
  4. 示例驱动程序使用连接 ID 打开与传感器设备的逻辑连接,并获取连接的句柄。
  5. 驱动程序将此句柄指定为它发送到设备的 I/O 请求的目标。

更新 DSDT 表

有关如何更新 DSDT 表的说明,请参阅在 Sharks Cove 上安装示例设备和驱动程序 主题。

修改示例 ASL 文件

如果修改示例驱动程序以支持另一台设备,则对示例 ASL 文件进行相应的更新。 大多数更新将更新到文件的_CRS部分,你可指定设备所需的 I2C 和 GPIO 资源。 还需要提供与更新的 INF _HID条目相匹配的唯一输入。

解码 I2C 或 GPIO 资源

如果未指定 /resdecode 选项,则_CRS部分将包含二进制 blob。 若要将本部分转换为可读文本,请应用 /resdecode,如下所示:Asl.exe /tab:dsdt /resdecode

更新 Windows setup-information 文件

模块 类/接口
SpbAccelerometer.inf 空值

除了更新 DSDT 表外,还需要更新 Windows 安装信息文件 (INF) 以指定设备支持 ACPI。 由于传感器始终由 ACPI 枚举,因此 INF 文件中的硬件标识符必须包含"ACPI"字符串。

; =================== Manufacturer/Models sections =======================

[Manufacturer]
%MSFT%                      = Microsoft,NTx86

[Microsoft.NTx86]
%SpbAccelerometer.DeviceDesc% = SpbAccelerometer_Install,ACPI\SpbAccelerometer

初始化驱动程序和设备

模块 类/接口
DllMain.cpp 空值
Device.cpp CMyDevice
Driver.cpp CMyDriver
Queue.cpp CMyQueue

以下方法由 Windows在早期初始化阶段由驱动程序调用。 初步设备初始化方法适用于驱动程序支持的任何设备。 它们显示在模块 Device.cpp 中。

步骤 方法 调用者 目的
1 DllGetClassObject WUDFHost.exe 获取驱动程序的类对象。 (COM DLL.)
2 CMyDevice::OnQueryRemove WUDFx.dll (用户模式Windows驱动程序框架的一个组件) 。
3 CMyDriver::OnDeviceAdd WUDFx.dll (用户模式Windows驱动程序框架的一个组件) 。 通知驱动程序已添加设备。
4 CMyDevice::Configure CMyDriver::OnDeviceAdd 配置设备的队列和相应的回调对象。
5 CMyQueue:CreateInstance CMyDevice::Configure 创建设备队列回调的实例
6 CMyDevice::CreateInstance CMyDevice::OnDeviceAdd 创建与给定设备对象相对应的设备对象实例 (在这种情况下,加速计) 。
7 CMyDevice::Initialize CMyDevice::CreateInstance 初始化设备回调对象。

建立数据连接

模块 类/接口
Device.cpp CMyDevice
SensorDdi.cpp CSensorDdi
AccelerometerDevice.cpp CAccelerometerDevice

以下方法由驱动程序在初始化期间调用,以准备设备对象、获取 ACPI 配置数据以及创建数据连接中断。 对于示例驱动程序,可以在文件 AccelerometerDevice.cpp 中找到这些方法。

如果要移植示例驱动程序以支持另一台设备(如罗盘),将创建并行模块 CompassDevice.cpp。 将 CAccelerometerDevice 类替换为 CCompassDevice 类,并修改示例模块中的方法以支持设备的对象、数据和中断。

步骤 方法 调用者 目的
1 CMyDevice::OnPrepareHardware WUDFx.dll (用户模式Windows驱动程序框架的一个组件) 。 启动使驱动程序可访问给定设备所需的操作。
2 CSensorDdi::Initialize CMyDevice::OnPrepareHardware 创建并初始化传感器设备对象。
3 CSensorDevice::Initialize CSensorDdi::Initialize 初始化传感器驱动程序接口、客户端管理器和报表管理器。
4 CAccelerometerDevice::InitializeDevice CSensorDevice::Initialize 初始化加速计设备对象。
5 CAccelerometerDevice::GetConfigurationData CAccelerometerDevice::InitializeDevice 启动从 ACPI 检索配置数据。
6 CAccelerometerDevice::P repareInputParametersForDsm CAccelerometerDevice::GetConfigurationData 在调用 DSM 参数函数 (ACPI_EVAL_INPUT_BUFFER) 特定于设备的方法之前,准备 ACPI (缓冲区) 缓冲区。
7 CAccelerometerDevice::P arseAcpiOutputBuffer CAccelerometerDevice::GetConfigurationData 分析 ACPI 输出缓冲区中返回的配置数据 (ACPI_EVAL_OUTPUT_BUFFER) 。
8 CAccelerometerDevice::P arseResources CAccelerometerDevice::InitializeDevice 分析设备资源,以确保它们支持串行 I2C 连接。
9 CAccelerometerDevice::ConnectInterrupt CAccelerometerDevice::P arseResources 创建数据连接中断。

初始化 SPB 请求对象

模块 类/接口
Device.cpp CMyDevice
SensorDdi.cpp CSensorDdi
AccelerometerDevice.cpp CAccelerometerDevice
SpbRequest.cpp CSpbRequest

以下方法在初始化期间由驱动程序调用,以打开基础 SPB 控制器的文件句柄。 (请注意,此序列的前四个方法与数据连接 sequence.)

步骤 方法 调用者 目的
1 CMyDevice::OnPrepareHardware WUDFx.dll (用户模式Windows驱动程序框架的一个组件) 。 启动使驱动程序可访问给定设备所需的操作。
2 CSensorDdi::Initialize CMyDevice::OnPrepareHardware 创建并初始化传感器设备对象。
3 CSensorDevice::Initialize CSensorDdi::Initialize 初始化传感器驱动程序接口、客户端管理器和报表管理器。
4 CAccelerometerDevice::InitializeDevice CSensorDevice::Initialize 初始化加速计设备对象。
5 CAccelerometerDevice::InitializeRequest CAccelerometerDevice::InitializeDevice 使用驱动程序之前检索到的资源中心路径和 (ID 启动 SPB 请求对象的初始化) 。
6 CSpbRequest::Initialize CAccelerometerDevice::InitializeRequest 打开基础 SPB 的文件句柄

初始化支持的传感器属性和数据字段

模块 类/接口
Device.cpp CMyDevice
SensorDdi.cpp CSensorDdi
AccelerometerDevice.cpp CAccelerometerDevice
SpbRequest.cpp CSpbRequest

以下方法在初始化期间由驱动程序调用,获取传感器支持的属性和数据字段。 对于Windows平台,加速计属性对应于读取或读写数据,例如传感器的报表间隔或支持的最小报告间隔。 数据字段对应于沿 X 轴、Y 轴和 Z 轴的实际加速计读数。 (请注意,此序列的前三个方法与上一个数据连接和 SPB request-object, sequences.)

步骤 方法 调用者 目的
1 CMyDevice::OnPrepareHardware WUDFx.dll (用户模式Windows驱动程序框架的一个组件) 。 启动使驱动程序可访问给定设备所需的操作。
2 CSensorDdi::Initialize CMyDevice::OnPrepareHardware 创建并初始化传感器设备对象。
3 CSensorDevice::Initialize CSensorDdi::Initialize 初始化传感器驱动程序接口、客户端管理器和报表管理器。
4 CSensorDevice::InitializeSensorDriverInterface CSensorDevice::Initialize 开始初始化存储属性键和数据 字段值的 IPortableDeviceValues 对象。
5 CSensorDevice::AddPropertyKeys CSensorDevice::InitializeSensorDriverInterface 会访问支持的属性,并添加 每个属性的 PROPERTYKEY
6 CAccelerometerDevice::GetSupportedProperties CSensorDevice::AddPropertyKeys 获取给定设备属性的 PROPERTYKEY 结构。
7 CSensorDevice::AddDataFieldKeys CSensorDevice::InitializeSensorDriverInterface 浏览支持的数据字段,并添加每个字段的 PROPERTYKEY
8 CSensorDevice::GetSupportedDataFields CSensorDevice::AddDataFieldKeys 获取给定设备的数据字段的 PROPERTYKEY

初始化持久唯一 ID 属性

模块 类/接口
Device.cpp CMyDevice
SensorDdi.cpp CSensorDdi
AccelerometerDevice.cpp CAccelerometerDevice
SensorDevice.cpp CSensorDevice

以下方法在初始化期间由驱动程序调用,以初始化传感器的 PUID (持久) 标识符。 Windows PUID 跨设备会话持久保存数据。 (请注意,此序列的前四个方法与上一个属性和数据字段 sequence.)

步骤 方法 调用者 目的
1 CMyDevice::OnPrepareHardware WUDFx.dll (用户模式Windows驱动程序框架的一个组件) 。 启动使驱动程序可访问给定设备所需的操作。
2 CSensorDdi::Initialize CMyDevice::OnPrepareHardware 创建并初始化传感器设备对象。
3 CSensorDevice::Initialize CSensorDdi::Initialize 初始化传感器驱动程序接口、客户端管理器和报表管理器。
4 CSensorDevice::InitializeSensorDriverInterface CSensorDevice::Initialize 开始初始化存储属性键和数据字段值的对象。
5 CSensorDevice::SetUniqueID CSensorDevice::InitializeSensorDriverInterface 调用方法,该方法获取 PUID (持久) 驱动程序可在会话之间使用的唯一标识符。
6 CAcclerometerDevice::GetSensorObjectID CSensorDevice::SetUniqueID 获取加速计的持久标识符 ("ADXL345") 。

设置默认属性值

模块 类/接口
Device.cpp CMyDevice
SensorDdi.cpp CSensorDdi
AccelerometerDevice.cpp CAccelerometerDevice
SensorDevice.cpp CSensorDevice

Windows传感器平台支持传感器类型、制造商名称、传感器型号和序列号的默认属性值。 SpbAccelerometer 示例中的代码将这些属性设置为驱动程序和设备初始化阶段的一部分。 以下方法由驱动程序在初始化期间调用,以设置加速计的默认值。 (请注意,此序列的前四个方法与上一个属性设置 sequences.)

步骤 方法 调用者 目的
1 CMyDevice::OnPrepareHardware WUDFx.dll (用户模式Windows驱动程序框架的一个组件) 。 启动使驱动程序可访问给定设备所需的操作。
2 CSensorDdi::Initialize CMyDevice::OnPrepareHardware 创建并初始化传感器设备对象。
3 CSensorDevice:: Initialize CSensorDdi:: Initialize 初始化传感器驱动程序接口、客户端管理器和报表管理器。
4 CSensorDevice::InitializeSensorDriverInterface CSensorDevice:: Initialize 开始初始化存储属性键和 datafield 值的对象。
5 CAccelerometerDevice::SetDefaultPropertyValues CSensorDevice::InitializeSensorDriverInterface 设置加速感应 (制造商、型号、序列号等 ) 的默认属性值

检索默认的可写属性

模块 类/接口
设备 .cpp CMyDevice
SensorDdi .cpp CSensorDdi
AccelerometerDevice .cpp CAccelerometerDevice
SensorDevice .cpp CSensorDevice

Windows 传感器平台支持传感器的只读和读写属性,这也适用于默认属性。 SpbAccelerometer 示例中的代码获取可写入 (列表,或) 默认属性设置为驱动程序和设备初始化阶段的可设置列表。 下面的方法由驱动程序在初始化期间调用,以获取加速感应的这些属性。 (请注意,此序列的前四个方法与之前的属性设置序列中的前四个方法相同。 )

步骤 方法 调用者 目的
1 CMyDevice::OnPrepareHardware WUDFx.dll (Windows 用户模式驱动程序框架) 的组件。 开始使给定设备可由驱动程序访问所需的操作。
2 CSensorDdi:: Initialize CMyDevice::OnPrepareHardware 创建并初始化传感器设备对象。
3 CSensorDevice:: Initialize CSensorDdi:: Initialize 初始化传感器驱动程序接口、客户端管理器和报表管理器。
4 CSensorDevice::InitializeSensorDriverInterface CSensorDevice:: Initialize 开始初始化存储属性键和 datafield 值的对象。
5 CAccelerometerDevice::SetDefaultPropertyValues CSensorDevice::InitializeSensorDriverInterface 设置加速感应 (制造商、型号、序列号等 ) 的默认属性值

激活对事件的支持

模块 类/接口
设备 .cpp CMyDevice
SensorDdi .cpp CSensorDdi
AccelerometerDevice .cpp CAccelerometerDevice
SensorDevice .cpp CSensorDevice

Windows 传感器平台支持事件。 应用程序注册事件处理程序以从驱动程序获取通知。 对于加速感应程序,当超过 G force) (度量或当前报表间隔过期时,将触发这些通知。

若要支持传感器平台中的事件模型,驱动程序必须激活线程才能处理事件通知。 下面的方法由驱动程序在初始化期间调用以执行此激活。 (请注意,此序列的前三种方法与前面的几个序列中的前三个方法相同。 )

步骤 方法 调用者 目的
1 CMyDevice::OnPrepareHardware WUDFx.dll (Windows 用户模式驱动程序框架) 的组件。 开始使给定设备可由驱动程序访问所需的操作。
2 CSensorDdi:: Initialize CMyDevice::OnPrepareHardware 创建并初始化传感器设备对象。
3 CSensorDevice:: Initialize CSensorDdi:: Initialize 初始化传感器驱动程序接口、客户端管理器和报表管理器。
4 CReportManager:: Initialize CSensorDevice:: Initialize 创建用于处理事件的线程。
5 CReportManager::ActivateDataEventingThread CReportManager:: Initialize 激活由上一个方法创建的线程。

初始化类扩展

模块 类/接口
设备 .cpp CMyDevice

Windows 传感器平台提供了传感器 API 的类扩展,它提供了一种用于获取传感器数据和引发事件通知的标准机制。 示例驱动程序在接收对 CMyDevice::OnPrepareHardware 的调用后调用 ISensorClassExtension::Initialize 方法初始化类扩展。

配置设备,将其置于待机模式

模块 类/接口
Device.cpp CMyDevice
SensorDdi.cpp CSensorDdi
AccelerometerDevice.cpp CAccelerometerDevice
SensorDevice.cpp CSensorDevice

设备和驱动程序初始化中的最后一系列方法将配置 ADXL345,并置于备用模式。 (此写入和读取操作序列重复多次,直到配置设备。)

步骤 方法 调用者 目的
1 CMyDevice::OnD0Entry WUDFx.dll (用户模式Windows驱动程序框架的一个组件) 。 在系统上显示新设备时调用。
2 CSensorDdi::Start CMyDevice::OnD0Entry 调用 CSensorDevice::Start 的传递方法。
3 CSensorDevice::Start CSensorDdi::Start 启动设备配置过程。
4 CAccelerometerDevice::ConfigureHardware CSensorDevice::Start 启动将值写入 ADXL345 的指定寄存器的操作。
5 CAcclerometerDevice::WriteRegister CAccelerometerDevice::ConfigureHardware 启动将值写入 ADXL345 的指定寄存器的操作。
6 CSpbRequest::CreateAndSendWrite CAcclerometerDevice::WriteRegister 通过 I2C 总线传输写入请求
7 CAcclerometerDevice::ReadRegister CAccelerometerDevice::ConfigureHardware 启动从指定的 ADXL345 寄存器读取值的操作。
8 CSpbRequest::CreateAndSendWriteReadSequence CAcclerometerDevice::ReadRegister 通过 I2C 总线接收读取结果。
9 CSpbRequest::CreateAndSendIoctl CSpbRequest::CreateAndSendWriteReadSequence 用于创建和发送 IOCTL 请求的帮助程序方法。

大多数设备配置工作都通过一系列 CAccelerometerDevice::WriteRegisterCAccelerometerDevice::ReadRegister 方法调用进行。 驱动程序使用 ::WriteRegister 方法将值写入 ADXL345 寄存器之一;然后,它会检查在相应的 ::ReadRegister 方法中返回的值,以验证写入操作是否成功。 下面是完整的写入和读取操作序列。

步骤 方法 注册 数据 目的
1 CAccelerometerDevice::WriteRegister 0x2d "\0" (0x00) 重置传感器的电源控制寄存器,将设备置于待机模式。
2 CAccelerometerDevice::ReadRegister 0x2d "\0" (0x00) 返回的寄存器值指示写入操作成功。
3 CAccelerometerDevice::WriteRegister 0x31 "\v" (0x0b) 将设备设置在全分辨率模式下,沿每个轴的范围为 +/- 16G。
4 CAccelerometerDevice::ReadRegister 0x31 "\v" (0x0b 返回的寄存器值指示写入操作成功。
5 CAccelerometerDevice::WriteRegister 0x38 "\0" (0x00) 将传感器的 FIFO 控制寄存器重置为绕过模式。
6 CAccelerometerDevice::ReadRegister 0x38 "\0" (0x00) 返回的寄存器值指示写入操作成功。
7 CAccelerometerDevice::WriteRegister 0x2C "\a" (0x07) 设置BW_RATE寄存器以启动低功率模式。
8 CAccelerometerDevice::ReadRegister 0x2C "\a" (0x07) 返回的寄存器值指示写操作成功。
9 CAccelerometerDevice::WriteRegister 0x24 "\x1" (0x01) 将 TRESH_ACT (活动阈值) 寄存器设置为1。
10 CAccelerometerDevice::ReadRegister 0x24 "\x1" (0x01)
11 CAccelerometerDevice::WriteRegister 0x27 (0xf0) 将 ACT_INACT_CTL (活动/非活动) 注册到0xf0。
12 CAccelerometerDevice::ReadRegister 0x27 (0xf0) 返回的 register 值指示写操作成功。
13 CAccelerometerDevice::WriteRegister 0x2f "\0x10" (0x10) 设置) register (中断映射 INT_MAP。 0x10 的值请求将水印映射到 INT2 pin。
14 CAccelerometerDevice::ReadRegister 0x2f "\0x10" (0x10) 返回的 register 值指示写操作成功。

在配置了驱动程序和设备之后,初始化序列完成,应用程序可以开始接收传感器数据。