如何建立接口总线(iBus)



主要软件: Driver Software>>Measurement Hardware DDK
主要软件版本: N/A
主要软件修正版本: N/A
次要软件: N/A

问题:

如何在没有安装接口总线(iBus)的操作系统上运用测量硬件驱动开发工具(Measurement Hardware Driver Development Kit \ MHDDK)?


解答:
为了调用操作系统上测量硬件驱动开发工具中的寄存器对象,必须要有一个操作系统的接口总线(iBus)。本文介绍了建立iBus的基本要素和注意事项。

Register Level Program Architecture
什么是iBus?
iBus是操作系统抽象层。它为MHDDK中的示例程序提供了PCI / PXI总线的简单接口。 它为寄存器I / O提供简单的功能,如果支持,它提供DMA缓冲区操作。
操作系统支持的用户定义的iBus功能
在RLP示例中,几乎所有与系统相关的代码都在osiUserCode.cpp中。为了使iBus在目标操作系统上工作,即将iBus移植到新的操作系统,需要定义以下两个功能:
  1. 重新定义getsBoard(...)和releaseBoard(...)。
  2. 使用void * osSpecific指向需要在getsBoard(...)和releaseBoard(...)之间共享的任何操作系统特定数据。
iBus* acquireBoard(tChar* brdLocation);
此功能创建iBus并将所选PCI设备的基本地址范围(BARs)映射到内存中。 它可以通过在iBus中使用void * osSpecific来存储系统特定的数据, 例如操作系统特定的结构,指针或文件编号。 这是与releaseBoard(...)共享数据的便捷方式。

在大多数系统上,acquireBoard(...)的功能有:
  1. 创建一个新的iBus。
  2. 使用VXI格式的资源字符串“PXI :: :: INSTR”找到所选的PCI设备。
  3. 将PCI设备的物理内存BARs存储在新的iBus中。
  4. 将PCI设备的BARs映射到内存中。
  5. 将内存映射的BARs的地址存储在iBus中。
void releaseBoard(iBus* &bus);
此功能删除由acquireBoard(...)创建的iBus。

在大多数系统上,releaseBoard(...)的功能有:
  1. 取消映射PCI设备的BARs。
  2. 如有必要,请告诉操作系统程序已完成访问PCI设备。
  3. 删除iBus。
支持DMA的用户定义iBus功能
为了使iBus在目标操作系统上支持DMA,需要定义以下两个功能:

tDMAMemory* iBus::allocDMA (u32 size);
该功能请求一块DMA存储器并将其映射到内存中。 通常情况下,tDMAMemory被划分为子类以存储系统特定的数据,以便可以与freeDMA(...)共享数据。

在大多数系统上,allocDMA(...)的功能有:
  1. 从内核分配内存。
  2. 映射内存。
  3. 创建,构造和返回一个tDMAMemory对象。
void iBus::freeDMA (tDMAMemory *mem);
此函数删除由allocDMA(...)创建的tDMAMemory对象。

在大多数系统上,freeDMA(...)的功能有:
  1. 取消映射DMA内存。
  2. 从内核释放内存。
预定义iBus功能
这些功能在Chip Objects和RLP范例(osiBus.h和osiBus.cpp)中已运用。在iBus导入新的操作系统的过程中,它们已被定义,不需要修改。

u32 iBus::get(u32 attribute, u32 occurrence);
get(...)允许程序获取PCI设备的属性。 在RLP示例中,唯一需要的属性是BARs的物理地址,用于在某些设备上初始化MITE。

tAddressSpace iBus::createAddressSpace(tBusWindowType windowType);
createAddressSpace(...)返回一个可以读写PCI设备的地址空间。createAddressSpace(...)也可以返回由acquireBoard(...)初始化的任何BARs的地址空间。

void iBus::destroyAddressSpace(tAddressSpace &addressSpace);
destroyAddressSpace(...)释放由createAddressSpace(...)保留的系统资源(如果有)。
通过tAddressSpace访问寄存器
使用tAddressSpace函数read8/16/32和write8/16/32来访问PCI寄存器。

write8( ), write16( ), write32( );
写8,16或32位数据。 这个函数是内联的,通常被编译成一个指针。

read8( ), read16( ), read32( );
读取8,16或32位数据。 这个函数是内联的,通常被编译成一个指针。

以下例子来自于RLP范例中的MITE初始化:

iBus* bus = NULL;
tAddressSpace miteSpace;
u32 physicalBar1 = 0;
u32 address = 0xC0;
u32 value = 0;

bus = acquireBoard("PXI::4::2::INSTR");
miteSpace = bus->createAddressSpace(kPCI_BAR0);
physicalBar1 = bus->get(kBusAddressPhysical, kPCI_BAR1);

value = (physicalBar1 & 0xFFFFFF00L) | 0x80;
miteSpace.write32(address, value);

bus->destroyAddressSpace(miteSpace);
releaseBoard(bus);

为什么要使用iBus
  1. iBus可以方便地移植到新的操作系统。 在iBus中有两个系统特定功能:portBoard(...)和releaseBoard(...)。 而对于支持DMA的系统,还需要分配allocDMA(...)和freeDMA(...)。
  2. iBus适用于Chip Objects,Chip Objects要求使用iBus进行操作。
  3. 在大多数编译器中,寄存器使用tAddressSpace和iBus来执行读写,这可以生成快速的执行代码。


相关链接:

附件:


Ex_Arch.png - Ex_Arch.png


报告日期: 11/15/2002
最近更新: 08/28/2017
文档编号: 2REG76PG