1.实现 CIM model change指令下发到机器。与之前的从CC link读数据逻辑稍有不同,下发指令为写数据,因此,从原CStep派生两个类,CReadStep(用于读数据),CWriteStep(用于写数据),然后根据使用场景选择合适的基数做应用层逻辑。已完成待测试验证
已添加6个文件
已修改18个文件
836 ■■■■ 文件已修改
SourceCode/Bond/Servo/CAttributeVector.cpp 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqAlarmStep.cpp 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqAlarmStep.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqCimModeChangeStep.cpp 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqCimModeChangeStep.h 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqModeStep.cpp 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqModeStep.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqProcessStep.cpp 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqProcessStep.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqStatusStep.cpp 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqStatusStep.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.cpp 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.cpp 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPanelAttributes.cpp 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CReadStep.cpp 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CReadStep.h 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CStep.cpp 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CStep.h 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CWriteStep.cpp 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CWriteStep.h 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Common.h 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj.filters 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CAttributeVector.cpp
@@ -10,7 +10,10 @@
    CAttributeVector::~CAttributeVector()
    {
        for (auto item : m_attributes) {
            delete item;
        }
        m_attributes.clear();
    }
    void CAttributeVector::addAttribute(CAttribute* pAttribute)
SourceCode/Bond/Servo/CEqAlarmStep.cpp
@@ -5,7 +5,7 @@
namespace SERVO {
    CEqAlarmStep::CEqAlarmStep() : CStep()
    CEqAlarmStep::CEqAlarmStep() : CReadStep()
    {
        m_nAlarmDev = 0;
        m_nAlarmState = 0;
@@ -22,7 +22,7 @@
    void CEqAlarmStep::getAttributeVector(CAttributeVector& attrubutes)
    {
        CStep::getAttributeVector(attrubutes);
        CReadStep::getAttributeVector(attrubutes);
        attrubutes.addAttribute(new CAttribute("Alarm State",
            std::to_string(m_nAlarmState).c_str(), ""));
@@ -42,7 +42,7 @@
    int CEqAlarmStep::onReadData()
    {
        CStep::onReadData();
        CReadStep::onReadData();
        char szBuffer[64];
        int nRet = m_pCclink->ReadData2(m_station, DeviceType::W,
@@ -66,7 +66,7 @@
    int CEqAlarmStep::onComplete()
    {
        CStep::onComplete();
        CReadStep::onComplete();
        LOGI("<CEqAlarmStep> onComplete.");
        return 0;
@@ -74,7 +74,7 @@
    int CEqAlarmStep::onTimeout()
    {
        CStep::onTimeout();
        CReadStep::onTimeout();
        LOGI("<CEqAlarmStep> onTimeout.");
        return 0;
SourceCode/Bond/Servo/CEqAlarmStep.h
@@ -1,9 +1,9 @@
#pragma once
#include "CStep.h"
#include "CReadStep.h"
namespace SERVO {
    class CEqAlarmStep : public CStep
    class CEqAlarmStep : public CReadStep
    {
    public:
        CEqAlarmStep();
SourceCode/Bond/Servo/CEqCimModeChangeStep.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
#include "stdafx.h"
#include "CEqCimModeChangeStep.h"
namespace SERVO {
    CEqCimModeChangeStep::CEqCimModeChangeStep() : CWriteStep()
    {
        m_nCimModeDev = 0;
    }
    CEqCimModeChangeStep::~CEqCimModeChangeStep()
    {
    }
    void CEqCimModeChangeStep::setCimModeDev(int nDev)
    {
        m_nCimModeDev = nDev;
    }
    int CEqCimModeChangeStep::cimOn()
    {
        short mode = 1;
        return writeData(m_nCimModeDev, (const char*)&mode, sizeof(short));
    }
    int CEqCimModeChangeStep::cimOff()
    {
        short mode = 2;
        return writeData(m_nCimModeDev, (const char*)&mode, sizeof(short));
    }
    int CEqCimModeChangeStep::setCimMode(short mode)
    {
        return writeData(m_nCimModeDev, (const char*)&mode, sizeof(short));
    }
    void CEqCimModeChangeStep::getAttributeVector(CAttributeVector& attrubutes)
    {
        CWriteStep::getAttributeVector(attrubutes);
        attrubutes.addAttribute(new CAttribute("Cim Mode Dev",
            std::to_string(m_nCimModeDev).c_str(), ""));
    }
}
SourceCode/Bond/Servo/CEqCimModeChangeStep.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
#pragma once
#include "CWriteStep.h"
namespace SERVO {
    class CEqCimModeChangeStep : public CWriteStep
    {
    public:
        CEqCimModeChangeStep();
        ~CEqCimModeChangeStep();
    public:
        void setCimModeDev(int nDev);
        int cimOn();
        int cimOff();
        int setCimMode(short mode);
        void getAttributeVector(CAttributeVector& attrubutes);
    private:
        int m_nCimModeDev;
    };
}
SourceCode/Bond/Servo/CEqModeStep.cpp
@@ -4,7 +4,7 @@
namespace SERVO {
    CEqModeStep::CEqModeStep() : CStep()
    CEqModeStep::CEqModeStep() : CReadStep()
    {
        m_nModeDev = 0;
        m_nMode = 0;
@@ -17,7 +17,7 @@
    void CEqModeStep::getAttributeVector(CAttributeVector& attrubutes)
    {
        CStep::getAttributeVector(attrubutes);
        CReadStep::getAttributeVector(attrubutes);
        std::string strTemp;
        attrubutes.addAttribute(new CAttribute("Mode",
@@ -28,7 +28,7 @@
    int CEqModeStep::onReadData()
    {
        CStep::onReadData();
        CReadStep::onReadData();
        DWordContainer dc;
        if (0 != m_pCclink->ReadDWordData(m_station, DeviceType::W, m_nModeDev, 1, dc)) {
@@ -48,7 +48,7 @@
    int CEqModeStep::onComplete()
    {
        CStep::onComplete();
        CReadStep::onComplete();
        LOGI("<CEqModeStep> onComplete.");
        return 0;
@@ -56,7 +56,7 @@
    int CEqModeStep::onTimeout()
    {
        CStep::onTimeout();
        CReadStep::onTimeout();
        LOGI("<CEqModeStep> onTimeout.");
        return 0;
SourceCode/Bond/Servo/CEqModeStep.h
@@ -1,9 +1,9 @@
#pragma once
#include "CStep.h"
#include "CReadStep.h"
namespace SERVO {
    class CEqModeStep : public CStep
    class CEqModeStep : public CReadStep
    {
    public:
        CEqModeStep();
SourceCode/Bond/Servo/CEqProcessStep.cpp
@@ -6,7 +6,7 @@
namespace SERVO {
    CEqProcessStep::CEqProcessStep()
    CEqProcessStep::CEqProcessStep() : CReadStep()
    {
        m_nProcessDev = 0;
        m_nTotalParameter = 0;
@@ -19,7 +19,7 @@
    void CEqProcessStep::getAttributeVector(CAttributeVector& attrubutes)
    {
        CStep::getAttributeVector(attrubutes);
        CReadStep::getAttributeVector(attrubutes);
        attrubutes.addAttribute(new CAttribute("Glass ID",
            m_strGlassId.c_str(), ""));
@@ -46,7 +46,7 @@
#define PROGRESS_BUF_SIZE        (1024 + 64)
    int CEqProcessStep::onReadData()
    {
        CStep::onReadData();
        CReadStep::onReadData();
        // W1864 ~ W1A74, 529个word, 1058 bytes
        char szBuffer[PROGRESS_BUF_SIZE];
@@ -107,7 +107,7 @@
    int CEqProcessStep::onComplete()
    {
        CStep::onComplete();
        CReadStep::onComplete();
        LOGI("<CEqProcessStep> onComplete.");
        return 0;
@@ -115,7 +115,7 @@
    int CEqProcessStep::onTimeout()
    {
        CStep::onTimeout();
        CReadStep::onTimeout();
        LOGI("<CEqProcessStep> onTimeout.");
        return 0;
SourceCode/Bond/Servo/CEqProcessStep.h
@@ -1,10 +1,10 @@
#pragma once
#include "CStep.h"
#include "CReadStep.h"
#include <list>
namespace SERVO {
    class CEqProcessStep : public CStep
    class CEqProcessStep : public CReadStep
    {
    public:
        CEqProcessStep();
SourceCode/Bond/Servo/CEqStatusStep.cpp
@@ -5,7 +5,7 @@
namespace SERVO {
    CEqStatusStep::CEqStatusStep() : CStep()
    CEqStatusStep::CEqStatusStep() : CReadStep()
    {
        m_nStatusDev = 0;
        for (int i = 0; i < STATUS_MAX; i++) {
@@ -23,7 +23,7 @@
    void CEqStatusStep::getAttributeVector(CAttributeVector& attrubutes)
    {
        CStep::getAttributeVector(attrubutes);
        CReadStep::getAttributeVector(attrubutes);
        char szName[256];
        for (int i = 0; i < STATUS_MAX; i++) {
@@ -49,7 +49,7 @@
    }
    int CEqStatusStep::onReadData()
    {
        CStep::onReadData();
        CReadStep::onReadData();
        char szBuffer[64];
        int nRet = m_pCclink->ReadData2(m_station, DeviceType::W,
@@ -82,7 +82,7 @@
    int CEqStatusStep::onComplete()
    {
        CStep::onComplete();
        CReadStep::onComplete();
        LOGI("<CEqStatusStep> onComplete.");
        return 0;
@@ -90,7 +90,7 @@
    int CEqStatusStep::onTimeout()
    {
        CStep::onTimeout();
        CReadStep::onTimeout();
        LOGI("<CEqStatusStep> onTimeout.");
        return 0;
SourceCode/Bond/Servo/CEqStatusStep.h
@@ -1,12 +1,12 @@
#pragma once
#include "CStep.h"
#include "CReadStep.h"
namespace SERVO {
#define UNIT_MAX        6
#define STATUS_MAX        (UNIT_MAX + 1)
    class CEqStatusStep : public CStep
    class CEqStatusStep : public CReadStep
    {
    public:
        CEqStatusStep();
SourceCode/Bond/Servo/CEquipment.cpp
@@ -267,9 +267,16 @@
            bFlag = isBitOn(pszData, size, index);
            pStep = getStep(index);
            if (pStep != nullptr) {
                pStep->onSignal(bFlag);
                ((CReadStep*)pStep)->onReadSignal(bFlag);
            }
        }
        index = 0x350;
        bFlag = isBitOn(pszData, size, index);
        pStep = getStep(index);
        if (pStep != nullptr) {
            ((CWriteStep*)pStep)->onRecvSignal(bFlag);
        }
    }
    BOOL CEquipment::isBitOn(const char* pszData, size_t size, int index)
SourceCode/Bond/Servo/CEquipment.h
@@ -5,6 +5,7 @@
#include "CEqStatusStep.h"
#include "CEqAlarmStep.h"
#include "CEqProcessStep.h"
#include "CEqCimModeChangeStep.h"
#include <map>
SourceCode/Bond/Servo/CMaster.cpp
@@ -234,6 +234,17 @@
                delete pStep;
            }
        }
        {
            CEqCimModeChangeStep* pStep = new CEqCimModeChangeStep();
            pStep->setName(STEP_CIM_MODE_CHANGE);
            pStep->setListener(listener);
            pStep->setWriteSignalDev(0x50);
            pStep->setCimModeDev(0x15);
            if (pEquipment->addStep(0x350, pStep) != 0) {
                delete pStep;
            }
        }
        pEquipment->init();
        LOGE("已添加“EFEM(ROBOT)”.");
SourceCode/Bond/Servo/CPanelAttributes.cpp
@@ -62,11 +62,12 @@
    unsigned int nSize = attrubutes.size();
    for (unsigned int i = 0; i < nSize; i++) {
        SERVO::CAttribute* pAttribute = attrubutes.getAttribute(i);
        m_gridCtrl.AddProperty(new CMFCPropertyGridProperty(
        CMFCPropertyGridProperty* pProperty = new CMFCPropertyGridProperty(
            pAttribute->getName().c_str(),
            pAttribute->getValue().c_str(),
            pAttribute->getDescription().c_str()));
            pAttribute->getDescription().c_str());
        pProperty->AllowEdit(TRUE);
        m_gridCtrl.AddProperty(pProperty);
    }
}
@@ -146,16 +147,20 @@
    pItem = GetDlgItem(IDC_LINE1);
    pItem->MoveWindow(rcClient.right - 3, 0, 3, rcClient.Height());
    int x2 = rcClient.right - 6;
    int y = 3;
    pItem = GetDlgItem(IDC_LABEL_TITLE);
    pItem->GetWindowRect(&rcItem);
    pItem->MoveWindow(5, y, rcClient.Width() - 8, rcItem.Height());
    pItem = GetDlgItem(IDC_BUTTON_CLOSE);
    pItem->GetWindowRect(&rcItem);
    pItem->MoveWindow(rcClient.right - 6 - rcItem.Width(), y, rcItem.Width(), rcItem.Height());
    pItem->MoveWindow(x2 - rcItem.Width(), y, rcItem.Width(), rcItem.Height());
    x2 -= rcItem.Width();
    x2 -= 3;
    pItem = GetDlgItem(IDC_LABEL_TITLE);
    pItem->GetWindowRect(&rcItem);
    pItem->MoveWindow(5, y, x2 - 5, rcItem.Height());
    y += rcItem.Height();
    y += 3;
    y += 8;
    GetDlgItem(IDC_MFCPROPERTYGRID1)->MoveWindow(5, y, rcClient.Width() - 13, rcClient.Height() - 3 - y);
}
SourceCode/Bond/Servo/CReadStep.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,187 @@
#include "stdafx.h"
#include "CReadStep.h"
#include "Common.h"
namespace SERVO {
#define TIMEOUT            15
    unsigned __stdcall ReadStepWorkThreadFunction(LPVOID lpParam)
    {
        CReadStep* pStep = (CReadStep*)lpParam;
        return pStep->WorkingProc();
    }
    CReadStep::CReadStep() : CStep()
    {
        m_nWordThreadAddr = 0;
        m_hWorkStop = nullptr;
        m_hWorkThreadHandle = nullptr;
        m_hReadSignalOn = ::CreateEvent(NULL, TRUE, FALSE, NULL);
        m_hReadSignalOff = ::CreateEvent(NULL, TRUE, FALSE, NULL);
        m_nCurStep = 0;
    }
    CReadStep::~CReadStep()
    {
        ASSERT(m_hReadSignalOn);
        CloseHandle(m_hReadSignalOn);
        m_hReadSignalOn = nullptr;
        ASSERT(m_hReadSignalOff);
        CloseHandle(m_hReadSignalOff);
        m_hReadSignalOff = nullptr;
    }
    void CReadStep::setWriteSignalDev(int dev)
    {
        m_nWriteSignalDev = dev;
    }
    void CReadStep::onReadSignal(BOOL bSignal)
    {
        Lock();
        if (m_nCurStep == 0 && bSignal) {
            SetEvent(m_hReadSignalOn);
        }
        else if (m_nCurStep == 3 && !bSignal) {
            SetEvent(m_hReadSignalOff);
        }
        Unlock();
    }
    int CReadStep::onReadData()
    {
        return 0;
    }
    unsigned CReadStep::WorkingProc()
    {
        HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
        BOOL bReadOk = FALSE;
        int nBeginAddr = 0x0;
        while (1) {
        RESET:
            resetStep();
            // å¾…退出信号或时间到
            HANDLE hEvents[] = { m_hWorkStop, m_hReadSignalOn };
            int nRet = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE);
            if (nRet == WAIT_OBJECT_0) {
                ResetEvent(m_hWorkStop);
                break;
            }
            else if (nRet == WAIT_OBJECT_0 + 1) {
                ResetEvent(m_hReadSignalOn);
                // 1.读取数据
                nextStep();
                ASSERT(m_pCclink);
                if (0 == onReadData()) {
                    if (m_listener.onEvent != nullptr) {
                        m_listener.onEvent(this, STEP_EVENT_READDATA, nullptr);
                    }
                }
                // 2.给对方写ON
                nextStep();
                m_pCclink->SetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
                // 3.等待对方OFF
                nextStep();
                int nStep3Ret = ::WaitForSingleObject(m_hReadSignalOff, TIMEOUT * 1000);
                if (nStep3Ret == WAIT_TIMEOUT) {
                    m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
                    onTimeout();
                    goto RESET;
                }
                ResetEvent(m_hReadSignalOff);
                // 4.给对方写OFF
                nextStep();
                m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
                // 6.完成
                nextStep();
                if (0 == onComplete()) {
                    if (m_listener.onEvent != nullptr) {
                        m_listener.onEvent(this, STEP_EVENT_COMPLETE, nullptr);
                    }
                }
            }
        }
        if (hEvent != nullptr) {
            CloseHandle(hEvent);
        }
        // _endthreadex(0);
        TRACE("CStep::WorkingProc çº¿ç¨‹é€€å‡º\n");
        return 0;
    }
    void CReadStep::getAttributeVector(CAttributeVector& attrubutes)
    {
        CStep::getAttributeVector(attrubutes);
        attrubutes.addAttribute(new CAttribute("Current Step",
            std::to_string(m_nCurStep).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("Signal Dev",
            std::to_string(m_nWriteSignalDev).c_str(), ""));
    }
    void CReadStep::init()
    {
        CStep::init();
        if (m_hWorkStop != nullptr) return;
        m_hWorkStop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
        m_hWorkThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::ReadStepWorkThreadFunction, this,
            0, &m_nWordThreadAddr);
    }
    void CReadStep::term()
    {
        CStep::term();
        ASSERT(m_hWorkStop);
        SetEvent(m_hWorkStop);
        if (m_hWorkThreadHandle != NULL) {
            WaitForSingleObject(m_hWorkThreadHandle, INFINITE);
            CloseHandle(m_hWorkThreadHandle);
            m_hWorkThreadHandle = NULL;
        }
        CloseHandle(m_hWorkStop);
        m_hWorkStop = NULL;
    }
    void CReadStep::resetStep()
    {
        Lock();
        m_nCurStep = 0;
        Unlock();
    }
    void CReadStep::nextStep()
    {
        Lock();
        m_nCurStep++;
        Unlock();
    }
    int CReadStep::onComplete()
    {
        return 0;
    }
    int CReadStep::onTimeout()
    {
        return 0;
    }
}
SourceCode/Bond/Servo/CReadStep.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
#pragma once
#include "CStep.h"
namespace SERVO {
    class CReadStep : public CStep
    {
    public:
        CReadStep();
        virtual ~CReadStep();
    public:
        unsigned WorkingProc();
        virtual void setWriteSignalDev(int dev);
        virtual void onReadSignal(BOOL bSignal);
        virtual int onReadData();
        virtual void init();
        virtual void term();
        virtual void getAttributeVector(CAttributeVector& attrubutes);
        virtual int onComplete();
        virtual int onTimeout();
        inline void nextStep();
        inline void resetStep();
    protected:
        HANDLE m_hWorkThreadHandle;
        unsigned m_nWordThreadAddr;
        HANDLE m_hWorkStop;
        HANDLE m_hReadSignalOn;
        HANDLE m_hReadSignalOff;
        int m_nCurStep;
        int m_nWriteSignalDev;            // å¯¹æ–¹BIT地址
    };
}
SourceCode/Bond/Servo/CStep.cpp
@@ -1,41 +1,18 @@
#include "stdafx.h"
#include "CStep.h"
#include "Common.h"
namespace SERVO {
#define TIMEOUT            15
    unsigned __stdcall StepWorkThreadFunction(LPVOID lpParam)
    {
        CStep* pStep = (CStep*)lpParam;
        return pStep->WorkingProc();
    }
    CStep::CStep()
    {
        m_listener = {nullptr};
        m_nWordThreadAddr = 0;
        m_hWorkStop = nullptr;
        m_hWorkThreadHandle = nullptr;
        m_hSignalOn = ::CreateEvent(NULL, TRUE, FALSE, NULL);
        m_hSignalOff = ::CreateEvent(NULL, TRUE, FALSE, NULL);
        m_nCurStep = 0;
        m_pCclink = nullptr;
        m_nWriteSignalDev = 0;
        InitializeCriticalSection(&m_criticalSection);
    }
    CStep::~CStep()
    {
        ASSERT(m_hSignalOn);
        CloseHandle(m_hSignalOn);
        m_hSignalOn = nullptr;
        ASSERT(m_hSignalOff);
        CloseHandle(m_hSignalOff);
        m_hSignalOff = nullptr;
        DeleteCriticalSection(&m_criticalSection);
    }
@@ -76,148 +53,16 @@
            std::to_string(m_station.nNetNo).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("Station",
            std::to_string(m_station.nStNo).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("Current Step",
            std::to_string(m_nCurStep).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("Signal Dev",
            std::to_string(m_nWriteSignalDev).c_str(), ""));
    }
    void CStep::setWriteSignalDev(int dev)
    {
        m_nWriteSignalDev = dev;
    }
    void CStep::init()
    {
        if (m_hWorkStop != nullptr) return;
        m_hWorkStop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
        m_hWorkThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::StepWorkThreadFunction, this,
            0, &m_nWordThreadAddr);
    }
    void CStep::term()
    {
        ASSERT(m_hWorkStop);
        SetEvent(m_hWorkStop);
        if (m_hWorkThreadHandle != NULL) {
            WaitForSingleObject(m_hWorkThreadHandle, INFINITE);
            CloseHandle(m_hWorkThreadHandle);
            m_hWorkThreadHandle = NULL;
        }
        CloseHandle(m_hWorkStop);
        m_hWorkStop = NULL;
    }
    unsigned CStep::WorkingProc()
    {
        HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
        BOOL bReadOk = FALSE;
        int nBeginAddr = 0x0;
        while (1) {
RESET:
            resetStep();
            // å¾…退出信号或时间到
            HANDLE hEvents[] = { m_hWorkStop, m_hSignalOn };
            int nRet = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE);
            if (nRet == WAIT_OBJECT_0) {
                ResetEvent(m_hWorkStop);
                break;
            }
            else if (nRet == WAIT_OBJECT_0 + 1) {
                ResetEvent(m_hSignalOn);
                // 1.读取数据
                nextStep();
                ASSERT(m_pCclink);
                if (0 == onReadData()) {
                    if (m_listener.onEvent != nullptr) {
                        m_listener.onEvent(this, STEP_EVENT_READDATA, nullptr);
                    }
                }
                // 2.给对方写ON
                nextStep();
                m_pCclink->SetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
                // 3.等待对方OFF
                nextStep();
                int nStep3Ret = ::WaitForSingleObject(m_hSignalOff, TIMEOUT * 1000);
                if (nStep3Ret == WAIT_TIMEOUT) {
                    m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
                    onTimeout();
                    goto RESET;
                }
                ResetEvent(m_hSignalOff);
                // 4.给对方写OFF
                nextStep();
                m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
                // 6.完成
                nextStep();
                if (0 == onComplete()) {
                    if (m_listener.onEvent != nullptr) {
                        m_listener.onEvent(this, STEP_EVENT_COMPLETE, nullptr);
                    }
                }
            }
        }
        if (hEvent != nullptr) {
            CloseHandle(hEvent);
        }
        // _endthreadex(0);
        TRACE("CStep::WorkingProc çº¿ç¨‹é€€å‡º\n");
        return 0;
    }
    void CStep::onSignal(BOOL bSignal)
    {
        Lock();
        if (m_nCurStep == 0 && bSignal) {
            SetEvent(m_hSignalOn);
        }
        else if (m_nCurStep == 3 && !bSignal) {
            SetEvent(m_hSignalOff);
        }
        Unlock();
    }
    int CStep::onReadData()
    {
        return 0;
    }
    int CStep::onComplete()
    {
        return 0;
    }
    int CStep::onTimeout()
    {
        return 0;
    }
    void CStep::resetStep()
    {
        Lock();
        m_nCurStep = 0;
        Unlock();
    }
    void CStep::nextStep()
    {
        Lock();
        m_nCurStep++;
        Unlock();
    }
    void CStep::convertString(const char* pszBuffer, int size, std::string& strOut)
SourceCode/Bond/Servo/CStep.h
@@ -19,7 +19,6 @@
        virtual ~CStep();
    public:
        unsigned WorkingProc();
        void setListener(StepListener listener);
        void setCcLink(CCCLinkIEControl* pCcLink);
        void setEquipment(CEquipment* pEquipment);
@@ -27,19 +26,13 @@
        void setName(const char* pszName);
        std::string& getName();
        virtual void getAttributeVector(CAttributeVector& attrubutes);
        virtual void setWriteSignalDev(int dev);
        virtual void init();
        virtual void CStep::term();
        virtual void onSignal(BOOL bSignal);
        virtual int onReadData();
        virtual int onComplete();
        virtual int onTimeout();
        virtual void term();
    protected:
        inline void Lock() { EnterCriticalSection(&m_criticalSection); }
        inline void Unlock() { LeaveCriticalSection(&m_criticalSection); }
        inline void nextStep();
        inline void resetStep();
        void convertString(const char* pszBuffer, int size, std::string& strOut);
    protected:
@@ -49,13 +42,6 @@
        CEquipment* m_pEquipment;
        CCCLinkIEControl* m_pCclink;
        CRITICAL_SECTION m_criticalSection;
        HANDLE m_hWorkThreadHandle;
        unsigned m_nWordThreadAddr;
        HANDLE m_hWorkStop;
        HANDLE m_hSignalOn;
        HANDLE m_hSignalOff;
        int m_nCurStep;
        int m_nWriteSignalDev;            // å¯¹æ–¹BIT地址
    };
}
SourceCode/Bond/Servo/CWriteStep.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,197 @@
#include "stdafx.h"
#include "CWriteStep.h"
#include "Common.h"
namespace SERVO {
#define TIMEOUT            15
    unsigned __stdcall WriteStepWorkThreadFunction(LPVOID lpParam)
    {
        CWriteStep* pStep = (CWriteStep*)lpParam;
        return pStep->WorkingProc();
    }
    CWriteStep::CWriteStep() : CStep()
    {
        m_nWordThreadAddr = 0;
        m_hWorkStop = nullptr;
        m_hWorkThreadHandle = nullptr;
        m_nCurStep = 0;
        m_nWriteSignalDev = 0;
        m_nWriteDataSize = 0;
        m_nWriteDevNo = 0;
        m_hWriteSignalOn = ::CreateEvent(NULL, TRUE, FALSE, NULL);
        m_hRecvSignalOn = ::CreateEvent(NULL, TRUE, FALSE, NULL);
    }
    CWriteStep::~CWriteStep()
    {
        ASSERT(m_hWriteSignalOn);
        CloseHandle(m_hWriteSignalOn);
        m_hWriteSignalOn = nullptr;
        ASSERT(m_hRecvSignalOn);
        CloseHandle(m_hRecvSignalOn);
        m_hRecvSignalOn = nullptr;
    }
    int CWriteStep::writeData(short devno, const char* pszData, int size)
    {
        if (size > 1024) return -1;
        if (m_nCurStep != 0) return -2;
        memcpy(m_szBuffer, pszData, size);
        m_nWriteDataSize = size;
        m_nWriteDevNo = devno;
        SetEvent(m_hWriteSignalOn);
        return 0;
    }
    void CWriteStep::setWriteSignalDev(int dev)
    {
        m_nWriteSignalDev = dev;
    }
    void CWriteStep::onRecvSignal(BOOL bSignal)
    {
        Lock();
        if (m_nCurStep == 3 && bSignal) {
            SetEvent(m_hRecvSignalOn);
        }
        Unlock();
    }
    unsigned CWriteStep::WorkingProc()
    {
        HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
        BOOL bReadOk = FALSE;
        int nBeginAddr = 0x0;
        while (1) {
        RESET:
            resetStep();
            // å¾…退出信号或时间到
            HANDLE hEvents[] = { m_hWorkStop, m_hWriteSignalOn };
            int nRet = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE);
            if (nRet == WAIT_OBJECT_0) {
                ResetEvent(m_hWorkStop);
                break;
            }
            else if (nRet == WAIT_OBJECT_0 + 1) {
                ResetEvent(m_hWriteSignalOn);
                // 1.写数据
                nextStep();
                ASSERT(m_pCclink);
                int nRet = m_pCclink->WriteData(m_station, (short)DeviceType::W,
                    m_nWriteDevNo, m_nWriteDataSize, (short*)m_szBuffer);
                if (0 != nRet) {
                    onTimeout();
                    goto RESET;
                }
                // 2.给对方写ON
                nextStep();
                m_pCclink->SetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
                // 3.等待对方ON
                nextStep();
                int nStep3Ret = ::WaitForSingleObject(m_hRecvSignalOn, TIMEOUT * 1000);
                if (nStep3Ret == WAIT_TIMEOUT) {
                    m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
                    onTimeout();
                    goto RESET;
                }
                ResetEvent(m_hRecvSignalOn);
                // 4.дOFF
                nextStep();
                m_pCclink->ResetBitDevice(m_station, DeviceType::B, m_nWriteSignalDev);
                // 6.完成
                nextStep();
                if (0 == onComplete()) {
                    if (m_listener.onEvent != nullptr) {
                        m_listener.onEvent(this, STEP_EVENT_COMPLETE, nullptr);
                    }
                }
            }
        }
        if (hEvent != nullptr) {
            CloseHandle(hEvent);
        }
        // _endthreadex(0);
        TRACE("CStep::WorkingProc çº¿ç¨‹é€€å‡º\n");
        return 0;
    }
    void CWriteStep::getAttributeVector(CAttributeVector& attrubutes)
    {
        CStep::getAttributeVector(attrubutes);
        attrubutes.addAttribute(new CAttribute("Current Step",
            std::to_string(m_nCurStep).c_str(), ""));
        attrubutes.addAttribute(new CAttribute("Signal Dev",
            std::to_string(m_nWriteSignalDev).c_str(), ""));
    }
    void CWriteStep::init()
    {
        CStep::init();
        if (m_hWorkStop != nullptr) return;
        m_hWorkStop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
        m_hWorkThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::WriteStepWorkThreadFunction, this,
            0, &m_nWordThreadAddr);
    }
    void CWriteStep::term()
    {
        CStep::term();
        ASSERT(m_hWorkStop);
        SetEvent(m_hWorkStop);
        if (m_hWorkThreadHandle != NULL) {
            WaitForSingleObject(m_hWorkThreadHandle, INFINITE);
            CloseHandle(m_hWorkThreadHandle);
            m_hWorkThreadHandle = NULL;
        }
        CloseHandle(m_hWorkStop);
        m_hWorkStop = NULL;
    }
    void CWriteStep::resetStep()
    {
        Lock();
        m_nCurStep = 0;
        Unlock();
    }
    void CWriteStep::nextStep()
    {
        Lock();
        m_nCurStep++;
        Unlock();
    }
    int CWriteStep::onComplete()
    {
        return 0;
    }
    int CWriteStep::onTimeout()
    {
        return 0;
    }
}
SourceCode/Bond/Servo/CWriteStep.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
#pragma once
#include "CStep.h"
namespace SERVO {
    class CWriteStep : public CStep
    {
    public:
        CWriteStep();
        virtual ~CWriteStep();
    public:
        unsigned WorkingProc();
        virtual void setWriteSignalDev(int dev);
        virtual void onRecvSignal(BOOL bSignal);
        int writeData(short devno, const char* pszData, int size);
        virtual void init();
        virtual void term();
        virtual void getAttributeVector(CAttributeVector& attrubutes);
        virtual int onComplete();
        virtual int onTimeout();
        inline void nextStep();
        inline void resetStep();
    protected:
        HANDLE m_hWorkThreadHandle;
        unsigned m_nWordThreadAddr;
        HANDLE m_hWorkStop;
        HANDLE m_hWriteSignalOn;
        HANDLE m_hRecvSignalOn;
        int m_nCurStep;
        int m_nWriteSignalDev;            // å¯¹æ–¹BIT地址
        char m_szBuffer[1024];
        int m_nWriteDataSize;
        int m_nWriteDevNo;
    };
}
SourceCode/Bond/Servo/Common.h
@@ -46,15 +46,16 @@
/* step name */
#define STEP_MODE            _T("EQMode")
#define STEP_STATUS            _T("EQStatus")
#define STEP_ALARM_START    _T("EQAlarm")
#define STEP_ALARM_BLOCK1    _T("EQAlarm1")
#define STEP_ALARM_BLOCK2    _T("EQAlarm2")
#define STEP_ALARM_BLOCK3    _T("EQAlarm3")
#define STEP_ALARM_BLOCK4    _T("EQAlarm4")
#define STEP_ALARM_BLOCK5    _T("EQAlarm5")
#define STEP_PROCESS        _T("EQProcess")
#define STEP_MODE                _T("EQMode")
#define STEP_STATUS                _T("EQStatus")
#define STEP_ALARM_START        _T("EQAlarm")
#define STEP_ALARM_BLOCK1        _T("EQAlarm1")
#define STEP_ALARM_BLOCK2        _T("EQAlarm2")
#define STEP_ALARM_BLOCK3        _T("EQAlarm3")
#define STEP_ALARM_BLOCK4        _T("EQAlarm4")
#define STEP_ALARM_BLOCK5        _T("EQAlarm5")
#define STEP_PROCESS            _T("EQProcess")
#define STEP_CIM_MODE_CHANGE    _T("EQCimModeChange")
#define BASE_ALARM_EFEM        10000
SourceCode/Bond/Servo/Servo.vcxproj
@@ -205,12 +205,15 @@
    <ClInclude Include="CCLinkPerformance\CCLinkIEControl.h" />
    <ClInclude Include="CCLinkPerformance\PerformanceMelsec.h" />
    <ClInclude Include="CEqAlarmStep.h" />
    <ClInclude Include="CEqCimModeChangeStep.h" />
    <ClInclude Include="CEqModeStep.h" />
    <ClInclude Include="CEqProcessStep.h" />
    <ClInclude Include="CEqStatusStep.h" />
    <ClInclude Include="CPanelAttributes.h" />
    <ClInclude Include="CPanelMaster.h" />
    <ClInclude Include="CReadStep.h" />
    <ClInclude Include="CStep.h" />
    <ClInclude Include="CWriteStep.h" />
    <ClInclude Include="DevicePropertyDlg.h" />
    <ClInclude Include="CEFEM.h" />
    <ClInclude Include="CEquipment.h" />
@@ -247,12 +250,15 @@
    <ClCompile Include="CCLinkPerformance\CCLinkIEControl.cpp" />
    <ClCompile Include="CCLinkPerformance\PerformanceMelsec.cpp" />
    <ClCompile Include="CEqAlarmStep.cpp" />
    <ClCompile Include="CEqCimModeChangeStep.cpp" />
    <ClCompile Include="CEqModeStep.cpp" />
    <ClCompile Include="CEqProcessStep.cpp" />
    <ClCompile Include="CEqStatusStep.cpp" />
    <ClCompile Include="CPanelAttributes.cpp" />
    <ClCompile Include="CPanelMaster.cpp" />
    <ClCompile Include="CReadStep.cpp" />
    <ClCompile Include="CStep.cpp" />
    <ClCompile Include="CWriteStep.cpp" />
    <ClCompile Include="DevicePropertyDlg.cpp" />
    <ClCompile Include="CEFEM.cpp" />
    <ClCompile Include="CEquipment.cpp" />
SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -48,6 +48,9 @@
    <ClCompile Include="VerticalLine.cpp" />
    <ClCompile Include="ApredTreeCtrl2.cpp" />
    <ClCompile Include="CPanelAttributes.cpp" />
    <ClCompile Include="CReadStep.cpp" />
    <ClCompile Include="CWriteStep.cpp" />
    <ClCompile Include="CEqCimModeChangeStep.cpp" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="AlarmManager.h" />
@@ -94,6 +97,9 @@
    <ClInclude Include="VerticalLine.h" />
    <ClInclude Include="ApredTreeCtrl2.h" />
    <ClInclude Include="CPanelAttributes.h" />
    <ClInclude Include="CReadStep.h" />
    <ClInclude Include="CWriteStep.h" />
    <ClInclude Include="CEqCimModeChangeStep.h" />
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="Servo.rc" />