LAPTOP-SNT8I5JK\Boounion
2025-05-27 e937700184e21d263b771921b269fbdda341dfc4
1.master调试线程实现,状态,运行时间等;
已修改8个文件
227 ■■■■■ 文件已修改
SourceCode/Bond/Servo/CMaster.cpp 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.h 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMyStatusbar.cpp 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMyStatusbar.h 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Common.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Model.cpp 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ServoDlg.cpp 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ServoDlg.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.cpp
@@ -6,6 +6,15 @@
namespace SERVO {
    CMaster* g_pMaster = NULL;
    unsigned __stdcall DispatchThreadFunction(LPVOID lpParam)
    {
        if (g_pMaster != NULL) {
            return g_pMaster->DispatchProc();
        }
        return 0;
    }
    unsigned __stdcall ReadBitsThreadFunction(LPVOID lpParam)
    {
        if (g_pMaster != NULL) {
@@ -24,12 +33,21 @@
    CMaster::CMaster()
    {
        m_listener = {nullptr, nullptr, nullptr, nullptr, nullptr};
        m_listener = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
        m_bDataModify = FALSE;
        m_hEventReadBitsThreadExit[0] = ::CreateEvent(NULL, TRUE, FALSE, NULL);
        m_hEventReadBitsThreadExit[1] = ::CreateEvent(NULL, TRUE, FALSE, NULL);
        m_hReadBitsThreadHandle = nullptr;
        m_nReadBitsThreadAddr = 0;
        m_hDispatchEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
        m_hEventDispatchThreadExit[0] = ::CreateEvent(NULL, TRUE, FALSE, NULL);
        m_hEventDispatchThreadExit[1] = ::CreateEvent(NULL, TRUE, FALSE, NULL);
        m_hDispatchThreadHandle = nullptr;
        m_nDispatchThreadAddr = 0;
        m_ullStartTime = 0;
        m_ullRunTime = 0;
        m_state = MASTERSTATE::READY;
        InitializeCriticalSection(&m_criticalSection);
    }
    CMaster::~CMaster()
@@ -43,10 +61,28 @@
            ::CloseHandle(m_hEventReadBitsThreadExit[1]);
            m_hEventReadBitsThreadExit[1] = nullptr;
        }
        if (m_hDispatchEvent != nullptr) {
            ::CloseHandle(m_hDispatchEvent);
            m_hDispatchEvent = nullptr;
        }
        if (m_hEventDispatchThreadExit[0] != nullptr) {
            ::CloseHandle(m_hEventDispatchThreadExit[0]);
            m_hEventDispatchThreadExit[0] = nullptr;
        }
        if (m_hEventDispatchThreadExit[1] != nullptr) {
            ::CloseHandle(m_hEventDispatchThreadExit[1]);
            m_hEventDispatchThreadExit[1] = nullptr;
        }
        DeleteCriticalSection(&m_criticalSection);
    }
    void CMaster::setListener(MasterListener listener)
    {
        m_listener.onMasterStateChanged = listener.onMasterStateChanged;
        m_listener.onEqAlive = listener.onEqAlive;
        m_listener.onEqCimStateChanged = listener.onEqCimStateChanged;
        m_listener.onEqAlarm = listener.onEqAlarm;
@@ -159,6 +195,12 @@
        SetTimer(NULL, 1, 250, (TIMERPROC)MasterTimerProc);
        // 调度线程
        m_hDispatchThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::DispatchThreadFunction, this,
            0, &m_nDispatchThreadAddr);
        // 监控bit线程
        m_hReadBitsThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::ReadBitsThreadFunction, this,
            0, &m_nReadBitsThreadAddr);
