已修改26个文件
562 ■■■■ 文件已修改
SourceCode/Bond/Servo/CAligner.cpp 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CAligner.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CArm.cpp 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CArm.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CBonder.cpp 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEFEM.cpp 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.cpp 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.h 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CGlass.cpp 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CGlass.h 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CLoadPort.cpp 96 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CLoadPort.h 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.cpp 103 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.h 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMeasurement.cpp 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageCassetteCtrlCmd.cpp 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageGraph2.cpp 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPath.cpp 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPath.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPortStatusReport.cpp 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPortStatusReport.h 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CVcrEventReport.cpp 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Common.h 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/PageTransferLog.cpp 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ServoCommo.h 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CAligner.cpp
@@ -48,6 +48,34 @@
        m_slot[0].setName("Slot 1");
    }
    void CAligner::initSteps()
    {
        CEquipment::initSteps();
        {
            // Panel Data Report
            CEqReadStep* pStep = new CEqReadStep(0x617f, 386 * 2,
                [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                    if (code == ROK && pszData != nullptr && size > 0) {
                        decodePanelDataReport((CStep*)pFrom, pszData, size);
                    }
                    return -1;
                });
            pStep->setName(STEP_EQ_PANEL_DATA_REPORT);
            pStep->setProp("Port", (void*)1);
            pStep->setWriteSignalDev(0x15e);
            if (addStep(STEP_ID_PANEL_DATA_REPORT, pStep) != 0) {
                delete pStep;
            }
        }
    }
    void CAligner::onReceiveLBData(const char* pszData, size_t size)
    {
        __super::onReceiveLBData(pszData, size);
        CHECK_READ_STEP_SIGNAL(STEP_ID_PANEL_DATA_REPORT, pszData, size);
    }
    void CAligner::onTimer(UINT nTimerid)
    {
        CEquipment::onTimer(nTimerid);
SourceCode/Bond/Servo/CAligner.h
@@ -16,6 +16,8 @@
        virtual void term();
        virtual void initPins();
        virtual void initSlots();
        virtual void initSteps();
        virtual void onReceiveLBData(const char* pszData, size_t size);
        virtual void onTimer(UINT nTimerid);
        virtual void serialize(CArchive& ar);
        virtual void getAttributeVector(CAttributeVector& attrubutes);
SourceCode/Bond/Servo/CArm.cpp
@@ -102,4 +102,33 @@
        return 0;
    }
    int CArm::glassUpdateJobDataS(CJobDataS* pJobDataS)
    {
        ASSERT(pJobDataS);
        Lock();
        CGlass* pGlass = (CGlass*)m_slot[0].getContext();
        if (pGlass == nullptr) {
            Unlock();
            LOGE("<CArm>glassUpdateJobDataS失败,找不到对应的Glass");
            return -1;
        }
        CJobDataS* pSrcJs = pGlass->getJobDataS();
        if (pSrcJs->getCassetteSequenceNo() != pJobDataS->getCassetteSequenceNo()
            || pSrcJs->getJobSequenceNo() != pJobDataS->getJobSequenceNo()) {
            Unlock();
            LOGE("<CArm>glassUpdateJobDataS失败,CassetteNo不匹配([%d,%d] != [%d,%d])",
                pSrcJs->getCassetteSequenceNo(),
                pJobDataS->getCassetteSequenceNo(),
                pSrcJs->getJobSequenceNo(),
                pJobDataS->getJobSequenceNo());
            return -2;
        }
        pGlass->updateJobDataS(pJobDataS);
        Unlock();
        return 0;
    }
}
SourceCode/Bond/Servo/CArm.h
@@ -26,6 +26,10 @@
        // 调用tempFetchOut后,pGlass必须release一次
        int tempFetchOut(OUT CGlass*& pGlass);
        // 更新JobDataS
        // Equipment在onReceivedJob事件时调用
        int glassUpdateJobDataS(CJobDataS* pJobDataS);
    };
}
SourceCode/Bond/Servo/CBonder.cpp
@@ -349,23 +349,6 @@
        }
        {
            // Panel Data Report
            CEqReadStep* pStep = new CEqReadStep(0xA17f, 386 * 2,
                [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                    if (code == ROK && pszData != nullptr && size > 0) {
                        decodePanelDataReport((CStep*)pFrom, pszData, size);
                    }
                    return -1;
                });
            pStep->setName(STEP_EQ_PANEL_DATA_REPORT);
            pStep->setProp("Port", (void*)1);
            pStep->setWriteSignalDev(0x45e);
            if (addStep(STEP_ID_PANEL_DATA_REPORT, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // FAC Data Report
            CEqReadStep* pStep = new CEqReadStep(0xA60E, 108 * 2,
                [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
SourceCode/Bond/Servo/CEFEM.cpp
@@ -473,6 +473,7 @@
            pStep->setName(STEP_EQ_VCR1_EVENT_REPORT);
            pStep->setProp("Port", (void*)1);
            pStep->setWriteSignalDev(0x4a);
            pStep->setReturnDev(0x91e);
            if (addStep(STEP_ID_VCR1_EVENT_REPORT, pStep) != 0) {
                delete pStep;
            }
@@ -676,23 +677,6 @@
        }
        {
            // Panel Data Report
            CEqReadStep* pStep = new CEqReadStep(0x617f, 386 * 2,
                [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                    if (code == ROK && pszData != nullptr && size > 0) {
                        decodePanelDataReport((CStep*)pFrom, pszData, size);
                    }
                    return -1;
                });
            pStep->setName(STEP_EQ_PANEL_DATA_REPORT);
            pStep->setProp("Port", (void*)1);
            pStep->setWriteSignalDev(0x15e);
            if (addStep(STEP_ID_PANEL_DATA_REPORT, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // FAC Data Report
            CEqReadStep* pStep = new CEqReadStep(0x6301, 108 * 2,
                [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
@@ -803,6 +787,8 @@
                m_pPort[i]->onReceiveLBData(pszData, size);
            }
        }
        m_pAligner->onReceiveLBData(pszData, size);
        // 更新信号到LoadPort, Robot, Aligner, Fliper
        m_pPort[0]->setLinkSignalUpstreamBlock(0, &m_bLinkSignalToUpstream[0][0]);
SourceCode/Bond/Servo/CEquipment.cpp
@@ -7,22 +7,6 @@
#include "Servo.h"
#define CHECK_READ_STEP_SIGNAL(addr, data, size) {                            \
    BOOL bFlag = isBitOn(data, size, addr);                                    \
    SERVO::CStep* pStep = getStep(addr);                                    \
    if (pStep != nullptr) {                                                    \
        ((CReadStep*)pStep)->onReadSignal(bFlag ? addr : 0);                \
    }                                                                        \
}
#define CHECK_WRITE_STEP_SIGNAL(addr, data, size) {                            \
    BOOL bFlag = isBitOn(data, size, addr);                                    \
    SERVO::CStep* pStep = getStep(addr);                                    \
    if (pStep != nullptr) {                                                    \
        ((CWriteStep*)pStep)->onRecvSignal(bFlag ? addr : 0);                \
    }                                                                        \
}
namespace SERVO {
    CEquipment::CEquipment() : m_nID(0), m_strName(""), m_strDescription(""), m_station(0, 255)
@@ -601,7 +585,7 @@
        CHECK_WRITE_STEP_SIGNAL(STEP_ID_IN_OP_CMD_REPLY, pszData, size);
        // Panel Data Report
        CHECK_WRITE_STEP_SIGNAL(STEP_ID_PANEL_DATA_REPORT, pszData, size);
        CHECK_READ_STEP_SIGNAL(STEP_ID_PANEL_DATA_REPORT, pszData, size);
        // Panel Data Request
        CHECK_WRITE_STEP_SIGNAL(STEP_ID_PANEL_DATA_REQUEST, pszData, size);    
@@ -612,6 +596,11 @@
        // job process start/end report
        CHECK_READ_STEP_SIGNAL(STEP_ID_JOB_PROCESS_START_REPORT, pszData, size);
        CHECK_READ_STEP_SIGNAL(STEP_ID_JOB_PROCESS_END_REPORT, pszData, size);
        CHECK_WRITE_STEP_SIGNAL(STEP_ID_PROT1_CASSETTE_CTR_CMD_REPLY, pszData, size);
        CHECK_WRITE_STEP_SIGNAL(STEP_ID_PROT2_CASSETTE_CTR_CMD_REPLY, pszData, size);
        CHECK_WRITE_STEP_SIGNAL(STEP_ID_PROT3_CASSETTE_CTR_CMD_REPLY, pszData, size);
        CHECK_WRITE_STEP_SIGNAL(STEP_ID_PROT4_CASSETTE_CTR_CMD_REPLY, pszData, size);
    }
    BOOL CEquipment::isBitOn(const char* pszData, size_t size, int index)
@@ -1308,6 +1297,7 @@
            CGlass* pGlass = (CGlass*)m_slot[i].getContext();
            if (!isSlotProcessed(i)) continue;
            if (pGlass == nullptr) continue;
            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]
@@ -1347,6 +1337,26 @@
                    return &m_slot[i];
                }
            }
        }
        return nullptr;
    }
    CSlot* CEquipment::getInspFailSlot()
    {
        for (int i = 0; i < SLOT_MAX; i++) {
            if (!m_slot[i].isEnable()) continue;
            if (m_slot[i].isLock()) continue;
            CGlass* pGlass = (CGlass*)m_slot[i].getContext();
            if (pGlass == nullptr) continue;
            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;
            return &m_slot[i];
        }
        return nullptr;
@@ -1439,17 +1449,15 @@
    {
        LOGI("<CEquipment-%s>onReceivedJob.", m_strName.c_str());
        // 可以在此更新JobDataS数据了
        CGlass* pGlass = getGlassFromSlot(port);
        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;
        }
        pGlass->updateJobDataS(pJobDataS);
        return 0;
        // 可以在此更新JobDataS数据了
        int nRet = ((CArm*)m_pArm)->glassUpdateJobDataS(pJobDataS);
        if (nRet < 0) {
            LOGE("<CEquipment-%s>onReceivedJob,更新JobDataS失败,glassUpdateJobDataS返回%d",
                m_strName.c_str(), nRet);
        }
        return nRet;
    }
    int CEquipment::decodeSentOutJobReport(CStep* pStep, int port, const char* pszData, size_t size)
