mrDarker
2025-06-19 4e5df2e71445ca3c0cc412e24510234e671b6072
Merge branch 'clh' into liuyang
已修改14个文件
546 ■■■■■ 文件已修改
SourceCode/Bond/Servo/CEFEM.cpp 126 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.cpp 249 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.h 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CGlass.cpp 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CGlass.h 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CJobDataS.cpp 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CJobDataS.h 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CLoadPort.cpp 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CLoadPort.h 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.cpp 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageGraph2.cpp 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CReadStep.cpp 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CReadStep.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Common.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEFEM.cpp
@@ -531,11 +531,59 @@
            }
        }
        // 使用CEqReadStep替换CEqJobEventStep
        {
            // Received Job Report Upstream#1~9
            char szBuffer[256];
            for (int i = 0; i < 9; i++) {
            for (int i = 0; i < 8; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x4c90 + 320 * i, 320 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                            if (port > 0) {
                                decodeReceivedJobReport((CStep*)pFrom, port, pszData, size);
                            }
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_RECEIVED_JOB_UPSn, i + 1);
                pStep->setName(szBuffer);
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0x0 + i);
                if (addStep(STEP_ID_RECIVE_JOB_UPS1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            // Sent Out Job Report Downstream #1~9
            char szBuffer[256];
            for (int i = 0; i < 8; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x4000 + 320 * i, 320 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                            if (port > 0) {
                                decodeSentOutJobReport((CStep*)pFrom, port, pszData, size);
                            }
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_SENT_OUT_JOB_DOWNSn, i + 1);
                pStep->setName(szBuffer);
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0x00a + i);
                if (addStep(STEP_ID_SENT_OUT_JOB_DOWNS1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            // Fetched Out Job Report #1~15
            char szBuffer[256];
            for (int i = 0; i < 8; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x5c31 + 18 * i, 18 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
@@ -545,15 +593,40 @@
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_RECEIVED_JOBn, i + 1);
                sprintf_s(szBuffer, "%s%d", STEP_EQ_FETCHED_OUT_JOBn, i + 1);
                pStep->setName(szBuffer);
                pStep->setProp("Upstream", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0x0 + i);
                if (addStep(STEP_ID_RECIVE_JOB_UPS1 + i, pStep) != 0) {
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0x023 + i);
                if (addStep(STEP_ID_FETCHED_OUT_JOB_REPORT1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            // Stored Job Report #1~15
            char szBuffer[256];
            for (int i = 0; i < 8; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x5b23 + 18 * i, 18 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                            if (port > 0) {
                                decodeStoredJobReport((CStep*)pFrom, port, pszData, size);
                            }
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_STORED_JOBn, i + 1);
                pStep->setName(szBuffer);
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0x014 + i);
                if (addStep(STEP_ID_STORE_JOB_REPORT1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            // Dispatching Mode Change Command
@@ -611,7 +684,7 @@
            CEqReadStep* pStep = new CEqReadStep(0x6301, 108 * 2,
                [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                    if (code == ROK && pszData != nullptr && size > 0) {
                        decodeFacDataReport((CStep*)pFrom, pszData, size);
                        decodePanelDataRequest((CStep*)pFrom, pszData, size);
                    }
                    return -1;
                });
@@ -624,17 +697,18 @@
        }
        {
            // Panel Data Request xxx
            CEqReadStep* pStep = new CEqReadStep(0x6301, 108 * 2,
            // Panel Data Request
            CEqReadStep* pStep = new CEqReadStep(0x617d, 2 * 2,
                [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                    if (code == ROK && pszData != nullptr && size > 0) {
                        decodeFacDataReport((CStep*)pFrom, pszData, size);
                        decodePanelDataRequest((CStep*)pFrom, pszData, size);
                    }
                    return -1;
                });
            pStep->setName(STEP_EQ_FAC_DATA_REPORT);
            pStep->setName(STEP_EFEM_PANEL_DATA_REQUEST);
            pStep->setProp("Port", (void*)1);
            pStep->setWriteSignalDev(0x04d);
            pStep->setWriteSignalDev(0x15d);
            pStep->setReturnDev(0x73a);
            if (addStep(STEP_ID_PANEL_DATA_REQUEST, pStep) != 0) {
                delete pStep;
            }
@@ -712,28 +786,26 @@
    int CEFEM::onReceivedJob(int port, CJobDataS* pJobDataS)
    {
        m_pPort[0]->onReceivedJob(port, pJobDataS);
        m_pPort[1]->onReceivedJob(port, pJobDataS);
        m_pPort[2]->onReceivedJob(port, pJobDataS);
        m_pPort[3]->onReceivedJob(port, pJobDataS);
        m_pArmTray[0]->onReceivedJob(port, pJobDataS);
        m_pArmTray[1]->onReceivedJob(port, pJobDataS);
        m_pAligner->onReceivedJob(port, pJobDataS);
        m_pFliper->onReceivedJob(port, pJobDataS);
        // 转发到子单元设备
        CEquipment* pEqs[] = { m_pPort[0], m_pPort[1], m_pPort[2], m_pPort[3], m_pArmTray[0], m_pArmTray[1],
            m_pAligner, m_pFliper };
        if (1 <= port && port <= 8) {
            pEqs[port - 1]->onReceivedJob(port, pJobDataS);
        }
        return 0;
    }
    int CEFEM::onSentOutJob(int port, CJobDataS* pJobDataS)
    {
        m_pPort[0]->onSentOutJob(port, pJobDataS);
        m_pPort[1]->onSentOutJob(port, pJobDataS);
        m_pPort[2]->onSentOutJob(port, pJobDataS);
        m_pPort[3]->onSentOutJob(port, pJobDataS);
        m_pArmTray[0]->onSentOutJob(port, pJobDataS);
        m_pArmTray[1]->onSentOutJob(port, pJobDataS);
        m_pAligner->onSentOutJob(port, pJobDataS);
        m_pFliper->onSentOutJob(port, pJobDataS);
        // 转发到子单元设备
        CEquipment* pEqs[] = { m_pPort[0], m_pPort[1], m_pPort[2], m_pPort[3], m_pArmTray[0], m_pArmTray[1],
            m_pAligner, m_pFliper };
        if (1 <= port && port <= 8) {
            pEqs[port - 1]->onSentOutJob(port, pJobDataS);
        }
        return 0;
    }
SourceCode/Bond/Servo/CEquipment.cpp
@@ -793,7 +793,7 @@
        CGlass* pContext = nullptr;
        for (int i = 0; i < SLOT_MAX; i++) {
            CGlass* pGlass = (CGlass*)m_slot[i].getContext();
            if (pGlass != nullptr && compareJobDataB(pJobDataB, pGlass->getJobDataB())) {
            if (pGlass != nullptr && compareJobData(pJobDataB, pGlass->getJobDataS())) {
                pContext = pGlass;
                if (pGlass != nullptr) pGlass->addRef();
                m_slot[i].setContext(nullptr);
@@ -873,6 +873,61 @@
                return pGlass;
            }
        }
        return nullptr;
    }
    CGlass* CEquipment::getGlassFromSlot(int slotNo)
    {
        CSlot* pSlot = nullptr;
        for (int i = 0; i < SLOT_MAX; i++) {
            if (!m_slot[i].isEnable()) continue;
            if (m_slot[i].getNo() != slotNo) continue;
            pSlot = &m_slot[i];
            break;
        }
        if (pSlot != nullptr) {
            return (CGlass*)pSlot->getContext();
        }
        return nullptr;
    }
    CGlass* CEquipment::getGlassWithCassette(int cassetteSequenceNo, int jobSequenceNo)
    {
        CSlot* pSlot = nullptr;
        for (int i = 0; i < SLOT_MAX; i++) {
            if (!m_slot[i].isEnable()) continue;
            CGlass* pGlass = (CGlass*)m_slot[i].getContext();
            if (pGlass == nullptr) continue;
            CJobDataS* pJobDataS = pGlass->getJobDataS();
            ASSERT(pJobDataS);
            if (pJobDataS->getCassetteSequenceNo() == cassetteSequenceNo
                && pJobDataS->getJobSequenceNo() == jobSequenceNo) {
                return pGlass;
            }
        }
        return nullptr;
    }
    CJobDataS* CEquipment::getJobDataSWithCassette(int cassetteSequenceNo, int jobSequenceNo)
    {
        CSlot* pSlot = nullptr;
        for (int i = 0; i < SLOT_MAX; i++) {
            if (!m_slot[i].isEnable()) continue;
            CGlass* pGlass = (CGlass*)m_slot[i].getContext();
            if (pGlass == nullptr) continue;
            CJobDataS* pJobDataS = pGlass->getJobDataS();
            ASSERT(pJobDataS);
            if (pJobDataS->getCassetteSequenceNo() == cassetteSequenceNo
                && pJobDataS->getJobSequenceNo() == jobSequenceNo) {
                return pJobDataS;
            }
        }
        return nullptr;
    }
@@ -1222,23 +1277,6 @@
        return &m_slot[index];
    }
    CGlass* CEquipment::getGlassFromSlot(int slotNo)
    {
        CSlot* pSlot = nullptr;
        for (int i = 0; i < SLOT_MAX; i++) {
            if (!m_slot[i].isEnable()) continue;
            if (m_slot[i].getNo() != slotNo) continue;
            pSlot = &m_slot[i];
            break;
        }
        if (pSlot != nullptr) {
            return (CGlass*)pSlot->getContext();
        }
        return nullptr;
    }
    CGlass* CEquipment::getAnyGlass()
    {
        CSlot* pSlot = nullptr;
@@ -1325,8 +1363,6 @@
    int CEquipment::onReceivedJob(int port, CJobDataS* pJobDataS)
    {
        LOGI("<CEquipment-%s>onReceivedJob.", m_strName.c_str());
        addJobDataS(pJobDataS);
        return 0;
    }
@@ -1343,7 +1379,7 @@
        pStep->addAttributeVector(attrubutes);
        onReceivedJob(port, &jobDataS);
        onSentOutJob(port, &jobDataS);
        return nRet;
    }
@@ -1352,13 +1388,16 @@
    {
        LOGI("<CEquipment-%s>onSentOutJob.", m_strName.c_str());
        int count = removeJobDataS(pJobDataS->getCassetteSequenceNo(), pJobDataS->getJobSequenceNo());
        if (count == 1) {
            LOGI("<CEquipment-%s>onSentOutJob,删除数据 %d 条", m_strName.c_str(), count);
        // 可以在此更新JobDataS数据了
        CGlass* pGlass = getGlass(pJobDataS->getGlass1Id().c_str());
        if (pGlass == nullptr) {
            LOGE("<CEquipment-%s>onSentOutJob,没有找到对应的Glass(CassetteSequenceNo:%d, JobSequenceNo:%d, ID=%s),请检查数据,注意风险。",
                m_strName.c_str(), pJobDataS->getCassetteSequenceNo(), pJobDataS->getJobSequenceNo(),
                pJobDataS->getGlass1Id().c_str());
            return -1;
        }
        else {
            LOGE("<CEquipment-%s>onSentOutJob,删除数据 %d 条,注意排查风险", m_strName.c_str(), count);
        }
        pGlass->updateJobDataS(pJobDataS);
        return 0;
    }
@@ -1546,15 +1585,64 @@
        return 0;
    }
    int CEquipment::decodePanelDataRequest(CStep* pStep, const char* pszData, size_t size)
    {
        int index = 0;
        short cassetteSequenceNo, jobSequenceNo;
        memcpy(&cassetteSequenceNo, &pszData[index], sizeof(short));
        index += sizeof(short);
        memcpy(&jobSequenceNo, &pszData[index], sizeof(short));
        index += sizeof(short);
        // efme, 获取数据后返回
        // Cassette Sequence No        1W
        // Job Sequence No            1W
        // Job DataS                256W
        char szBuffer[1024];
        index = 0;
        memcpy(&szBuffer[index], &cassetteSequenceNo, sizeof(short));
        index += sizeof(short);
        memcpy(&szBuffer[index], &jobSequenceNo, sizeof(short));
        index += sizeof(short);
        CJobDataS* pJobDataS = getJobDataSWithCassette(cassetteSequenceNo, jobSequenceNo);
        if (pJobDataS != nullptr) {
            index += pJobDataS->serialize(&szBuffer[index], 1024 - sizeof(short) - sizeof(short));
            ((CEqReadStep*)pStep)->setReturnData(szBuffer, index);
        }
        // 缓存Attribute,用于调试时显示信息
        unsigned int weight = 201;
        pStep->addAttribute(new CAttribute("CassetteSequenceNo",
            (std::to_string(cassetteSequenceNo)).c_str(), "", weight++));
        pStep->addAttribute(new CAttribute("JobSequenceNo",
            (std::to_string(jobSequenceNo)).c_str(), "", weight++));
        return 0;
    }
    int CEquipment::onPreStoredJob(int port, CJobDataB* pJobDataB, short& putSlot)
    {
        LOGI("<CEquipment-%s>onPreStoredJob:port:%d|GlassId:%s",
            m_strName.c_str(), port, pJobDataB->getGlassId().c_str());
        CJobDataS* pJobDataS = getJobDataS(pJobDataB->getCassetteSequenceNo(), pJobDataB->getJobSequenceNo());
        if (pJobDataS == nullptr) {
            LOGE("<CFliper-%s>onPreFetchedOutJob,找不到对应的JobDataS(CassetteSequenceNo:%d, JobSequenceNo:%d), 注意排查风险!", m_strName.c_str(),
        // 当前要存片,之前肯定有拔片,因此片子在Arm那里
        CGlass* pGlass = ((CArm*)m_pArm)->getGlassFromSlot(1);
        if (pGlass == nullptr) {
            LOGE("<CFliper-%s>onPreStoredJob,缓存中没有找到对应的Glass(CassetteSequenceNo:%d, JobSequenceNo:%d),请检查数据,注意风险。", m_strName.c_str(),
                pJobDataB->getCassetteSequenceNo(), pJobDataB->getJobSequenceNo());
            return FALSE;
        }
        CJobDataS* pJobDataS = pGlass->getJobDataS();
        ASSERT(pJobDataS);
        if (!compareJobData(pJobDataB, pJobDataS)) {
            LOGE("<CFliper-%s>onPreFetchedOutJob,JobData数据不匹配(JobDataB(%d, %d),JobDataS(%d, %d)), 注意排查风险!", m_strName.c_str(),
                pJobDataB->getCassetteSequenceNo(), pJobDataB->getJobSequenceNo(),
                pJobDataS->getCassetteSequenceNo(), pJobDataS->getJobSequenceNo());
            return FALSE;
        }
@@ -1590,7 +1678,6 @@
        short putSlot = 0;
        BOOL bCheck = onPreStoredJob(port, pJobDataB, putSlot);
        if (bCheck) {
            addJobDataB(pJobDataB);
            return storedJob(pJobDataB, putSlot);
        }
@@ -1632,104 +1719,14 @@
        return 0;
    }
    int CEquipment::addJobDataB(CJobDataB* pJobDataB)
    BOOL CEquipment::compareJobData(CJobDataB* pJobDataB, CJobDataS* pJobDataS)
    {
        // 添加之前先删除旧的,以免数据重复
        Lock();
        int count = removeJobDataB(pJobDataB->getCassetteSequenceNo(), pJobDataB->getJobSequenceNo());
        if (count > 0) {
            LOGE("<CEquipment-%s>addJobDataB,删除重复数据 %d 条,注意排查风险", m_strName.c_str(), count);
        }
        ASSERT(pJobDataB);
        ASSERT(pJobDataS);
        m_listJobDataB.push_back(std::move(*pJobDataB));
        Unlock();
        return (int)m_listJobDataB.size();
    }
    int CEquipment::removeJobDataB(int nCassetteSequenceNo, int nJobSequenceNo)
    {
        int count = 0;
        for (auto it = m_listJobDataB.begin(); it != m_listJobDataB.end(); ) {
            if ((*it).getCassetteSequenceNo() == nCassetteSequenceNo
                && (*it).getJobSequenceNo() == nJobSequenceNo) {
                it = m_listJobDataB.erase(it);
                count++;
            }
            else {
                ++it;
            }
        }
        return count;
    }
    CJobDataB* CEquipment::getJobDataB(int nCassetteSequenceNo, int nJobSequenceNo)
    {
        for (auto& item : m_listJobDataB) {
            if (item.getCassetteSequenceNo() == nCassetteSequenceNo
                && item.getJobSequenceNo() == nJobSequenceNo) {
                return &item;
            }
        }
        return nullptr;
    }
    int CEquipment::addJobDataS(CJobDataS* pJobDataS)
    {
        // 添加之前先删除旧的,以免数据重复
        Lock();
        int count = removeJobDataS(pJobDataS->getCassetteSequenceNo(), pJobDataS->getJobSequenceNo());
        if (count > 0) {
            LOGE("<CEquipment-%s>addJobDataS,删除重复数据 %d 条,注意排查风险", m_strName.c_str(), count);
        }
        m_listJobDataS.push_back(std::move(*pJobDataS));
        Unlock();
        return (int)m_listJobDataB.size();
    }
    int CEquipment::removeJobDataS(int nCassetteSequenceNo, int nJobSequenceNo)
    {
        int count = 0;
        Lock();
        for (auto it = m_listJobDataS.begin(); it != m_listJobDataS.end(); ) {
            if ((*it).getCassetteSequenceNo() == nCassetteSequenceNo
                && (*it).getJobSequenceNo() == nJobSequenceNo) {
                it = m_listJobDataS.erase(it);
                count++;
            }
            else {
                ++it;
            }
        }
        Unlock();
        return count;
    }
    CJobDataS* CEquipment::getJobDataS(int nCassetteSequenceNo, int nJobSequenceNo)
    {
        for (auto& item : m_listJobDataS) {
            if (item.getCassetteSequenceNo() == nCassetteSequenceNo
                && item.getJobSequenceNo() == nJobSequenceNo) {
                return &item;
            }
        }
        return nullptr;
    }
    BOOL CEquipment::compareJobDataB(CJobDataB* pJobDataB1, CJobDataB* pJobDataB2)
    {
        ASSERT(pJobDataB1);
        ASSERT(pJobDataB2);
        if (pJobDataB1->getCassetteSequenceNo() != pJobDataB2->getCassetteSequenceNo())
        if (pJobDataB->getCassetteSequenceNo() != pJobDataS->getCassetteSequenceNo())
            return FALSE;
        if (pJobDataB1->getJobSequenceNo() != pJobDataB2->getJobSequenceNo())
        if (pJobDataB->getJobSequenceNo() != pJobDataS->getJobSequenceNo())
            return FALSE;
        return TRUE;
SourceCode/Bond/Servo/CEquipment.h
@@ -176,16 +176,16 @@
        // 获取玻璃物料
        CGlass* getGlassFromSlot(int slotNo);
        CGlass* getGlassWithCassette(int cassetteSequenceNo, int jobSequenceNo);
        CGlass* getAnyGlass();
        CGlass* getGlass(const char* pszGlassId);
        CJobDataS* getJobDataSWithCassette(int cassetteSequenceNo, int jobSequenceNo);
        // 验证玻璃和槽是否匹配
        BOOL ValidateGlassSlotMatch();
        // 是否有玻璃
        BOOL hasGlass();
        // 获取指定ID的glass
        CGlass * getGlass(const char* pszGlassId);
        // 指定槽位是否可以放置玻璃
        BOOL canPlaceGlassInSlot(const short slotIndex);
@@ -223,13 +223,8 @@
        int decodeVCREventReport(CStep* pStep, const char* pszData, size_t size);
        int decodePanelDataReport(CStep* pStep, const char* pszData, size_t size);
        int decodeFacDataReport(CStep* pStep, const char* pszData, size_t size);
        int addJobDataB(CJobDataB* pJobDataB);
        int removeJobDataB(int nCassetteSequenceNo, int nJobSequenceNo);
        CJobDataB* getJobDataB(int nCassetteSequenceNo, int nJobSequenceNo);
        int addJobDataS(CJobDataS* pJobDataS);
        int removeJobDataS(int nCassetteSequenceNo, int nJobSequenceNo);
        CJobDataS* getJobDataS(int nCassetteSequenceNo, int nJobSequenceNo);
        BOOL compareJobDataB(CJobDataB* pJobDataB1, CJobDataB* pJobDataB2);
        int decodePanelDataRequest(CStep* pStep, const char* pszData, size_t size);
        BOOL compareJobData(CJobDataB* pJobDataB, CJobDataS* pJobDataS);
        void setProcessState(PROCESS_STATE state);
    protected:
@@ -266,8 +261,6 @@
    private:
        CEquipment* m_pArm;
        std::list<CJobDataS> m_listJobDataS;
        std::list<CJobDataB> m_listJobDataB;
    };
}
SourceCode/Bond/Servo/CGlass.cpp
@@ -108,8 +108,6 @@
                m_pPath->serialize(ar);
            }
            char temp[JOBDATAS_SIZE] = { 0 };
            m_jobDataB.serialize(temp, JOBDATAB_SIZE);
            ar.Write(temp, JOBDATAB_SIZE);
            m_jobDataS.serialize(temp, JOBDATAS_SIZE);
            ar.Write(temp, JOBDATAS_SIZE);
            ar << (ULONGLONG)m_pBuddy;
@@ -131,8 +129,6 @@
                m_pPath->serialize(ar);
            }
            char temp[JOBDATAS_SIZE];
            ar.Read(temp, JOBDATAB_SIZE);
            m_jobDataB.unserialize(temp, JOBDATAB_SIZE);
            ar.Read(temp, JOBDATAS_SIZE);
            m_jobDataS.unserialize(temp, JOBDATAS_SIZE);
            ar >> ullPath;    m_pBuddy = (CGlass*)ullPath;
@@ -141,21 +137,16 @@
        }
    }
    void CGlass::setJobDataB(CJobDataB* pJobDataB)
    {
        m_jobDataB.copy(pJobDataB);
    }
    CJobDataB* CGlass::getJobDataB()
    {
        return &m_jobDataB;
    }
    void CGlass::setJobDataS(CJobDataS* pJobDataS)
    {
        m_jobDataS.copy(pJobDataS);
    }
    void CGlass::updateJobDataS(CJobDataS* pJobDataS)
    {
        m_jobDataS.update(pJobDataS);
    }
    CJobDataS* CGlass::getJobDataS()
    {
        return &m_jobDataS;
SourceCode/Bond/Servo/CGlass.h
@@ -28,9 +28,8 @@
        CPath* getPath();
        void addPath(unsigned int nEqId, unsigned int nUnit);
        void serialize(CArchive& ar);
        void setJobDataB(CJobDataB* pJobDataB);
        CJobDataB* getJobDataB();
        void setJobDataS(CJobDataS* pJobDataS);
        void updateJobDataS(CJobDataS* pJobDataS);
        CJobDataS* getJobDataS();
        BOOL setBuddy(CGlass* pGlass);
        BOOL forceSetBuddy(CGlass* pGlass);
@@ -43,7 +42,6 @@
        MaterialsType m_type;
        std::string m_strID;
        CPath* m_pPath;
        CJobDataB m_jobDataB;
        CJobDataS m_jobDataS;
        CGlass* m_pBuddy;
        std::string m_strBuddyId;
SourceCode/Bond/Servo/CJobDataS.cpp
@@ -88,6 +88,51 @@
        m_pOwner = pScr->m_pOwner;
    }
    void CJobDataS::update(CJobDataS* pScr)
    {
        // m_nCassetteSequenceNo = pScr->m_nCassetteSequenceNo;
        // m_nJobSequenceNo = pScr->m_nJobSequenceNo;
        m_strLotId = pScr->m_strLotId;
        m_strProductId = pScr->m_strProductId;
        m_strOperationId = pScr->m_strOperationId;
        // m_strGlass1Id = pScr->m_strGlass1Id;
        m_strGlass2Id = pScr->m_strGlass2Id;
        m_nJobType = pScr->m_nJobType;
        m_nMaterialsType = pScr->m_nMaterialsType;
        m_nProductType = pScr->m_nProductType;
        m_nDummyType = pScr->m_nDummyType;
        m_nSkipFlag = pScr->m_nSkipFlag;
        m_nProcessFlag = pScr->m_nProcessFlag;
        m_nProcessResonCode = pScr->m_nProcessResonCode;
        m_nLastGlassFlag = pScr->m_nLastGlassFlag;
        m_nFirstGlassFlag = pScr->m_nFirstGlassFlag;
        m_nQTime[0] = pScr->m_nQTime[0];
        m_nQTime[1] = pScr->m_nQTime[1];
        m_nQTime[2] = pScr->m_nQTime[2];
        m_nQTimeOverFlag = pScr->m_nQTimeOverFlag;
        m_nMasterRecipe = pScr->m_nMasterRecipe;
        m_strProductRecipeId = pScr->m_strProductRecipeId;
        m_strPCode = pScr->m_strPCode;
        m_strUseType = pScr->m_strUseType;
        m_strPanelMeasure = pScr->m_strPanelMeasure;
        m_nMode = pScr->m_nMode;
        m_nSlotUnitSelectFlag = pScr->m_nSlotUnitSelectFlag;
        m_nSourcePortNo = pScr->m_nSourcePortNo;
        m_nSourceSlotNo = pScr->m_nSourceSlotNo;
        m_nTargetPortNo = pScr->m_nTargetPortNo;
        m_nTargetSlotNo = pScr->m_nTargetSlotNo;
        m_pOwner = pScr->m_pOwner;
    }
    CJobDataB& CJobDataS::getJobDataB(CJobDataB& jobDataB)
    {
        jobDataB.setCassetteSequenceNo(this->getCassetteSequenceNo());
        jobDataB.setJobSequenceNo(this->getJobSequenceNo());
        jobDataB.setGlassId(this->getGlass1Id().c_str());
        return jobDataB;
    }
    void* CJobDataS::getOwner()
    {
        return m_pOwner;
SourceCode/Bond/Servo/CJobDataS.h
@@ -1,5 +1,6 @@
#pragma once
#include "CAttributeVector.h"
#include "CJobDataB.h"
#define JOBDATAS_SIZE        (256 * 2)
@@ -15,6 +16,8 @@
        void* getOwner();
        void setOwner(void* pOwner);
        void copy(CJobDataS* pScr);
        void update(CJobDataS* pScr);
        CJobDataB& getJobDataB(CJobDataB& jobDataB);
        int getCassetteSequenceNo();
        void setCassetteSequenceNo(int no);
        int getJobSequenceNo();
SourceCode/Bond/Servo/CLoadPort.cpp
@@ -22,6 +22,7 @@
        m_transferMode = TransferMode::AGVMode;
        m_bEnable = FALSE;
        m_bAutoChangeEnable = FALSE;
        m_nNextCassetteSequenceNo = 0;
    }
    CLoadPort::~CLoadPort()
@@ -485,6 +486,16 @@
        Unlock();
        return pStep;
    }
    short CLoadPort::getNextCassetteSequenceNo()
    {
        m_nNextCassetteSequenceNo++;
        if (m_nNextCassetteSequenceNo >= 1000) {
            m_nNextCassetteSequenceNo = 0;
        }
        return (m_nIndex + 1) * 1000 + m_nNextCassetteSequenceNo;
    }
    void CLoadPort::setIndex(unsigned int index)
@@ -1138,13 +1149,8 @@
    /*
     * 生成测试用的玻璃列表
     */
    int CLoadPort::testGenerateGlassList(MaterialsType type, const char* pszPrefix, int startSuffix)
    int CLoadPort::testGenerateGlassList(MaterialsType type)
    {
        static unsigned short nJobSequenceNo = 0;
        static unsigned short nCassetteSequenceNo = 0;
        nCassetteSequenceNo++;
        // 如果非空就不生成了
        Lock();
        if (hasGlass()) {
@@ -1155,32 +1161,21 @@
        char szBuffer[64];
        int suffix = startSuffix;
        for (int i = 0; i < 1; i++) {
            if (!m_slot[i].isEnable()) continue;
            CJobDataB jb;
            CJobDataS js;
            sprintf_s(szBuffer, "%s%d", pszPrefix, suffix++);
            jb.setGlassId(szBuffer);
            jb.setCassetteSequenceNo(nCassetteSequenceNo);
            jb.setJobSequenceNo(++nJobSequenceNo);
            js.setMaterialsType((int)type);
            js.setCassetteSequenceNo(nCassetteSequenceNo);
            js.setJobSequenceNo(nJobSequenceNo);
            if (type == MaterialsType::G1) {
            js.setCassetteSequenceNo(getNextCassetteSequenceNo());
            js.setJobSequenceNo(m_slot[i].getNo());
            sprintf_s(szBuffer, 64, "%05d%05d", js.getCassetteSequenceNo(), js.getJobSequenceNo());
                js.setGlass1Id(szBuffer);
            }
            else if (type == MaterialsType::G2) {
                js.setGlass2Id(szBuffer);
            }
            js.setJobType(1);
            js.setMaterialsType((int)type);
            CGlass* pGlass = theApp.m_model.m_glassPool.allocaGlass();
            pGlass->addPath(m_nID, 0);
            pGlass->processEnd(m_nID, 0);
            pGlass->setID(szBuffer);
            pGlass->setJobDataB(&jb);
            pGlass->setType(type);
            pGlass->setJobDataS(&js);
            m_slot[i].setContext(pGlass);
SourceCode/Bond/Servo/CLoadPort.h
@@ -39,6 +39,7 @@
        void localAutoChangeEnable(BOOL bEnable);
    public:
        short getNextCassetteSequenceNo();
        void setIndex(unsigned int index);
        unsigned int getIndex();
        BOOL isEnable();
@@ -54,7 +55,7 @@
        int getQTimeFlag();
        int getCassetteMappingState();
        int getCassetteStatus();
        int testGenerateGlassList(MaterialsType type, const char* pszPrefix, int startSuffix);
        int testGenerateGlassList(MaterialsType type);
    public:
        static std::string& getPortTypeDescription(PortType portType, std::string& strDescription);
@@ -89,6 +90,7 @@
        BOOL m_bEnable;
        BOOL m_bAutoChangeEnable;
        CPortStatusReport m_portStatusReport;
        int m_nNextCassetteSequenceNo;
    };
}
SourceCode/Bond/Servo/CMaster.cpp
@@ -829,10 +829,10 @@
                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, 已校验数据一致性.");
                        }
SourceCode/Bond/Servo/CPageGraph2.cpp
@@ -213,14 +213,12 @@
            BOOL bTestGenerate = FALSE;
            SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData;
            if (pEquipment->getID() == EQ_ID_LOADPORT4 && !pEquipment->hasGlass()) {
                ((SERVO::CLoadPort*)pEquipment)->testGenerateGlassList(SERVO::MaterialsType::G1,
                    "P20250320G1X", 1);
                ((SERVO::CLoadPort*)pEquipment)->testGenerateGlassList(SERVO::MaterialsType::G1);
                bTestGenerate = TRUE;
            }
            /*
            else if (pEquipment->getID() == EQ_ID_LOADPORT2 && !pEquipment->hasGlass()) {
                ((SERVO::CLoadPort*)pEquipment)->testGenerateGlassList(SERVO::MaterialsType::G2,
                    "P20250320G2X", 1);
            else if (pEquipment->getID() == EQ_ID_LOADPORT1 && !pEquipment->hasGlass()) {
                ((SERVO::CLoadPort*)pEquipment)->testGenerateGlassList(SERVO::MaterialsType::G2);
                bTestGenerate = TRUE;
            }
            */
@@ -228,10 +226,10 @@
                SERVO::CRobotTask* pTask = theApp.m_model.getMaster().getActiveRobotTask();
                if (pTask != nullptr) {
                    SERVO::CGlass* pGlass = (SERVO::CGlass*)pTask->getContext();
                    SERVO::CJobDataB* pJobDataB = pGlass->getJobDataB();
                    SERVO::CJobDataS* pJobDataS = pGlass->getJobDataS();
                    if (pJobDataB != nullptr && pJobDataS != nullptr) {
                        pEquipment->onFetchedOutJob(0, pJobDataB);
                    if (pJobDataS != nullptr) {
                        SERVO::CJobDataB jobDataB;
                        pEquipment->onFetchedOutJob(0, &pJobDataS->getJobDataB(jobDataB));
                        pEquipment->onSentOutJob(0, pJobDataS);
                    }
                }
@@ -243,12 +241,12 @@
            if (pArm != nullptr) {
                SERVO::CGlass* pGlass = pArm->getAnyGlass();
                if (pGlass != nullptr) {
                    SERVO::CJobDataB* pJobDataB = pGlass->getJobDataB();
                    SERVO::CJobDataS* pJobDataS = pGlass->getJobDataS();
                    if (pJobDataB != nullptr && pJobDataS != nullptr) {
                    if (pJobDataS != nullptr) {
                        pEquipment->onReceivedJob(0, pJobDataS);
                        Sleep(600);
                        pEquipment->onStoredJob(0, pJobDataB);
                        SERVO::CJobDataB jobDataB;
                        pEquipment->onStoredJob(0, &pJobDataS->getJobDataB(jobDataB));
                    }
                }
            }
SourceCode/Bond/Servo/CReadStep.cpp
@@ -218,4 +218,13 @@
        return 0;
    }
    int CReadStep::setReturnData(const char* pszData, unsigned int size)
    {
        ASSERT(size < 1024);
        memcpy(m_szReturnBuf, pszData, size);
        m_nReturnDataSize = size;
        return 0;
    }
}
SourceCode/Bond/Servo/CReadStep.h
@@ -23,6 +23,7 @@
        inline void nextStep();
        inline void resetStep();
        virtual int setReturnCode(short code);
        virtual int setReturnData(const char* pszData, unsigned int size);
    protected:
        HANDLE m_hWorkThreadHandle;
SourceCode/Bond/Servo/Common.h
@@ -246,7 +246,7 @@
#define STEP_PORT4_CASSETTE_TYPE_CHANGE    _T("Port4CassetteTypeChange")
#define STEP_EQ_PANEL_DATA_REPORT        _T("EQPanelDataReport")
#define STEP_EQ_FAC_DATA_REPORT            _T("EQFacDataReport")
#define STEP_EFEM_PANEL_DATA_REQUEST    _T("EFEMPanelDataRequest")
/* Step ID */
#define STEP_ID_CIMMODE_CHANGED_CMD_REPLY        0x550