@@ -170,7 +212,9 @@
    int CMaster::term()
    {
        SetEvent(m_hEventReadBitsThreadExit[0]);
        SetEvent(m_hEventDispatchThreadExit[0]);
        ::WaitForSingleObject(m_hEventReadBitsThreadExit[1], INFINITE);
        ::WaitForSingleObject(m_hEventDispatchThreadExit[1], INFINITE);
        LOGI("<Master>正在结束程序.");
        for (auto item : m_listEquipment) {
@@ -190,13 +234,86 @@
    int CMaster::start()
    {
        AfxMessageBox("start");
        if (m_state != MASTERSTATE::READY) {
            return -1;
        }
        setState(MASTERSTATE::STARTING);
        m_ullStartTime = GetTickCount64();
        return 0;
    }
    int CMaster::stop()
    {
        AfxMessageBox("stop");
        // 运行时间为累加结果,本次停止时刷新;
        if (m_state != MASTERSTATE::RUNNING) {
            return -1;
        }
        m_ullRunTime += (GetTickCount64() - m_ullStartTime);
        setState(MASTERSTATE::STOPPING);
        return 0;
    }
    ULONGLONG CMaster::getRunTime()
    {
        if (m_state == MASTERSTATE::RUNNING)
            return m_ullRunTime + (GetTickCount64() - m_ullStartTime);
        else
            return m_ullRunTime;
    }
    MASTERSTATE CMaster::getState()
    {
        return m_state;
    }
    unsigned CMaster::DispatchProc()
    {
        while (1) {
            // 待退出信号或时间到
            HANDLE hEvents[] = { m_hEventDispatchThreadExit[0], m_hDispatchEvent };
            int nRet = WaitForMultipleObjects(2, hEvents, FALSE, 1000);
            if (nRet == WAIT_OBJECT_0) {
                break;
            }
            // 如果状态为STARTING,开始工作并切换到RUNNING状态
            lock();
            if (m_state == MASTERSTATE::STARTING) {
                unlock();
                Sleep(1000);
                setState(MASTERSTATE::RUNNING);
                continue;
            }
            // 处理完成当前事务后,切换到停止或就绪状态
            else if (m_state == MASTERSTATE::STOPPING) {
                unlock();
                Sleep(1000);
                setState(MASTERSTATE::READY);
                continue;
            }
            // 调度逻辑处理
            else if (m_state == MASTERSTATE::RUNNING) {
                unlock();
                LOGI("调度处理中...");
                Sleep(1000);
            }
            unlock();
        }
        SetEvent(m_hEventDispatchThreadExit[1]);
        // _endthreadex(0);
        TRACE("CMaster::DispatchProc 线程退出\n");
        return 0;
    }
@@ -668,4 +785,12 @@
            item->serialize(ar);
        }
    }
    void CMaster::setState(MASTERSTATE state)
    {
        m_state = state;
        if (m_listener.onMasterStateChanged != nullptr) {
            m_listener.onMasterStateChanged(this, m_state);
        }
    }
}
SourceCode/Bond/Servo/CMaster.h
@@ -15,6 +15,14 @@
namespace SERVO {
    enum MASTERSTATE {
        READY = 0,
        STARTING,
        RUNNING,
        STOPPING
    };
    typedef std::function<void(void* pMaster, MASTERSTATE state)> ONMASTERSTATECHANGED;
    typedef std::function<void(void* pMaster, CEquipment* pEiuipment, BOOL bAlive)> ONEQALIVE;
    typedef std::function<void(CStep* pStep, int code, void* pData)> ONEQSTEPEVENT;
    typedef std::function<void(void* pMaster, CEquipment* pEquipment, int state, int alarmId, int unitId, int level)> ONEQALARM;
@@ -22,6 +30,7 @@
    typedef std::function<void(void* pMaster, CEquipment* pEquipment, int code)> ONEQDATACHANGED;
    typedef struct _MasterListener
    {
        ONMASTERSTATECHANGED    onMasterStateChanged;
        ONEQALIVE                onEqAlive;
        ONEQALIVE                onEqCimStateChanged;
        ONEQALARM               onEqAlarm;
@@ -42,6 +51,9 @@
        int term();
        int start();
        int stop();
        ULONGLONG getRunTime();
        MASTERSTATE getState();
        unsigned DispatchProc();
        unsigned ReadBitsProc();
        void onTimer(UINT nTimerid);
        std::list<CEquipment*>& getEquipmentList();
@@ -49,6 +61,8 @@
        void setCacheFilepath(const char* pszFilepath);
    private:
        inline void lock() { EnterCriticalSection(&m_criticalSection); }
        inline void unlock() { LeaveCriticalSection(&m_criticalSection); }
        int addToEquipmentList(CEquipment* pEquipment);
        CLoadPort* addLoadPort(int index);
        CFliper* addFliper();
@@ -65,8 +79,10 @@
        int saveCacheAndBackups();
        int readCache();
        void serialize(CArchive& ar);
        void setState(MASTERSTATE state);
    private:
        CRITICAL_SECTION m_criticalSection;
        MasterListener m_listener;
        CCCLinkIEControl m_cclink;
        std::list<CEquipment*> m_listEquipment;
@@ -74,9 +90,21 @@
        BOOL m_bDataModify;
    private:
        /* 监控比特位的线程*/
        HANDLE m_hEventReadBitsThreadExit[2];
        HANDLE m_hReadBitsThreadHandle;
        unsigned m_nReadBitsThreadAddr;
        // 调度线程
        HANDLE m_hDispatchEvent;
        HANDLE m_hEventDispatchThreadExit[2];
        HANDLE m_hDispatchThreadHandle;
        unsigned m_nDispatchThreadAddr;
        // 启动时间,运行时间,状态
        ULONGLONG m_ullStartTime;
        ULONGLONG m_ullRunTime;
        MASTERSTATE m_state;
    };
}
SourceCode/Bond/Servo/CMyStatusbar.cpp
@@ -37,7 +37,7 @@
// CMyStatusbar 消息处理程序
void CMyStatusbar::setBkgnd(COLORREF color)
void CMyStatusbar::setBackgroundColor(COLORREF color)
{
    if (m_brBkgnd.GetSafeHandle() != nullptr) {
        m_brBkgnd.DeleteObject();
@@ -45,6 +45,13 @@
    m_brBkgnd.CreateSolidBrush(color);
    Invalidate(); 
    UpdateWindow();
}
void CMyStatusbar::setForegroundColor(COLORREF cr)
{
    m_crForeground = cr;
    Invalidate();
    UpdateWindow();
}
@@ -72,7 +79,7 @@
    if (nCtlColor == CTLCOLOR_STATIC) {
        pDC->SetBkMode(TRANSPARENT);
        pDC->SetBkColor(m_crBkgnd);
        pDC->SetTextColor(RGB(255, 255, 255));
        pDC->SetTextColor(m_crForeground);
    }
    if (m_brBkgnd.GetSafeHandle() == nullptr) {
SourceCode/Bond/Servo/CMyStatusbar.h
@@ -13,13 +13,15 @@
public:
    void setBkgnd(COLORREF color);
    void setBackgroundColor(COLORREF color);
    void setForegroundColor(COLORREF cr);
    void setRunTimeText(const char* pszText);
private:
    void Resize();
private:
    COLORREF m_crForeground;
    COLORREF m_crBkgnd;
    CBrush m_brBkgnd;
SourceCode/Bond/Servo/Common.h
@@ -16,6 +16,7 @@
#define RX_CODE_ALARM_SET                1008
#define RX_CODE_ALARM_CLEAR                1009
#define RX_CODE_EQ_DATA_CHANGED            1010
#define RX_CODE_MASTER_STATE_CHANGED    1011
/* Channel Name */
SourceCode/Bond/Servo/Model.cpp
@@ -103,6 +103,10 @@
    SERVO::MasterListener masterListener;
    masterListener.onMasterStateChanged = [&](void* pMaster, SERVO::MASTERSTATE state) -> void {
        LOGI("<CModel>Master state changed(%d)", (int)state);
        notify(RX_CODE_MASTER_STATE_CHANGED);
    };
    masterListener.onEqAlive = [&](void* pMaster, SERVO::CEquipment* pEquipment, BOOL bAlive) -> void {
        LOGI("<CModel>Equipment onAlive:%s(%s).\n", pEquipment->getName().c_str(),
            bAlive ? _T("ON") : _T("OFF"));
SourceCode/Bond/Servo/ServoDlg.cpp
@@ -169,6 +169,22 @@
                    }
                }
            }
            else if (RX_CODE_MASTER_STATE_CHANGED == code) {
                SERVO::MASTERSTATE state = theApp.m_model.getMaster().getState();
                if (state == SERVO::MASTERSTATE::READY) {
                    m_pMyStatusbar->setBackgroundColor(STATUSBAR_BK_NORMAL);
                    m_pMyStatusbar->setForegroundColor(RGB(0, 0, 0));
                    KillTimer(TIMER_ID_UPDATE_RUMTIME);
                    CString strText;
                    GetRuntimeFormatText(strText, "");
                    m_pMyStatusbar->setRunTimeText((LPTSTR)(LPCTSTR)strText);
                }
                else if (state == SERVO::MASTERSTATE::RUNNING) {
                    m_pMyStatusbar->setBackgroundColor(STATUSBAR_BK_RUNNING);
                    m_pMyStatusbar->setForegroundColor(RGB(255, 255, 255));
                    SetTimer(TIMER_ID_UPDATE_RUMTIME, 500, nullptr);
                }
            }
            pAny->release();
        }, [&]() -> void {
@@ -704,12 +720,8 @@
        if (index >= 4) index = 0;
        static char* status[] = {"|", "/", "--", "\\"};
        CTime time = CTime::GetCurrentTime();
        CString strText;
        strText.Format(_T("已运行:%d-%02d-%02d %02d:%02d:%02d   %s"),
            time.GetYear(), time.GetMonth(), time.GetDay(),
            time.GetHour(), time.GetMinute(), time.GetSecond(),
            status[index]);
        GetRuntimeFormatText(strText, status[index]);
        m_pMyStatusbar->setRunTimeText((LPTSTR)(LPCTSTR)strText);
    }
