16 #include "base classses.h" 17 #include "named pipes.h" 18 #include "mcdaq_device.h" 19 #include "misc tools.h" 23 int (EXTCCONV *lpf_cbDOut)(
int BoardNum,
int PortNum, USHORT DataValue) = NULL;
24 int (EXTCCONV *lpf_cbDIn)(
int BoardNum,
int PortNum, USHORT *DataValue) = NULL;
25 int (EXTCCONV *lpf_cbGetErrMsg)(
int ErrCode,
char *ErrMsg) = NULL;
26 int (EXTCCONV *lpf_cbDeclareRevision)(
float *RevNum) = NULL;
27 int (EXTCCONV *lpf_cbGetRevision)(
float *RevNum,
float *VxDRevNum) = NULL;
30 DWORD WINAPI MCDAQProc(LPVOID lpParameter)
36 CManagerMCDAQ::CManagerMCDAQ(
CComm* pcComm,
const TCHAR szPipe[],
int nChan,
int &nError) :
37 m_usChans(GINUMBOARDS + GINUMEXPBOARDS),
CManager(MCDAQ_MAN_STR, std::tstring(szPipe), nChan)
46 if (!pcComm || !szPipe)
48 nError= BAD_INPUT_PARAMS;
51 BOOL bRes= GetProcAddresses(&m_hLib,
57 , 5, &lpf_cbDOut,
"cbDOut", &lpf_cbDIn,
"cbDIn", &lpf_cbGetErrMsg,
"cbGetErrMsg",
58 &lpf_cbDeclareRevision,
"cbDeclareRevision", &lpf_cbGetRevision,
"cbGetRevision");
64 float fVer = (float)(CURRENTREVNUM);
65 if (nError = MCDAQ_ERROR(lpf_cbDeclareRevision(&fVer), nError))
68 m_acDAQDevices.assign(m_usChans, NULL);
81 ((
SBaseOut*)pHead)->sBaseIn.eType= eResponseEx;
82 ((
SBaseOut*)pHead)->sBaseIn.nChan= m_nChan;
83 ((
SBaseOut*)pHead)->sBaseIn.nError= 0;
85 _tcsncpy_s(((
SBaseOut*)pHead)->szName, DEVICE_NAME_SIZE, m_csName.c_str(), _TRUNCATE);
90 CManagerMCDAQ::~CManagerMCDAQ()
92 for (
size_t i= 0; i < m_acDAQDevices.size(); ++i)
93 delete m_acDAQDevices[i];
111 if (!pHead || dwSize <
sizeof(
SBaseIn) || dwSize != ((
SBaseIn*)pHead)->dwSize)
113 sBase.nError= SIZE_MISSMATCH;
114 }
else if (((
SBaseIn*)pHead)->eType == eQuery && dwSize ==
sizeof(
SBaseIn))
117 if (((
SBaseIn*)pHead)->nChan < 0 || ((
SBaseIn*)pHead)->nChan >= m_acDAQDevices.size() ||
118 !m_acDAQDevices[((
SBaseIn*)pHead)->nChan])
120 sBase.nError= INVALID_CHANN;
124 DWORD dwSizeInfo= m_acDAQDevices[((
SBaseIn*)pHead)->nChan]->GetInfo(NULL, 0);
125 pBase= (
SBaseIn*)m_pcMemPool->PoolAcquire(dwSizeInfo);
128 m_acDAQDevices[((
SBaseIn*)pHead)->nChan]->GetInfo(pBase, dwSizeInfo);
129 sData.dwSize= dwSizeInfo;
131 m_pcComm->SendData(&sData, llId);
134 }
else if (dwSize ==
sizeof(
SBaseIn) && ((
SBaseIn*)pHead)->eType == eDelete)
136 sBase.eType= eDelete;
137 if (((
SBaseIn*)pHead)->nChan < 0 || ((
SBaseIn*)pHead)->nChan >= m_acDAQDevices.size() ||
138 !m_acDAQDevices[((
SBaseIn*)pHead)->nChan])
139 sBase.nError= INVALID_CHANN;
142 delete m_acDAQDevices[((
SBaseIn*)pHead)->nChan];
143 m_acDAQDevices[((
SBaseIn*)pHead)->nChan]= NULL;
144 sBase.nChan= ((
SBaseIn*)pHead)->nChan;
146 }
else if (dwSize ==
sizeof(
SBaseIn) && ((
SBaseIn*)pHead)->eType == eVersion &&
147 ((
SBaseIn*)pHead)->nChan == -1)
150 sBase.nError= MCDAQ_ERROR(lpf_cbGetRevision(&fVer1, &fVer2), sBase.nError);
151 sBase.dwInfo= (DWORD)(fVer1 * 10000);
152 sBase.eType= eVersion;
153 }
else if (((
SBaseIn*)pHead)->nChan < 0 || ((
SBaseIn*)pHead)->nChan >= m_acDAQDevices.size())
155 sBase.eType= ((
SBaseIn*)pHead)->eType;
156 sBase.nError= INVALID_CHANN;
157 }
else if (((
SBaseIn*)pHead)->eType == eSet && m_acDAQDevices[((
SBaseIn*)pHead)->nChan])
159 sBase.eType= ((
SBaseIn*)pHead)->eType;
160 sBase.nError= ALREADY_OPEN;
161 }
else if (((
SBaseIn*)pHead)->eType == eSet &&
163 ((
SBase*)((
char*)pHead+
sizeof(
SBaseIn)))->eType == eMCDAQChanInit)
166 LARGE_INTEGER llStart;
169 std::tstringstream ss;
171 std::tstringstream ss2;
173 std::tstring csPipeName= m_csPipeName+_T(
":")+ss2.str()+_T(
":")+ss.str();
176 pcChan=
new CChannelMCDAQ(csPipeName.c_str(), ((
SBaseIn*)pHead)->nChan, sChanInit, sBase.nError, llStart);
179 m_acDAQDevices[((
SBaseIn*)pHead)->nChan]= pcChan;
183 pBaseO->sBaseIn.dwSize=
sizeof(
SBaseOut);
184 pBaseO->sBaseIn.eType= eResponseExL;
185 pBaseO->sBaseIn.nChan= ((
SBaseIn*)pHead)->nChan;
186 pBaseO->sBaseIn.nError= 0;
187 pBaseO->llLargeInteger= llStart;
188 pBaseO->bActive=
true;
190 sData.dwSize= pBaseO->sBaseIn.dwSize;
191 m_pcComm->SendData(&sData, llId);
196 sBase.nError= INVALID_COMMAND;
198 if (sBase.nError || bRes)
204 memcpy(sData.pHead, &sBase,
sizeof(
SBaseIn));
205 m_pcComm->SendData(&sData, llId);
215 LARGE_INTEGER &llStart) :
CDevice(MCDAQ_CHAN_STR), m_csPipeName(szPipe),
216 m_sChanInit(sChanInit), m_usChan(nChan), m_hWriteEvent(CreateEvent(NULL,TRUE, FALSE, NULL)),
217 m_asWPackets(m_hWriteEvent)
223 InitializeCriticalSection(&m_hReadSafe);
225 m_usLastWrite = m_sChanInit.usInitialVal;
227 if (!szPipe || m_sChanInit.ucDirection > 2)
229 nError= BAD_INPUT_PARAMS;
232 m_hReadEvent = CreateEvent(NULL,TRUE, FALSE, NULL);
233 m_hStopEvent= CreateEvent(NULL,TRUE, FALSE, NULL);
234 if (!m_hStopEvent || !m_hReadEvent || !m_hWriteEvent)
236 nError= NO_SYS_RESOURCE;
240 unsigned short usRead = 0;
241 if (m_sChanInit.ucDirection)
242 nError= MCDAQ_ERROR(lpf_cbDOut(m_usChan, AUXPORT, m_sChanInit.usInitialVal), nError);
243 if (!nError && m_sChanInit.ucDirection != 1)
244 nError= MCDAQ_ERROR(lpf_cbDIn(m_usChan, AUXPORT, &usRead), nError);
249 nError=
static_cast<CPipeServer*
>(m_pcComm)->Init(szPipe, ~0x80000000, MIN_BUFF_IN,
250 MIN_BUFF_OUT,
this, NULL);
253 m_hThread= CreateThread(NULL, 0, MCDAQProc,
this, 0, NULL);
256 nError= NO_SYS_RESOURCE;
271 ((
SBaseOut*)pHead)->sBaseIn.eType= eResponseEx;
272 ((
SBaseOut*)pHead)->sBaseIn.nChan= m_usChan;
273 ((
SBaseOut*)pHead)->sBaseIn.nError= 0;
275 _tcsncpy_s(((
SBaseOut*)pHead)->szName, DEVICE_NAME_SIZE,
m_csName.c_str(), _TRUNCATE);
276 pHead= (
char*)pHead+
sizeof(
SBaseOut);
279 ((
SBaseOut*)pHead)->sBaseIn.eType = eResponseExL;
280 ((
SBaseOut*)pHead)->sBaseIn.nChan = m_usChan;
281 ((
SBaseOut*)pHead)->sBaseIn.nError = 0;
284 pHead = (
char*)pHead +
sizeof(
SBaseOut);
287 ((
SBase*)pHead)->eType= eMCDAQChanInit;
288 pHead= (
char*)pHead+
sizeof(
SBase);
294 CChannelMCDAQ::~CChannelMCDAQ()
296 if (m_hThread && (WAIT_OBJECT_0 != SignalObjectAndWait(m_hStopEvent, m_hThread, 2000, FALSE)))
297 TerminateThread(m_hThread, 0);
298 if (m_hThread) CloseHandle(m_hThread);
299 if (m_pcComm) m_pcComm->
Close();
305 psPackt= m_asWPackets.
Front(
true, bValid);
306 if (psPackt && bValid)
308 delete psPackt->psData;
313 if (m_hStopEvent) CloseHandle(m_hStopEvent);
314 if (m_hWriteEvent) CloseHandle(m_hWriteEvent);
315 if (m_hReadEvent) CloseHandle(m_hReadEvent);
316 DeleteCriticalSection(&m_hReadSafe);
327 if (!pBase || dwSize <
sizeof(
SBaseIn) || dwSize != pBase->dwSize)
328 nError= SIZE_MISSMATCH;
329 else if (!((pBase->eType == eQuery || ((pBase->eType == eTrigger ||
330 pBase->eType == eCancelReadRequest) && m_sChanInit.ucDirection != 1)) &&
331 dwSize ==
sizeof(
SBaseIn)) && !(pBase->eType == eData && m_sChanInit.ucDirection &&
332 ((
SBase*)((
char*)pBase+
sizeof(
SBaseIn)))->eType == eMCDAQWriteData &&
334 nError= INVALID_COMMAND;
335 else if (pBase->nChan != m_usChan)
336 nError= INVALID_CHANN;
343 pBase= (
SBaseIn*)m_pcMemPool->PoolAcquire(sData.dwSize);
346 pBase->dwSize=
sizeof(
SBaseIn);
347 pBase->eType= eResponse;
349 pBase->nError= nError;
353 }
else if (pBase->eType == eQuery)
355 sData.dwSize=
GetInfo(NULL, 0);
356 sData.pHead= m_pcMemPool->PoolAcquire(sData.dwSize);
357 if (sData.pHead &&
GetInfo(sData.pHead, sData.dwSize) == sData.dwSize)
359 }
else if (pBase->eType == eData)
362 psPacket->llId = llId;
365 m_asWPackets.
Push(psPacket);
366 }
else if (pBase->eType == eTrigger)
368 EnterCriticalSection(&m_hReadSafe);
370 for (; k < m_allReads.size(); ++k)
371 if (m_allReads[k] == llId)
373 if (!m_sChanInit.bContinuous || k == m_allReads.size())
375 m_allReads.push_back(llId);
376 SetEvent(m_hReadEvent);
379 LeaveCriticalSection(&m_hReadSafe);
382 pBase= (
SBaseIn*)m_pcMemPool->PoolAcquire(sData.dwSize);
385 pBase->dwSize=
sizeof(
SBaseIn);
386 pBase->eType= ((
SBaseIn*)pHead)->eType;
387 pBase->nChan= ((
SBaseIn*)pHead)->nChan;
388 pBase->nError= ALREADY_OPEN;
395 EnterCriticalSection(&m_hReadSafe);
396 for (
int k = 0; k < m_allReads.size(); ++k)
398 if (m_allReads[k] == llId)
400 m_allReads.erase(m_allReads.begin() + k);
404 if (!m_allReads.size())
405 ResetEvent(m_hReadEvent);
406 LeaveCriticalSection(&m_hReadSafe);
407 pBase= (
SBaseIn*)m_pcMemPool->PoolAcquire(sData.dwSize);
410 pBase->dwSize= sData.dwSize;
411 pBase->eType= ((
SBaseIn*)pHead)->eType;
412 pBase->nChan= ((
SBaseIn*)pHead)->nChan;
420 DWORD CChannelMCDAQ::ThreadProc()
422 HANDLE ahEvents[]= {m_hStopEvent, m_hWriteEvent, m_hReadEvent};
423 bool bDone=
false, bValid;
424 DWORD dwWait = INFINITE;
425 unsigned short usData;
430 memset(&sBaseOut, 0,
sizeof(
SBaseOut));
431 sBaseOut.bActive=
true;
432 sBaseOut.sBaseIn.eType= eResponseExD;
433 sBaseOut.sBaseIn.nChan= m_usChan;
435 sBaseIn.eType = eData;
436 sBaseIn.dwSize =
sizeof(
SBaseIn);
441 switch (WaitForMultipleObjects(
sizeof(ahEvents) /
sizeof(HANDLE), &ahEvents[0], FALSE, dwWait))
443 case WAIT_OBJECT_0+1:
445 ResetEvent(m_hWriteEvent);
446 psPacket= m_asWPackets.
Front(
true, bValid);
448 SetEvent(m_hWriteEvent);
449 if (!psPacket || !bValid)
451 sBaseOut.sBaseIn.nError = MCDAQ_ERROR(lpf_cbDOut(m_usChan, AUXPORT,
452 (psPacket->psData->usBitSelect & psPacket->psData->usValue) |
453 (~psPacket->psData->usBitSelect & m_usLastWrite)), sBaseOut.sBaseIn.nError);
454 m_usLastWrite = ((psPacket->psData->usBitSelect & psPacket->psData->usValue) |
455 (~psPacket->psData->usBitSelect & m_usLastWrite));
456 sBaseOut.dDouble = g_cTimer.
Seconds();
458 sBaseOut.sBaseIn.dwSize = sData.dwSize;
464 m_pcComm->
SendData(&sData, psPacket->llId);
466 delete psPacket->psData;
470 case WAIT_OBJECT_0 + 2:
472 ResetEvent(m_hReadEvent);
473 sBaseOut.sBaseIn.nError = MCDAQ_ERROR(lpf_cbDIn(m_usChan, AUXPORT, &usData), sBaseOut.sBaseIn.nError);
474 sBaseIn.dwInfo = usData;
475 sBaseOut.dDouble= g_cTimer.
Seconds();
477 sBaseOut.sBaseIn.dwSize = sData.dwSize;
478 EnterCriticalSection(&m_hReadSafe);
480 for (
int i = 0; i < m_allReads.size(); ++i)
482 pBase = (
SBaseOut *)m_pcMemPool->PoolAcquire(sData.dwSize);
488 if (m_pcComm->
SendData(&sData, m_allReads[i]))
492 if (!m_sChanInit.bContinuous)
495 while (k < m_allReads.size())
497 if (m_allReads[k] == -1)
498 m_allReads.erase(m_allReads.begin() + k);
502 if (m_allReads.size())
503 SetEvent(m_hReadEvent);
504 LeaveCriticalSection(&m_hReadSafe);
515 sBaseOut.sBaseIn.dwSize=
sizeof(
SBaseIn);
516 sBaseOut.sBaseIn.eType= eResponse;
517 sBaseOut.sBaseIn.nError= DEVICE_CLOSING;
519 EnterCriticalSection(&m_hReadSafe);
520 for (
int i = 0; i < m_allReads.size(); ++i)
522 sData.pHead = m_pcMemPool->PoolAcquire(sData.dwSize);
525 *(
SBaseIn *)sData.pHead = sBaseOut.sBaseIn;
526 m_pcComm->
SendData(&sData, m_allReads[i]);
530 LeaveCriticalSection(&m_hReadSafe);
533 psPacket = m_asWPackets.
Front(
true, bValid);
534 if (!psPacket || !bValid)
536 sData.pHead= m_pcMemPool->PoolAcquire(sData.dwSize);
539 *(
SBaseIn *)sData.pHead = sBaseOut.sBaseIn;
540 m_pcComm->
SendData(&sData, psPacket->llId);
542 delete psPacket->psData;
virtual int SendData(const SData *pData, __int64 llId)=0
LARGE_INTEGER GetStart() const
void ProcessData(const void *pHead, DWORD dwSize, __int64 llId)
virtual DWORD GetInfo(void *pHead, DWORD dwSize)
void ProcessData(const void *pHead, DWORD dwSize, __int64 llId)
CChannelMCDAQ(const TCHAR szPipe[], int nChan, SChanInitMCDAQ &sChanInit, int &nError, LARGE_INTEGER &llStart)
DWORD GetInfo(void *pHead, DWORD dwSize)
const std::tstring m_csName
T Front(bool bPop, bool &bValid)