plcsim2016/PLCSim2016/core/cCore.cpp
2016-08-02 00:36:22 +09:00

812 lines
22 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "cCore.h"
#include "..\\lib\\lib.h"
#include "..\Resource.h"
#include <memory.h>
//#define ENABLE_TRECE
cPLCCore* thePLCCore;
int iTimerCount;
cPLCCore::cPLCCore(){
pInPut = new stInPut[MAX_NUM_INPUT];
pOutPut = new stOutPut[MAX_NUM_OUTPUT];
pAUX = new stAUX[MAX_NUM_AUX];
pSTATUS = new stSTATUS[MAX_NUM_STATUS];
pTimer = new stTimer[MAX_NUM_TIMER];
pCounter = new stCounter[MAX_NUM_COUNTER];
pMEMBUF = new BYTE[MAX_PROG_SIZE];
sLogPath = new char[256];
sLadderFilePath = new char[256];
memset(pMEMBUF,0x00,MAX_PROG_SIZE);
iProgSize = MAX_PROG_SIZE;
bRUN = FALSE;
hFlowThread = NULL;
hClockThread = NULL;
iTimerHandle = 0;
bEnableTrace = FALSE;
thePLCCore = this; /* ³o¬O¬°¤FÅý Call Back Function ?°÷¦s¨ú PLC Core */
::iTimerCount = 0;
thePLCCore->fnRESETAll();
thePLCCore->fnWriteOutput();
pTRACE = fopen(TRACE_PATH,"ab");
PLCTRACE("PLCCore Log open");
}
cPLCCore::~cPLCCore(){
thePLCCore->fnRESETAll();
thePLCCore->fnWriteOutput();
delete pInPut;
delete pOutPut;
delete pAUX;
delete pSTATUS;
delete pTimer;
delete pCounter;
delete pMEMBUF;
delete sLogPath;
delete sLadderFilePath;
PLCTRACE("PLCCore Log close");
fclose(pTRACE);
}
void cPLCCore::fnRESETAll()
{
int i=0;
for(i = 0;i < MAX_NUM_INPUT;i++)pInPut[i].status = 0;
for(i = 0;i < MAX_NUM_OUTPUT;i++)pOutPut[i].status = 0;
for(i = 0;i < MAX_NUM_AUX;i++)pAUX[i].status = 0;
for(i = 0;i < MAX_NUM_STATUS;i++)pSTATUS[i].status = 0;
for(i = 0;i < MAX_NUM_TIMER;i++){
pTimer[i].status = 0;
pTimer[i].timeup = 0;
pTimer[i].clock = 0;
pTimer[i].limit = 0;
}
for(i = 0;i < MAX_NUM_COUNTER;i++){
pCounter[i].count = 0;
pCounter[i].fire = 0;
pCounter[i].limit = 0;
pCounter[i].status = 0;
pCounter[i].filpflop = 0;
}
}
int cPLCCore::cReadProgIntoMEM(char* sPath)
{
return iFileR(sPath,pMEMBUF,&iProgSize);
}
VOID CALLBACK MyTimerProc(HWND hwnd, UINT iMsg, UINT iTimerID, DWORD dwTime)
{
/* timeup do timer proc */
HWND hWnd;
char strBuf[20];
#ifdef ENABLE_TRECE
thePLCCore->PLCTRACE("timer msg");
#endif
hWnd = GetDlgItem(thePLCCore->m_Hwnd,IDC_STATUS);
GetWindowText(hWnd,strBuf,20);
switch(strBuf[0])
{
case '-':
SetWindowText(hWnd,"\\");
break;
case '\\':
SetWindowText(hWnd,"|");
break;
case '|':
SetWindowText(hWnd,"/");
break;
case '/':
SetWindowText(hWnd,"-");
break;
default:
SetWindowText(hWnd,"-");
break;
}
}
DWORD WINAPI fnClockThread( LPVOID pParam)
{
/* Multimedia Timer */
while(thePLCCore->bRUN)
{
#ifdef ENABLE_TRECE
thePLCCore->PLCTRACE("clock thread msg");
#endif
Sleep(100);
}
return 0;
}
void CALLBACK timerRoutine(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
#ifdef ENABLE_TRECE
thePLCCore->PLCTRACE("timerRoutine ...");
#endif
int i;
/* ³B²z PLC Timer */
for(i = 0;i < MAX_NUM_TIMER;i++){
if(thePLCCore->pTimer[i].status == 1){
if(thePLCCore->pTimer[i].clock == thePLCCore->pTimer[i].limit)
thePLCCore->pTimer[i].timeup = 1;
else
thePLCCore->pTimer[i].clock+=100;
}else{
thePLCCore->pTimer[i].timeup = 0;
thePLCCore->pTimer[i].clock = 0;
}
}
}
int cPLCCore::fnLDAndCompute(sString* pCOMMAND, stPLC_OBJ *pPLC_OBJ,int* piStackDepth)
{
int iObjIndex = 0;
iObjIndex = atoi(&pCOMMAND[1].m_String[1]);
switch(pCOMMAND[1].m_String[0]){
case 'X':
pPLC_OBJ[*piStackDepth]=thePLCCore->pInPut[iObjIndex];
break;
case 'Y':
pPLC_OBJ[*piStackDepth]=thePLCCore->pOutPut[iObjIndex];
break;
case 'M':
pPLC_OBJ[*piStackDepth]=thePLCCore->pAUX[iObjIndex];
break;
case 'S':
pPLC_OBJ[*piStackDepth]=thePLCCore->pSTATUS[iObjIndex];
break;
case 'T':
pPLC_OBJ[*piStackDepth]=thePLCCore->pTimer[iObjIndex];
break;
case 'C':
pPLC_OBJ[*piStackDepth]=thePLCCore->pCounter[iObjIndex];
break;
default:
return -1;
}
return 0;
}
int cPLCCore::fnLDNotAndCompute(sString* pCOMMAND, stPLC_OBJ *pPLC_OBJ,int* piStackDepth)
{
int iObjIndex = 0;
iObjIndex = atoi(&pCOMMAND[1].m_String[1]);
switch(pCOMMAND[1].m_String[0]){
case 'X':
pPLC_OBJ[*piStackDepth]=!thePLCCore->pInPut[iObjIndex];
break;
case 'Y':
pPLC_OBJ[*piStackDepth]=!thePLCCore->pOutPut[iObjIndex];
break;
case 'M':
pPLC_OBJ[*piStackDepth]=!thePLCCore->pAUX[iObjIndex];
break;
case 'S':
pPLC_OBJ[*piStackDepth]=!thePLCCore->pSTATUS[iObjIndex];
break;
case 'T':
pPLC_OBJ[*piStackDepth]=!thePLCCore->pTimer[iObjIndex];
break;
case 'C':
pPLC_OBJ[*piStackDepth]=!thePLCCore->pCounter[iObjIndex];
break;
default:
return -1;
}
return 0;
}
int cPLCCore::fnANDAndCompute(sString* pCOMMAND, stPLC_OBJ *pPLC_OBJ,int* piStackDepth)
{
int iObjIndex = 0;
iObjIndex = atoi(&pCOMMAND[1].m_String[1]);
switch(pCOMMAND[1].m_String[0]){
case 'X':
pPLC_OBJ[*piStackDepth-1]=pPLC_OBJ[*piStackDepth-1]*thePLCCore->pInPut[iObjIndex];
break;
case 'Y':
pPLC_OBJ[*piStackDepth-1]=pPLC_OBJ[*piStackDepth-1]*thePLCCore->pOutPut[iObjIndex];
break;
case 'M':
pPLC_OBJ[*piStackDepth-1]=pPLC_OBJ[*piStackDepth-1]*thePLCCore->pAUX[iObjIndex];
break;
case 'S':
pPLC_OBJ[*piStackDepth-1]=pPLC_OBJ[*piStackDepth-1]*thePLCCore->pSTATUS[iObjIndex];
break;
case 'T':
pPLC_OBJ[*piStackDepth-1]=pPLC_OBJ[*piStackDepth-1]*thePLCCore->pTimer[iObjIndex];
break;
case 'C':
pPLC_OBJ[*piStackDepth-1]=pPLC_OBJ[*piStackDepth-1]*thePLCCore->pCounter[iObjIndex];
break;
default:
return -1;
}
return 0;
}
int cPLCCore::fnANDNotAndCompute(sString* pCOMMAND, stPLC_OBJ *pPLC_OBJ,int* piStackDepth)
{
int iObjIndex = 0;
iObjIndex = atoi(&pCOMMAND[1].m_String[1]);
switch(pCOMMAND[1].m_String[0]){
case 'X':
pPLC_OBJ[*piStackDepth-1]=(pPLC_OBJ[*piStackDepth-1]*!thePLCCore->pInPut[iObjIndex]);
break;
case 'Y':
pPLC_OBJ[*piStackDepth-1]=(pPLC_OBJ[*piStackDepth-1]*!thePLCCore->pOutPut[iObjIndex]);
break;
case 'M':
pPLC_OBJ[*piStackDepth-1]=(pPLC_OBJ[*piStackDepth-1]*!thePLCCore->pAUX[iObjIndex]);
break;
case 'S':
pPLC_OBJ[*piStackDepth-1]=(pPLC_OBJ[*piStackDepth-1]*!thePLCCore->pSTATUS[iObjIndex]);
break;
case 'T':
pPLC_OBJ[*piStackDepth-1]=(pPLC_OBJ[*piStackDepth-1]*!thePLCCore->pTimer[iObjIndex]);
break;
case 'C':
pPLC_OBJ[*piStackDepth-1]=(pPLC_OBJ[*piStackDepth-1]*!thePLCCore->pCounter[iObjIndex]);
break;
default:
return -1;
}
return 0;
}
int cPLCCore::fnORAndCompute(sString* pCOMMAND, stPLC_OBJ *pPLC_OBJ,int* piStackDepth)
{
int iObjIndex = 0;
iObjIndex = atoi(&pCOMMAND[1].m_String[1]);
switch(pCOMMAND[1].m_String[0]){
case 'X':
pPLC_OBJ[*piStackDepth-1]=pPLC_OBJ[*piStackDepth-1]+thePLCCore->pInPut[iObjIndex];
break;
case 'Y':
pPLC_OBJ[*piStackDepth-1]=pPLC_OBJ[*piStackDepth-1]+thePLCCore->pOutPut[iObjIndex];
break;
case 'M':
pPLC_OBJ[*piStackDepth-1]=pPLC_OBJ[*piStackDepth-1]+thePLCCore->pAUX[iObjIndex];
break;
case 'S':
pPLC_OBJ[*piStackDepth-1]=pPLC_OBJ[*piStackDepth-1]+thePLCCore->pSTATUS[iObjIndex];
break;
case 'T':
pPLC_OBJ[*piStackDepth-1]=pPLC_OBJ[*piStackDepth-1]+thePLCCore->pTimer[iObjIndex];
break;
case 'C':
pPLC_OBJ[*piStackDepth-1]=pPLC_OBJ[*piStackDepth-1]+thePLCCore->pCounter[iObjIndex];
break;
default:
return -1;
}
return 0;
}
int cPLCCore::fnORNotAndCompute(sString* pCOMMAND, stPLC_OBJ *pPLC_OBJ,int* piStackDepth)
{
int iObjIndex = 0;
iObjIndex = atoi(&pCOMMAND[1].m_String[1]);
switch(pCOMMAND[1].m_String[0]){
case 'X':
pPLC_OBJ[*piStackDepth-1]=(pPLC_OBJ[*piStackDepth-1]+!thePLCCore->pInPut[iObjIndex]);
break;
case 'Y':
pPLC_OBJ[*piStackDepth-1]=(pPLC_OBJ[*piStackDepth-1]+!thePLCCore->pOutPut[iObjIndex]);
break;
case 'M':
pPLC_OBJ[*piStackDepth-1]=(pPLC_OBJ[*piStackDepth-1]+!thePLCCore->pAUX[iObjIndex]);
break;
case 'S':
pPLC_OBJ[*piStackDepth-1]=(pPLC_OBJ[*piStackDepth-1]+!thePLCCore->pSTATUS[iObjIndex]);
break;
case 'T':
pPLC_OBJ[*piStackDepth-1]=(pPLC_OBJ[*piStackDepth-1]+!thePLCCore->pTimer[iObjIndex]);
break;
case 'C':
pPLC_OBJ[*piStackDepth-1]=(pPLC_OBJ[*piStackDepth-1]+!thePLCCore->pCounter[iObjIndex]);
break;
default:
return -1;
}
return 0;
}
int cPLCCore::fnOUTAndCompute(sString *pCOMMAND, stPLC_OBJ *pPLC_OBJ, int *piStackDepth)
{
char sDebugBuffer[256];
int iObjIndex = 0;
int iK_Value = 0;
iObjIndex = atoi(&pCOMMAND[1].m_String[1]);
switch(pCOMMAND[1].m_String[0]){
case 'Y':
thePLCCore->pOutPut[iObjIndex].status = pPLC_OBJ[*piStackDepth-1].status;
break;
case 'M':
thePLCCore->pAUX[iObjIndex].status=pPLC_OBJ[*piStackDepth-1].status;
break;
case 'T':
thePLCCore->pTimer[iObjIndex].status=pPLC_OBJ[*piStackDepth-1].status;
iK_Value = atoi(&pCOMMAND[2].m_String[1]);
thePLCCore->pTimer[iObjIndex].limit = iK_Value;
break;
case 'C':
if(pPLC_OBJ[*piStackDepth-1].status == 1){
iK_Value = atoi(&pCOMMAND[2].m_String[1]);
thePLCCore->pCounter[iObjIndex].limit = iK_Value;
if(thePLCCore->pCounter[iObjIndex].filpflop==0 && thePLCCore->pCounter[iObjIndex].fire==0){
thePLCCore->pCounter[iObjIndex].count++;
thePLCCore->pCounter[iObjIndex].status=1;
thePLCCore->pCounter[iObjIndex].filpflop=1;
#ifdef ENABLE_TRECE
sprintf(sDebugBuffer,"count msg ok : %d ,%d, %d",
iObjIndex,
thePLCCore->pCounter[iObjIndex].count,
thePLCCore->pCounter[iObjIndex].status);
thePLCCore->PLCTRACE(sDebugBuffer);
#endif
}
}else{
thePLCCore->pCounter[iObjIndex].filpflop=0;
#ifdef ENABLE_TRECE
thePLCCore->PLCTRACE("count msg off");
#endif
}
if((thePLCCore->pCounter[iObjIndex].count >= thePLCCore->pCounter[iObjIndex].limit)&&(thePLCCore->pCounter[iObjIndex].status==1))
thePLCCore->pCounter[iObjIndex].fire=1;
break;
default:
return -1;
}
return 0;
}
int cPLCCore::fnANBAndCompute(sString *pCOMMAND, stPLC_OBJ *pPLC_OBJ, int *piStackDepth)
{
pPLC_OBJ[*piStackDepth-2]=pPLC_OBJ[*piStackDepth-2]*pPLC_OBJ[*piStackDepth-1];
return 0;
}
int cPLCCore::fnORBAndCompute(sString *pCOMMAND, stPLC_OBJ *pPLC_OBJ, int *piStackDepth)
{
pPLC_OBJ[*piStackDepth-2]=pPLC_OBJ[*piStackDepth-2]+pPLC_OBJ[*piStackDepth-1];
return 0;
}
int cPLCCore::fnSETAndCompute(sString *pCOMMAND, stPLC_OBJ *pPLC_OBJ, int *piStackDepth)
{
int iObjIndex = 0;
iObjIndex = atoi(&pCOMMAND[1].m_String[1]);
switch(pCOMMAND[1].m_String[0]){
case 'Y':
if(pPLC_OBJ[*piStackDepth-1].status == 1)
thePLCCore->pOutPut[iObjIndex].status = 1;
break;
case 'M':
if(pPLC_OBJ[*piStackDepth-1].status == 1)
thePLCCore->pAUX[iObjIndex].status=1;
break;
case 'S':
if(pPLC_OBJ[*piStackDepth-1].status == 1)
thePLCCore->pSTATUS[iObjIndex].status=1;
break;
case 'T':
if(pPLC_OBJ[*piStackDepth-1].status == 1)
thePLCCore->pTimer[iObjIndex].status=1;
break;
case 'C':
if(pPLC_OBJ[*piStackDepth-1].status == 1){
thePLCCore->pCounter[iObjIndex].status=1;
thePLCCore->pCounter[iObjIndex].fire=1;
}
break;
default:
return -1;
}
return 0;
}
int cPLCCore::fnRSTAndCompute(sString *pCOMMAND, stPLC_OBJ *pPLC_OBJ, int *piStackDepth)
{
int iObjIndex = 0;
iObjIndex = atoi(&pCOMMAND[1].m_String[1]);
switch(pCOMMAND[1].m_String[0]){
case 'Y':
if(pPLC_OBJ[*piStackDepth-1].status == 1)
thePLCCore->pOutPut[iObjIndex].status = 0;
break;
case 'M':
if(pPLC_OBJ[*piStackDepth-1].status == 1)
thePLCCore->pAUX[iObjIndex].status=0;
break;
case 'S':
if(pPLC_OBJ[*piStackDepth-1].status == 1)
thePLCCore->pSTATUS[iObjIndex].status=0;
break;
case 'T':
if(pPLC_OBJ[*piStackDepth-1].status == 1)
thePLCCore->pTimer[iObjIndex].status=0;
break;
case 'C':
if(pPLC_OBJ[*piStackDepth-1].status == 1){
thePLCCore->pCounter[iObjIndex].status=0;
thePLCCore->pCounter[iObjIndex].count=0;
thePLCCore->pCounter[iObjIndex].fire=0;
thePLCCore->pCounter[iObjIndex].filpflop=0;
}
break;
default:
return -1;
}
return 0;
}
DWORD WINAPI fnFlowCtrlThread( LPVOID pParam)
{
char cClearStack;
int iTokenStartPos;
int iStackDepth;
int iParseProgOffset;
int iTempBufferLength;
int iRet;
BOOL bProgEnd;
sString sCOMMAND[5];
char* pTempBuffer = new char[256];
stPLC_OBJ* pPLC_OBJ = new stPLC_OBJ[MAX_LADDER_DEPTH];
/* Ladder Prog */
thePLCCore->cReadProgIntoMEM(LADDER_PATH);
iTokenStartPos = 0;
iStackDepth = 0;
iParseProgOffset = 0;
thePLCCore->fnRESETAll();
thePLCCore->fnWriteOutput();
// HANDLE m_hEvent=CreateEvent(NULL,TRUE,TRUE,"XXXEvent");
while(thePLCCore->bRUN)
{
iStackDepth = 0;
iParseProgOffset = 0;
cClearStack = 0x00;
#ifdef ENABLE_TRECE
thePLCCore->PLCTRACE("flow thread msg");
#endif
/* Ū¨ú Input ª¬ºAۦܰO¾ÐÅ餤 */
thePLCCore->fnReadInput();
do{
memset(sCOMMAND,0x00,sizeof(sString)*5);
iTokenStartPos = iParseProgOffset;
/* ¨ú±o Ladder ?¦¡ªº?¤p¬q such as LD X000¡A¤À¬qªº¤è¦¡¬O¥H 0x0d,0x0a ?¬°ÃѧO²Å¸¹ */
bProgEnd = thePLCCore->GetProgToken(&iParseProgOffset);
if(bProgEnd == TRUE){
memset(pTempBuffer,0x00,256);
memcpy(pTempBuffer,&thePLCCore->pMEMBUF[iTokenStartPos],iParseProgOffset - iTokenStartPos);
iParseProgOffset += 2;
iTempBufferLength = strlen(pTempBuffer);
/* LD X000 aa[0] = LD,aa[1] = X000 */
iRet = sSplitToStringArray(sCOMMAND,5,pTempBuffer,&iTempBufferLength,' ');
/* Ladder Prog Command */
// LD
if((sCOMMAND[0].m_String[0] == 'L') && (sCOMMAND[0].m_String[1] == 'D') && (sCOMMAND[0].m_String[2] == 0x00)){
if(cClearStack == 0x01){
iStackDepth--;
cClearStack = 0x00;
}
iRet = thePLCCore->fnLDAndCompute(sCOMMAND,pPLC_OBJ,&iStackDepth);
iStackDepth++;
}// LDI
else if((sCOMMAND[0].m_String[0] == 'L') && (sCOMMAND[0].m_String[1] == 'D') && (sCOMMAND[0].m_String[2] == 'I')){
iRet = thePLCCore->fnLDNotAndCompute(sCOMMAND,pPLC_OBJ,&iStackDepth);
iStackDepth++;
}// AND
else if((sCOMMAND[0].m_String[0] == 'A') && (sCOMMAND[0].m_String[1] == 'N') && (sCOMMAND[0].m_String[2] == 'D')){
iRet = thePLCCore->fnANDAndCompute(sCOMMAND,pPLC_OBJ,&iStackDepth);
}// ANI
else if((sCOMMAND[0].m_String[0] == 'A') && (sCOMMAND[0].m_String[1] == 'N') && (sCOMMAND[0].m_String[2] == 'I')){
iRet = thePLCCore->fnANDNotAndCompute(sCOMMAND,pPLC_OBJ,&iStackDepth);
}// OR
else if((sCOMMAND[0].m_String[0] == 'O') && (sCOMMAND[0].m_String[1] == 'R') && (sCOMMAND[0].m_String[2] == 0x00)){
iRet = thePLCCore->fnORAndCompute(sCOMMAND,pPLC_OBJ,&iStackDepth);
}// ORI
else if((sCOMMAND[0].m_String[0] == 'O') && (sCOMMAND[0].m_String[1] == 'R') && (sCOMMAND[0].m_String[2] == 'I')){
iRet = thePLCCore->fnORNotAndCompute(sCOMMAND,pPLC_OBJ,&iStackDepth);
}// ANB
else if((sCOMMAND[0].m_String[0] == 'A') && (sCOMMAND[0].m_String[1] == 'N') && (sCOMMAND[0].m_String[2] == 'B')){
iRet = thePLCCore->fnANBAndCompute(sCOMMAND,pPLC_OBJ,&iStackDepth);
iStackDepth--;
}// ORB
else if((sCOMMAND[0].m_String[0] == 'O') && (sCOMMAND[0].m_String[1] == 'R') && (sCOMMAND[0].m_String[2] == 'B')){
iRet = thePLCCore->fnORBAndCompute(sCOMMAND,pPLC_OBJ,&iStackDepth);
iStackDepth--;
}// SET
else if((sCOMMAND[0].m_String[0] == 'S') && (sCOMMAND[0].m_String[1] == 'E') && (sCOMMAND[0].m_String[2] == 'T')){
iRet = thePLCCore->fnSETAndCompute(sCOMMAND,pPLC_OBJ,&iStackDepth);
if(iStackDepth > 0)cClearStack=0x01;
}// RST
else if((sCOMMAND[0].m_String[0] == 'R') && (sCOMMAND[0].m_String[1] == 'S') && (sCOMMAND[0].m_String[2] == 'T')){
iRet = thePLCCore->fnRSTAndCompute(sCOMMAND,pPLC_OBJ,&iStackDepth);
if(iStackDepth > 0)cClearStack=0x01;
}// OUT
else if((sCOMMAND[0].m_String[0] == 'O') && (sCOMMAND[0].m_String[1] == 'U') && (sCOMMAND[0].m_String[2] == 'T')){
iRet = thePLCCore->fnOUTAndCompute(sCOMMAND,pPLC_OBJ,&iStackDepth);
if(iStackDepth > 0)cClearStack=0x01;
//ResetEvent(m_hEvent); ¨Ï¥Î EVENT ¨Ã¤£??§C CPU ªº Loading,©Ò¥HÁÙ¬O¥Î Sleep(1)
//WaitForSingleObject(m_hEvent,1);
//Sleep(1);
}else if((sCOMMAND[0].m_String[0] == 'E') && (sCOMMAND[0].m_String[1] == 'N') && (sCOMMAND[0].m_String[2] == 'D')){
;
}else{
;
}
}
}while(bProgEnd);
thePLCCore->fnWriteOutput();
Sleep(100);
}
thePLCCore->fnRESETAll();
thePLCCore->fnWriteOutput();
// CloseHandle(m_hEvent);
delete pTempBuffer;
delete pPLC_OBJ;
return 0;
}
BOOL cPLCCore::GetProgToken(int* iParseProgOffset)
{
int iStringLen,iBufferLen;
char sCMD_Buffer[]={0x0d,0x0a};
iStringLen = MAX_PROG_SIZE;
iBufferLen = 2;
if(iFindKeyCharacterFromBuffer((char*)pMEMBUF,&iStringLen,sCMD_Buffer,&iBufferLen,iParseProgOffset) == 0)
return TRUE;
return FALSE;
}
void cPLCCore::fnReadInput()
{
FILE* pFile;
char* pBuffer;
pBuffer = new char[256];
pFile = fopen("input.txt","r");
fread(pBuffer,1,256,pFile);
fclose(pFile);
for(int i = 0;i < MAX_NUM_INPUT;i++){
pInPut[i].status = (pBuffer[i] - 0x30);
}
delete pBuffer;
}
void cPLCCore::fnWriteOutput()
{
int iOutputFile,iPos,iStatus;
char sFileName[256];
char sBuffer[3];
sBuffer[0] = 0x30;
sBuffer[1] = 0x31;
sBuffer[2] = 0x00;
sprintf(sFileName,"%s","output.txt");
iOutputFile = _open(sFileName,_O_RDWR , _S_IREAD | _S_IWRITE );
if(iOutputFile != -1){
for(int i = 0;i < MAX_NUM_OUTPUT;i++){
iPos = i;
_lseek( iOutputFile, iPos, SEEK_SET );
iStatus = pOutPut[i].status;
if(iStatus == 1)
_write( iOutputFile, &sBuffer[1], 1);
else
_write( iOutputFile, &sBuffer[0], 1);
}
close(iOutputFile);
}
}
int cPLCCore::fRUN()
{
if(bRUN == FALSE){
bRUN = TRUE;
PLCTRACE("plc core running");
iTimerHandle = SetTimer(m_Hwnd,500,10,MyTimerProc);
if(iTimerHandle == 0)
return -1;
hFlowThread = CreateThread(NULL,(4096*1024),fnFlowCtrlThread,NULL,0,&dwFlowThreadID);
// ¹Á¸Õ¨Ï¥Î Multimedia Timer ¨ú¥N
//hClockThread = CreateThread(NULL,(4096*1024),fnClockThread,NULL,0,&dwClockThreadID);
m_timerID = timeSetEvent(100,5,timerRoutine, NULL,TIME_PERIODIC);
}
else{
return -2;
}
return 0;
}
int cPLCCore::fSTOP()
{
DWORD dwThread;
if(bRUN == TRUE){
bRUN = FALSE;
KillTimer(m_Hwnd,iTimerHandle);
dwThread = WaitForSingleObject(hFlowThread,5000);
if(dwThread == WAIT_TIMEOUT)
{
TerminateThread(hFlowThread,0);
}
/* ¹Á¸Õ¨Ï¥Î Multimedia Timer ¨ú¥N
dwThread = WaitForSingleObject(hClockThread,5000);
if(dwThread == WAIT_TIMEOUT)
{
TerminateThread(hClockThread,0);
}
*/
PLCTRACE("plc core stoped");
// CloseHandle(hClockThread);
CloseHandle(hFlowThread);
ASSERT(m_timerID != 0);
timeKillEvent(m_timerID);
}
else
{
return -2;
}
return 0;
}
int cPLCCore::PLCTRACE(char* pMsg)
{
SYSTEMTIME dt;
#ifdef ENABLE_TRECE
GetSystemTime(&dt);
fprintf(pTRACE,"[%04d/%02d/%02d %02d:%02d:%02d %03d] %s\r\n",
dt.wYear,dt.wMonth,dt.wDay,dt.wHour,dt.wMinute,dt.wSecond,dt.wMilliseconds,pMsg);
fflush(pTRACE);
#endif
return 0;
}
stPLC_OBJ stPLC_OBJ::operator +(const stPLC_OBJ& a)
{
stPLC_OBJ _stPLC_OBJ;
stTimer* b = (stTimer*)&a;
stCounter* c = (stCounter*)&a;
if((this->iClassType != IS_TIMER) && (this->iClassType != IS_COUNTER))
{
switch(a.iClassType){
case IS_INPUT:
case IS_OUTPUT:
case IS_AUX:
case IS_STATUS:
if((this->status == 1) || (a.status == 1)) _stPLC_OBJ.status = 1;
else _stPLC_OBJ.status = 0;
break;
case IS_TIMER:
if((this->status == 1) || (a.status == 1 && b->timeup == 1)) _stPLC_OBJ.status = 1;
else _stPLC_OBJ.status = 0;
break;
case IS_COUNTER:
if((this->status == 1) || (a.status == 1 && c->fire == 1)) _stPLC_OBJ.status = 1;
else _stPLC_OBJ.status = 0;
break;
}
}else{
if(this->iClassType == IS_TIMER){
stTimer* d = (stTimer*)this;
if(a.iClassType == IS_TIMER){
if((d->status == 1 && d->timeup==1) || (a.status == 1 && b->timeup == 1)) _stPLC_OBJ.status = 1;
else _stPLC_OBJ.status = 0;
}else{
if((d->status == 1 && d->timeup==1) || (a.status == 1 && c->fire == 1)) _stPLC_OBJ.status = 1;
else _stPLC_OBJ.status = 0;
}
}
if(this->iClassType == IS_COUNTER){
stCounter* d = (stCounter*)this;
if(a.iClassType == IS_TIMER){
if((d->status == 1 && d->fire==1) || (a.status == 1 && b->timeup == 1)) _stPLC_OBJ.status = 1;
else _stPLC_OBJ.status = 0;
}else{
if((d->status == 1 && d->fire==1) || (a.status == 1 && c->fire == 1)) _stPLC_OBJ.status = 1;
else _stPLC_OBJ.status = 0;
}
}
}
return _stPLC_OBJ;
}
stPLC_OBJ stPLC_OBJ::operator *(const stPLC_OBJ& a)
{
stPLC_OBJ _stPLC_OBJ;
stTimer* b = (stTimer*)&a;
stCounter* c = (stCounter*)&a;
if((this->iClassType != IS_TIMER) && (this->iClassType != IS_COUNTER))
{
switch(a.iClassType){
case IS_INPUT:
case IS_OUTPUT:
case IS_AUX:
case IS_STATUS:
if((this->status == 1) && (a.status == 1)) _stPLC_OBJ.status = 1;
else _stPLC_OBJ.status = 0;
break;
case IS_TIMER:
if((this->status == 1) && (a.status == 1 && b->timeup == 1)) _stPLC_OBJ.status = 1;
else _stPLC_OBJ.status = 0;
break;
case IS_COUNTER:
if((this->status == 1) && (a.status == 1 && c->fire == 1)) _stPLC_OBJ.status = 1;
else _stPLC_OBJ.status = 0;
break;
}
}else{
if(this->iClassType == IS_TIMER){
stTimer* d = (stTimer*)this;
if(a.iClassType == IS_TIMER){
if((d->status == 1 && d->timeup==1) && (a.status == 1 && b->timeup == 1)) _stPLC_OBJ.status = 1;
else _stPLC_OBJ.status = 0;
}else{
if((d->status == 1 && d->timeup==1) && (a.status == 1 && c->fire == 1)) _stPLC_OBJ.status = 1;
else _stPLC_OBJ.status = 0;
}
}
if(this->iClassType == IS_COUNTER){
stCounter* d = (stCounter*)this;
if(a.iClassType == IS_TIMER){
if((d->status == 1 && d->fire==1) && (a.status == 1 && b->timeup == 1)) _stPLC_OBJ.status = 1;
else _stPLC_OBJ.status = 0;
}else{
if((d->status == 1 && d->fire==1) && (a.status == 1 && c->fire == 1)) _stPLC_OBJ.status = 1;
else _stPLC_OBJ.status = 0;
}
}
}
return _stPLC_OBJ;
}
void stPLC_OBJ::operator =(const stPLC_OBJ& a)
{
stTimer* b = (stTimer*)&a;
stCounter* c = (stCounter*)&a;
if((a.iClassType != IS_TIMER) && (a.iClassType != IS_COUNTER))
this->status = a.status;
if(a.iClassType == IS_TIMER)
this->status = (a.status == 1 & b->timeup == 1);
if(a.iClassType == IS_COUNTER)
this->status = (a.status == 1 & c->fire == 1);
}
stPLC_OBJ stPLC_OBJ::operator!() const
{
stPLC_OBJ _stPLC_OBJ;
stTimer* d = (stTimer*)this;
stCounter* e = (stCounter*)this;
switch(this->iClassType){
case IS_INPUT:
case IS_OUTPUT:
case IS_AUX:
case IS_STATUS:
if(this->status == 1)
_stPLC_OBJ.status = 0;
else
_stPLC_OBJ.status = 1;
break;
case IS_TIMER:
if((this->status == 1)&&(d->timeup == 1))
_stPLC_OBJ.status = 0;
else
_stPLC_OBJ.status = 1;
break;
case IS_COUNTER:
if((this->status == 1)&&(e->fire == 1))
_stPLC_OBJ.status = 0;
else
_stPLC_OBJ.status = 1;
break;
}
return _stPLC_OBJ;
}