#include "StdAfx.h"
|
#include "SMemoryInterface.h"
|
#include "SMacroFile.h"
|
|
CSMemoryInterface::CSMemoryInterface(int nType, ISMemoryInterface2Parent* pISMI2P, DWORD dwPeriod) : m_nMemoryType(nType), m_pISMI2P(pISMI2P), CSTimerThread(dwPeriod)
|
{
|
m_pSemaPhore = NULL;
|
m_hAsignedMemory = NULL;
|
m_pSharedMemory = NULL;
|
m_dwMemorySize = 0;
|
m_dwSignalDataSize = sizeof(CSSignalData);
|
|
// clear signal data
|
memset(&m_curSignalData, 0, sizeof(CSSignalData));
|
memset(&m_prevSignalData, 0, sizeof(CSSignalData));
|
|
// alloc send signal thread
|
m_pWorkThread = new CSWorkThread(static_cast<ISWorkThread2Parent*>(this));
|
}
|
|
CSMemoryInterface::~CSMemoryInterface(void)
|
{
|
// delete send signal thread
|
if (m_pWorkThread)
|
{
|
delete m_pWorkThread;
|
m_pWorkThread = NULL;
|
}
|
|
StopThread();
|
|
DeleteMemory();
|
}
|
|
void CSMemoryInterface::DeleteMemory()
|
{
|
if(m_pSharedMemory)
|
{
|
UnmapViewOfFile(m_pSharedMemory);
|
m_pSharedMemory = NULL;
|
}
|
|
if(m_hAsignedMemory)
|
{
|
CloseHandle(m_hAsignedMemory);
|
m_hAsignedMemory = NULL;
|
}
|
|
if (m_pSemaPhore)
|
{
|
delete m_pSemaPhore;
|
m_pSemaPhore = NULL;
|
}
|
|
m_dwMemorySize = 0;
|
}
|
|
BOOL CSMemoryInterface::CreateMemory(DWORD64 dwSize)
|
{
|
DeleteMemory();
|
|
m_dwMemorySize = -1; // DWORD max
|
DWORD64 nMaxSize = dwSize + m_dwSignalDataSize;
|
|
// check size
|
if (nMaxSize>=m_dwMemorySize)
|
{
|
return FALSE;
|
}
|
|
// set memory size
|
m_dwMemorySize = DWORD(nMaxSize);
|
|
// set memory name
|
CString strMemoryName = _T("");
|
switch(m_nMemoryType)
|
{
|
case SMemoryInterface::MemoryType_Control:
|
strMemoryName = _T("MemoryType_Control");
|
break;
|
|
case SMemoryInterface::MemoryType_Inspect:
|
strMemoryName = _T("MemoryType_Inspect");
|
break;
|
|
case SMemoryInterface::MemoryType_Review:
|
strMemoryName = _T("MemoryType_Review");
|
break;
|
|
default:
|
return FALSE;
|
break;
|
}
|
|
// Create File
|
m_hAsignedMemory = (HANDLE) CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, m_dwMemorySize, strMemoryName);
|
if(m_hAsignedMemory==NULL)
|
{
|
DeleteMemory();
|
return FALSE;
|
}
|
|
// Map File
|
m_pSharedMemory = (BYTE *)MapViewOfFile(m_hAsignedMemory, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
|
if(m_pSharedMemory==NULL)
|
{
|
DeleteMemory();
|
return FALSE;
|
}
|
|
// Alloc Semaphore
|
if (m_pSemaPhore)
|
{
|
delete m_pSemaPhore;
|
m_pSemaPhore = NULL;
|
}
|
m_pSemaPhore = new CSemaphore(1, 1, strMemoryName);
|
|
if (m_pSemaPhore==NULL)
|
{
|
DeleteMemory();
|
return FALSE;
|
}
|
|
return TRUE;
|
}
|
|
BOOL CSMemoryInterface::LockMemory()
|
{
|
if (m_pSemaPhore==NULL) return FALSE;
|
|
return m_pSemaPhore->Lock();
|
}
|
|
BOOL CSMemoryInterface::UnlockMemory()
|
{
|
if (m_pSemaPhore==NULL) return FALSE;
|
|
return m_pSemaPhore->Unlock();
|
}
|
|
BOOL CSMemoryInterface::StartThread()
|
{
|
if (m_pISMI2P==NULL) return FALSE;
|
return CreateTimerThread(this);
|
}
|
|
void CSMemoryInterface::StopThread()
|
{
|
CSTimerThread::StopThread();
|
}
|
|
LPVOID CSMemoryInterface::GetMemoryAddress(DWORD dwAddress)
|
{
|
if (m_pSharedMemory==NULL) return NULL;
|
|
if (dwAddress >= m_dwMemorySize) return NULL;
|
|
return &(m_pSharedMemory[dwAddress]);
|
}
|
|
const LPVOID CSMemoryInterface::GetMemoryAddress(DWORD dwAddress) const
|
{
|
if (m_pSharedMemory==NULL) return NULL;
|
|
if (dwAddress >= m_dwMemorySize) return NULL;
|
|
return &(m_pSharedMemory[dwAddress]);
|
}
|
|
LPVOID CSMemoryInterface::GetMemoryData( DWORD dwAddress )
|
{
|
return GetMemoryAddress(m_dwSignalDataSize+dwAddress);
|
}
|
|
const LPVOID CSMemoryInterface::GetMemoryData( DWORD dwAddress ) const
|
{
|
return GetMemoryAddress(m_dwSignalDataSize+dwAddress);
|
}
|
|
const LPVOID CSMemoryInterface::GetSignalData() const
|
{
|
return GetMemoryAddress(0);
|
}
|
|
const BOOL CSMemoryInterface::GetSignalData(int nSignalType, int nSignalIndex, BOOL& bValue) const
|
{
|
if (nSignalType<0 || nSignalType>=MAX_SIGNAL_TYPE_COUNT) return FALSE;
|
|
if (nSignalIndex<0 || nSignalIndex>=MAX_SIGNAL_INDEX_COUNT) return FALSE;
|
|
const CSSignalData* pData = static_cast<const CSSignalData*>(GetSignalData());
|
if (pData==NULL) return FALSE;
|
|
DWORD64 dwCurValue = pData->m_dwSendSignal[nSignalType];
|
|
DWORD64 dwBitValue = 1 << nSignalIndex;
|
|
bValue = ( ( dwCurValue & dwBitValue ) == dwBitValue ) ? TRUE : FALSE;
|
|
return TRUE;
|
}
|
|
BOOL CSMemoryInterface::ClearSignalData()
|
{
|
CSSignalData *pData = static_cast<CSSignalData*>(GetMemoryAddress(0));
|
if (pData==NULL) return FALSE;
|
|
LockMemory();
|
|
memset(pData, 0, sizeof(CSSignalData));
|
memset(&m_curSignalData, 0, sizeof(CSSignalData));
|
memset(&m_prevSignalData, 0, sizeof(CSSignalData));
|
|
UnlockMemory();
|
|
return TRUE;
|
}
|
|
BOOL CSMemoryInterface::SendSignal(int nSignalType, int nSignalIndex, int nSignalValue)
|
{
|
if (nSignalType<0 || nSignalType>=MAX_SIGNAL_TYPE_COUNT) return FALSE;
|
|
if (nSignalIndex<0 || nSignalIndex>=MAX_SIGNAL_INDEX_COUNT) return FALSE;
|
|
CSSignalData* pData = static_cast<CSSignalData*>(GetMemoryAddress(0));
|
if (pData==NULL) return FALSE;
|
|
LockMemory();
|
|
DWORD64 nBitValue = 1 << nSignalIndex;
|
if (nSignalValue)
|
{
|
pData->m_dwSendSignal[nSignalType] = pData->m_dwSendSignal[nSignalType] | nBitValue;
|
}
|
else
|
{
|
pData->m_dwSendSignal[nSignalType] = pData->m_dwSendSignal[nSignalType] & (~nBitValue);
|
}
|
|
UnlockMemory();
|
|
return TRUE;
|
}
|
|
void CSMemoryInterface::ISWT2P_ProcessSendSignalData(int nSignalType, int nSignalIndex, int nSignalValue, DWORD dwDelayTime, DWORD dwHoldTime)
|
{
|
// send
|
::Sleep(dwDelayTime);
|
if (SendSignal(nSignalType, nSignalIndex, nSignalValue)==FALSE)
|
{
|
return;
|
}
|
|
// clear (1->0) (0->1)
|
::Sleep(dwHoldTime);
|
if (SendSignal(nSignalType, nSignalIndex, !nSignalValue)==FALSE)
|
{
|
return;
|
}
|
}
|
|
BOOL CSMemoryInterface::SendSignal( int nSignalType, int nSignalIndex, int nValue, DWORD dwDelayTime, DWORD dwHoldTime )
|
{
|
if (m_pWorkThread==NULL) return FALSE;
|
|
return m_pWorkThread->AddThreadData(nSignalType, nSignalIndex, nValue, dwDelayTime, dwHoldTime);
|
}
|
|
void CSMemoryInterface::TimerThreadProcess(PVOID pParameter)
|
{
|
if (m_pISMI2P==NULL) return;
|
|
const CSSignalData* pData = static_cast<const CSSignalData*>(GetSignalData());
|
if (pData==NULL) return;
|
|
// save cur signal
|
m_curSignalData = *pData;
|
|
// check prev signal
|
for (int nSignalType=0; nSignalType<MAX_SIGNAL_TYPE_COUNT; nSignalType++)
|
{
|
if(m_curSignalData.m_dwSendSignal[nSignalType] != m_prevSignalData.m_dwSendSignal[nSignalType])
|
{
|
DWORD64 dwBitValue = 1;
|
BOOL bCurValue = FALSE;
|
BOOL bPrevValue = FALSE;
|
for (int nSignalIdx=0; nSignalIdx<MAX_SIGNAL_INDEX_COUNT; nSignalIdx++)
|
{
|
// compare current and prev
|
bCurValue = BOOL(dwBitValue & m_curSignalData.m_dwSendSignal[nSignalType]);
|
bPrevValue = BOOL(dwBitValue & m_prevSignalData.m_dwSendSignal[nSignalType]);
|
|
// change check
|
if ( bCurValue != bPrevValue )
|
{
|
m_pISMI2P->ISMI2P_SendSignalValue(m_nMemoryType, nSignalType, nSignalIdx, bCurValue);
|
}
|
|
dwBitValue = dwBitValue << 1;
|
}
|
}
|
}
|
|
// save current signal
|
m_prevSignalData = m_curSignalData;
|
}
|