@@ -750,16 +762,11 @@
        theApp.m_model.getMaster().start();
        m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(FALSE);
        m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(TRUE);
        m_pMyStatusbar->setBkgnd(STATUSBAR_BK_RUNNING);
        SetTimer(TIMER_ID_UPDATE_RUMTIME, 1000, nullptr);
    }
    else if (id == IDC_BUTTON_STOP) {
        theApp.m_model.getMaster().stop();
        m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(TRUE);
        m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(FALSE);
        m_pMyStatusbar->setBkgnd(STATUSBAR_BK_ALARM);
        KillTimer(TIMER_ID_UPDATE_RUMTIME);
    }
    else if (id == IDC_BUTTON_ROBOT) {
        SERVO::CEFEM* pEFEM = (SERVO::CEFEM*)theApp.m_model.getMaster().getEquipment(EQ_ID_EFEM);
@@ -768,4 +775,23 @@
        dlg.DoModal();
    }
    return 0;
}
CString& CServoDlg::GetRuntimeFormatText(CString& strText, const char* pszSuffix)
{
    ULONGLONG ullRunTime = (ULONGLONG)(theApp.m_model.getMaster().getRunTime() * 0.001);
    int h, m, s;
    h = int(ullRunTime / 3600);
    m = int((ullRunTime % 3600) / 60);
    s = int(ullRunTime % 60);
    SERVO::MASTERSTATE state = theApp.m_model.getMaster().getState();
    if (state == SERVO::MASTERSTATE::RUNNING) {
        strText.Format(_T("正在运行:%02d:%02d:%02d   %s"), h, m, s, pszSuffix);
    }
    else {
        strText.Format(_T("已运行:%02d:%02d:%02d   %s"), h, m, s, pszSuffix);
    }
    return strText;
}
SourceCode/Bond/Servo/ServoDlg.h
@@ -32,7 +32,7 @@
    void InitRxWindows();
    void Resize();
    void ShowChildPage(int index);
    CString& GetRuntimeFormatText(CString& strText, const char* pszSuffix);
private:
    IObserver* m_pObserver;