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

关于IO读写问题(30分)

楼主#
更多 发布于:2003-10-17 07:03
我用DS编写了一个驱动程序,实现简单的PCI9054读写功能。采用Buffer方式。
程序代码如下。本代码实现对Base2的读功能:

应用程序中的代码片断:

#define PCI9054_IOCTL_802_ReadBase2 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_READ_DATA)

void Test_PCI9054_IOCTL_802_ReadBase2(void)
{
ULONG bufOutput[IOCTL_OUTBUF_SIZE]; // Output from device
ULONG nOutput; // Count written to bufOutput

printf(\"\\n---------ready for reading from device---------\");
if (!DeviceIoControl(hDevice,
PCI9054_IOCTL_802_ReadBase2,
NULL,
0,
bufOutput,
IOCTL_OUTBUF_SIZE,
&nOutput,
NULL)
  )
{
printf(\"ERROR: DeviceIoControl returns %0x.\", GetLastError());
Exit(1);
}
}

对应的驱动程序代码如下:
VOID PCI9054Device::Serial_PCI9054_IOCTL_802_ReadBase2_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

PULONG pbuffer=(PULONG)I.IoctlBuffer();

ULONG dwtotalsize=I.IoctlOutputBufferSize(CURRENT); //bytes

m_MemoryRange1_ForBase2.ind(0x00,pbuffer,dwtotalsize );



I.Information() = dwtotalsize;
I.Status() = status;

m_DriverManagedQueue.PnpNextIrp(I);
}

但是每次读的都是不正确的数据(事先已经向Base2写入了数据)。请各位高手指教错在哪里?
如果分不够,我可以开贴再加分数。

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

[编辑 -  10/17/03 by  stephen80320]
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-10-17 10:51
我觉得是Serial_PCI9054_IOCTL_802_ReadBase2_Handler(KIrp I)
里面的代码有问题。但是不知道如何改?

哪位能指出如何改正?
CYoung
驱动中牛
驱动中牛
  • 注册日期2003-06-10
  • 最后登录2005-01-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-10-17 10:58
你的应用程序要进行通讯,是下在test_xx下面加入这个:
PULONG pbuffer=(PULONG)bufInput;
答得好的话,请兄弟们加点分,那是对我的肯定
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-10-17 12:25
你的应用程序要进行通讯,是下在test_xx下面加入这个:
PULONG pbuffer=(PULONG)bufInput;  


又麻烦CYoung大哥了。
不过能不能说得详细些?最好能帮我把相关的那几个语句写出来。如果分数嫌少,我可以再开贴给分。
CYoung
驱动中牛
驱动中牛
  • 注册日期2003-06-10
  • 最后登录2005-01-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-10-17 13:07
在应用程序里面:
PULONG pbuffer=(PULONG)bufInput;
然后驱动程序里面试试这样:
m_MemoryRange1_ForBase2.ind(0x00);




答得好的话,请兄弟们加点分,那是对我的肯定
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-10-17 14:04
在应用程序里面:
PULONG pbuffer=(PULONG)bufInput;
然后驱动程序里面试试这样:
m_MemoryRange1_ForBase2.ind(0x00);




 


我试了,不过还是不行。
午饭后看了一些资料,说是对于大量的数据传送,采用IO-Direct好一些。所以刚才我改写了程序,改成Method-IN-DIRECT和METHOD-OUT-DIRECT.
不过Write Base2的例程不会写。框架如下:
应用程序:
void Test_PCI9054_IOCTL_803_WriteBase2(void)
{
ULONG bufInput[IOCTL_INBUF_SIZE]; // Input to device
ULONG bufOutput[IOCTL_OUTBUF_SIZE]; // Output from device
ULONG nOutput; // Count written to bufOutput
ULONG   j;

for(j=0;j<IOCTL_INBUF_SIZE;j++)  
bufInput[j]=16;

if (!DeviceIoControl(hDevice,
PCI9054_IOCTL_803_WriteBase2,
pBuffer,
IOCTL_INBUF_SIZE,
bufOutput,
IOCTL_OUTBUF_SIZE,
&nOutput,
NULL)
  )
{
printf(\"\\nERROR: DeviceIoControl returns %0x.\", GetLastError());
Exit(1);
}
}

相关的驱动程序:
VOID PCI9054Device::Serial_PCI9054_IOCTL_803_WriteBase2_Handler(KIrp I)
{
KMemory Mem(I.Mdl());
// Use the memory object to create a pointer to the caller\'s buffer
PULONG pOutBuffer = (PULONG) Mem.MapToSystemSpace();  //输出缓冲区
PULONG  pInBuffer       = (PULONG) I.IoctlBuffer();     //输入缓冲区

ULONG   Offset=0;
ULONG   count;

Offset   = *pInBuffer;
count    = *(pInBuffer+1);
    

m_MemoryRange1_ForBase2.outd(Offset,pOutBuffer,count);
I.Information() = count;
I.Status() = status;
}
但是每次执行到这里,就系统重启。

你能不能告诉我改怎么写好这个write base2的例程?
(我采用的METHOD-OUT-DIRECT方式)



[编辑 -  10/17/03 by  stephen80320]
CYoung
驱动中牛
驱动中牛
  • 注册日期2003-06-10
  • 最后登录2005-01-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-10-17 14:14
我给你一个例子给你参考吧:
test_xxx:
#pragma pack(push,1)
struct pMEMRW
{
ULONG m_nAddress;
UCHAR m_nData;
}*m_pMEMRW;
#pragma pack(pop)

m_pMEMRW = (pMEMRW*)bufInput;
          m_pMEMRW->m_nAddress = 0x12345;
         printf(\"A:%X\\n\",m_pMEMRW->m_nData);


xxx_handle:
#pragma pack(push,1)
struct pMEMRW
{
ULONG m_nAddress;
UCHAR m_nData;
}*m_pMEMRW;
#pragma pack(pop)
        m_pMEMRW = (pMEMRW*)I.IoctlBuffer();
        m_pMEMRW->m_nData = m_MemoryRange.ind(m_pMEMRW->m_nAddress)



肯定可以的。试下
答得好的话,请兄弟们加点分,那是对我的肯定
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-10-17 14:43
是BUFFER方式的吧,我试试

[编辑 -  10/17/03 by  stephen80320]
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-10-17 15:35
我试了,还是不行。可能是某些地方我忽视了。你能不能把test_xxx和xxx_handle完整的给我?

无论如何,还是非常感谢你给我的帮助。并期待test_xxx,xxx_handle完整的代码。

我的信箱是ZhangZL@vip.163.com
CYoung
驱动中牛
驱动中牛
  • 注册日期2003-06-10
  • 最后登录2005-01-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-10-17 16:25
没有理由阿,这个加上DeviceIoControl就是完整的程序了阿
答得好的话,请兄弟们加点分,那是对我的肯定
stephen80320
驱动小牛
驱动小牛
  • 注册日期2003-07-01
  • 最后登录2003-12-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-10-17 16:58
没有理由阿,这个加上DeviceIoControl就是完整的程序了阿


那我再试试,成功了我告诉你。
还想请教一下,能不能给个DIRECT-OUT方式的驱动程序例子,几句关键代码也行?主要是DIRECT-OUT方式的驱动程序,明天要交给导师了。急!
游客

返回顶部