@@ -1616,7 +1624,7 @@
        index += sizeof(short);
        CToolUnits::convertString(&pszData[index], 128 * 2, strPanelJudgeData);
        index += 128 * 2;
        CToolUnits::convertString(&pszData[index], 256 * 2, strPanelJudgeData);
        CToolUnits::convertString(&pszData[index], 256 * 2, strPanelGradeData);
        index += 256 * 2;
@@ -1631,6 +1639,15 @@
        pStep->addAttribute(new CAttribute("PanelGradeData",
            strPanelGradeData.c_str(), "", weight++));
        // 更新检测结果
        CGlass* pGlass = getGlassWithCassette(cassetteNo, jobSequenceNo);
        if (pGlass == nullptr) {
            LOGE("<CEquipment-%s>更新Panel Data失败,找不到对应的Glass.cassetteNo=%d, jobSequenceNo=%d",
                getName().c_str(), cassetteNo, jobSequenceNo);
            return -1;
        }
        pGlass->setInspResult(m_nID, 0, judgeStringToInspResult(strPanelJudgeData));
        return 0;
    }
@@ -1971,4 +1988,16 @@
            );
        }
    }
    InspResult CEquipment::judgeStringToInspResult(std::string& strJudge)
    {
        if (strJudge.compare("N") == 0) {
            return InspResult::Fail;
        }
        if (strJudge.compare("G") == 0) {
            return InspResult::Pass;
        }
        return InspResult::NotInspected;
    }
}
SourceCode/Bond/Servo/CEquipment.h
@@ -179,6 +179,7 @@
        // 获取一个指定物料类型(G1,G2,G1&G2)的且已经加工处理的槽位
        CSlot* getProcessedSlot(MaterialsType putSlotType);
        CSlot* getProcessedSlot2(MaterialsType putSlotType, const std::vector<int>& candidates);
        CSlot* getInspFailSlot();
        // 获取玻璃物料
        CGlass* getGlassFromSlot(int slotNo);
