EM335x主板ISA总线的高级应用

 2015-7-15          [nemail]    
[lablebox]

  对工控主板EM335x精简ISA扩展总线基本读写操作的介绍,已包含在EM335x编程手册中。本文将介绍在Windows CE平台上,通过精简ISA总线进行数据块读写的方法。所谓数据块读写,是指一次API调用对一个地址端口读写多个数据的操作。数据块读写能有效提高数据读写的效率,在数据采集传输中有广泛的应用。

 

  要对ISA总线进行读写,首先需要打开设备文件“ISA1:”如下:

 

  打开ISA文件
  HANDLE hISA;
  hISA = CreateFile(_T('ISA1:'), // name of device
    GENERIC_READ|GENERIC_WRITE, // desired access
    FILE_SHARE_READ|FILE_SHARE_WRITE, // sharing mode
    NULL, // security attributes (ignored)
    OPEN_EXISTING, // creation disposition
    FILE_FLAG_RANDOM_ACCESS, // flags/attributes
    NULL); // template file (ignored)

 

  数据块读写功能是通过设备驱动的DeviceIoControl来完成的,需要用到以下数据结构:
  typedef struct
  {
    PBYTE pReadBuf; // ISA读数据buffer, 只能一个buffer有效
    PBYTE pWriteBuf; // ISA写数据buffer, 只能一个buffer有效
    DWORD dwDataLength; // length of data in byte
    DWORD dwDataPortOfs; // 读写的起始地址 = 0x00 – 0xFF
    DWORD dwInc; // = 0: 固定地址, > 0: 读写后地址自动增加
  } ISA_BLOCK_INFO, *PISA_BLOCK_INFO;

 

  在上述数据结构中:

  pReadBuf为进行读操作时的数据buffer,读操作具体为8-bit数据读。注意:数据结构中,pReadBuf和pWrietBuf只能有一个有效。

  pWriteBuf为进行写操作时的数据buffer,写操作具体为8-bit数据读。注意:数据结构中,pReadBuf和pWrietBuf只能有一个有效。

  dwDataPortOfs为读写的端口地址,范围为0x00 – 0xFF。

  dwDataLength为本数据块读或写的字节数。

  dwInc为每次读写后,地址的自动增量,dwInc = 0:表示固定地址读写,dwInc > 0: 表示每次读写后,地址会自动增加dwInc,作为下一次的读写地址。当地址超过0xFF时,会折回到地址0x00。

 

  如果要进行单一数据块读写功能,只需定义一个ISA_BLOCK_INFO结构变量,如BlockInfo,并按照应用需求填写相应的参数。然后就可调用系统API进行设置了:

  ISA_BLOCK_INFO BlockInfo;

  memset(&BlockInfo, 0, sizeof(ISA_BLOCK_INFO));
  // 填写输入参数值BlockInfo...

 

  对读操作,直接调用标准读函数:
  DWORD dwNbBytesRead = 0;
  BOOL bRet = ReadFile(hISA, // 打开“ISA1:”返回的Handler
    &BlockInfo, // 输入数据结构指针
    sizeof(ISA_BLOCK_INFO), // 数据结构Size
    &dwNbByteRead, NULL);

 

  对写操作则为:
  DWORD dwNbBytesWritten = 0;
  BOOL bRet = WriteFile(hISA, // 打开“ISA1:”返回的Handler
    &BlockInfo, // 输入数据结构指针
    sizeof(ISA_BLOCK_INFO), // 数据结构Size
    &dwNbByteWritten, NULL);

 

  如果要执行混合的数据块的读写操作,则需要定义ISA_BLOCK_INFO数组,并根据实际应用填写数组参数。例如需要进行3组数据块读写,实现代码如下:
  ISA_BLOCK_INFO BlockInfo[3];
  DWORD dwTotalSize = sizeof(ISA_BLOCK_INFO) * 3;

  memset(BlockInfo, 0, dwTotalSize);
  // 填写输入参数值BlockInfo... 

  BOOL bRet = DeviceIoControl(hISA, // 打开“ISA1:”返回的Handler
    0, // 无需定义命令码,置为0
    (LPVOID)BlockInfo, // 块读写数据结构变量指针
    dwTotalSize, // 整个结构数组的size 
    NULL, 0, // 不使用这组参数 
    NULL, NULL);

  

  上述操作的主要特点是提高访问ISA总线的效率,因为每次调用驱动程序API,都会有一个几微秒的系统开销。对多字节的数据块读写,这样的开销应用程序就需要注意,否则会发现CPU的负载不合理的升高。


  相关阅读:《ESM335x工控主板ISA总线DMA数据传输》

[lablebox]