PCI设备RTX驱动开发方法

[编辑简介]:本文简要介绍了PCI驱动程序的特点、RTX 驱动整体架构,并对基于反射内存卡的 RTX 驱动进行分析,给出RTX API 列表。
[摘要]:
[关键词]:PCI, 反射内存, RTX API,中断资源冲突

  PCI 设备 RTX 驱动开发方法


1. RTX 下操作外设时, 需要把设备从 Windows 移动到 RTX 下面,

具体移植方法可以参考 RTX Help 文档中间 Converting a Windows Device to an RTX Device 一节或者参考附件<<串口设备移植向导.doc>>


2. PCI驱动程序的特点

在设计驱动程序之前,首先要对欲控制的硬件设备进行细致地分析,更需要详细了解硬件设备的特性。硬件设备的特性会对驱动程序设计产生重大的影响。需要了解的最主要的硬件特性包括:

(1) 设备的总线结构

设备采用什么总线结构非常关键,因为不同的总线类型(如ISA和PCI)在许多硬件工作机制上是不同的,所以驱动程序设计也不同。

(2) 寄存器

要了解设置的控制寄存器、数据寄存器和状态寄存器,以及这些寄存器工作的特性。

(3) 设备错误和状态

要了解如何判断设备的状态和错误信号,这些信号要通过驱动程序返回给用户。

(4) 中断行为

要了解设备产生中断的条件和使用中断的数量。

(5) 数据传输机制

最常见的数据传输机制是通过I/O端口(port),也就是通过CPU进行数据读写。PC的另一种重要的传输机制是DMA,但PCI规范不包括从属DMA的说明。

(6) 设备内存

许多设备自身带有内存,PCI设备大多是采用映射的方式映射到PC系统的物理内存。有的设备还要通过驱动程序设置设备的接口寄存器


3. RTX 驱动整体架构

使用 RTX Device Driver 开发向导, 选择支持

(1) Interrupt Service Routine (ISR)

(2) Support for Sharing an Interrupt

(3) Basic Port I/O Support

(4) Basic Mapped Memory Support,

即可生成 RTX PCI 设备驱动程序框架。

该程序框架分成两个函数, Driver 文件和 DriverFunc 文件:

Driver 文件主要包括 main 函数,中断服务程序和中断服务线程;

DriverFunc 文件主要是对 PCI 设备的基本操作函数, 包括 PCI 设备搜索, PCI 设备初始化,使能或关闭中断, 处理 PCI 设备共享中断, 以及 PCI 驱动程序资源清理等函数。

4. 完整的 RTX PCI驱动

基于RTX PCI 设备驱动程序框架, 用户需要添加相应的代码, 下面基于反射内存卡的 RTX 驱动进行分析。

反射内存卡的基本特点:

(1) PCI、PCIe、PMC、VME 外形, 节点之间组成环形连接或通过光纤 Hub 组成星型连接

(2) 节点之间数据确定性的传输延迟, 延迟小于 750us

PCI 反射内存卡的 RTX 驱动也分成 Driver 文件和DriverFunc 文件两个文件。Driver 文件主要包括 main 函数,中断服务程序和中断服务线程, 下面是详细的分析:

(1) Main 函数:

Main 函数并不是 RTX PCI 驱动程序的一部分, 准确的讲它是如何使用 RTX PCI驱动程序的流程。用户需要做的工作:

a. 在 RTX PCI 设备驱动程序框架生成的 main 函数需要在设备初始化 (DeviceInit()) 完成之后与使能 PCI 中断之前添加设备打开(open())函数, 该函数的功能主要是创建信号量和初始化板卡.

b. 使能 PCI 中断之后, 用户即可调用 PCI驱动程序里的读写等函数写一段简单的读写测试程序。

(2) 中断服务程序:

这个函数接收到中断后交给中断服务线程来处理, 用户一般不需要改动。

(3) 中断服务线程:

中断服务线程主要完成读取和记录 PCI 板卡的中断信息, 释放相关的信号量等工作, 一般不完成具体的中断处理工作。PCI 驱动程序一般还提供一个函数来捕捉这些释放的信号量, 完成中断具体含义的解析工作。

DriverFunc 文件主要是对 PCI 设备的基本操作函数, 包括 PCI 设备搜索, PCI 设备初始化,使能或关闭中断, 处理 PCI 设备共享中断, 以及 PCI 驱动程序资源清理, 数据读写, 发送和接收消息类中断等函数。下面是详细的分析:

(1) DeviceSearch 函数

这个函数根据 PCI 设备的 Vendor ID 和 Device ID 搜索 PCI 设备, 返回 PCI 配置信息和 slot Number. 用户修改 Vendor ID 和 Device ID 即可。

(2) DeviceInit 函数

PCI设备初始化函数. 该函数中间调用了两个RTX 系统函数RtTranslateBusAddress() 和 RtMapMemory(), RtTranslateBusAddress() 作用为把 PCI 设备地址转换为 CPU 可以直接访问的物理地址, RtMapMemory() 函数把物理地址映射到虚拟地址。映射到虚拟地址空间后 ring3用户即可以读写 PCI 内存空间或者 I/O 空间了。用户需要关注的是物理地址到虚拟地址映射的地址范围,一般设置为 4K Bytes. RtMapMemory() 函数默认最大可以映射的地址范围为 64M Bytes, 如果需要更大的范围, 可以参考内存管理一节。

(3) Enable/Disable Interrupts On Chip 函数

使能或者关闭 PCI 设备上的中断。用户根据 PCI 设备进行修改。

(4) IsMyInterrupt函数

RTX 下 PCI 设备中断号可以共享。如果有 RTX 下 PCI 设备共享, 需要在该函数中间区分是否是该设备的中断.

(5) DeviceCleanup 函数