@@ -199,6 +200,12 @@
        // 手动移除物料
        int removeGlass(int slotNo);
        // 字符串检测结果转换
        InspResult judgeStringToInspResult(std::string& strJudge);
    // 以下为从CC-Link读取到的Bit标志位检测函数
    public:
        BOOL isAlive();
SourceCode/Bond/Servo/CGlass.cpp
@@ -8,6 +8,8 @@
        m_pPath = nullptr;
        m_type = MaterialsType::G1;
        m_pBuddy = nullptr;
        m_nOriginPort = 0;
        m_nOriginSlot = 0;
    }
    CGlass::~CGlass()
@@ -66,6 +68,18 @@
        return m_strID;
    }
    void CGlass::setOriginPort(int port, int slot)
    {
        m_nOriginPort = port;
        m_nOriginSlot = slot;
    }
    void CGlass::getOrginPort(int& port, int& slot)
    {
        port = m_nOriginPort;
        slot = m_nOriginSlot;
    }
    CPath* CGlass::getPath()
    {
        return m_pPath;
@@ -103,6 +117,8 @@
            Lock();
            ar << (int)m_type;
            WriteString(ar, m_strID);
            ar << m_nOriginPort;
            ar << m_nOriginSlot;
            ar << (ULONGLONG)m_pPath;
            if (m_pPath != nullptr) {
                m_pPath->serialize(ar);
@@ -123,6 +139,8 @@
            ar >> type;
            m_type = (MaterialsType)type;
            ReadString(ar, m_strID);
            ar >> m_nOriginPort;
            ar >> m_nOriginSlot;
            ar >> ullPath;
            if (ullPath != 0) {
                m_pPath = new CPath();
@@ -182,12 +200,13 @@
        return m_strBuddyId;
    }
    void CGlass::processEnd(unsigned int nEqId, unsigned int nUnit)
    int CGlass::processEnd(unsigned int nEqId, unsigned int nUnit)
    {
        CPath* pPath = getPathWithEq(nEqId, nUnit);
        if (pPath != nullptr) {
            pPath->processEnd();
        }
        if (pPath == nullptr) return -1;
        pPath->processEnd();
        return 0;
    }
    BOOL CGlass::isProcessed(unsigned int nEqId, unsigned int nUnit)
@@ -197,4 +216,21 @@
        return pPath->isProcessEnd();
    }
    int CGlass::setInspResult(unsigned int nEqId, unsigned int nUnit, InspResult result)
    {
        CPath* pPath = getPathWithEq(nEqId, nUnit);
        if (pPath == nullptr) return -1;
        pPath->setInspResult(result);
        return 0;
    }
    InspResult CGlass::getInspResult(unsigned int nEqId, unsigned int nUnit)
    {
        CPath* pPath = getPathWithEq(nEqId, nUnit);
        if (pPath == nullptr) return InspResult::NotInspected;
        return pPath->getInspResult();
    }
}
SourceCode/Bond/Servo/CGlass.h
@@ -24,6 +24,8 @@
        void setType(MaterialsType type);
        void setID(const char* pszID);
        std::string& getID();
        void setOriginPort(int port, int slot);
        void getOrginPort(int& port, int& slot);
        CPath* getPathWithEq(unsigned int nEqId, unsigned int nUnit);
        CPath* getPath();
        void addPath(unsigned int nEqId, unsigned int nUnit);
@@ -35,8 +37,10 @@
        BOOL forceSetBuddy(CGlass* pGlass);
        CGlass* getBuddy();
        std::string& getBuddyId();
        void processEnd(unsigned int nEqId, unsigned int nUnit);
        int processEnd(unsigned int nEqId, unsigned int nUnit);
        BOOL isProcessed(unsigned int nEqId, unsigned int nUnit);
        int setInspResult(unsigned int nEqId, unsigned int nUnit, InspResult result);
        InspResult getInspResult(unsigned int nEqId, unsigned int nUnit);
    private:
        MaterialsType m_type;
