stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:3148回复: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...
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-10-29 21:48
谢谢各位
问题已经解决了
实际上,我编写的程序基本上没有问题(不过感谢楼上的一位朋友指出其中的一个小问题)。
因为硬件是我师兄作的,驱动程序是我编写的,所以在和我师兄沟通的时候,不是能很好的沟通。

不过非常感谢这么多的朋友出谋划策,提出解决问题的方案。
每位朋友都加了分数。

以后有问题,希望各位能继续赐教。

X_ray
驱动中牛
驱动中牛
  • 注册日期2003-02-03
  • 最后登录2004-07-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-10-27 21:21
硬件是你自己做的吗?故障的可能性太多了
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-10-27 19:55
用WINDRIVER附带的功能作了一个试验:

在PCIBAR2偏移地址为0出写了一个USHORT型数据0,然后读出也是0

在偏移地址4处写入数据OX44,然后读出也是0X44。

在偏移地址8处写入数据0X88,然后读出也是0X88。此时,我再在偏移地址为0处读数据,读出为0;接着,在偏移地址为4处读取数据,读出也正确,为0X44。但是,我接下来在偏移地址为8处读数据时,此时读出的数据是0XFFFF。

看来这表明硬件有错是不是?如果是硬件有错,请问有可能是哪里处错?

凡提供建议者均会在最后给分!  
X_ray
驱动中牛
驱动中牛
  • 注册日期2003-02-03
  • 最后登录2004-07-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-10-25 19:33
板子的Local方数据线16根
PCI方数据线32根


你的硬件不支持32位操作,9054好像是pci to isa bridge,isa是16位的。
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-10-24 22:17
非整字边界读写功能是硬件决定的,和软件无关。你申请pci资源时到底是申请的IO空间还是MEM空间。


对Base2声请的是MEM空间
X_ray
驱动中牛
驱动中牛
  • 注册日期2003-02-03
  • 最后登录2004-07-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-10-24 20:15
非整字边界读写功能是硬件决定的,和软件无关。你申请pci资源时到底是申请的IO空间还是MEM空间。
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-10-24 10:26
板子的Local方数据线16根
PCI方数据线32根
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-10-23 23:17
把你的源代码发上来我给你看看。


那么让大侠费心了。

源代码在本帖附件中。在代码里,我是想实现对Base2的IO读写功能,但对数组不能成功。请尤其注意驱动程序中的:Serial_PCI9054_IOCTL_802_ReadBase2_Handler(KIrp I)
Serial_PCI9054_IOCTL_803_WriteBase2_Handler(KIrp I)
以及应用程序中的:
Test_PCI9054_IOCTL_802_ReadBase2(void)
Test_PCI9054_IOCTL_803_WriteBase2(void)
这四个例程是否正确。

对于Base3的读写例程,因为硬件中没有用到它,所以对Base3的例程基本上没有怎么写。所以对这些例程,忽略就够了。重点是对Base2的读写。

另外,使用向导生成框架的过程在前面几个帖子里贴出来了(也在附件中)。

我的电子邮件是 ZhangZL@vip.163.com


[编辑 -  10/24/03 by  stephen80320]
附件名称/大小 下载次数 最后更新
2003-10-23_pci9054.rar (2585KB)  6
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-10-23 21:54
双字边界就是能够被4整除的地址,10就不是双字边界,所以你的硬件要支持非双字边界。资源可以在系统中看到。


谢谢大侠指点。那么要使硬件支持非双字边界,是不是通过EEPROM对Local方的配置进行设置?
zmmh_77
驱动牛犊
驱动牛犊
  • 注册日期2003-06-10
  • 最后登录2008-12-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-10-23 20:21
把你的源代码发上来我给你看看。
X_ray
驱动中牛
驱动中牛
  • 注册日期2003-02-03
  • 最后登录2004-07-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-10-23 20:06
双字边界就是能够被4整除的地址,10就不是双字边界,所以你的硬件要支持非双字边界。资源可以在系统中看到。
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2003-10-23 11:39
你的问题应该从硬件和软件两方面去查找,硬件是否支持非双字边界读取?系统是否分配了资源允许你读写?


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

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

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

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

[编辑 -  10/23/03 by  stephen80320]
附件名称/大小 下载次数 最后更新
2003-10-23_PCI9054开发过程.doc (364KB)  2
wirelessboy
驱动牛犊
驱动牛犊
  • 注册日期2002-04-21
  • 最后登录2003-12-17
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2003-10-22 23:33
各位老大,是否是硬件配置不对?

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


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

实在着急,希望高人帮助我一把。
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2003-10-22 15:54
看看你的数据线有多少条,如果是只有8条的话,会出现这个问题,数据线要和数据类型相配合


即使这样,那么当我把数据类型由ULONG(32位) 改为USHORT(16位)时,理应不会发生这样的问题了,但是为什么还是这种现象呢?
sunyou120
驱动牛犊
驱动牛犊
  • 注册日期2002-10-23
  • 最后登录2005-04-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2003-10-21 09:18

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

[编辑 -  10/21/03 by  sunyou120]
CYoung
驱动中牛
驱动中牛
  • 注册日期2003-06-10
  • 最后登录2005-01-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2003-10-21 09:11
看看你的数据线有多少条,如果是只有8条的话,会出现这个问题,数据线要和数据类型相配合
答得好的话,请兄弟们加点分,那是对我的肯定
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
19楼#
发布于: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数据传输,已经困扰我很久了,请高人指教。
上一页
游客

返回顶部