| | |
| | | return m_nIndex; |
| | | } |
| | | |
| | | BOOL CBonder::hasBondClass() |
| | | BOOL CBonder::hasBondGlass() |
| | | { |
| | | CGlass* pGlass = (CGlass*)m_slot[1].getContext(); |
| | | if (pGlass == nullptr) return FALSE; |
| | |
| | | return pBuddy != nullptr; |
| | | } |
| | | |
| | | BOOL CBonder::hasG2Class() |
| | | BOOL CBonder::hasG2Glass() |
| | | { |
| | | CGlass* pGlass = (CGlass*)m_slot[0].getContext(); |
| | | return (pGlass != nullptr); |
| | |
| | | public: |
| | | void setIndex(unsigned int index); |
| | | unsigned int getIndex(); |
| | | BOOL hasBondClass(); |
| | | BOOL hasG2Class(); |
| | | BOOL hasBondGlass(); |
| | | BOOL hasG2Glass(); |
| | | |
| | | private: |
| | | unsigned int m_nIndex; |
| | |
| | | { |
| | | LOGI("<CEFEM>Robot status:%d, ARM1:%s, ARM2:%s", |
| | | m_robotData.status, |
| | | m_robotData.armState[1] ? _T("ON") : _T("OFF"), |
| | | m_robotData.armState[2] ? _T("ON") : _T("OFF")); |
| | | m_robotData.armState[0] ? _T("ON") : _T("OFF"), |
| | | m_robotData.armState[1] ? _T("ON") : _T("OFF")); |
| | | } |
| | | } |
| | |
| | | m_pArm = nullptr; |
| | | m_processState = PROCESS_STATE::Ready; |
| | | m_blockReadBit = { 0 }; |
| | | m_nTestFlag = 0; |
| | | InitializeCriticalSection(&m_criticalSection); |
| | | } |
| | | |
| | |
| | | CSlot* CEquipment::getProcessedSlot(MaterialsType putSlotType, BOOL bJobMode/* = FALSE*/) |
| | | { |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | | if (m_nTestFlag == 1) LOGI("getProcessedSlot 001"); |
| | | if (!m_slot[i].isEnable()) continue; |
| | | if (m_nTestFlag == 1) LOGI("getProcessedSlot 002"); |
| | | if (m_slot[i].isLock()) continue; |
| | | if (m_nTestFlag == 1) LOGI("getProcessedSlot 003"); |
| | | CGlass* pGlass = (CGlass*)m_slot[i].getContext(); |
| | | if (!isSlotProcessed(i)) continue; |
| | | if (m_nTestFlag == 1) LOGI("getProcessedSlot 004"); |
| | | if (pGlass == nullptr) continue; |
| | | if (m_nTestFlag == 1) LOGI("getProcessedSlot 005"); |
| | | if (!pGlass->isScheduledForProcessing()) continue; |
| | | if (m_nTestFlag == 1) LOGI("getProcessedSlot 006"); |
| | | if (bJobMode && pGlass->getProcessJob() == nullptr) continue; |
| | | if (m_nTestFlag == 1) LOGI("getProcessedSlot 007"); |
| | | if(pGlass->getInspResult(m_nID, 0) == InspResult::Fail) continue; |
| | | int lsPath = m_slot[i].getLinkSignalPath(); |
| | | if(!m_bLinkSignalToUpstream[lsPath][SIGNAL_UPSTREAM_INLINE] |
| | | || m_bLinkSignalToUpstream[lsPath][SIGNAL_UPSTREAM_TROUBLE] |
| | | || !m_bLinkSignalToUpstream[lsPath][SIGNAL_INTERLOCK] |
| | | || !m_bLinkSignalToUpstream[lsPath][SIGNAL_SEND_ABLE] ) continue; |
| | | |
| | | if (m_nTestFlag == 1) LOGI("getProcessedSlot 008"); |
| | | MaterialsType glassType = pGlass->getType(); |
| | | if (glassType == MaterialsType::G1 && putSlotType == MaterialsType::G2) continue; |
| | | if (m_nTestFlag == 1) LOGI("getProcessedSlot 009"); |
| | | if (glassType == MaterialsType::G2 && putSlotType == MaterialsType::G1) continue; |
| | | |
| | | if (m_nTestFlag == 1) LOGI("getProcessedSlot 00a"); |
| | | return &m_slot[i]; |
| | | } |
| | | |
| | |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CEquipment::slotHasGlass(int slotIndex/* = 0*/) |
| | | { |
| | | ASSERT(slotIndex < 8); |
| | | CGlass* pGlass = (CGlass*)m_slot[slotIndex].getContext(); |
| | | return (pGlass != nullptr); |
| | | } |
| | | |
| | | int CEquipment::removeGlass(int slotNo) |
| | | { |
| | | CSlot* pSlot = nullptr; |
| | |
| | | |
| | | // æ¯å¦æç»ç |
| | | BOOL hasGlass(); |
| | | BOOL slotHasGlass(int slotIndex = 0); |
| | | |
| | | // æå®æ§½ä½æ¯å¦å¯ä»¥æ¾ç½®ç»ç |
| | | BOOL canPlaceGlassInSlot(const short slotIndex); |
| | |
| | | |
| | | private: |
| | | CEquipment* m_pArm; |
| | | |
| | | public: |
| | | int m_nTestFlag; |
| | | }; |
| | | } |
| | | |
| | |
| | | |
| | | SERVO::CGlass* pGlass = (SERVO::CGlass*)pSlot->getContext(); |
| | | if (pGlass != nullptr) { |
| | | m_listCtrl.SetItemText(index, 3, pGlass->getID().c_str()); |
| | | CString strText; |
| | | if (pGlass->getType() == SERVO::MaterialsType::G1) { |
| | | strText.Format(_T("(G1)%s"), pGlass->getID().c_str()); |
| | | } |
| | | else if (pGlass->getType() == SERVO::MaterialsType::G2) { |
| | | strText.Format(_T("(G2)%s"), pGlass->getID().c_str()); |
| | | } |
| | | else { |
| | | strText.Format(_T("(%s"), pGlass->getID().c_str()); |
| | | } |
| | | m_listCtrl.SetItemText(index, 3, strText); |
| | | SERVO::CGlass* pBuddy = pGlass->getBuddy(); |
| | | if (pBuddy != nullptr) { |
| | | m_listCtrl.SetItemText(index, 4, pBuddy->getID().c_str()); |
| | |
| | | |
| | | |
| | | // æ¨¡ææµè¯ |
| | | /* |
| | | if (m_nIndex == 0) { |
| | | static int ii = 0; |
| | | ii++; |
| | | if (ii == 50) { |
| | | char szBuffer[64] = {0}; |
| | | CStep* pStep = getStepWithName(STEP_EQ_PORT1_INUSE); |
| | | CStep* pStep = getStepWithName(STEP_EQ_PORT1_BLOCKED); |
| | | CPortStatusReport portStatusReport; |
| | | portStatusReport.setPortStatus(PORT_INUSE); |
| | | portStatusReport.setPortStatus(PORT_BLOCKED); |
| | | portStatusReport.setJobExistenceSlot(0xf); |
| | | portStatusReport.setCassetteId("CID1001"); |
| | | int nRet = portStatusReport.serialize(szBuffer, 64); |
| | |
| | | ii++; |
| | | if (ii == 55) { |
| | | char szBuffer[64] = { 0 }; |
| | | CStep* pStep = getStepWithName(STEP_EQ_PORT2_INUSE); |
| | | CStep* pStep = getStepWithName(STEP_EQ_PORT2_BLOCKED); |
| | | CPortStatusReport portStatusReport; |
| | | portStatusReport.setPortStatus(PORT_INUSE); |
| | | portStatusReport.setPortStatus(PORT_BLOCKED); |
| | | portStatusReport.setJobExistenceSlot(0xff ); |
| | | portStatusReport.setCassetteId("CID1004"); |
| | | int nRet = portStatusReport.serialize(szBuffer, 64); |
| | | decodePortStatusReport(pStep, szBuffer, 64); |
| | | } |
| | | } |
| | | */ |
| | | } |
| | | |
| | | void CLoadPort::serialize(CArchive& ar) |
| | |
| | | m_nContinuousTransferCount = 0; |
| | | m_nContinuousTransferStep = CTStep_Unknow; |
| | | m_pControlJob = nullptr; |
| | | m_nTestFlag = 0; |
| | | InitializeCriticalSection(&m_criticalSection); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | // æ£æ¥çæ¯å¦é½å·²ç»åæ¢å°STARTç¶æ |
| | | /* |
| | | if (!bIomcOk[6]) { |
| | | unlock(); |
| | | setState(MASTERSTATE::MSERROR); |
| | | continue; |
| | | } |
| | | */ |
| | | |
| | | unlock(); |
| | | if(m_bContinuousTransfer) |
| | |
| | | } |
| | | |
| | | |
| | | // æ¤å¤æ£æµä¼å
ç±»å忬¡è¦ç±»åï¼G1æG2ï¼ |
| | | // 妿å
¶ä¸ä¸Bonderæå个ç»çï¼ä¼å
åå®çé
对类åï¼å¦åæ æè°äº |
| | | primaryType = MaterialsType::G1; |
| | | secondaryType = MaterialsType::G2; |
| | | if ((!pBonder1->canPlaceGlassInSlot(0) && !pBonder1->canPlaceGlassInSlot(1)) |
| | | && (!pBonder2->canPlaceGlassInSlot(0) && !pBonder2->canPlaceGlassInSlot(1))) { |
| | | // 妿G1åG2齿»¡äºï¼é£å°±çAligner, 妿Aligneræç»ç为G1, ååG2 |
| | | CGlass* pGlass = pAligner->getGlassFromSlot(1); |
| | | if (pGlass != nullptr && pGlass->getType() == MaterialsType::G1) { |
| | | primaryType = MaterialsType::G2; |
| | | secondaryType = MaterialsType::G1; |
| | | } |
| | | // Bonder1ãBonder2ãFliperãVacuumBakeãAlignerï¼ç»è®¡G2åG1çæ°é, é
å¯¹ç»æ°, å¤åºçç±»å |
| | | int nG2Count = 0, nG1Count = 0, nGlassGroup, nExtraType; |
| | | if (pBonder1->slotHasGlass(0)) { |
| | | nG2Count++; |
| | | } |
| | | else if ((pBonder1->canPlaceGlassInSlot(0) && !pBonder1->canPlaceGlassInSlot(1)) |
| | | || (pBonder2->canPlaceGlassInSlot(0) && !pBonder2->canPlaceGlassInSlot(1))) { |
| | | primaryType = MaterialsType::G2; |
| | | secondaryType = MaterialsType::G1; |
| | | if (pBonder1->slotHasGlass(1)) { |
| | | nG1Count++; |
| | | } |
| | | |
| | | if (pBonder2->slotHasGlass(0)) { |
| | | nG2Count++; |
| | | } |
| | | if (pBonder2->slotHasGlass(1)) { |
| | | nG1Count++; |
| | | } |
| | | |
| | | if (pFliper->slotHasGlass(0)) { |
| | | nG2Count++; |
| | | } |
| | | |
| | | if (pVacuumBake->slotHasGlass(0)) { |
| | | nG1Count++; |
| | | } |
| | | if (pVacuumBake->slotHasGlass(1)) { |
| | | nG1Count++; |
| | | } |
| | | |
| | | CGlass* pTempGlass = pAligner->getGlassFromSlot(0); |
| | | if (pTempGlass != nullptr) { |
| | | MaterialsType type = pTempGlass->getType(); |
| | | if(type == MaterialsType::G1) |
| | | nG1Count++; |
| | | else if (type == MaterialsType::G2) |
| | | nG2Count++; |
| | | } |
| | | nGlassGroup = min(nG1Count, nG2Count); |
| | | |
| | | if (nG1Count == nG2Count) { |
| | | nExtraType = 0; |
| | | } |
| | | else if (nG1Count > nG2Count) { |
| | | nExtraType = 1; |
| | | } |
| | | else { |
| | | nExtraType = 2; |
| | | } |
| | | secondaryType = MaterialsType::G0; |
| | | |
| | | |
| | | // Measurement -> LoadPort |
| | | if (rmd.armState[0] || rmd.armState[1]) { |
| | | LOGI("Arm1 %s, Arm2 %s.", rmd.armState[0] ? _T("ä¸å¯ç¨") : _T("å¯ç¨"), |
| | | rmd.armState[1] ? _T("ä¸å¯ç¨") : _T("å¯ç¨")); |
| | | } |
| | | for (int s = 0; s < 4; s++) { |
| | | PortType pt = pLoadPorts[s]->getPortType(); |
| | | if (!rmd.armState[0] && pLoadPorts[s]->isEnable() |
| | | && (pt == PortType::Unloading || pt == PortType::Both) |
| | | && pLoadPorts[s]->getPortStatus() == PORT_INUSE) { |
| | | m_pActiveRobotTask = createTransferTask(pMeasurement, pLoadPorts[s], primaryType, secondaryType); |
| | | m_pActiveRobotTask = createTransferTask(pMeasurement, pLoadPorts[s], MaterialsType::G1, secondaryType); |
| | | if (m_pActiveRobotTask != nullptr) { |
| | | goto PORT_PUT; |
| | | } |
| | |
| | | |
| | | |
| | | // Fliper(G2) -> Bonder |
| | | auto pSrcSlot = pVacuumBake->getProcessedSlot(primaryType); |
| | | if (pSrcSlot != nullptr && !rmd.armState[1] && !pBonder1->hasBondClass()) { |
| | | m_pActiveRobotTask = createTransferTask(pFliper, pBonder1, primaryType, secondaryType, 2); |
| | | //m_nTestFlag = 1; |
| | | //pVacuumBake->m_nTestFlag = 1; |
| | | auto pSrcSlot = pVacuumBake->getProcessedSlot(MaterialsType::G1); |
| | | //LOGI("<Master>pSrcSlot = %x", pSrcSlot,); |
| | | if (pSrcSlot != nullptr && !rmd.armState[1] |
| | | && pBonder1->canPlaceGlassInSlot(0)) { |
| | | m_pActiveRobotTask = createTransferTask(pFliper, pBonder1, MaterialsType::G2, MaterialsType::G0, 2); |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | | if (pSrcSlot != nullptr && !rmd.armState[1] && !pBonder2->hasBondClass()) { |
| | | m_pActiveRobotTask = createTransferTask(pFliper, pBonder2, primaryType, secondaryType, 2); |
| | | if (pSrcSlot != nullptr && !rmd.armState[1] |
| | | && pBonder2->canPlaceGlassInSlot(0)) { |
| | | m_pActiveRobotTask = createTransferTask(pFliper, pBonder2, MaterialsType::G2, MaterialsType::G0, 2); |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | | |
| | | |
| | | //m_nTestFlag = 0 |
| | | ; |
| | | // VacuumBake(G1) -> Bonder |
| | | if (!rmd.armState[0] && !pBonder1->hasBondClass()) { |
| | | m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder1, primaryType, secondaryType); |
| | | if (!rmd.armState[0] && pBonder1->slotHasGlass(0) && !pBonder1->slotHasGlass(1)) { |
| | | m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder1, MaterialsType::G1, MaterialsType::G0); |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | | |
| | | if (!rmd.armState[0] && !pBonder2->hasBondClass()) { |
| | | m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder2, primaryType, secondaryType); |
| | | if (!rmd.armState[0] && pBonder2->slotHasGlass(0) && !pBonder2->slotHasGlass(1)) { |
| | | m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder2, MaterialsType::G1, MaterialsType::G0); |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | | |
| | |
| | | // Aligner -> Fliper(G2) |
| | | // Aligner -> VacuumBake(G1) |
| | | if (!rmd.armState[1]) { |
| | | m_pActiveRobotTask = createTransferTask(pAligner, pFliper, primaryType, secondaryType); |
| | | m_pActiveRobotTask = createTransferTask(pAligner, pFliper, MaterialsType::G2, secondaryType); |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | | |
| | | if (!rmd.armState[0]) { |
| | | m_pActiveRobotTask = createTransferTask(pAligner, pVacuumBake, primaryType, secondaryType); |
| | | // m_nTestFlag = 1; |
| | | if (m_nTestFlag == 1) LOGI("createTransferTask 004df %d, %d", MaterialsType::G1, secondaryType); |
| | | m_pActiveRobotTask = createTransferTask(pAligner, pVacuumBake, MaterialsType::G1, secondaryType); |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | m_nTestFlag = 0; |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | |
| | | // LoadPort -> Aligner |
| | | if (nGlassGroup >= 2) { |
| | | unlock(); |
| | | continue; |
| | | } |
| | | |
| | | if(nExtraType == 0) |
| | | primaryType = MaterialsType::G2; |
| | | else { |
| | | primaryType = MaterialsType::G1; |
| | | } |
| | | |
| | | for (int s = 0; s < 4; s++) { |
| | | PortType pt = pLoadPorts[s]->getPortType(); |
| | | if (!rmd.armState[0] && pLoadPorts[s]->isEnable() |
| | |
| | | if (m_pControlJob->state() == CJState::Queued) { |
| | | LOGI("<Master>ControlJobå·²ç»å¯å¨"); |
| | | m_pControlJob->start(); |
| | | |
| | | if (m_listener.onCjStart != nullptr) { |
| | | m_listener.onCjStart(this, m_pControlJob); |
| | | } |
| | | } |
| | | if (m_pControlJob->state() == CJState::Paused) { |
| | | LOGI("<Master>ControlJobå·²ç»æ¢å¤è¿è¡"); |
| | |
| | | |
| | | // Fliper(G2) -> Bonder |
| | | auto pSrcSlot = pVacuumBake->getProcessedSlot(primaryType); |
| | | if (pSrcSlot != nullptr && !rmd.armState[1] && !pBonder1->hasBondClass()) { |
| | | if (pSrcSlot != nullptr && !rmd.armState[1] && !pBonder1->hasBondGlass()) { |
| | | m_pActiveRobotTask = createTransferTask(pFliper, pBonder1, primaryType, secondaryType, 2); |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | | if (pSrcSlot != nullptr && !rmd.armState[1] && !pBonder2->hasBondClass()) { |
| | | if (pSrcSlot != nullptr && !rmd.armState[1] && !pBonder2->hasBondGlass()) { |
| | | m_pActiveRobotTask = createTransferTask(pFliper, pBonder2, primaryType, secondaryType, 2); |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | | |
| | | |
| | | // VacuumBake(G1) -> Bonder |
| | | if (!rmd.armState[0] && !pBonder1->hasBondClass()) { |
| | | if (!rmd.armState[0] && !pBonder1->hasBondGlass()) { |
| | | m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder1, primaryType, secondaryType); |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | | |
| | | if (!rmd.armState[0] && !pBonder2->hasBondClass()) { |
| | | if (!rmd.armState[0] && !pBonder2->hasBondGlass()) { |
| | | m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder2, primaryType, secondaryType); |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | |
| | | else { |
| | | LOGE("<Master>Glass(%s)ä»çå¾
åéå°å·¥èºåé转移失败.", |
| | | pGlass->getID().c_str()); |
| | | } |
| | | |
| | | // è¿é䏿¥Panel Startäºä»¶ |
| | | if (m_listener.onPanelStart != nullptr) { |
| | | m_listener.onPanelStart(this, pGlass); |
| | | } |
| | | |
| | | goto BATCH_PORT_GET; |
| | |
| | | |
| | | // Bonder1 -> Bonder2 |
| | | if ((m_nContinuousTransferStep == CTStep_Unknow || m_nContinuousTransferStep == CTStep_Fliper_Bonder1) |
| | | && !rmd.armState[0] && !pBonder2->hasBondClass()) { |
| | | && !rmd.armState[0] && !pBonder2->hasBondGlass()) { |
| | | m_pActiveRobotTask = createTransferTask_continuous_transfer(pBonder1, |
| | | 1, pBonder2, 1); |
| | | if (m_pActiveRobotTask != nullptr) { |
| | |
| | | |
| | | // Fliper(G2) -> Bonder1 |
| | | if ((m_nContinuousTransferStep == CTStep_Unknow || m_nContinuousTransferStep == CTStep_Aligner_Fliper) |
| | | &&!rmd.armState[0] && !pBonder1->hasBondClass()) { |
| | | &&!rmd.armState[0] && !pBonder1->hasBondGlass()) { |
| | | m_pActiveRobotTask = createTransferTask_continuous_transfer(pFliper, |
| | | 0, pBonder1, 1); |
| | | if (m_pActiveRobotTask != nullptr) { |
| | |
| | | if (pGlass == nullptr) { |
| | | bOk = TRUE; |
| | | slot = m_pActiveRobotTask->getTarSlot(); |
| | | LOGI("<CMaster>onPreFethedOutJob, å·²æ ¡éªæ°æ®ä¸è´æ§."); |
| | | LOGI("<CMaster>onPreStoredJob, å·²æ ¡éªæ°æ®ä¸è´æ§."); |
| | | } |
| | | } |
| | | |
| | |
| | | if (pGlass == nullptr && m_pActiveRobotTask->getSrcSlot() == port) { |
| | | bOk = TRUE; |
| | | slot = m_pActiveRobotTask->getSrcSlot(); |
| | | LOGI("<CMaster>onPreFethedOutJob, å·²æ ¡éªæ°æ®ä¸è´æ§."); |
| | | LOGI("<CMaster>onPreStoredJob, å·²æ ¡éªæ°æ®ä¸è´æ§."); |
| | | } |
| | | } |
| | | } |
| | |
| | | if (m_pActiveRobotTask->getSrcPosition() == EQ_ID_MEASUREMENT) { |
| | | CGlass* pGlass = (CGlass*)m_pActiveRobotTask->getContext(); |
| | | pGlass->complete(); |
| | | this->saveState(); |
| | | bool bMoved = glassFromInPorcessToComplete(pGlass); |
| | | if (bMoved) { |
| | | LOGI("<Master>Glass(%s)ä»å·¥èºåéå°å®æåé转移æå.", |
| | |
| | | LOGE("<Master>Glass(%s)ä»å·¥èºåéå°å®æåé转移失败.", |
| | | pGlass->getID().c_str()); |
| | | } |
| | | if (m_listener.onPanelEnd != nullptr) { |
| | | m_listener.onPanelEnd(this, pGlass); |
| | | } |
| | | |
| | | // æ£æ¥PJæ¯å¦å·²ç»å®æ |
| | | CProcessJob* pJob = getGlassProcessJob((CGlass*)m_pActiveRobotTask->getContext()); |
| | | if (pJob != nullptr && checkAndUpdatePjComplete(pJob)) { |
| | | this->saveState(); |
| | | LOGE("<Master>ProcessJob(%s)宿.", |
| | | pJob->id().c_str()); |
| | | if (m_listener.onPjEnd != nullptr) { |
| | | m_listener.onPjEnd(this, pJob); |
| | | } |
| | | |
| | | // æ£æ¥CJæ¯å¦å·²ç»å®æ |
| | | ASSERT(m_pControlJob); |
| | | if (checkAndUpdateCjComplete(m_pControlJob)) { |
| | | this->saveState(); |
| | | LOGE("<Master>ControlJob(%s)宿.", |
| | | m_pControlJob->id().c_str()); |
| | | if (m_listener.onCjEnd != nullptr) { |
| | | m_listener.onCjEnd(this, pJob); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | |
| | | // æ¨¡ææµè¯ |
| | | /* |
| | | static int aaa = 0; |
| | | aaa++; |
| | | if (aaa % 30 == 0) { |
| | |
| | | CGlass* pGlass = m_queueGlasses.front(); |
| | | pGlass->start(); |
| | | glassFromQueueToInPorcess(pGlass); |
| | | this->saveState(); |
| | | |
| | | // è¿é䏿¥Panel Startäºä»¶ |
| | | if (m_listener.onPanelStart != nullptr) { |
| | | m_listener.onPanelStart(this, pGlass); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | CGlass* pGlass = m_inProcesGlasses.front(); |
| | | pGlass->complete(); |
| | | glassFromInPorcessToComplete(pGlass); |
| | | this->saveState(); |
| | | |
| | | // è¿é䏿¥Panel Endäºä»¶ |
| | | if (m_listener.onPanelEnd != nullptr) { |
| | | m_listener.onPanelEnd(this, pGlass); |
| | | } |
| | | |
| | | CProcessJob* pJob = getGlassProcessJob(pGlass); |
| | | if (pJob != nullptr && checkAndUpdatePjComplete(pJob)) { |
| | | processJobFromInPorcessToComplete(pJob); |
| | | this->saveState(); |
| | | LOGE("<Master>ProcessJob(%s)宿.", |
| | | pJob->id().c_str()); |
| | | if (m_listener.onPjEnd != nullptr) { |
| | | m_listener.onPjEnd(this, pJob); |
| | | } |
| | | |
| | | // æ£æ¥CJæ¯å¦å·²ç»å®æ |
| | | ASSERT(m_pControlJob); |
| | | if (checkAndUpdateCjComplete(m_pControlJob)) { |
| | | this->saveState(); |
| | | LOGE("<Master>ControlJob(%s)宿.", |
| | | m_pControlJob->id().c_str()); |
| | | if (m_listener.onCjEnd != nullptr) { |
| | | m_listener.onCjEnd(this, pJob); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | */ |
| | | |
| | | } |
| | | |
| | | void CMaster::connectEquipments() |
| | |
| | | if (!pSrcEq->IsEnabled()) { |
| | | return nullptr; |
| | | } |
| | | |
| | | CRobotTask* pTask = nullptr; |
| | | CSlot* pSrcSlot, * pTarSlot; |
| | | pSrcEq->m_nTestFlag = m_nTestFlag; |
| | | pTarSlot = pTarEq->getAvailableSlotForGlass(primaryType); |
| | | pSrcSlot = pSrcEq->getProcessedSlot(primaryType, bJobMode); |
| | | if (pSrcSlot == nullptr || nullptr == pTarSlot) { |
| | | if (m_nTestFlag == 1) LOGI("createTransferTask 003 %x, %x", pTarSlot, pSrcSlot); |
| | | if (pSrcSlot == nullptr || nullptr == pTarSlot && secondaryType != SERVO::MaterialsType::G0) { |
| | | pTarSlot = pTarEq->getAvailableSlotForGlass(secondaryType); |
| | | pSrcSlot = pSrcEq->getProcessedSlot(secondaryType, bJobMode); |
| | | } |
| | | |
| | | if (m_nTestFlag == 1) LOGI("createTransferTask 004 %x, %x", pTarSlot, pSrcSlot); |
| | | |
| | | if (pSrcSlot != nullptr && nullptr != pTarSlot) { |
| | | pTask = new CRobotTask(); |
| | |
| | | for (const auto pj : pjs) { |
| | | if (pj->state() == PJState::Queued) { |
| | | pj->start(); |
| | | return pj; |
| | | } |
| | | return pj; |
| | | } |
| | | |
| | | |
| | |
| | | return false; |
| | | } |
| | | |
| | | bool CMaster::processJobFromInPorcessToComplete(CProcessJob* pProcessJob) |
| | | { |
| | | auto it = std::find(m_inProcesJobs.begin(), m_inProcesJobs.end(), pProcessJob); |
| | | if (it != m_inProcesJobs.end()) { |
| | | m_completeProcessJobs.push_back(*it); |
| | | m_inProcesJobs.erase(it); |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | bool CMaster::checkAndUpdatePjComplete(CProcessJob* pJob) |
| | | { |
| | | ASSERT(pJob); |
| | |
| | | |
| | | for (auto c : pJob->carriers()) { |
| | | for (auto g : c.contexts) { |
| | | CGlass* pGlass = (CGlass*)g; |
| | | if (pGlass->state() != GlsState::Aborted |
| | | && pGlass->state() != GlsState::Completed |
| | | && pGlass->state() != GlsState::Failed) return false; |
| | | auto state = ((CGlass*)g)->state(); |
| | | if (state != GlsState::Aborted && state != GlsState::Completed |
| | | && state != GlsState::Failed) return false; |
| | | } |
| | | } |
| | | |
| | | return pJob->complete(); |
| | | } |
| | | |
| | | bool CMaster::checkAndUpdateCjComplete(CControlJob* pJob) |
| | | { |
| | | ASSERT(pJob); |
| | | auto state = pJob->state(); |
| | | if (state != CJState::Executing && state != CJState::Paused) return false; |
| | | |
| | | for (auto pj : pJob->getPjs()) { |
| | | auto state = pj->state(); |
| | | if (state != PJState::Aborted && state != PJState::Completed |
| | | && state != PJState::Failed) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | |
| | | ONROBOTTASKEVENT onRobotTaskEvent; |
| | | ONLOADPORTSTATUSCHANGED onLoadPortStatusChanged; |
| | | ONCTROUNDEND onCTRoundEnd; |
| | | ONPJSTART onCjStart; |
| | | ONPJSTART onCjEnd; |
| | | ONPJSTART onPjStart; |
| | | ONPJSTART onPjEnd; |
| | | ONPJSTART onPanelStart; |
| | | ONPJSTART onPanelEnd; |
| | | } MasterListener; |
| | | |
| | | class CMaster : public IResourceView |
| | |
| | | bool addGlassToQueue(CGlass* pGlass); |
| | | bool glassFromQueueToInPorcess(CGlass* pGlass); |
| | | bool glassFromInPorcessToComplete(CGlass* pGlass); |
| | | bool processJobFromInPorcessToComplete(CProcessJob* pProcessJob); |
| | | bool checkAndUpdatePjComplete(CProcessJob* pJob); |
| | | bool checkAndUpdateCjComplete(CControlJob* pJob); |
| | | CProcessJob* getGlassProcessJob(CGlass* pGlass); |
| | | |
| | | |
| | |
| | | |
| | | // æ°å¢å·²ç»å¼å§å¤ççProcessJobå表 |
| | | std::vector<CProcessJob*> m_inProcesJobs; |
| | | std::vector<CProcessJob*> m_completeProcessJobs; |
| | | std::vector<CGlass*> m_queueGlasses; |
| | | std::vector<CGlass*> m_inProcesGlasses; |
| | | std::vector<CGlass*> m_completeGlasses; |
| | |
| | | SERVO::CControlJob* m_pControlJob; |
| | | std::vector<SERVO::CProcessJob*> m_processJobs; |
| | | std::string m_strStatePath; |
| | | |
| | | int m_nTestFlag; |
| | | }; |
| | | } |
| | | |
| | |
| | | return requestEventReportSend("CarrierID_Readed"); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_Port_Unload_Ready() |
| | | { |
| | | return requestEventReportSend("Port_Unload_Ready"); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_Port_Load_Ready() |
| | | { |
| | | return requestEventReportSend("Port_Load_Ready"); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_Port_Blocked() |
| | | { |
| | | return requestEventReportSend("Port_Blocked"); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_PJ_Queued() |
| | | { |
| | | return requestEventReportSend("PJ_Queued"); |
| | |
| | | return requestEventReportSend("PJ_End"); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_CJ_Start() |
| | | { |
| | | return requestEventReportSend("CJ_Start"); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_CJ_End() |
| | | { |
| | | return requestEventReportSend("CJ_End"); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_Panel_Start() |
| | | { |
| | | return requestEventReportSend("Panel_Start"); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_Panel_End() |
| | | { |
| | | return requestEventReportSend("Panel_End"); |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | int requestEventReportSend(unsigned int CEID); |
| | | int requestEventReportSend(const char* pszEventName); |
| | | int requestEventReportSend_CarrierID_Readed(); |
| | | int requestEventReportSend_Port_Unload_Ready(); |
| | | int requestEventReportSend_Port_Load_Ready(); |
| | | int requestEventReportSend_Port_Blocked(); |
| | | int requestEventReportSend_PJ_Queued(); |
| | | int requestEventReportSend_PJ_Start(); |
| | | int requestEventReportSend_PJ_End(); |
| | | int requestEventReportSend_CJ_Start(); |
| | | int requestEventReportSend_CJ_End(); |
| | | int requestEventReportSend_Panel_Start(); |
| | | int requestEventReportSend_Panel_End(); |
| | | |
| | | private: |
| | | void replyAck(int s, int f, unsigned int systemBytes, BYTE ack, const char* pszAckName); |
| | |
| | | } |
| | | m_hsmsPassive.requestEventReportSend_CarrierID_Readed(); |
| | | } |
| | | else if (status == PORT_BLOCKED) { |
| | | SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment); |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("BlockedPortId", pLoadPort->getID()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend_Port_Blocked(); |
| | | } |
| | | else if (status == PORT_LOAD_READY) { |
| | | SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment); |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("LoadReadyPortId", pLoadPort->getID()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend_Port_Load_Ready(); |
| | | } |
| | | else if (status == PORT_UNLOAD_READY) { |
| | | SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment); |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("UnloadReadyPortId", pLoadPort->getID()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend_Port_Unload_Ready(); |
| | | } |
| | | notifyPtr(RX_CODE_LOADPORT_STATUS_CHANGED, pEquipment); |
| | | }; |
| | | masterListener.onCTRoundEnd = [&](void* pMaster, int round) { |
| | | m_configuration.setContinuousTransferCount(round); |
| | | }; |
| | | masterListener.onCjStart = [&](void* pMaster, void* pj) { |
| | | m_hsmsPassive.setVariableValue("CJStartID", ((SERVO::CControlJob*)pj)->id().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_CJ_Start(); |
| | | }; |
| | | masterListener.onCjEnd = [&](void* pMaster, void* pj) { |
| | | m_hsmsPassive.setVariableValue("CJEndID", ((SERVO::CControlJob*)pj)->id().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_CJ_End(); |
| | | |
| | | // ç»æ¹ï¼ä¿åControlJob |
| | | // |
| | | }; |
| | | masterListener.onPjStart = [&](void* pMaster, void* pj) { |
| | | m_hsmsPassive.setVariableValue("PJStartID", ((SERVO::CProcessJob*)pj)->id().c_str()); |
| | |
| | | m_hsmsPassive.setVariableValue("PJEndID", ((SERVO::CProcessJob*)pj)->id().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_PJ_End(); |
| | | }; |
| | | masterListener.onPanelStart = [&](void* pMaster, void* pj) { |
| | | m_hsmsPassive.setVariableValue("PanelStartID", ((SERVO::CGlass*)pj)->getID().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_Panel_Start(); |
| | | }; |
| | | masterListener.onPanelEnd = [&](void* pMaster, void* pj) { |
| | | m_hsmsPassive.setVariableValue("PanelEndID", ((SERVO::CGlass*)pj)->getID().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_Panel_End(); |
| | | }; |
| | | m_master.setListener(masterListener); |
| | | m_master.setContinuousTransferCount(m_configuration.getContinuousTransferCount()); |
| | | |
| | |
| | | } |
| | | |
| | | // è·å Grid è¡¨æ ¼ä¸ Slot ç¶æï¼ç¬¬1~8è¡ï¼ |
| | | /* |
| | | for (int i = 1; i <= SLOT_MAX; ++i) { |
| | | SERVO::CGlass* pGlass = (SERVO::CGlass*)m_wndGrid.GetItemData(i, 0); |
| | | if (pGlass != nullptr) { |
| | |
| | | ASSERT(pCheck); |
| | | pGlass->setScheduledForProcessing(pCheck->GetCheck()); |
| | | pGlass->setType(static_cast<SERVO::MaterialsType>(config.nMaterialType)); |
| | | LOGI("i: %d, nMaterialType:%d", i, config.nMaterialType); |
| | | |
| | | SERVO::CJobDataS* pJobDataS = pGlass->getJobDataS(); |
| | | pJobDataS->setLotId(config.strLotID.c_str()); |
| | |
| | | } |
| | | } |
| | | } |
| | | */ |
| | | |
| | | |
| | | // æå¾ä¸ºæ´æ°ç±»åï¼ææ¶æµè¯ä½¿ç¨ï¼åæè²ä¸ºæ¯å¦å å·¥ |
| | | for (int i = 1; i <= SLOT_MAX; ++i) { |
| | | SERVO::CGlass* pGlass = (SERVO::CGlass*)m_wndGrid.GetItemData(i, 0); |
| | | if (pGlass != nullptr) { |
| | | CGridCellCheck* pCheck = dynamic_cast<CGridCellCheck*>(m_wndGrid.GetCell(i, 1)); |
| | | ASSERT(pCheck); |
| | | pGlass->setScheduledForProcessing(TRUE); |
| | | if (pCheck->GetCheck()) { |
| | | pGlass->setType(static_cast<SERVO::MaterialsType>(config.nMaterialType)); |
| | | LOGI("i: %d, nMaterialType:%d", i, config.nMaterialType); |
| | | |
| | | SERVO::CJobDataS* pJobDataS = pGlass->getJobDataS(); |
| | | pJobDataS->setLotId(config.strLotID.c_str()); |
| | | pJobDataS->setProductId(config.strProductID.c_str()); |
| | | pJobDataS->setOperationId(config.strOperationID.c_str()); |
| | | pJobDataS->setMaterialsType(config.nMaterialType); |
| | | |
| | | RecipeInfo stRecipeInfo = RecipeManager::getInstance().getRecipeByPPID(config.strRecipe); |
| | | std::vector<DeviceRecipe> vecRecipeInfo = stRecipeInfo.vecDeviceList; |
| | | |
| | | for (const auto& info : vecRecipeInfo) { |
| | | const std::string& name = info.strDeviceName; |
| | | short nRecipeID = (short)info.nRecipeID; |
| | | |
| | | if (name == EQ_NAME_EFEM) { |
| | | pJobDataS->setDeviceRecipeId(0, nRecipeID); |
| | | } |
| | | else if (name == EQ_NAME_BONDER1) { |
| | | pJobDataS->setDeviceRecipeId(1, nRecipeID); |
| | | } |
| | | else if (name == EQ_NAME_BONDER2) { |
| | | pJobDataS->setDeviceRecipeId(2, nRecipeID); |
| | | } |
| | | else if (name == EQ_NAME_BAKE_COOLING) { |
| | | pJobDataS->setDeviceRecipeId(3, nRecipeID); |
| | | } |
| | | else if (name == EQ_NAME_VACUUMBAKE) { |
| | | pJobDataS->setDeviceRecipeId(4, nRecipeID); |
| | | } |
| | | else if (name == EQ_NAME_MEASUREMENT) { |
| | | pJobDataS->setDeviceRecipeId(5, nRecipeID); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | GetDlgItem(IDC_BUTTON_PROCESS_START)->EnableWindow(TRUE); |
| | | GetDlgItem(IDC_BUTTON_PROCESS_CANCEL)->EnableWindow(TRUE); |
| | |
| | | <RemoteDebuggerCommand>\\DESKTOP-IODBVIQ\Servo\Debug\Servo.exe</RemoteDebuggerCommand> |
| | | <RemoteDebuggerWorkingDirectory>\\DESKTOP-IODBVIQ\Servo\Debug\</RemoteDebuggerWorkingDirectory> |
| | | <RemoteDebuggerServerName>DESKTOP-IODBVIQ</RemoteDebuggerServerName> |
| | | <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> |
| | | <DebuggerFlavor>WindowsRemoteDebugger</DebuggerFlavor> |
| | | </PropertyGroup> |
| | | </Project> |
| | |
| | | }; |
| | | |
| | | enum class MaterialsType { |
| | | G0 = 0, |
| | | G1 = 1, |
| | | G2 = 2, |
| | | G1G2 = 3 |
| | |
| | | pEq2 = theApp.m_model.getMaster().getEquipment(pTask->getTarPosition()); |
| | | if (pEq1 != nullptr && pEq2 != nullptr) { |
| | | CString strText; |
| | | if (theApp.m_model.getMaster().getContinuousTransferCount() > 0) { |
| | | if (theApp.m_model.getMaster().getState() == SERVO::MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER) { |
| | | strText.Format(_T("[%d]%s --> %s"), |
| | | theApp.m_model.getMaster().getContinuousTransferCount(), |
| | | pEq1->getName().c_str(), pEq2->getName().c_str()); |
| | |
| | | 50000,CarrierID_Readed,,(50000) |
| | | 50001,PJ_Queued,,(50001) |
| | | 50002,PJ_Start,,(50002) |
| | | 50002,PJ_End,,(50003) |
| | | 50003,PJ_End,,(50003) |
| | | 50004,Panel_Start,,(50004) |
| | | 50005,Panel_End,,(50005) |
| | | 50006,CJ_Start,,(50006) |
| | | 50007,CJ_End,,(50007) |
| | | 50008,Port_Unload_Ready,,(50008) |
| | | 50009,Port_Load_Ready,,(50009) |
| | | 50010,Port_Blocked,,(50010) |
| | | |
| | |
| | | 50000,(5000) |
| | | 50001,(5003) |
| | | 50002,(5004) |
| | | 50003,(5005) |
| | | 50004,(5006) |
| | | 50005,(5007) |
| | | 50006,(5008) |
| | | 50007,(5009) |
| | | 50008,(5010) |
| | | 50009,(5011) |
| | | 50010,(5012) |
| | | |
| | | |
| | |
| | | 701,PreviousProcessState,U1, |
| | | 800,EFEMPPExecName,A20, |
| | | 801,EQPPExecName,A20, |
| | | 2000,RbRAxisTorque,I2,æºå¨äººRè½´æç© |
| | | 2001,RbLAxisTorque,l2,æºå¨äººLè½´æç© |
| | | 2002,RbZAxisTorque,l2,æºå¨äººZè½´æç© |
| | | 2003,RbTHAxisTorque,l2,æºå¨äººTHè½´æç© |
| | | 2004,RbXAxisTorque,l2,æºå¨äººXè½´æç© |
| | | 2005,AxisX111,l2,X111ç¸æºåç§»æ ½çµæºæç© |
| | | 2006,AxisX112,l2,X112ç¸æºåç§»æ ½çµæºæç© |
| | | 2007,AxisU113,l2,U113产åæè½¬çµæºæç© |
| | | 2008,AxisX114,l2,X114产åå·¦æ´åçµæºæç© |
| | | 2009,AxisY121,l2,Y121产å峿´åçµæºæç© |
| | | 2010,AxisY122,l2,Y122产ååæ´åçµæºæç© |
| | | 2011,AxisY123,l2,Y123产ååéµåçµæºæç© |
| | | 2012,MainAir,U2,æ»è¿æ°ååå¼ |
| | | 2013,MainVacuum,l2,æ»ç空ååå¼ |
| | | 2014,RbMainVacuum,l2,æºå¨äººçç©ºå¼ |
| | | 2015,LPMainVacuum,l2,LPç空å¼#D265 |
| | | 2016,LPMainAir,U2,LPåç©ºå¼ |
| | | 2017,ALVacuum,l2,Alignerçç©ºå¼ |
| | | 2018,FFU1RPM,U2,FFU1转é |
| | | 2019,FFU2RPM,U2,FFU2转é |
| | | 2020,FFU3RPM,U2,FFU3转é |
| | | 2021,FFU4RPM,U2,FFU4转é |
| | | 2022,ESDValue,I2,éçµæ£æµå¼ |
| | | 2023,OCREnable,U2,"OCR使è½ï¼O:å¼å¯ 1ï¼å±è½" |
| | | 2024,CCDEnable,U2,"CCD使è½ï¼O:å¼å¯ 1ï¼å±è½" |
| | | 2025,FFUParameter,U2,FFU设å®å¼ |
| | | 5000,CarrierID,A20,å¡å£ID |
| | | 2000,RbRAxisTorque,I2,æºå¨äººRè½´æç© |
| | | 2001,RbLAxisTorque,l2,æºå¨äººLè½´æç© |
| | | 2002,RbZAxisTorque,l2,æºå¨äººZè½´æç© |
| | | 2003,RbTHAxisTorque,l2,æºå¨äººTHè½´æç© |
| | | 2004,RbXAxisTorque,l2,æºå¨äººXè½´æç© |
| | | 2005,AxisX111,l2,X111ç¸æºåç§»æ ½çµæºæç© |
| | | 2006,AxisX112,l2,X112ç¸æºåç§»æ ½çµæºæç© |
| | | 2007,AxisU113,l2,U113产åæè½¬çµæºæç© |
| | | 2008,AxisX114,l2,X114产åå·¦æ´åçµæºæç© |
| | | 2009,AxisY121,l2,Y121产å峿´åçµæºæç© |
| | | 2010,AxisY122,l2,Y122产ååæ´åçµæºæç© |
| | | 2011,AxisY123,l2,Y123产ååéµåçµæºæç© |
| | | 2012,MainAir,U2,æ»è¿æ°ååå¼ |
| | | 2013,MainVacuum,l2,æ»ç空ååå¼ |
| | | 2014,RbMainVacuum,l2,æºå¨äººçç©ºå¼ |
| | | 2015,LPMainVacuum,l2,LPç空å¼#D265 |
| | | 2016,LPMainAir,U2,LPåç©ºå¼ |
| | | 2017,ALVacuum,l2,Alignerçç©ºå¼ |
| | | 2018,FFU1RPM,U2,FFU1转é |
| | | 2019,FFU2RPM,U2,FFU2转é |
| | | 2020,FFU3RPM,U2,FFU3转é |
| | | 2021,FFU4RPM,U2,FFU4转é |
| | | 2022,ESDValue,I2,éçµæ£æµå¼ |
| | | 2023,OCREnable,U2,"OCR使è½ï¼O:å¼å¯ 1ï¼å±è½" |
| | | 2024,CCDEnable,U2,"CCD使è½ï¼O:å¼å¯ 1ï¼å±è½" |
| | | 2025,FFUParameter,U2,FFU设å®å¼ |
| | | 5000,CarrierID,A20,å¡å£ID |
| | | 5001,CJobSpace,U1,CJ Space |
| | | 5002,PJobSpace,U1,PJ Space |
| | | 5003,PJQueued,L,PJ Queued |
| | | 5004,PJStartID,A20,PJStartID |
| | | 5004,PJStartID,A20,PJStartID |
| | | 5005,PJEndID,A20,PJEndID |
| | | 5006,PanelStartID,A20,PanelStartID |
| | | 5007,PanelEndID,A20,PanelEndID |
| | | 5008,CJStartID,A20,CJStartID |
| | | 5009,CJEndID,A20,CJEndID |
| | | 5010,UnloadReadyPortId,U2,"Port ID" |
| | | 5011,LoadReadyPortId,U2,"Port ID" |
| | | 5012,BlockedPortId,U2,"Port ID" |