@@ -45,6 +49,8 @@
        CJobDataS m_jobDataS;
        CGlass* m_pBuddy;
        std::string m_strBuddyId;
        int m_nOriginPort;
        int m_nOriginSlot;
    };
}
SourceCode/Bond/Servo/CLoadPort.cpp
@@ -2,23 +2,8 @@
#include "CLoadPort.h"
#include "CGlassPool.h"
#include "Servo.h"
#include "ServoCommo.h"
#define CHECK_READ_STEP_SIGNAL2(addr, data, size) {                            \
    BOOL bFlag = isBitOn(data, size, addr);                                    \
    SERVO::CStep* pStep = getStep(addr);                                    \
    if (pStep != nullptr) {                                                    \
        ((CReadStep*)pStep)->onReadSignal(bFlag ? addr : 0);                \
    }                                                                        \
}
#define CHECK_WRITE_STEP_SIGNAL2(addr, data, size) {                            \
    BOOL bFlag = isBitOn(data, size, addr);                                    \
    SERVO::CStep* pStep = getStep(addr);                                    \
    if (pStep != nullptr) {                                                    \
        ((CWriteStep*)pStep)->onRecvSignal(bFlag ? addr : 0);                \
    }                                                                        \
}
namespace SERVO {
    CLoadPort::CLoadPort() : CEquipment()
@@ -83,15 +68,15 @@
        {
            // Cassette Ctrl Cmd
            static char* pszName[] = { STEP_EQ_P1_CASSETTE_CTRL_CMD,    STEP_EQ_P2_CASSETTE_CTRL_CMD, STEP_EQ_P3_CASSETTE_CTRL_CMD,    STEP_EQ_P4_CASSETTE_CTRL_CMD };
            static int writeSignalDev[] = { 0x120, 0x121, 0x122, 0x123 };
            static char* pszName[] = { STEP_EQ_P1_CASSETTE_CTRL_CMD, STEP_EQ_P2_CASSETTE_CTRL_CMD, STEP_EQ_P3_CASSETTE_CTRL_CMD, STEP_EQ_P4_CASSETTE_CTRL_CMD };
            static int writeSignalDev[] = { 0x130, 0x131, 0x132, 0x133 };
            static int dev[] = { 0x45, 0x1a5, 0x305, 0x465 };
            static int addr[] = { 0x480, 0x481, 0x482, 0x483 };
            static int addr[] = { STEP_ID_PROT1_CASSETTE_CTR_CMD_REPLY, STEP_ID_PROT2_CASSETTE_CTR_CMD_REPLY, STEP_ID_PROT3_CASSETTE_CTR_CMD_REPLY, STEP_ID_PROT4_CASSETTE_CTR_CMD_REPLY };
            CEqCassetteCtrlCmdStep* pStep = new CEqCassetteCtrlCmdStep();
            CEqWriteStep* pStep = new CEqWriteStep();
            pStep->setName(pszName[m_nIndex]);
            pStep->setWriteSignalDev(writeSignalDev[m_nIndex]);
            pStep->setCtrlCmdDev(dev[m_nIndex]);
            pStep->setDataDev(dev[m_nIndex]);
            if (addStep(addr[m_nIndex], pStep) != 0) {
                delete pStep;
            }
@@ -324,12 +309,12 @@
            };
            static int dev[] = { 0x6050, 0x6070, 0x6090, 0x60b0 };
            static int writeSignalDev[6][4] = {
                {0xc8, 0xc9, 0xca, 0xcb},
                {0xd0, 0xd1, 0xd2, 0xd3},
                {0xd8, 0xd9, 0xda, 0xdb},
                {0xe0, 0xe1, 0xe2, 0xe3},
                {0xe8, 0xe9, 0xea, 0xeb},
                {0xf0, 0xf1, 0xf2, 0xf3},
                {0xf8, 0xf9, 0xfa, 0xfb},
                {0x100, 0x101, 0x102, 0x103}
                {0xf0, 0xf1, 0xf2, 0xf3}
            };
            static int addr[6][4] = {
                { STEP_ID_PORT1_EMPTY, STEP_ID_PORT2_EMPTY, STEP_ID_PORT3_EMPTY, STEP_ID_PORT4_EMPTY },
@@ -345,6 +330,7 @@
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            decodePortStatusReport((CStep*)pFrom, pszData, size);
                            return 0;
                        }
                        return -1;
                    });