该函数释放中断句柄和解除物理地址于虚拟地址之间的映射。用户基本不需要修改该函数。

(6) RFM2gOpen 函数

反射内存功能函数。该函数的功能主要是为 DMA 通道,发送和接收Event(反射内存的一种消息类中断)等硬件功能模块创建信号量和初始化板卡。为了防止对硬件资源的访问冲突, 使用这些硬件资源前需要先拿到信号量, 使用结束后释放这些信号量。

(7) RFM2gEnableEvent函数

反射内存功能函数。使能板卡接收消息类中断。

(8) RFM2gSendEvent 函数

反射内存功能函数。向其它节点发送消息类中断。

(9) RFM2gWaitForEvent函数

反射内存功能函数。该函数结束中断服务线程释放的信号量, 解析中断的具体含义, 记录接收到的信息类型, 根据返回值判断是否接收到信息。

(10) RFM2gWrite函数

反射内存功能函数。该函数把数据写入到本地节点, 通过光纤传输到其它节点, 通过 DMA 或者 CPU 进行读取。写入完成后, 一般发送消息中断通知其它节点。

(11) RFM2gRead函数

反射内存功能函数。该函数读取从其它节点通过光纤传输到本地的数据, 通过 DMA 或者 CPU 进行读取。该函数一般在接收到其它节点发送的消息中断后使用。

 

. 反射内存卡 RTX 驱动调用的 RTX API 列表

RtCreateSemaphore;

RtWaitForSingleObject;

RtReleaseSemaphore;


RtQueryPciMsiCapability;

RtGetCurrentProcessorNumber;

RtAttachInterrupt;

RtReleaseInterrupt;

RtAttachInterruptVectorEx;

RtReleaseInterruptVector;

RtGetBusDataByOffset;

RtSetBusDataByOffset

RtTranslateBusAddress

RtMapMemory

RtUnmapMemory

RtGetPhysicalAddress


RtCloseHandle

RtExitProcess


RtEnablePortIo

RtDisablePortIo


RtPrintf

RtSleep


6. PCI 设备 RTX 驱动的发布形式

PCI 设备 RTX 驱动的发布形式包括 .rtss, .rtdll, rtss dll, .lib.

.rtss 驱动程序是一个包含 PCI 设备驱动 RTX 应用;

.rtdll 是常见的 RTX 驱动存在形式, 类似 Windows 下的 DLL.

使用 RTDLL 前需要注册 RTDLL, 可以使用 RTSSRun 对话框注册, 也可以使用命令行注册。当 RTDLL 需要被多个进程加载时, 需要在注册 RTDLL 时选中“Shared between processes”对话框, 或者使用命令行时增加 /s 参数。

命令行RTSSrun 参数如下:

RTSSrun 【/q /f】 /d 【/s /t】 filename.rtdll, 其中, /s 参数含义是:

This optional flag allows an RTDLL to be loaded by several processes at the same time.

详细可以参考 RTX help 文档<<Registering an RTDLL>> 一节.

. rtss dll 是以 RTX 应用程序存在的 DLL, 可以为其它应用程序提供函数, 必须先于其它 RTX 进程启动, 一般不推荐使用。

. lib 是静态函数库。

7. RTDLL 使用方法

在 RTX 应用程序中使用 RTDLL 方法不在这里讨论。

8. PCI 设备中断资源冲突

中断资源冲突是用户使用 PCI 设备时经常遇到的问题, 解决中断资源冲突的方法有以下三种:

(1) 禁用中断资源冲突的 PCI 设备

(2) 把 PCI 设备移动到其它 PCI 槽位

(3) 升级板卡支持 MSI 中断, 可以从根本上避免资源冲突

9. RTX 驱动开发的一些技巧

a. 把其它操作系统下驱动源代码移植到 RTX 下是比较常见的 RTX 驱动开发思路。

b. Getlasterror() 函数对于定位错误比较有帮助。

 

 

 

 补充:

RTXWindows的实时扩展,RTX的出现,使得用户既可以利用Windows的良好界面,又使应用具有了微秒级的实时特性。

RTX不仅支持PCIISA总线的板块,也支持PCI-E总线板卡。在驱动开发上,PCIISAPCI-E板卡开发方法没有任何区别,RTX提供了良好驱动开发框架,通过设置向导,用户可以选择需要的功能模块,如:内存映射,I/O映射,ISRIST等。

RTX对中断类型的支持,不仅包括line-based类型,还包括MSIMSI-X中断类型。当然,对MSIMSI-X中断类型,需要硬件板卡具有此中断功能。目前,符合PCI2.2协议的板卡和PCI-E板卡一般都支持MSIMSI-X中断。

下面简单介绍RTX的驱动框架,

1.       DeviceSearch( )函数来搜索指定的设备,开发人员需要将device ID Vendor ID 指定。

2.       DeviceInit( )函数来初始化搜索到的指定设备。

2.1    使能I/O。(如果在构建框架时选择了I/O映射)

2.2     将物理内存地址,寄存器地址进行映射,这杨,开发人员对设备寄存器的访问就如同对数组的访问一样简单。

2.3     根据需要,对设备寄存器进行相应的配置。

3.       RtQueryPciMsiCapability( )函数来探测板卡是否支持MSIMSI-X中断。

4.       根据中断类型来设置参数,包括ISTISR

5.       RtAttachInterrupt( )函数来挂接中断。

以上是驱动的大致框架,开发人员可以根据需要,封装成自己的函数,以方便应用层的开发。驱动程序可以被编译成RTSS文件或RTDLL文件。若不希望驱动代码泄露,可以编译成RTDLL文件,只需提供函数接口即可。

文献来源:http://www.autooo.net/papers/paper/2011-04-11/68870_3.html



 


 

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值