[讨论]FPGA2USB (68013)传输数据时出现的一些现象
小弟在做一个FPAG to USB(68013)数据传输的项目,Xilinx的sptan3系列FPGA和56管脚的68013;采用的方案:上位机程序用VC++编写,由于传输文件数据大概在几十M到几百兆之间,所以采用多线程,单独开个线程来发数据,这样可以避免数据堵塞。68013固件是采用slavefifo模式,4缓冲配置。
FPGA固件是一个USB接收模块,将数据接收后放在一个ip核的ram中,待ram满后在一次发给主板的SDRAM中。
调试现象:点击上位机程序的开始发送后,用USBHOUND观察数据,发现没有,然后关掉上位机程序,发现任务管理器中程序的进程还在运行,强行杀也杀不掉,接着我断开主板与电脑USB连接,发现任务管理器的程序进程没了,同时USBHOUND中有了我发的数据,通过核对,发现数据是正确的。这次希望你通过请教和讨论,帮我排除点干扰找出原因,下附代码:
上位机的发数据线程函数:UINT StartThread(void * pParam)
{
CThreadParam* ThreadParam;
CPrint4Dlg* TestDlg;
HANDLE hOutDevice = NULL;
PUCHAR outBuffer = NULL;
ULONG CurrentTransferSize;
ULONG OutPipeNum;
ULONGi;
BULK_TRANSFER_CONTROL outBulkControl;
THREAD_CONTROL outThreadControl;
//得到线程参数
ThreadParam=(CThreadParam *)pParam;
TestDlg=ThreadParam->testDlg;
//打开设备
if(bOpenDriver(&hOutDevice,strDevname.GetBuffer(strDevname.GetLength()))!= TRUE)
{
TestDlg->m_strOutput+="打开设备失败,测试线程结束\r\n";
ThreadParam->bUpdate=TRUE;
return 0;
}
//进行数据传输
OutPipeNum=0;
CurrentTransferSize = 8192;
outBuffer = (unsigned char *)malloc(CurrentTransferSize);
Ripdata_buf =(BYTE*)HeapAlloc(GetProcessHeap(),0,CurrentTransferSize);
TestDlg->file.Seek(438560,CFile::begin);
TestDlg->file.Read(Ripdata_buf,CurrentTransferSize);
while(!gStopPrint)//全局变量来决定是否退出测试线程
{
for (i=0;i<CurrentTransferSize;i++)
outBuffer = Ripdata_buf;
outBulkControl.pipeNum = OutPipeNum;
outThreadControl.hDevice = hOutDevice;
outThreadControl.Ioctl = IOCTL_EZUSB_BULK_WRITE;
outThreadControl.InBuffer = (PVOID)&outBulkControl;
outThreadControl.InBufferSize = sizeof(BULK_TRANSFER_CONTROL);
outThreadControl.OutBuffer = outBuffer;
outThreadControl.OutBufferSize = CurrentTransferSize;
outThreadControl.status = FALSE;
outThreadControl.BytesReturned = 0;
outThreadControl.status= DeviceIoControl(outThreadControl.hDevice,
outThreadControl.Ioctl,
outThreadControl.InBuffer,
outThreadControl.InBufferSize,
outThreadControl.OutBuffer,
outThreadControl.OutBufferSize,
&outThreadControl.BytesReturned,
NULL
);
//如果发生错误,停止数据传输
if ((!outThreadControl.status)||(outThreadControl.BytesReturned != CurrentTransferSize))
{
TestDlg->m_strOutput+= "Error: Write failed\r\n";
Errors++;
gStopPrint = TRUE;
}
SetEvent(hEvent);
ThreadParam->bUpdate=TRUE;
}
free(outBuffer);
CloseHandle(hOutDevice);
ThreadParam->bUpdate=TRUE;
return 0;
}
68013固件一些配置: CPUCS = 0x12;//48MHZ CLKOUT ENALBE
IFCONFIG =0x43;//使用外部时钟,IFCLK输入不反向
SYNCDELAY;
EP2CFG=0xA0; //需要设定为四缓冲,每个缓冲区大小为512字节
SYNCDELAY;
EP4CFG=0x00;
SYNCDELAY;
EP6CFG=0xE0;
SYNCDELAY;
EP8CFG=0x00;
SYNCDELAY;
FIFORESET = 0x80; // activate NAK-ALL to avoid race conditions
SYNCDELAY; // see TRM section 15.14
FIFORESET = 0x02; // reset, FIFO 2
SYNCDELAY; //
FIFORESET = 0x06; // reset, FIFO 6
SYNCDELAY; //
FIFORESET = 0x00; // deactivate NAK-ALL
SYNCDELAY;
PINFLAGSAB = 0xE6; // FLAGA - fixed EP6PF, FLAGB - fixed EP6FF
SYNCDELAY;
PINFLAGSCD = 0xf8; // FLAGC - fixed EP2EF, FLAGD - reserved
SYNCDELAY;
PORTACFG |=0x00;//0x40; // SLCS, set alt. func. of PA7 pin
SYNCDELAY;
FIFOPINPOLAR = 0x00; // all signals active low,
SYNCDELAY;
OEA|=0x0F;
//小于64字节有效
//EP6FIFOPFH=0x00; //DEIS PKSTATPK2 PK1 PK0 0 PFC9 PFC8
//EP6FIFOPFL=0x40; //PFC7 PFC6 PFC5 PFC4 PFC3 PFC2 PFC1 PFC0
// handle the case where we were already in AUTO mode...
EP2FIFOCFG = 0x01; // AUTOOUT=0, WORDWIDE=1
SYNCDELAY;
EP2FIFOCFG = 0x11; // AUTOOUT=1, WORDWIDE=1
SYNCDELAY;
EP6FIFOCFG = 0x09; // AUTOIN=1, ZEROLENIN=0, WORDWIDE=1
SYNCDELAY;
//IO设置
PORTCCFG=0x00;
PORTECFG=0x00;
OEC=0x00;
OEE=0xff;
//串口初始化
// PA3=0;
PA0=1;
enum_high_speed=FALSE;
FPGA接收模块状态机:case(STATE)
IDLE:
begin
//添加RESET状态
data_wr<='h0;//写数据初始化
u_slwr<='b1;
u_slrd<='b1;
u_sloe<='b1;
u_addr0<='b1;
u_addr1<='b1;
oe<='b0;
ena<='b0;
enb<='b0;
addra<=13'h1fff;
addrb<=13'h1fff;
dina_i<='h0;
wr_flag<='b0;
flag <= 'b0;
STATE<=READ_EVENT;
end
READ_EVENT:
begin
//enb<='b0;
wr_flag<='b1;
u_addr0<='b0;
u_addr1<='b0;
STATE<=POINT_TO_OUT_FIFO;
end
POINT_TO_OUT_FIFO:
begin
if(u_flagc)
begin
u_sloe<='b0;
u_slrd<='b1;
STATE<=DATA_READY;
end
else
begin
u_sloe<='b1;
u_slrd<='b1;
STATE<=POINT_TO_OUT_FIFO;
end
end
DATA_READY:
begin
if((u_flagc&&data=='h0100&&!flag)||(u_flagc&&flag))
begin
flag<=1'b1;
u_slrd<='b0;
addra<=addra+1;
dina_i<=data;////////////////////data_src
ena<='b1;
enb<='b0;
STATE<=READ;
end
else
begin
u_slrd<='b1;
u_sloe<='b1;
STATE<=POINT_TO_OUT_FIFO;
end
end
READ:
begin
u_slrd<='b1;
ena<='b0;
if(addra!=ADDR_FULL)
STATE<=DATA_READY;
else
STATE<=READ_END;
end
READ_END:
begin
u_slrd<='b1;
u_sloe<='b1;
u_addr0<='b0;
u_addr1<='b0;
addra<='h1fff;
STATE<=WRITE_EVENT;
end
WRITE_EVENT:
begin
wr_flag<='b0;
sd_flag<='b0;
; enb<='b0;
STATE<=POINT_TO_IN_FIFO;
end
POINT_TO_IN_FIFO:
begin
addrb<=addrb+1;
ena<='b0;
enb<='b1;
STATE<=WRITE;
end
WRITE:
begin
if(addrb!=ADDR_FULL)
begin
addrb<=addrb+1;
sd_data<=doutb;
ena<='b0;
enb<='b1;
sd_flag<=1;
STATE<=WRITE;
end
else
begin
addrb<='h1fff;
ena<='b0;
enb<='b0;
STATE<=WRITE_END;
end
end
WRITE_END:
begin
sd_flag<='b0;
wr_flag<='b0;
addrb<='h1fff;//add by lww
u_addr0<='b1;
u_addr1<='b1;
STATE<=IDLE;
end
default:
STATE<=IDLE;
endcase
end
end 没人理。。。。
坚持我的,调试补充:
线程中outbuffer初始化把
for (i=0;i<CurrentTransferSize;i++)
outBuffer = Ripdata_buf;
改成for (i=0;i<CurrentTransferSize;i++)
outBuffer = i;
是可以正常传输的,而且我通过显示Ripdata_buf看到的数据和我文件数据时一致的,说明我读取文件时没错的,还有没改时按开始线程,程序一致是挂起状态,初步判断是DeviceIoControl 这个函数被长时间阻塞了,可为什么会阻塞却搞不清
当你读一个包,而EPIN没有数据时,或者你发一个包,而EPOUT满了的时候,就会导致这种现象。这个没办法解决,除非你能让读线程超时自动返回(好象不行吧,我直接在板上焊了个小开关,一卡掉立刻关程序复位芯片)。 wye11083 发表于 2012-4-19 20:38 static/image/common/back.gif
当你读一个包,而EPIN没有数据时,或者你发一个包,而EPOUT满了的时候,就会导致这种现象。这个没办法解决 ...
终于等到你了,当时看到你回别人的帖子就知道你应该能帮到我,可以没权限短信你,
我再补充几点我的看法吧:
1、我在网上也查到很多解释说当EPIN没数据时,读包会出现这种状况。为了排除这个可能我单独写了个写线程,没有读的过程只要发出去就ok了,但也出现这种状况。
2、你说的EPOUT满了也会出现这种状况,但是我选用的是SLAVEFIFO模式,不是EPOUT满了就自动发出去了吗?FPGA是一直等待接受,如果有数据分批接受储存在8K的ram里,当ram满时再返回给PC
3、最实际的一个问题是在初始化outbuffer时当我outbuffer=(UCHAR)i;时程序完全正常运行,也有数据流通,但当我outbuffer=Ripdata_buf;是程序就出现挂起状态,只有拔了USB才能关了程序进程,
Ripdata_buf是UCHAR*类型的,它的定义和初始化:
UCHAR* Ripdata_buf;
Ripdata_buf=(unsigned char*)malloc(datasize);
file.Read((void*)Ripdata_buf,datasize); ?那个就不知道了,估计是链接库的问题,我现在没遇到过这种问题了,但是我的确开始时是走了些弯路,因为我用的C#开发,用C++写DLL,结果开始没处理好,传进去的是Unicode字符串,然后也是出问题。 wye11083 发表于 2012-4-20 00:11 static/image/common/back.gif
?那个就不知道了,估计是链接库的问题,我现在没遇到过这种问题了,但是我的确开始时是走了些弯路,因为我 ...
我没用链接库,直接加了个ezusbsysy.h的头文件,发的数据应该是什么格式的呢,是不是要强制转换下? wye11083 发表于 2012-4-20 00:11 static/image/common/back.gif
?那个就不知道了,估计是链接库的问题,我现在没遇到过这种问题了,但是我的确开始时是走了些弯路,因为我 ...
我没用链接库,直接加了个ezusbsysy.h的头文件,发的数据应该是什么格式的呢,是不是要强制转换下? C++的话就简单多了,就用windows.h里面定义的BYTE * 就行,BYTE 就是unsigned char。我现在就是用byte,没任何问题。我把我的库的头文件贴出来你看看就知道了。传进去的是一个BYTE *数组和一个长度。
#include "stdafx.h"
#include "windows.h"
#include "winioctl.h"
#include "malloc.h"
ULONG DEV_BULK_CONTROL_OUT_EDP = 0;
ULONG DEV_BULK_DATA_OUT_EDP = 1;
ULONG DEV_BULK_CONTROL_IN_EDP = 2;
ULONG DEV_BULK_DATA_IN_EDP = 3;
#define I2CProgram16KA0is0 0xF0
#define I2CProgram16KA0is1 0xF1
#define I2CRead16KA0is0 0xF2
#define I2CRead16KA0is1 0xF3
#define A0TOGGLE 0xF4
#define DATA_BLOCK_SIZE 256
typedef struct _VENDOR_REQUEST_IN
{
BYTE bRequest;
WORD wValue;
WORD wIndex;
WORD wLength;
BYTE direction;
BYTE bData;
} VENDOR_REQUEST_IN, *PVENDOR_REQUEST_IN;
typedef struct __usb_Dev_Descriptor__ {
UCHAR bLength;
UCHAR bDescriptorType;
USHORT bcdUSB;
UCHAR bDeviceClass;
UCHAR bDeviceSubClass;
UCHAR bDeviceProtocol;
UCHAR bMaxPacketSize0;
USHORT idVendor;
USHORT idProduct;
USHORT bcdDevice;
UCHAR iManufacturer;
UCHAR iProduct;
UCHAR iSerialNumber;
UCHAR bNumConfigurations;
} Usb_Device_Descriptor, *pUsb_Device_Descriptor;
typedef struct __usb_String_Descriptor__ {
UCHAR bLength;
UCHAR bDescriptorType;
WCHAR bString;
} Usb_String_Descriptor, *pUsb_String_Descriptor;
typedef PVOID USBD_PIPE_HANDLE;
typedef PVOID USBD_CONFIGURATION_HANDLE;
typedef PVOID USBD_INTERFACE_HANDLE;
typedef enum _USBD_PIPE_TYPE {
UsbdPipeTypeControl,
UsbdPipeTypeIsochronous,
UsbdPipeTypeBulk,
UsbdPipeTypeInterrupt
} USBD_PIPE_TYPE;
typedef struct _USBD_PIPE_INFORMATION {
USHORT MaximumPacketSize;
UCHAR EndpointAddress;
UCHAR Interval;
USBD_PIPE_TYPE PipeType;
USBD_PIPE_HANDLE PipeHandle;
ULONG MaximumTransferSize;
ULONG PipeFlags;
} USBD_PIPE_INFORMATION, *PUSBD_PIPE_INFORMATION;
typedef struct _USBD_INTERFACE_INFORMATION {
USHORT Length;
UCHAR InterfaceNumber;
UCHAR AlternateSetting;
UCHAR Class;
UCHAR SubClass;
UCHAR Protocol;
UCHAR Reserved;
USBD_INTERFACE_HANDLE InterfaceHandle;
ULONG NumberOfPipes;
USBD_PIPE_INFORMATION Pipes;
} USBD_INTERFACE_INFORMATION, *PUSBD_INTERFACE_INFORMATION;
typedef LONG USBD_STATUS;
UCHAR InterfaceInfo;
PUSBD_INTERFACE_INFORMATION pInterface;
typedef struct _BULK_TRANSFER_CONTROL
{
ULONG pipeNum;
} BULK_TRANSFER_CONTROL, *PBULK_TRANSFER_CONTROL;
#define Ezusb_IOCTL_INDEX 0x0800
#define IOCTL_Ezusb_GET_PIPE_INFO CTL_CODE(FILE_DEVICE_UNKNOWN,Ezusb_IOCTL_INDEX + 0,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_Ezusb_GET_DEVICE_DESCRIPTOR CTL_CODE(FILE_DEVICE_UNKNOWN,Ezusb_IOCTL_INDEX + 1,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_EZUSB_BULK_READ CTL_CODE(FILE_DEVICE_UNKNOWN,Ezusb_IOCTL_INDEX + 19,METHOD_OUT_DIRECT,FILE_ANY_ACCESS)
#define IOCTL_EZUSB_BULK_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN,Ezusb_IOCTL_INDEX + 20,METHOD_IN_DIRECT,FILE_ANY_ACCESS)
#define IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN,Ezusb_IOCTL_INDEX+22,METHOD_IN_DIRECT,FILE_ANY_ACCESS)
#define IOCTL_Ezusb_VENDOR_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN,Ezusb_IOCTL_INDEX+5,METHOD_BUFFERED,FILE_ANY_ACCESS)
typedef struct _VENDOR_OR_CLASS_REQUEST_CONTROL
{
// transfer direction (0=host to device, 1=device to host)
UCHAR direction;
// request type (1=class, 2=vendor)
UCHAR requestType;
// recipient (0=device,1=interface,2=endpoint,3=other)
UCHAR recepient;
//
// see the USB Specification for an explanation of the
// following paramaters.
//
UCHAR requestTypeReservedBits;
UCHAR request;
USHORT value;
USHORT index;
} VENDOR_OR_CLASS_REQUEST_CONTROL, *PVENDOR_OR_CLASS_REQUEST_CONTROL;
char pcDriverName[] = "Ezusb-0";
extern "C" __declspec(dllexport) BOOL bOpenDriver (HANDLE & hDevice)
{
char completeDeviceName = "";
strcat (completeDeviceName,"\\\\.\\");
strcat (completeDeviceName,pcDriverName);
hDevice = CreateFile(completeDeviceName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
if (hDevice == INVALID_HANDLE_VALUE)
return (FALSE);
else
return (TRUE);
}
extern "C" __declspec(dllexport) int WriteBuf(int edpnum,BYTE * pBuf,int Length)
{
HANDLE hDevice;
if (bOpenDriver (hDevice) != TRUE)
{
MessageBox(NULL, "Please connect Hardware.",0,0);
return (-1);
}
BULK_TRANSFER_CONTROL bulkControl;
BOOL bResult = FALSE;
int nBytes = 0;
bulkControl.pipeNum = (ULONG)edpnum;
bResult = DeviceIoControl(hDevice,IOCTL_EZUSB_BULK_WRITE,&bulkControl,sizeof(BULK_TRANSFER_CONTROL),pBuf,Length,(unsigned long *)&nBytes,NULL);
if(!bResult)
{
MessageBox(NULL, "Failed To Write Specific Endpoint","Error",MB_ICONSTOP);
CloseHandle(hDevice);
return -1;
}
CloseHandle(hDevice);
return nBytes;
}
extern "C" __declspec(dllexport) int ReadBuf(int edpnum,BYTE * pBuf,int Length)
{
HANDLE hDevice;
if (bOpenDriver (hDevice) != TRUE)
{
MessageBox(NULL, "Please connect Hardware.",0,0);
return (-1);
}
BULK_TRANSFER_CONTROL bulkControl;
BOOL bResult = FALSE;
int nBytes = 0;
bulkControl.pipeNum = (ULONG)edpnum;
bResult = DeviceIoControl(hDevice,IOCTL_EZUSB_BULK_READ,&bulkControl,sizeof(BULK_TRANSFER_CONTROL),pBuf,Length,(unsigned long *)&nBytes,NULL);
if(!bResult)
{
MessageBox(NULL, "Failed To Read Specific Endpoint","Error",MB_ICONSTOP);
CloseHandle(hDevice);
return -1;
}
CloseHandle(hDevice);
return nBytes;
}
extern "C" __declspec(dllexport) BOOL Get_EZUSB_Device_Info()
{
HANDLE hDevice;
if (bOpenDriver (hDevice) != TRUE)
{
MessageBox(NULL, "Please connect Hardware.",0,0);
return (-1);
}
PVOID pvBuffer = 0;
PVOID pdBuffer = 0;
BOOL bResult = FALSE;
int nBytes = 0;
USHORT bVendor;
USHORT bProduct;
PUSBD_PIPE_INFORMATION pPipe;
pvBuffer = (void*)malloc(sizeof(Usb_String_Descriptor) + 128);
pdBuffer = (void*)malloc(sizeof(Usb_Device_Descriptor) + 128);
// Get VID/PID from Device Descriptor
bResult = DeviceIoControl(hDevice,IOCTL_Ezusb_GET_DEVICE_DESCRIPTOR,pdBuffer,sizeof (Usb_Device_Descriptor),pdBuffer,sizeof (Usb_Device_Descriptor),(unsigned long *)&nBytes,NULL);
bVendor = ((Usb_Device_Descriptor*)((void*)pdBuffer))->idVendor;
bProduct = ((Usb_Device_Descriptor*)((void*)pdBuffer))->idProduct;
if (bResult != TRUE)
{
MessageBox(NULL,"Get VID/PID Failed",0,0);
CloseHandle(hDevice);
return FALSE;
}
else if(bVendor != 0x0474 || bProduct != 0x1128)
{
MessageBox(NULL,"Specific Device Not Found (Ven_0474&Dev_1128)","Error",MB_ICONSTOP);
CloseHandle(hDevice);
return FALSE;
}
bResult = DeviceIoControl(hDevice,IOCTL_Ezusb_GET_PIPE_INFO,NULL,0,InterfaceInfo,sizeof(InterfaceInfo),(unsigned long *)&nBytes,NULL);
if (bResult == TRUE)
{
pInterface = (PUSBD_INTERFACE_INFORMATION) InterfaceInfo;
pPipe = pInterface->Pipes;
}
else
{
MessageBox(NULL,"Get Pipe Info Failed",0,0);
CloseHandle(hDevice);
return FALSE;
}
free (pvBuffer); // Free the memory
CloseHandle(hDevice);
return TRUE;
}
extern "C" __declspec(dllexport) int InitUSB()
{
HANDLE hDevice;
if (bOpenDriver (hDevice) != TRUE)
{
MessageBox(NULL, "Please connect Hardware.",0,0);
return (-1);
}
CloseHandle(hDevice);
if(!Get_EZUSB_Device_Info())
return -1;
if (pInterface->NumberOfPipes != 2)
{
MessageBox(NULL, "Specific Hardware not found.",0,0);
return (-1);
}
return 1;
}
extern "C" __declspec(dllexport) int Set_Device_Mode(int Value)
{
HANDLE hDevice;
if (bOpenDriver (hDevice) != TRUE)
{
MessageBox(NULL, "Please connect Hardware.",0,0);
return (-1);
}
VENDOR_OR_CLASS_REQUEST_CONTROL venderctrl;
venderctrl.direction=0;
venderctrl.requestType=2;
venderctrl.recepient=0;
venderctrl.request=0x80;
venderctrl.requestTypeReservedBits=0;
venderctrl.index=0;
venderctrl.value=(USHORT)Value;
BOOL bResult = FALSE;
int nBytes = 0;
bResult = DeviceIoControl(
hDevice,
IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST,
&venderctrl,
sizeof(venderctrl),
NULL,
0,
(unsigned long *)&nBytes,
NULL
);
if (bResult != TRUE)
{
MessageBox(NULL,"Operation Failed.",0,0);
CloseHandle(hDevice);
return -1;
}
CloseHandle(hDevice);
return 0;
}
extern "C" __declspec(dllexport) int RestartDevice()
{
HANDLE hDevice;
if (bOpenDriver (hDevice) != TRUE)
{
MessageBox(NULL, "Please connect Hardware.",0,0);
return (-1);
}
BOOL bResult = FALSE;
VENDOR_REQUEST_IN myRequest;
myRequest.bRequest = 0xA0;
myRequest.wValue = 0xE600; // using CPUCS.0 in FX2
myRequest.wIndex = 0x00;
myRequest.wLength = 0x01;
myRequest.bData = 1; // set RESET
myRequest.direction = 0x00;
int nBytes = 0;
bResult = DeviceIoControl (hDevice,IOCTL_Ezusb_VENDOR_REQUEST,&myRequest,sizeof(VENDOR_REQUEST_IN),NULL,0,(unsigned long *)&nBytes,NULL);
myRequest.bRequest = 0xA0;
myRequest.wValue = 0xE600; // using CPUCS.0 in FX2
myRequest.wIndex = 0x00;
myRequest.wLength = 0x01;
myRequest.bData = 0; // set RESET
myRequest.direction = 0x00;
bResult = DeviceIoControl (hDevice,IOCTL_Ezusb_VENDOR_REQUEST,&myRequest,sizeof(VENDOR_REQUEST_IN),NULL,0,(unsigned long *)&nBytes,NULL);
if(bResult != TRUE)
{
MessageBox(NULL,"Operation Failed.",0,0);
CloseHandle(hDevice);
return -1;
}
CloseHandle(hDevice);
return 0;
}
这个库改了之后目前可以支持多线程,HANDLE切记不能共享,要不然多个线程调用就锁了。 extern "C" __declspec(dllexport) int WriteBuf(int edpnum,BYTE * pBuf,int Length)
extern "C" __declspec(dllexport) int ReadBuf(int edpnum,BYTE * pBuf,int Length)
看来你这两个库函数我觉得我的读写线程是没错的DeviceIoControl()的参数配置都一样,HANDLE也是in,out独立的,
我想我的问题应该出在文件读取上,能加下我qq458648903吗?谢谢你耐心的解释和讨论
wye11083 发表于 2012-4-20 11:35 static/image/common/back.gif
C++的话就简单多了,就用windows.h里面定义的BYTE * 就行,BYTE 就是unsigned char。我现在就是用byte,没 ...
问题已解决,是下位机FPGA状态机问题,3q
页:
[1]