@@ -422,17 +408,25 @@
        int jobExistenceSize,
        short slotProcess,
        short jopCount,
        CJobDataA* pJobDataA)
        CJobDataA* pJobDataA,
        ONWRITED onWritedBlock)
    {
        int id = getID();
        if ( !(id == EQ_ID_LOADPORT1 || id == EQ_ID_LOADPORT2) ) {
            return -1;
        SERVO::CEqWriteStep* pStep = (SERVO::CEqWriteStep*)getCassetteCtrlCmdStep();
        ASSERT(pStep);
        char szBuffer[1024] = { 0 };
        memcpy(&szBuffer[0], &cmd, sizeof(short));
        if (jobExistence != nullptr && jobExistenceSize == 12) {
            memcpy(&szBuffer[2], jobExistence, sizeof(short) * jobExistenceSize);
        }
        memcpy(&szBuffer[26], &slotProcess, sizeof(short));
        memcpy(&szBuffer[36], &jopCount, sizeof(short));
        if (pJobDataA != nullptr) {
            pJobDataA->serialize(&szBuffer[38], 1024 - 38);
        }
        SERVO::CEqCassetteCtrlCmdStep* pStep = (SERVO::CEqCassetteCtrlCmdStep*)getCassetteCtrlCmdStep();
        ASSERT(pStep);
        return pStep->sendCtrlCmd(cmd, jobExistence, jobExistenceSize, slotProcess, jopCount, pJobDataA);
        return pStep->writeDataEx(szBuffer, 352 * 2, onWritedBlock);
    }
    CStep* CLoadPort::getCassetteCtrlCmdStep()
@@ -854,12 +848,12 @@
        static int autoType[] = { STEP_ID_PORT1_TYPE_AUTO_CHANGE, STEP_ID_PORT2_TYPE_AUTO_CHANGE,
            STEP_ID_PORT3_TYPE_AUTO_CHANGE, STEP_ID_PORT4_TYPE_AUTO_CHANGE };
        CHECK_READ_STEP_SIGNAL2(type[m_nIndex], pszData, size);
        CHECK_READ_STEP_SIGNAL2(mode[m_nIndex], pszData, size);
        CHECK_READ_STEP_SIGNAL2(cassetteType[m_nIndex], pszData, size);
        CHECK_READ_STEP_SIGNAL2(transferMode[m_nIndex], pszData, size);
        CHECK_READ_STEP_SIGNAL2(enable[m_nIndex], pszData, size);
        CHECK_READ_STEP_SIGNAL2(autoType[m_nIndex], pszData, size);
        CHECK_READ_STEP_SIGNAL(type[m_nIndex], pszData, size);
        CHECK_READ_STEP_SIGNAL(mode[m_nIndex], pszData, size);
        CHECK_READ_STEP_SIGNAL(cassetteType[m_nIndex], pszData, size);
        CHECK_READ_STEP_SIGNAL(transferMode[m_nIndex], pszData, size);
        CHECK_READ_STEP_SIGNAL(enable[m_nIndex], pszData, size);
        CHECK_READ_STEP_SIGNAL(autoType[m_nIndex], pszData, size);
        static int typeReply[] = { STEP_ID_PROT1_TYPE_CHANGE_REPLY, STEP_ID_PROT2_TYPE_CHANGE_REPLY,
@@ -875,12 +869,12 @@
        static int cassetteTypeReply[] = { STEP_ID_PROT1_CASSETTE_TYPE_CHANGE_REPLY, STEP_ID_PROT2_CASSETTE_TYPE_CHANGE_REPLY,
            STEP_ID_PROT3_CASSETTE_TYPE_CHANGE_REPLY, STEP_ID_PROT4_CASSETTE_TYPE_CHANGE_REPLY };
        CHECK_WRITE_STEP_SIGNAL2(typeReply[m_nIndex], pszData, size);
        CHECK_WRITE_STEP_SIGNAL2(modeReply[m_nIndex], pszData, size);
        CHECK_WRITE_STEP_SIGNAL2(transferModeReply[m_nIndex], pszData, size);
        CHECK_WRITE_STEP_SIGNAL2(enableModeReply[m_nIndex], pszData, size);
        CHECK_WRITE_STEP_SIGNAL2(typeAutoReply[m_nIndex], pszData, size);
        CHECK_WRITE_STEP_SIGNAL2(cassetteTypeReply[m_nIndex], pszData, size);
        CHECK_WRITE_STEP_SIGNAL(typeReply[m_nIndex], pszData, size);
        CHECK_WRITE_STEP_SIGNAL(modeReply[m_nIndex], pszData, size);
        CHECK_WRITE_STEP_SIGNAL(transferModeReply[m_nIndex], pszData, size);
        CHECK_WRITE_STEP_SIGNAL(enableModeReply[m_nIndex], pszData, size);
        CHECK_WRITE_STEP_SIGNAL(typeAutoReply[m_nIndex], pszData, size);
        CHECK_WRITE_STEP_SIGNAL(cassetteTypeReply[m_nIndex], pszData, size);
    }
    int CLoadPort::decodePortStatusReport(CStep* pStep, const char* pszData, size_t size)
@@ -890,14 +884,24 @@
        if (nRet < 0) return nRet;
        m_portStatusReport.copyEx(portStatusReport);
        if (m_portStatusReport.getPortStatus() == PORT_INUSE) {
            this->sendCassetteCtrlCmd(5, nullptr, 0, 0, 0, nullptr, nullptr);
        }
        // 缓存Attribute,用于调试时显示信息
        unsigned int weight = 201;
        CAttributeVector& attrubutes = pStep->attributeVector();
        m_portStatusReport.getAttributeVector(attrubutes, weight);
        LOGI("<CCassetteTranserStateStep>decodePortStatusReport<Status:%d, CassetteSequenceNo:%d>",
            m_portStatusReport.getPortStatus(), m_portStatusReport.getCassetteSequenceNo());
        LOGI("<CCassetteTranserStateStep>decodePortStatusReport<Status:%d, CassetteSequenceNo:%d, CassetteId:%s>",
            m_portStatusReport.getPortStatus(), m_portStatusReport.getCassetteSequenceNo(),
            m_portStatusReport.getCassetteId().c_str());
        if (m_portStatusReport.getPortStatus() == 3) {
            LOGI("<CCassetteTranserStateStep>InUse<JobExistenceSlot:%d>",
                m_portStatusReport.getJobExistenceSlot());
        }
        return nRet;
@@ -1135,6 +1139,7 @@
            js.setMaterialsType((int)type);
            CGlass* pGlass = theApp.m_model.m_glassPool.allocaGlass();
            pGlass->setOriginPort(m_nIndex, i);
            pGlass->addPath(m_nID, 0);
            pGlass->processEnd(m_nID, 0);
            pGlass->setID(szBuffer);
@@ -1173,6 +1178,7 @@
            js.setGlass1Id(szBuffer);
            CGlass* pGlass = theApp.m_model.m_glassPool.allocaGlass();
            pGlass->setOriginPort(m_nIndex, nSlotIndex);
            pGlass->addPath(m_nID, 0);
            pGlass->processEnd(m_nID, 0);
            pGlass->setID(szBuffer);
SourceCode/Bond/Servo/CLoadPort.h
@@ -76,7 +76,8 @@
            int jobExistenceSize,
            short slotProcess,
            short jopCount,
            CJobDataA* pJobDataA);
            CJobDataA* pJobDataA,
            ONWRITED onWritedBlock);
        CStep* getCassetteCtrlCmdStep();
    private:
SourceCode/Bond/Servo/CMaster.cpp
@@ -297,11 +297,12 @@
        // 各种机器
        CLoadPort* pLoadPorts[4];
        CEFEM* pEFEM = (CEFEM*)getEquipment(EQ_ID_EFEM);
        CLoadPort* pLoadPort1 = (CLoadPort*)getEquipment(EQ_ID_LOADPORT1);
        CLoadPort* pLoadPort2 = (CLoadPort*)getEquipment(EQ_ID_LOADPORT2);
        CLoadPort* pLoadPort3 = (CLoadPort*)getEquipment(EQ_ID_LOADPORT3);
        CLoadPort* pLoadPort4 = (CLoadPort*)getEquipment(EQ_ID_LOADPORT4);
        pLoadPorts[0] = (CLoadPort*)getEquipment(EQ_ID_LOADPORT1);
        pLoadPorts[1] = (CLoadPort*)getEquipment(EQ_ID_LOADPORT2);
        pLoadPorts[2] = (CLoadPort*)getEquipment(EQ_ID_LOADPORT3);
        pLoadPorts[3] = (CLoadPort*)getEquipment(EQ_ID_LOADPORT4);
        CFliper* pFliper = (CFliper*)getEquipment(EQ_ID_FLIPER);
        CVacuumBake* pVacuumBake = (CVacuumBake*)getEquipment(EQ_ID_VACUUMBAKE);
        CAligner* pAligner = (CAligner*)getEquipment(EQ_ID_ALIGNER);
