| | |
| | | #include "stdafx.h" |
| | | #include "Common.h" |
| | | #include "CMaster.h" |
| | | #include <future> |
| | | #include <vector> |
| | | |
| | | |
| | | namespace SERVO { |
| | |
| | | m_ullRunTime = 0; |
| | | m_state = MASTERSTATE::READY; |
| | | m_pActiveRobotTask = nullptr; |
| | | m_nLastError = 0; |
| | | InitializeCriticalSection(&m_criticalSection); |
| | | } |
| | | |
| | |
| | | return 0; |
| | | } |
| | | |
| | | void CMaster::clearError() |
| | | { |
| | | m_nLastError = 0; |
| | | m_strLastError = ""; |
| | | setState(MASTERSTATE::READY); |
| | | } |
| | | |
| | | ULONGLONG CMaster::getRunTime() |
| | | { |
| | | if (m_state == MASTERSTATE::RUNNING) |
| | |
| | | // 如果状态为STARTING,开始工作并切换到RUNNING状态 |
| | | lock(); |
| | | if (m_state == MASTERSTATE::STARTING) { |
| | | // 发送indexerOperationModeChange到各个机台,成功后切换到RUNNING状态 |
| | | // 否则切换到MSERROR状态 |
| | | int nRet; |
| | | CEquipment* pEq[6] = { pEFEM, pBonder1, pBonder2, pBakeCooling, |
| | | pVacuumBake, pMeasurement}; |
| | | BOOL bIomcOk[7] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE}; |
| | | std::vector<std::promise<void>> promises(6); |
| | | std::vector<std::future<void>> futures; |
| | | |
| | | nRet = pEq[0]->indexerOperationModeChange(IDNEXER_OPERATION_MODE::Start, |
| | | [&](int writeCode, int retCode) -> void { |
| | | bIomcOk[0] = retCode == (int)RET::OK; |
| | | promises[0].set_value(); |
| | | TRACE("a0001\n", writeCode, retCode); |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGI("<Master>EFEM切换Start状态失败"); |
| | | m_strLastError = "EFEM切换Start状态失败."; |
| | | goto WAIT; |
| | | } |
| | | futures.push_back(promises[0].get_future()); |
| | | |
| | | nRet = pEq[1]->indexerOperationModeChange(IDNEXER_OPERATION_MODE::Start, |
| | | [&](int writeCode, int retCode) -> void { |
| | | bIomcOk[1] = retCode == (int)RET::OK; |
| | | promises[1].set_value(); |
| | | TRACE("a0002\n"); |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGI("<Master>Bonder1切换Start状态失败"); |
| | | m_strLastError = "Bonder1切换Start状态失败."; |
| | | goto WAIT; |
| | | } |
| | | futures.push_back(promises[1].get_future()); |
| | | |
| | | nRet = pEq[2]->indexerOperationModeChange(IDNEXER_OPERATION_MODE::Start, |
| | | [&](int writeCode, int retCode) -> void { |
| | | bIomcOk[2] = retCode == (int)RET::OK; |
| | | promises[2].set_value(); |
| | | TRACE("a0003\n"); |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGI("<Master>Bonder2切换Start状态失败"); |
| | | m_strLastError = "Bonder2切换Start状态失败."; |
| | | goto WAIT; |
| | | } |
| | | futures.push_back(promises[2].get_future()); |
| | | |
| | | nRet = pEq[3]->indexerOperationModeChange(IDNEXER_OPERATION_MODE::Start, |
| | | [&](int writeCode, int retCode) -> void { |
| | | bIomcOk[3] = retCode == (int)RET::OK; |
| | | promises[3].set_value(); |
| | | TRACE("a0004\n"); |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGI("<Master>BakeCooling切换Start状态失败"); |
| | | m_strLastError = "BakeCooling切换Start状态失败."; |
| | | goto WAIT; |
| | | } |
| | | futures.push_back(promises[3].get_future()); |
| | | |
| | | nRet = pEq[4]->indexerOperationModeChange(IDNEXER_OPERATION_MODE::Start, |
| | | [&](int writeCode, int retCode) -> void { |
| | | bIomcOk[4] = retCode == (int)RET::OK; |
| | | promises[4].set_value(); |
| | | TRACE("a0005\n"); |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGI("<Master>VacuumBake切换Start状态失败"); |
| | | m_strLastError = "VacuumBake切换Start状态失败."; |
| | | goto WAIT; |
| | | } |
| | | futures.push_back(promises[4].get_future()); |
| | | |
| | | nRet = pEq[5]->indexerOperationModeChange(IDNEXER_OPERATION_MODE::Start, |
| | | [&](int writeCode, int retCode) -> void { |
| | | bIomcOk[5] = retCode == (int)RET::OK; |
| | | promises[5].set_value(); |
| | | TRACE("a0006\n"); |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGI("<Master>Measurement切换Start状态失败"); |
| | | m_strLastError = "Measurement切换Start状态失败."; |
| | | goto WAIT; |
| | | } |
| | | futures.push_back(promises[5].get_future()); |
| | | |
| | | WAIT: |
| | | for (auto& f : futures) { |
| | | f.wait(); // 阻塞等待对应设备完成 |
| | | } |
| | | for (int i = 0; i < 6; i++) { |
| | | if (!bIomcOk[i]) { |
| | | bIomcOk[6] = FALSE; |
| | | LOGI("<Master>%s切换Start状态失败", pEq[i]->getName().c_str()); |
| | | } |
| | | } |
| | | |
| | | // 检查看是否都已经切换到START状态 |
| | | if (!bIomcOk[6]) { |
| | | unlock(); |
| | | setState(MASTERSTATE::MSERROR); |
| | | continue; |
| | | } |
| | | |
| | | |
| | | unlock(); |
| | | Sleep(1000); |
| | | setState(MASTERSTATE::RUNNING); |
| | | continue; |
| | | } |
| | |
| | | if (m_pActiveRobotTask->getSrcPosition() == p->getID()) { |
| | | CGlass* pGlass = p->getGlassFromSlot(m_pActiveRobotTask->getSrcSlot()); |
| | | if (pGlass != nullptr) { |
| | | CJobDataB* pJobDataBSrc = pGlass->getJobDataB(); |
| | | if (pJobDataBSrc != nullptr |
| | | && pJobDataBSrc->getCassetteSequenceNo() == pJobDataB->getCassetteSequenceNo() |
| | | && pJobDataBSrc->getJobSequenceNo() == pJobDataB->getJobSequenceNo()) { |
| | | CJobDataS* pJobDataS = pGlass->getJobDataS(); |
| | | if (pJobDataS != nullptr |
| | | && pJobDataS->getCassetteSequenceNo() == pJobDataB->getCassetteSequenceNo() |
| | | && pJobDataS->getJobSequenceNo() == pJobDataB->getJobSequenceNo()) { |
| | | bOk = TRUE; |
| | | LOGI("<CMaster>onPreFethedOutJob, 已校验数据一致性."); |
| | | } |