发表于:2002-07-21 17:43:00
楼主
我有幸被某奸商宰了一刀,花了8000多买了一块microcomputerboard
的CIO-DAS1602/12数据采集卡,却发现“凌华PCI-DASK驱动程序中严重的bug!!!”
请看samples 中SDK9112Dma是如何在VC中调用AI_ContScanChannels()的,结果发现pci-dask有严重的问题:
In PCI-dask samples SDK9112Dma,
// allocate a memory for user DMA buffer
mem_size=data_size*2;
hMem = GlobalAlloc(GMEM_ZEROINIT,mem_size); ?????????
ai_buf = GlobalLock(hMem); ???????????????
if (ai_buf == NULL )
{
MessageBox(hWnd,"INT",
"No Memory", MB_OK);
}
GlobalFix(hMem);
AI_9112_Config(card,TRIG_INT_PACER);
AI_AsyncDblBufferMode(card, 0);
AI_ContScanChannels (card, channel, range, ai_buf, data_size, (F64)sample_rate, SYNCH_OP);
//AI_ContReadChannel(card, channel, AD_B_5_V, ai_buf, data_size, (F64)sample_rate, SYNCH_OP);
{
The GlobalAlloc function allocates the specified number of bytes from the heap. In the linear Win32 API environment, there is no difference between the local heap and the global heap.
If the function succeeds, the return value is the handle of the newly allocated memory object.
}
既然在DASK2000 Device Driver Configuration中定义了PCI9112的AI Buffer, 用函数AI_InitialMemoryAllocated ()也能返回buffer的大小,可为什么还要在SDK9112Dma中用:
hMem = GlobalAlloc(GMEM_ZEROINIT,mem_size);
ai_buf = GlobalLock(hMem);
再重复申请内存??????
本来应当直接有个函数返回DASK2000 Device Driver Configuration中定义了PCI9112的AI Buffer的句柄,这样就能直接在AI_ContScanChannels (card, channel, range, ai_buf, data_size, (F64)sample_rate, SYNCH_OP);中调用buffer了。
其实看看AI_ContScanChannels()中ai_buffer,应该是申请内存区的句柄,而不是指针或别的。
在PCI-dask help中关于buffer是这样解释的:
{
Buffer : An integer array to contain the acquired data. The length of Buffer must be equal to or greater than the value of parameter ReadCount. The acquired data is stored in interleaved sequence. For example, if the value of Channel is 3, and the scanned channel numbers is descending (e.g. PCI-9112), then this function input data from channel 2, then channel 1, then channel 0, then channel 2, then channel 1, ... The data acquired is put to Buffer by order. So the data read from channel 2 is stored in Buffer[0], Buffer[3], Buffer[6], ... The data from channel 1 is stored in Buffer[1],
Buffer[4], Buffer[7], ... The data from channel 0 is stored in Buffer[2], Buffer[5], Buffer[8], ... If double-buffered mode is enabled, this buffer is of no use, you can ignore this argument. Please refer to Appendix C, AI Data Format for the data format in Buffer.
}
真不知道这个驱动是谁写的,出了这么大的bug竟然到了3.23版还没人发现, I fu l adlink!
如果不是我用delphi写程序,可能那些自诩VC高手还在不停的按照SDK9112Dma 中的GlobalAlloc, GlobalLock,GlobalFree写下去。
那个NuDAQ PCI Configuration Utility其实一点用也没有。
microcomputerboard 的Universal Library 中的函数为:
1.cbWinBufAlloc()
Description: Allocates a Windows global memory buffer which can be used with the scan functions and returns a memory handle for it.
Function Prototype:
C/C++:
int cbWinBufAlloc (long NumPoints)
Visual Basic:
Function cbWinBufAlloc(ByVal NumPoints&) As Long
Delphi:
function cbWinBufAlloc (NumPoints:Longint):Integer;
Arguments:
NumPoints
Size of buffer to allocate. Specifies how many data points (16-bit integers, NOT bytes) can be stored in the buffer.
Returns 0 if buffer could not be allocated or a non-zero integer handle to the buffer.
2.int cbAInScan ()
C/C++:
int cbAInScan (int BoardNum, int LowChan, int HighChan, long Count, long *Rate, int Range, int MemHandle, int Options)
Visual Basic:
Function cbAInScan(ByVal BoardNum&, ByVal LowChan&, ByVal HighChan&, ByVal Count&, Rate&, ByVal Gain&, ByVal MemHandle&, ByVal Options&) As Long
Delphi:
function cbAInScan (BoardNum:Integer; LowChan:Integer; HighChan:Integer; Count:Longint; var Rate:Longint; Gain:Integer;MemHandle:Integer; Options:Integer):Integer;
3.cbWinBufToArray()
Description: Copies data from a Windows memor