@@ -311,10 +312,10 @@
        CMeasurement* pMeasurement = (CMeasurement*)getEquipment(EQ_ID_MEASUREMENT);
        ASSERT(pEFEM);
        ASSERT(pLoadPort1);
        ASSERT(pLoadPort2);
        ASSERT(pLoadPort3);
        ASSERT(pLoadPort4);
        ASSERT(pLoadPorts[0]);
        ASSERT(pLoadPorts[1]);
        ASSERT(pLoadPorts[2]);
        ASSERT(pLoadPorts[3]);
        ASSERT(pFliper);
        ASSERT(pVacuumBake);
        ASSERT(pAligner);
@@ -544,17 +545,16 @@
                    LOGI("Arm1 %s, Arm2 %s.", rmd.armState[0] ? _T("不可用") : _T("可用"),
                        rmd.armState[1] ? _T("不可用") : _T("可用"));
                }
                CLoadPort* pEqLoadPort[] = { pLoadPort1, pLoadPort2, pLoadPort3, pLoadPort4 };
                CEquipment* pEqTar[] = { pVacuumBake, pFliper };
                if (primaryType == MaterialsType::G2) {
                    pEqTar[0] = pFliper;
                    pEqTar[1] = pVacuumBake;
                }
                for (int s = 0; s < 4; s++) {
                    if (!rmd.armState[0] && pEqLoadPort[s]->isEnable()
                        && pEqLoadPort[s]->getPortType() == PortType::Unloading
                        && pEqLoadPort[s]->getPortMode() == PortMode::ReadyToUnload) {
                        m_pActiveRobotTask = createTransferTask(pMeasurement, pEqLoadPort[s], primaryType, secondaryType);
                    if (!rmd.armState[0] && pLoadPorts[s]->isEnable()
                        && pLoadPorts[s]->getPortType() == PortType::Unloading
                        && pLoadPorts[s]->getPortMode() == PortMode::ReadyToUnload) {
                        m_pActiveRobotTask = createTransferTask(pMeasurement, pLoadPorts[s], primaryType, secondaryType);
                        if (m_pActiveRobotTask != nullptr) {
                            goto PORT_PUT;
                        }
@@ -572,6 +572,25 @@
                    LOGI("创建新任务<%s>...", strDescription.c_str());
                    continue;
                }
                // Measurement NG -> LoadPort
                // NG回原位
                if (!rmd.armState[1]) {
                    m_pActiveRobotTask = createTransferTask_restore(pMeasurement, pLoadPorts);
                    if (m_pActiveRobotTask != nullptr) {
                        m_pActiveRobotTask->pick();
                        std::string strDescription = m_pActiveRobotTask->getDescription();
                        unlock();
                        if (m_listener.onRobotTaskEvent != nullptr) {
                            m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
                        }
                        LOGI("创建Measurement回退任务<%s>...", strDescription.c_str());
                        continue;
                    }
                }
                // BakeCooling ->Measurement
@@ -727,12 +746,30 @@
                    }
                }
                // Aligner -> LoadPort
                if (!rmd.armState[1]) {
                    m_pActiveRobotTask = createTransferTask_restore(pAligner, pLoadPorts);
                    if (m_pActiveRobotTask != nullptr) {
                        m_pActiveRobotTask->pick();
                        std::string strDescription = m_pActiveRobotTask->getDescription();
                        unlock();
                        if (m_listener.onRobotTaskEvent != nullptr) {
                            m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
                        }
                        LOGI("创建Aligner回退任务<%s>...", strDescription.c_str());
                        continue;
                    }
                }
                // LoadPort -> Aligner
                for (int s = 0; s < 4; s++) {
                    if (!rmd.armState[0] && pEqLoadPort[s]->isEnable()
                        && pEqLoadPort[s]->getPortType() == PortType::Loading
                        && pEqLoadPort[s]->getPortMode() == PortMode::ReadyToLoad) {
                        m_pActiveRobotTask = createTransferTask(pEqLoadPort[s], pAligner, primaryType, secondaryType);
                    if (!rmd.armState[0] && pLoadPorts[s]->isEnable()
                        && pLoadPorts[s]->getPortType() == PortType::Loading
                        && pLoadPorts[s]->getPortMode() == PortMode::ReadyToLoad) {
                        m_pActiveRobotTask = createTransferTask(pLoadPorts[s], pAligner, primaryType, secondaryType);
                        if (m_pActiveRobotTask != nullptr) {
                            pEFEM->setContext(m_pActiveRobotTask->getContext());
                            goto PORT_GET;
@@ -1454,6 +1491,38 @@
        return pTask;
    }
    CRobotTask* CMaster::createTransferTask_restore(CEquipment* pEqSrc, CLoadPort** pPorts)
    {
        CRobotTask* pTask = nullptr;
        CSlot* pSrcSlot, * pTarSlot = nullptr, * pTempSlot;
        pSrcSlot = pEqSrc->getInspFailSlot();
        if (pSrcSlot != nullptr) {
            CGlass* pGlass = (CGlass*)pSrcSlot->getContext();
            ASSERT(pGlass);
            int port, slot;
            pGlass->getOrginPort(port, slot);
            pGlass->setInspResult(pPorts[port]->getID(), 0, InspResult::Fail);
            ASSERT(0 <= port && port < 4);
            ASSERT(0 <= slot && slot < 8);
            pTempSlot = pPorts[port]->getSlot(slot);
            if (pTempSlot->getContext() == nullptr) {
                pTarSlot = pTempSlot;
            }
        }
        if (pSrcSlot != nullptr && nullptr != pTarSlot) {
            pTask = new CRobotTask();
            pTask->setContext(pSrcSlot->getContext());
            pTask->setEFEM((CEFEM*)getEquipment(EQ_ID_EFEM));
            taskSeqNo = pTask->setRobotTransferParam(taskSeqNo, 1, pSrcSlot->getPosition(),
                pTarSlot->getPosition(), pSrcSlot->getNo(), pTarSlot->getNo());
        }
        return pTask;
    }
    int CMaster::abortCurrentTask()
    {
        lock();
SourceCode/Bond/Servo/CMaster.h
@@ -96,7 +96,8 @@
        CRobotTask* createTransferTask_bonder_to_bakecooling(CEquipment* pSrcEq, CEquipment* pTarEq);
        CRobotTask* createTransferTask_bake_to_cooling(CEquipment* pSrcEq);
        CRobotTask* createTransferTask_bakecooling_to_measurement(CEquipment* pSrcEq, CEquipment* pTarEq);
        CRobotTask* createTransferTask_restore(CEquipment* pEqSrc, CLoadPort** pPorts);
    private:
        CRITICAL_SECTION m_criticalSection;
        MasterListener m_listener;
SourceCode/Bond/Servo/CMeasurement.cpp
@@ -363,6 +363,23 @@
                delete pStep;
            }
        }
        {
            // Panel Data Report
            CEqReadStep* pStep = new CEqReadStep(0x1A17f, 386 * 2,
                [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                    if (code == ROK && pszData != nullptr && size > 0) {
                        decodePanelDataReport((CStep*)pFrom, pszData, size);
                    }
                    return -1;
                });
            pStep->setName(STEP_EQ_PANEL_DATA_REPORT);
            pStep->setProp("Port", (void*)1);
            pStep->setWriteSignalDev(0x105e);
            if (addStep(STEP_ID_PANEL_DATA_REPORT, pStep) != 0) {
                delete pStep;
            }
        }
    }
    // 必须要实现的虚函数,在此初始化Slot信息
SourceCode/Bond/Servo/CPageCassetteCtrlCmd.cpp
@@ -90,7 +90,9 @@
{
    ASSERT(m_pEquipment != nullptr);
    ASSERT(m_pEquipment->getID() == EQ_ID_LOADPORT1
        || m_pEquipment->getID() == EQ_ID_LOADPORT2);
        || m_pEquipment->getID() == EQ_ID_LOADPORT2
        || m_pEquipment->getID() == EQ_ID_LOADPORT3
        || m_pEquipment->getID() == EQ_ID_LOADPORT4);
    SERVO::CLoadPort* pLoadPort = (SERVO::CLoadPort*)m_pEquipment;
    short cmd = 0;
@@ -112,5 +114,14 @@
    pLoadPort->sendCassetteCtrlCmd(cmd, &jobExistence[0], jobExistenceSize, slotProcess,
        jobCount, pJobDataA);
        jobCount, pJobDataA, [&](int code) -> int {
            if (code == WOK) {
                LOGI("sendCassetteCtrlCmd 成功.");
            }
            else {
                LOGI("sendCassetteCtrlCmd 失败.");
            }
            return 0;
        });
}
SourceCode/Bond/Servo/CPageGraph2.cpp
@@ -159,7 +159,9 @@
        }
        if (pEquipment->getID() == EQ_ID_LOADPORT1
            || pEquipment->getID() == EQ_ID_LOADPORT2) {
            || pEquipment->getID() == EQ_ID_LOADPORT2
            || pEquipment->getID() == EQ_ID_LOADPORT3
            || pEquipment->getID() == EQ_ID_LOADPORT4) {
            CPageCassetteCtrlCmd* pPage = new CPageCassetteCtrlCmd();
            pPage->setEquipment(pEquipment);
            pPage->Create(IDD_PAGE_CASSETTE_CTRL_CMD);
SourceCode/Bond/Servo/CPath.cpp
@@ -10,6 +10,7 @@
        m_timeOut = 0;
        m_timeIn = CToolUnits::getTimestamp();
        m_bProcessed = FALSE;
        m_inspResult = InspResult::NotInspected;
        m_pPrev = nullptr;
        m_pNext = nullptr;
    }
