#include "stdafx.h" #include "LoadMonitor.h" #include "Common.h" #include "CBonder.h" #include "Log.h" #define ALARM_MAX 200 unsigned __stdcall LoadMonitorRunRecipeThreadFunction(LPVOID lpParam) { CLoadMonitor* p = (CLoadMonitor*)lpParam; return p->RunRecipeThreadFunction(); } CLoadMonitor::CLoadMonitor() { m_nBeginAddr = 0; m_nLastId = 0; m_nLastLevel = 0; m_hEventRunRecipeResult = ::CreateEvent(NULL, TRUE, FALSE, NULL); m_nRunRecipeResult = 0; m_hRunRecipeWorkThreadHandle = NULL; m_nRunRecipeWorkThrdaddr = 0; m_bRunRecipeWorking = FALSE; m_hRunRecipeWorkEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); m_bWaitingRecipeResult = FALSE; } CLoadMonitor::~CLoadMonitor() { if (m_hEventRunRecipeResult != nullptr) { CloseHandle(m_hEventRunRecipeResult); m_hEventRunRecipeResult = nullptr; } } std::string& CLoadMonitor::getClassName() { static std::string strClassName = "CLoadMonitor"; return strClassName; } void CLoadMonitor::onRecvBroadcast(void* pSender, CIntent* pIntent) { } void CLoadMonitor::onData(int id, const void* pData, int size) { const char* pszData = (const char*)pData; if (3 != id) return; BOOL bPause, bReqLoad, bReqUnload; if (m_nIndex == 0 || m_nIndex == 1) { // ÈëÁÏÇëÇó bPause = pszData[m_nIndex * 2] & 0x04; if (bPause) { ReqNotReady(1); } else { bReqLoad = pszData[m_nIndex * 2] & 0x01; if (bReqLoad) { ReqLoad(1); } else { // ³öÁÏÇëÇó bReqUnload = pszData[m_nIndex * 2 + 1] & 0x01; if (bReqUnload) { ReqUnload(1); } } } } else if (m_nIndex == 2) { // Layer1 ÈëÁÏÇëÇó bReqLoad = pszData[m_nIndex * 2] & 0x01; if (bReqLoad) { ReqLoad(1); } else { // ³öÁÏÇëÇó bReqUnload = pszData[m_nIndex * 2] & 0x20; if (bReqUnload) { ReqUnload(1); } } // Layer2 bReqLoad = pszData[m_nIndex * 2] & 0x02; if (bReqLoad) { ReqLoad(2); } else { bReqUnload = pszData[m_nIndex * 2] & 0x40; if (bReqUnload) { ReqUnload(2); } } // Layer3 bReqLoad = pszData[m_nIndex * 2] & 0x04; if (bReqLoad) { ReqLoad(3); } else { bReqUnload = pszData[m_nIndex * 2] & 0x80; if (bReqUnload) { ReqUnload(3); } } // Layer4 bReqLoad = pszData[m_nIndex * 2] & 0x08; if (bReqLoad) { ReqLoad(4); } else { bReqUnload = pszData[m_nIndex * 2 + 1] & 0x01; if (bReqUnload) { ReqUnload(4); } } } // Çл»Åä·½½á¹û if (m_nIndex == 0 || m_nIndex == 1) { int nAddr = (90 + m_nIndex) * 2; m_nRunRecipeResult = (pszData[nAddr] & 0xff) | (pszData[nAddr + 1]) << 8; if (m_bWaitingRecipeResult) { LOGI("ÕýÔÚ¶ÁÈ¡PLCÇл»Åä·½µÄ½á¹û(RunRecipeResult:%d).", m_nRunRecipeResult); } if (m_nRunRecipeResult != 0) { SetEvent(m_hEventRunRecipeResult); } } } void CLoadMonitor::init() { m_bRunRecipeWorking = TRUE; m_hRunRecipeWorkThreadHandle = (HANDLE)_beginthreadex(NULL, 0, ::LoadMonitorRunRecipeThreadFunction, this, 0, &m_nRunRecipeWorkThrdaddr); CComponent::init(); } void CLoadMonitor::term() { // ½áÊøÏß³Ì m_bRunRecipeWorking = FALSE; SetEvent(m_hRunRecipeWorkEvent); if (m_hRunRecipeWorkThreadHandle != NULL) { WaitForSingleObject(m_hRunRecipeWorkThreadHandle, INFINITE); CloseHandle(m_hRunRecipeWorkThreadHandle); m_hRunRecipeWorkThreadHandle = NULL; } for (auto item : m_alarms) { item->release(); } } void CLoadMonitor::setBeginAddr(int nAddr) { m_nBeginAddr = nAddr; } void CLoadMonitor::OnTimer(UINT nTimerid) { /* char szBuffer[184]; memset(szBuffer, 0, 184); if (m_nIndex == 0) { static int iii = 0; iii++; if (iii > 30 && iii < 35) { szBuffer[0] = 0x01; onData(3, &szBuffer[0], 184); } else if (iii > 35 && iii < 52) { szBuffer[90 * 2] = 0x08; onData(3, &szBuffer[0], 184); } else if (iii > 60 && iii < 90) { szBuffer[1] = 0x01; onData(3, &szBuffer[0], 184); } } if (m_nIndex == 1) { static int iii = 0; iii++; if (iii > 130 && iii < 160) { szBuffer[2] = 0x01; onData(3, &szBuffer[0], 184); } else if (iii > 160 && iii < 190) { szBuffer[3] = 0x01; onData(3, &szBuffer[0], 184); } } if (m_nIndex == 2) { static int iii = 0; iii++; if (iii > 30 && iii < 60) { szBuffer[4] = 0x20; onData(3, &szBuffer[0], 184); } else if (iii > 60 && iii < 90) { szBuffer[4] = 0x40; onData(3, &szBuffer[0], 184); } else if (iii > 90 && iii < 120) { szBuffer[4] = 0x80; szBuffer[5] = 0x1; onData(3, &szBuffer[0], 184); } } */ } void CLoadMonitor::ReqNotReady(int layer) { BEQ::IUnit* pUnit = m_pBonder->getUnit(m_nIndex); ASSERT(pUnit); // ÇëÇóÉÏÁÏ if (0 == pUnit->reqNotReady(layer)) LOGI("Layer%dÔÝÍ£ÉÏÏÂÁÏ.", m_nIndex, layer); } void CLoadMonitor::ReqLoad(int layer) { BEQ::IUnit* pUnit = m_pBonder->getUnit(m_nIndex); ASSERT(pUnit); // ÇëÇóÉÏÁÏ if(0 == pUnit->reqLoad(layer)) LOGI("Layer%dÇëÇóÉÏÁÏ.", m_nIndex, layer); } void CLoadMonitor::ReqUnload(int layer) { BEQ::IUnit* pUnit = m_pBonder->getUnit(m_nIndex); ASSERT(pUnit); // ÇëÇóÉÏÁÏ if(0 == pUnit->reqUnload(layer)) LOGI("Layer%dÇëÇóÏÂÁÏ.", m_nIndex, layer); } int CLoadMonitor::loadReady(const char* pszMaterielId, const char* pszRecipeId) { // ¸ù¾Ýµ¥ÔªºÅÈ¡µÃPLCµØÖ· int nMaterielIdAddr, nRecipeIdAddr; if (m_nIndex == 0) { nMaterielIdAddr = 4720; nRecipeIdAddr = 4780; } else if (m_nIndex == 1) { nMaterielIdAddr = 4750; nRecipeIdAddr = 4781; } else { return 0; } // дÈëÎïÁÏID HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); BOOL bWriteOk = TRUE; char szBuffer[40]; memset(szBuffer, 0, 40); memcpy(szBuffer, pszMaterielId, min(40, strlen(pszMaterielId))); WriteData(MC::SOFT_COMPONENT::D, nMaterielIdAddr, szBuffer, 40, [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void { if (flag != 0) { LOGE("PLC1дÊý¾Ý³¬Ê±.flag=%d", __LINE__, flag); bWriteOk = FALSE; } SetEvent(hEvent); }); WaitForSingleObject(hEvent, INFINITE); ResetEvent(hEvent); if (!bWriteOk) { LOGE("%sÉÏÁÏ×¼±¸¾ÍÐ÷, PLCÒÑдÈëÎïÁÏidʧ°Ü", m_strName.c_str()); CloseHandle(hEvent); return -3; } LOGI("%sÉÏÁÏ×¼±¸¾ÍÐ÷£¬PLCÒÑдÈëÎïÁÏid", m_strName.c_str()); // дÈëÅä·½ID bWriteOk = TRUE; int nRecipeId = atoi(pszRecipeId); szBuffer[0] = (nRecipeId & 0xff); szBuffer[1] = (nRecipeId & 0xff00) >> 8; WriteData(MC::SOFT_COMPONENT::D, nRecipeIdAddr, szBuffer, 2, [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void { if (flag != 0) { LOGE("PLC1дÊý¾Ý³¬Ê±.flag=%d", __LINE__, flag); bWriteOk = FALSE; } SetEvent(hEvent); }); WaitForSingleObject(hEvent, INFINITE); ResetEvent(hEvent); CloseHandle(hEvent); if (!bWriteOk) { LOGE("%sÉÏÁÏ×¼±¸¾ÍÐ÷, PLCдÅä·½IDÎÞÏìÓ¦", m_strName.c_str()); return -4; } LOGI("%sÉÏÁÏ×¼±¸¾ÍÐ÷£¬PLCÒÑдÈëÅä·½id", m_strName.c_str()); // µÈ´ýPLCÏìÓ¦£¬PLC D4790(D4791)Çл»Åä·½½á¹û£º1³É¹¦£¬2ÉÔºòÖØÊÔ£¬3±¨¾¯.txt // ÕâÀïÒª·Åµ½Ïß³ÌÈ¥Ö´ÐÐÁË SetEvent(m_hRunRecipeWorkEvent); return 1; } void CLoadMonitor::Serialize(CArchive& ar) { if (ar.IsStoring()) { Lock(); int count = (int)m_alarms.size(); ar << count; for (auto item : m_alarms) { item->Serialize(ar); } Unlock(); } else { Lock(); int count; ar >> count; for (int i = 0; i < count; i++) { CAlarm* pAlarm = new CAlarm(); pAlarm->addRef(); pAlarm->Serialize(ar); AddAlarm(pAlarm); pAlarm->release(); } Unlock(); } } void CLoadMonitor::AddAlarm(CAlarm* pAlarm) { Lock(); pAlarm->addRef(); m_alarms.push_back(pAlarm); if (m_alarms.size() > ALARM_MAX) { CAlarm* pTemp = m_alarms.front(); pTemp->release(); m_alarms.pop_front(); } Unlock(); } DWORD CLoadMonitor::WaitForGetRunRecipeResult(int timeout, int& result) { m_bWaitingRecipeResult = TRUE; ResetEvent(m_hEventRunRecipeResult); m_nRunRecipeResult = 0; DWORD nRet = WaitForSingleObject(m_hEventRunRecipeResult, timeout); result = m_nRunRecipeResult; m_bWaitingRecipeResult = FALSE; return nRet; } unsigned CLoadMonitor::RunRecipeThreadFunction() { while (m_bRunRecipeWorking) { // ´ýÍ˳öÐźŻòʱ¼äµ½ int nRet = WaitForSingleObject(m_hRunRecipeWorkEvent, INFINITE); ResetEvent(m_hRunRecipeWorkEvent); if (!m_bRunRecipeWorking) break; // µÈ´ýPLCÇл»Åä·½½á¹û int nError = 0; int nRunRecipeResult = 0; nRet = WaitForGetRunRecipeResult(3000, nRunRecipeResult); if (nRet != WAIT_OBJECT_0) { LOGE("%s, ¶ÁÈ¡PLCÇл»Åä·½½á¹û³¬Ê±", m_strName.c_str()); nError = -5; } else { if (nRunRecipeResult == 1) { LOGI("%s, PLCÇл»Åä·½³É¹¦", m_strName.c_str()); nError = 0; } else if (nRunRecipeResult == 2) { LOGE("%s, PLCæµ£¬ÇëÉÔºòÖØÊÔ¡£", m_strName.c_str()); nError = -6; } else { LOGE("%s, PLCÇл»Å䷽ʧ°Ü", m_strName.c_str()); nError = -7; } } SendBroadcast(&CIntent(BC_CODE_RUN_RECIPE_RESULT, "", (CContext*)(__int64)nError)); TRACE("RunRecipeThreadFunction...... \n"); } // _endthreadex(0); TRACE("RunRecipeThreadFunction exit\n"); return 0; }