用DriverStudio开发PCI总线设备驱动程序

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
开发 PCI 驱动程序, 笔者使用 DriverStudio。DriverStudio 是 一套 NuMega 公司为简化 Windows 设备驱动程序和应用程序而 开 发 的 编 写 、编 译 和 调 试 的 软 件 工 具 包 。 它 以 面 向 对 象 (OOP)的 方式, 将驱动程序编写所需的与内核访问及对硬件的访问封装 成类, 加上设计的驱动程序代码生成向导, 大大简化了驱动程序 开发的难度, 减少了工作量。同时, DriverStudio 被嵌入到 VC 中, 方便了开发。本文根据笔者编写 PCI9656 驱动的实际经验, 介绍 使用 DriverStudio 开发 PCI 设备驱动程序的流程和方法。
和 DMA 传 输 功 能 的 驱 动 程 序 。
关键词:PCI 局部总线; 驱动程序; Dr iver Studio
中 图 分 类 号 : T P 311
文献标识码:A
Abstr act:Through an example of PCI9656,the method and step that develop the driver for PCI device is introduced. The driver for PCI device that can read and write memory,I/O and handle interrupt,and DMA transmission is realized in this paper. Key wor ds:PCI local bus, device dr iver , Dr iver Studio
2.2 中断的处理
KInterrupt 类 实 现 硬 件 中 断 的 处 理 。 中 断 服 务 例 程 不 是
KInterrupt 类 的成 员 函 数 , 这 样 做 的 目 的 是 减 少 中 断 延 迟 时 间 。
如果 中 断 延迟 时 间 不是 问 题 , 可 以 用 MEMBER_ISR 宏 声 明 中

