stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2986回复:27

Direct-IO方式只能读取单个双字,而不能读取多个双字,为什么?(90分)

楼主#
更多 发布于:2003-10-18 19:05
采用DS编写的Direct-IO方式驱动程序(PCI9054),已经实现了单个双字的读取。

单如果我在应用程序中开辟一个双字的数组,想写入PCI9054中,然后读出来。却不能成功。请高手指教。

部分程序如下:
应用程序:
#define PCI9054_IOCTL_802_ReadBase2 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_IN_DIRECT, FILE_READ_DATA)
#define PCI9054_IOCTL_803_WriteBase2 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_OUT_DIRECT, FILE_WRITE_DATA)

#define IOCTL_INBUF_SIZE 10
#define IOCTL_OUTBUF_SIZE 10
写数据给设备
void Test_PCI9054_IOCTL_803_WriteBase2(void)
{
ULONG bufInput[IOCTL_INBUF_SIZE]; // Input to device
ULONG nOutput; // Count written to bufOutput
//开辟数组,准备写入设备卡中:
for(ULONG n=0;n<IOCTL_INBUF_SIZE;n++)
{
bufInput[n]=20;
}
// Call device IO Control interface in driver
if (!DeviceIoControl(hDevice,
PCI9054_IOCTL_803_WriteBase2,
bufInput,
sizeof(bufInput),
NULL,
0,
&nOutput,
NULL)
  )
{
printf(\"\\nERROR: DeviceIoControl returns %0x.\", GetLastError());
Exit(1);
}
}

读设备中已经写入的数据:
void Test_PCI9054_IOCTL_802_ReadBase2(void)
{

ULONG bufOutput[IOCTL_OUTBUF_SIZE]; // Output from device
ULONG nOutput; //

if (!DeviceIoControl(hDevice,
PCI9054_IOCTL_802_ReadBase2,
NULL,
                         0,
bufOutput,
sizeof(bufOutput),
&nOutput,
NULL)
  )
{
printf(\"\\nERROR: DeviceIoControl returns %0x.\", GetLastError());
Exit(1);
}
    printf(\"\\n------>>>>>> data read <<<<<<------\");
for(ULONG m=0;m<nOutput;m++)
{
printf(\"\\nread data[%d]=%x\",m,bufOutput[m]);
}
printf(\"\\n\\n\");
}


驱动程序:
写:
VOID PCI9054Device::Serial_PCI9054_IOCTL_803_WriteBase2_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

PULONG  pInBuffer  = (PULONG) I.IoctlBuffer(); //输入缓冲区指针,传入要写入的数据

ULONG   count=10;    //从输入缓冲区要写入的数据个数

m_MemoryRange1_ForBase2.outd(0x10,pInBuffer,count);

I.Information() = count;
I.Status() = status;
m_DriverManagedQueue.PnpNextIrp(I);
}


VOID PCI9054Device::Serial_PCI9054_IOCTL_802_ReadBase2_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

KMemory Mem(I.Mdl());    
PULONG pOutBuffer = (PULONG) Mem.MapToSystemSpace();  //输出缓冲区指针,传出读取的数据
 
ULONG   count=10;    //读取的数据个数

m_MemoryRange1_ForBase2.ind(0x10,pOutBuffer,count);

I.Information() = count;
I.Status() = status;
m_DriverManagedQueue.PnpNextIrp(I);
}

读取的结果显示,只有数组的第一个元素读取正确,而其他读取的数据不正确。我分析是可能没有把数组写入PCI9054板卡中,只是把数组的第一个元素写入了板卡中。

请高手指教,如何能实现把应用程序中的一个数组的数据全部写入PCI9054中,又能正确读取出来?





[编辑 -  10/23/03 by  stephen80320]

[编辑 -  10/27/03 by  stephen80320]

最新喜欢:

hardkinghardki...
X_ray
驱动中牛
驱动中牛
  • 注册日期2003-02-03
  • 最后登录2004-07-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-10-18 20:03
你把数据写到什么地方?9052的配置空间?FIFO?还是LOCAL MEM?
从你的驱动看似乎是配置空间
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-10-18 20:09
你把数据写到什么地方?9052的配置空间?FIFO?还是LOCAL MEM?
从你的驱动看似乎是配置空间


是写在Local Memory空间里的。
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-10-19 13:36
进一步分析结果,发现高16位数据读取是正确的,而低16位数据不正确。

但我把原来的ULONG 型改成USHORT型后,再次进行读写,发现所有的数组元素读取都不正确了。

而且,还不知道是读的问题还是写的问题。

请高手指点迷津



[编辑 -  10/19/03 by  stephen80320]
X_ray
驱动中牛
驱动中牛
  • 注册日期2003-02-03
  • 最后登录2004-07-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-10-20 00:05
硬件是否有问题?可以用示波器看看波形从而确定是读还是写的问题
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-10-20 13:47
现在又发现:
当我在偏移地址为0处写入数据10 , 然后在偏移地址为0处读出10

在偏移地址为4处 写入数据11, 然后在偏移地址为4处读出11,立即再次调用DeviceIoControl在偏移地址0处读出10;紧接着,再次在偏移地址为4处读取数据,这时发现读出的数据变为ffff(Hex)了。

请问这是什么原因?
sunyou120
驱动牛犊
驱动牛犊
  • 注册日期2002-10-23
  • 最后登录2005-04-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-10-20 16:36
你的
m_MemoryRange1_ForBase2.outd(0x10,pInBuffer,count);
I.Information() = count;
两句话是不是有问题呀?
ds帮助文档中outd的最后一个参数count为要写的dwords的个数
而Information为:informs the I/O manager how many bytes of data the driver is returning。也就是以字节为单位。

不知是不是有问题。
sunyou120
驱动牛犊
驱动牛犊
  • 注册日期2002-10-23
  • 最后登录2005-04-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-10-20 16:37
你的
m_MemoryRange1_ForBase2.outd(0x10,pInBuffer,count);
I.Information() = count;
两句话是不是有问题呀?
ds帮助文档中outd的最后一个参数count为要写的dwords的个数
而Information为:informs the I/O manager how many bytes of data the driver is returning。也就是以字节为单位。

所以是不是I.Information() = count*(sizeof (ULONG);
不知是不是有问题。
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-10-20 23:54
硬件是否有问题?可以用示波器看看波形从而确定是读还是写的问题


谢谢提供建议。不过教研室里的示波器最近坏了,正在打算购买新的一台 :(
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-10-21 00:00
你的
m_MemoryRange1_ForBase2.outd(0x10,pInBuffer,count);
I.Information() = count;
两句话是不是有问题呀?
ds帮助文档中outd的最后一个参数count为要写的dwords的个数
而Information为:informs the I/O manager how many bytes of data the driver is returning。也就是以字节为单位。

所以是不是I.Information() = count*(sizeof (ULONG);
不知是不是有问题。


的确写的不正确,谢谢指正。不过我改正后,还是不能解决问题。读出的数组中,如果是USHORT型的,则只有数组的头两个数据读取完全正确。后面的其它数据仅仅个别读取正确,而大多数数据不正确。

更奇怪的是,当我连续从同一地址读取数据,则每次读取的数据都有变化(除了数组头两个数据始终正确)。

使用DeviceIoControl()进行IO数据传输,已经困扰我很久了,请高人指教。
CYoung
驱动中牛
驱动中牛
  • 注册日期2003-06-10
  • 最后登录2005-01-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-10-21 09:11
看看你的数据线有多少条,如果是只有8条的话,会出现这个问题,数据线要和数据类型相配合
答得好的话,请兄弟们加点分,那是对我的肯定
sunyou120
驱动牛犊
驱动牛犊
  • 注册日期2002-10-23
  • 最后登录2005-04-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-10-21 09:18

你的硬件有没有用Windriver之类的东东调试呀?通不通?

[编辑 -  10/21/03 by  sunyou120]
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2003-10-22 15:54
看看你的数据线有多少条,如果是只有8条的话,会出现这个问题,数据线要和数据类型相配合


即使这样,那么当我把数据类型由ULONG(32位) 改为USHORT(16位)时,理应不会发生这样的问题了,但是为什么还是这种现象呢?
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2003-10-22 15:56
各位老大,是否是硬件配置不对?

实在着急,希望高人帮助我一把。
X_ray
驱动中牛
驱动中牛
  • 注册日期2003-02-03
  • 最后登录2004-07-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2003-10-22 22:12
你的问题应该从硬件和软件两方面去查找,硬件是否支持非双字边界读取?系统是否分配了资源允许你读写?
wirelessboy
驱动牛犊
驱动牛犊
  • 注册日期2002-04-21
  • 最后登录2003-12-17
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2003-10-22 23:33
各位老大,是否是硬件配置不对?

实在着急,希望高人帮助我一把。


你的总线是16的吧?
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2003-10-23 11:39
你的问题应该从硬件和软件两方面去查找,硬件是否支持非双字边界读取?系统是否分配了资源允许你读写?


请问:什么是非双字边界读取?

另外,因为我是用DS开发的,在生成框架的向导里,我定义了把Base2映射成Memory空间。

使用向导开发的过程请见附件。

除了在向导里做了某些指定外,我没有再对PCI方的配置进行任何操作(当然EEPROM配置是做了的)。因为我认为在DS生成时,各种配置已经为我做好了。不知道这样对不对?是否还需要在驱动程序中再进行PCI方的配置?

[编辑 -  10/23/03 by  stephen80320]
附件名称/大小 下载次数 最后更新
2003-10-23_PCI9054开发过程.doc (364KB)  2
X_ray
驱动中牛
驱动中牛
  • 注册日期2003-02-03
  • 最后登录2004-07-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2003-10-23 20:06
双字边界就是能够被4整除的地址,10就不是双字边界,所以你的硬件要支持非双字边界。资源可以在系统中看到。
zmmh_77
驱动牛犊
驱动牛犊
  • 注册日期2003-06-10
  • 最后登录2008-12-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2003-10-23 20:21
把你的源代码发上来我给你看看。
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2003-10-23 21:54
双字边界就是能够被4整除的地址,10就不是双字边界,所以你的硬件要支持非双字边界。资源可以在系统中看到。


谢谢大侠指点。那么要使硬件支持非双字边界,是不是通过EEPROM对Local方的配置进行设置?
上一页
游客

返回顶部