@@ -20,9 +21,10 @@
        m_nUnit = nUnit;
        m_timeOut = 0;
        m_timeIn = CToolUnits::getTimestamp();
        m_bProcessed = FALSE;
        m_inspResult = InspResult::NotInspected;
        m_pPrev = nullptr;
        m_pNext = nullptr;
        m_bProcessed = FALSE;
    }
    CPath::~CPath()
@@ -52,17 +54,21 @@
            ar << m_timeIn;
            ar << m_timeOut;
            ar << m_bProcessed;
            ar << (int)m_inspResult;
            ar << (ULONGLONG)m_pNext;
            if (m_pNext != nullptr) {
                m_pNext->serialize(ar);
            }
        }
        else {
            int temp;
            ar >> m_nEqID;
            ar >> m_nUnit;
            ar >> m_timeIn;
            ar >> m_timeOut;
            ar >> m_bProcessed;
            ar >> temp; m_inspResult = (InspResult)temp;
            ULONGLONG ulNext;
            ar >> ulNext;
            if ((CPath*)ulNext != nullptr) {
@@ -109,6 +115,16 @@
        return m_bProcessed;
    }
    void CPath::setInspResult(InspResult result)
    {
        m_inspResult = result;
    }
    InspResult CPath::getInspResult()
    {
        return m_inspResult;
    }
    CPath* CPath::getPrev()
    {
        return m_pPrev;
SourceCode/Bond/Servo/CPath.h
@@ -1,4 +1,5 @@
#pragma once
#include "ServoCommo.h"
namespace SERVO {
@@ -24,6 +25,8 @@
        ULONGLONG getOutTime();
        void processEnd();
        BOOL isProcessEnd();
        void setInspResult(InspResult result);
        InspResult getInspResult();
    private:    
        unsigned int m_nEqID;
@@ -31,6 +34,7 @@
        ULONGLONG m_timeIn;
        ULONGLONG m_timeOut;
        BOOL m_bProcessed;
        InspResult m_inspResult;
        CPath* m_pPrev;
        CPath* m_pNext;
    };
SourceCode/Bond/Servo/CPortStatusReport.cpp
@@ -237,6 +237,11 @@
        return false;
    }
    short CPortStatusReport::getJobExistenceSlot()
    {
        return m_nJobExistenceSlot[0];
    }
    void CPortStatusReport::WriteString(CArchive& ar, std::string& string)
    {
        CString strTemp = string.c_str();
SourceCode/Bond/Servo/CPortStatusReport.h
@@ -28,6 +28,7 @@
    public:
        bool canPickFromPort();
        bool isJobExistenceSlot();
        short getJobExistenceSlot();
    private:
        void WriteString(CArchive& ar, std::string& string);
@@ -40,7 +41,7 @@
        short m_nJobExistenceSlot[12];        // 12 * 16 = 192 个slot是否存在glass
        short m_nLoadingCassetteType;        // 1: Actual Cassette 2 : Empty Cassette
        short m_nQTimeFlag;
        short m_nCassetteMappingState;        // 1: mapping use  2: mapping not use
        short m_nCassetteMappingState;        // 1: mapping use, 2: mapping not use
        short m_nCassetteStatus;
    };
}
SourceCode/Bond/Servo/CVcrEventReport.cpp
@@ -46,7 +46,7 @@
    int CVcrEventReport::serialize(char* pszBuffer, int nBufferSize)
    {
        if (nBufferSize < 640) return -1;
        if (nBufferSize < 30) return -1;
        int index = 0;
        int strLen = min(20, m_strGlassId.size());
@@ -73,7 +73,7 @@
    int CVcrEventReport::unserialize(const char* pszBuffer, int nBufferSize)
    {
        if (nBufferSize < 640) return -1;
        if (nBufferSize < 30) return -1;
        int index = 0;
        CToolUnits::convertString(&pszBuffer[index], 20, m_strGlassId);
SourceCode/Bond/Servo/Common.h
@@ -34,7 +34,7 @@
#define PAGE_GRPAH2_BACKGROUND_COLOR        RGB(255, 255, 255)
#define EQ_BOX_OFFLINE                        RGB(222, 222, 222)
#define EQ_BOX_ONLINE                        RGB(0, 176, 80)
#define EQ_BOX_OCCUPIED                     RGB(0, 204, 102)
#define EQ_BOX_OCCUPIED                     RGB(255, 127, 39)
#define EQ_BOX_FRAME1                        RGB(22, 22, 22)
#define EQ_BOX_FRAME2                        RGB(255, 127, 39)
#define CR_MSGBOX_BKGND                        RGB(7, 71, 166)
@@ -444,6 +444,10 @@
#define STEP_ID_PROT2_CASSETTE_TYPE_CHANGE_REPLY    0x699
#define STEP_ID_PROT3_CASSETTE_TYPE_CHANGE_REPLY    0x69A
#define STEP_ID_PROT4_CASSETTE_TYPE_CHANGE_REPLY    0x69B
#define STEP_ID_PROT1_CASSETTE_CTR_CMD_REPLY        0x6A0
#define STEP_ID_PROT2_CASSETTE_CTR_CMD_REPLY        0x6A1
#define STEP_ID_PROT3_CASSETTE_CTR_CMD_REPLY        0x6A2
#define STEP_ID_PROT4_CASSETTE_CTR_CMD_REPLY        0x6A3
#define STEP_ID_ROBOT_CMD_REPLY                        0x6b0
SourceCode/Bond/Servo/PageTransferLog.cpp
@@ -275,7 +275,12 @@
        return;
    }
    int nItem = m_listCtrl.InsertItem(0, _T(""));
    int nIndex = m_listCtrl.GetItemCount();
    if (nIndex < 0) {
        return;
    }
    int nItem = m_listCtrl.InsertItem(nIndex, _T(""));
    CString str;
    str.Format(_T("%d"), data.nRecordId);
    m_listCtrl.SetItemText(nItem, 1, str);
SourceCode/Bond/Servo/Servo.vcxproj
@@ -135,8 +135,8 @@
    </ResourceCompile>
    <PostBuildEvent>
      <Command>if exist "\\DESKTOP-IODBVIQ\Servo\Debug\" (
    xcopy /Y /D "$(OutDir)*.exe" "\\DESKTOP-IODBVIQ\Servo\Debug\"
    xcopy /Y /D "$(OutDir)*.pdb" "\\DESKTOP-IODBVIQ\Servo\Debug\"
    xcopy /Y /D "$(OutDir)Servo.exe" "\\DESKTOP-IODBVIQ\Servo\Debug\"
    xcopy /Y /D "$(OutDir)Servo.pdb" "\\DESKTOP-IODBVIQ\Servo\Debug\"
)</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
SourceCode/Bond/Servo/ServoCommo.h
@@ -2,6 +2,23 @@
#include <string>
#include <vector>
#define CHECK_READ_STEP_SIGNAL(addr, data, size) {                            \
    BOOL bFlag = isBitOn(data, size, addr);                                    \
    SERVO::CStep* pStep = getStep(addr);                                    \
    if (pStep != nullptr) {                                                    \
        ((CReadStep*)pStep)->onReadSignal(bFlag ? addr : 0);                \
    }                                                                        \
}
#define CHECK_WRITE_STEP_SIGNAL(addr, data, size) {                            \
    BOOL bFlag = isBitOn(data, size, addr);                                    \
    SERVO::CStep* pStep = getStep(addr);                                    \
    if (pStep != nullptr) {                                                    \
        ((CWriteStep*)pStep)->onRecvSignal(bFlag ? addr : 0);                \
    }                                                                        \
}
namespace SERVO {
#define BLOCK_BUFFER_MAX            1024
#define ALIVE_TIMEOUT                15
@@ -14,7 +31,14 @@
        OK = 1,
        NG,
    };
    typedef RET JobDataRequestAck;
    using JobDataRequestAck = RET;
    enum class InspResult
    {
        NotInspected = 0,  // 初始化状态,尚未检测
        Pass,              // 检测合格
        Fail               // 检测不合格
    };
    enum class PortType {
        Loading = 1,