在 OnStartDevice 函 数 中, 调 用 KInterruptr 的 成员 函 数 Ini-
tializeAndConnect 初始化中断变量和调用 宏 LinkTo 连 接中 断 例
程。如下:
status=m_IrΒιβλιοθήκη Baidu.InitializeAndConnect(
pResListTranslated,
《P LC 技术应用 200 例》
邮局订阅号: 82-946 360 元 / 年 - 279 -
软件天地
中 文 核 心 期 刊 《 微 计 算 机 信 息 》( 测 控 自 动 化 )2007 年 第 23 卷 第 9-1 期
NtReadFile。
驱动程序的编写主要有三个方面的问题:硬件访问 、中 断 处
存器(0~5)值决定请 求 的 地址 空 间 类型 和 大 小, 驱 动 程 序根 据 以
上情况声明 KIoRange 类实例。例如:
KIoRange m_IoPortRange0;
KIoRange m_IoPortRange1;
对 PCI 设 备 首 先 需 要 在 OnStarDevice 函 数 中 取 得 I/O 资
status=m_MemoryRange0.Initialize(
pResListTranslated,
pResListRaw,
PciConfig.BaseAddressIndexToOrdinal(0)
);
函数的参量同 I/O 端口的操作。KMemoryRange 的其他成员
函数操作同 I/O 端口的操作。
源, 然后初始化。如下:
status=m_IoPortRange1.Initialize(
pResListTranslated, //转换后的资源列表指针
pResListRaw,
//原 始 的 资 源 列 表 指 针
PciConfig.BaseAddressIndexToOrdinal(1) //‘1' 代 表 分 配 的
(国防科技大学)杨 波 柳 征 姜 文 利
YANG BO LIU ZHENG J IANG WENLI
摘要:以 PCI9656 为 例 , 介 绍 了 利 用 DriverStudio 开 发 PCI 设 备 驱 动 程 序 的 方 法 步 骤 , 并 实 现 了 具 有 I/O 和 内 存 读 写 、中 断 处 理
PCI 总线配置机构分配的物理内存, 如果在驱动 程序 中 是 无法
使 用 的 , 必 须 将 其 转 换 成 系 统 可 以 访 问 的 非 分 页 内 存 , 在 DDK
中 , 调 用 函 数 MmMapIoSpace。 在 KMemoryRange 的 成 员 函 数
Initialize 中实现这个转换。在 OnStartDevice 函数中, 如下:
杨 波: 研究生
技 线配置时提供给系统, 系统根据这些信息 来 匹 配已 注 册 的 PCI
设备的驱动程序。
术 (2) 第 7 步, 选择 IRP 串 行 处 理的 类 型 和串 行 处 理的 函 数 。
分发例程可以将 IRP 进行排队, 交给统一处理 IRP 的 例 程 Star-
创 tIo 串行 处 理 。串行 的 处 理例 程 有 两种 类 型:驱动 程 序 自行 处 理
Windows 操 作 系 统 为 了 保 证 系 统 的 安 全 性 、稳 定 性 和 可 移 植性, 不支持应用程序对硬件资源的直接操作。因而在设计开 发 PCI 设 备时 , 往 往 需要 硬 件 开发 人 员 自行 开 发 设备 驱 动 程 序 来 实 现 对 PCI 设 备 的 操 作 , 应 用 程 序 通 过 驱 动 程 序 来 访 问 PCI 设备。
服务例程
BOOLEAN Isr_Irq(void);
//声 明 中 断 服 务 例 程 函 数
VOID DpcFor_Irq(PVOID Arg1,PVOID Arg2);
protected:
KInterrupt m_Irq;
//中 断 变 量
KDeferredCall m_DpcFor_Irq; //延迟调用
断服务例程为 KDevcie 或其它类的一个成员函数。
中断处理需要中断服务例程和延迟过程调用例程, 需要声明:
class PCI9656Device:public KPnpDevice
{…
puclic:
MEMBER_ISR(PCI9656Device,Isr_Irq); //声 明 连 接 的 中 断
理和 DMA 传输。以 PCI9656 驱动代码为例, 下面就这三个方面
的编程展开讨论。
2.1 硬件访问
2.1.1 I/O 端口的访问
类 KIoRange 封 装 了 对 I/O 端 口 的 操 作 , 它 实 现 对 I/O 映 射
芯片 的 访问 。对 于 所设 计 的 PCI 设备 , 其 配 置空 间 的 基 地 址 寄
您的论文得到两院院士关注 文章编号:1008- 0570(2007)09- 1- 0279- 03
软件天地
用 Drive rS tu d io 开发 PCI 总线设备驱动程序
De ve lo p m e n t o f PCI b u s d e vice d rive r u s in g Drive rS tu d i
PCI(Peripheral Component Interconnect, 即外 围 部 件 互 连)总 线是一种高性能的且独立于处理器的 32/64 位地址数据复用总 线, 它与 CPU 无关, 与时钟频率亦无关, 可适用于各种平台。它 支持无限读写猝发操作, 支持并发工作方式。PCI 总线以其优良 性 能 和 可 适 应 性 成 为 微 型 计 算 机 系 统 的 主 流 总 线 。开 发 微 机 接 口设备, 通常采用 PCI 总线。
创 和 TranslatedResources 得到上述参数。

初始化完之后, 就可以调用访问函数了, 如下所示: status=m_IoPortRange0.ind(INTCSR);
m_IoPortRange0.outd(DMAMODE0,0x20800);
在驱动程序停止运行之前, 一定要卸载资源, 对 于 I/O 端 口
和系统处理。驱动程序可以设置多个 StartIo 处理函数, 对于 PCI
新 设备来说, 一般只对一个设备操作, 只需要一个 StartIo 处理。一
般 处 理 ReadFile 和 WriteFile 函 数 的 分 发 例 程 需 要 进 行 IRP 排 队, 在此全部选中。
(3)第 9 步 , 选 择 设 备 文 件 中 的 类 名 和 接 口 类 型 , 类 名 通 常 取默认值。在 Resources 项中, 需要声明所需的硬件资源如存储 空间和 I/O 空间, 中断和 DMA 等。如图 1 所示。
调用成员函数 Invalidate, 如下所示:
m_IoPortRange0.Invalidate( );
m_IoPortRange1.Invalidate( );
2.1.2 内存的访问
类 KMemoryRange 封 装 了 对 PCI 设 备 的 映 射 内 存 的 操 作 ,
它实现对映射内存的访问。在 WDM 中, 驱动程序得到的只是
图 1 DriverStudio 驱动程序向导第 9 步 最 后 一 个 步 骤 是 选 择 生 成 一 个 Win32 Console 应 用 程 序 。 单击 Finish 按钮, 驱动程序框架就生成好了。
2 添加功能代码
在开始驱动程序代码编写前, 我们先了解一下操作系统与 驱 动 程 序 之 间 的 通 信 方 式 。当 用 户 模 式 程 序 需 要 读 取 设 备 数 据 时, 它就调用 Win32 API 函数, 如 Readfile。在 ReadFile 调用中, 调 用 首 先 到 达 系 统 DLL(NTDLL.DLL)中 的 一 个 入 口 点 :NtRead- File 函数。NtReadFile 函数接着调用系统服务接口, 最后由系统 服务接口调用内核模式中的服务例程, 该例程同样名为
//转 换 后 的 资 源 列 表 指 针
LinkTo(Isr_Irq),
//连 接 中 断 服 务 例 程
this
);
在中断服务例程中, 相应的处理时间应当尽可能地短, 因
为中断例程运行的级别很高, 当有中断请求时, 不但会打断应
用程序的执行, 而且会打断在硬件中断级以下的所有运行程
序。所以, 在 WDM 中提供了 DPC(Deferred Procedure Call)例程,
1 利 用 Wizar d 生 成 PCI 设 备 驱 动 程序框架
DriverWizard 是 DriverStudio 创 建 框 架 程 序 的 工 具 , 它 能 够 生成驱动程序的基本框架和用户自定义信息, 虽然没有实现 PCI 设备的具体功能, 但对于功能的实现设置了框 架 , 功 能代 码 都 在该 框 架 下完 成 。创 建程 序 框 架, 共 有 11 个 步骤 , 大 部 分 步 骤采用默认设置即可, 下面介绍其中的几个关键步骤:
(1) 第 4 步 , 选 择 设 备 的 类 型 并 填 写 相 应 信 息 。 我 们 选 择 PCI, 并填写 PCI 设备的设备标识符。PCI Vendor ID 是厂商标识 符 , 此 例 填 10B5h; PCI Device ID 为 设 备 标 识 符 , 填 9656h; PCI Subsystem ID 为子 系 统 ID 号, 填 默 认 设置 00000000 即 可 ; PCI Revision ID 为 修 订 号 , 填 BAh。 这 些 信 息 由 PCI 设 备 在 PCI 总
I/O 资源在 PCI

//基地址的序数, PCI 设备最多可以有 6 个 I/O 资源空间 );
参 数 pResListTranslated 和 pResListRaw 在 DDK 中 从
术 IRP_MN_START_DEVICE 的 IRP 中 取 出 。 DriverStudio 封 装 了
IRP 为 KIrp。在 OnStartDevice 函数中由函数 AllocatedResources
相关文档
最新文档