| SourceCode/Bond/Servo/CMaster.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/Servo/CMaster.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/Servo/CMyStatusbar.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/Servo/CMyStatusbar.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/Servo/Common.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/Servo/Model.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/Servo/ServoDlg.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/Servo/ServoDlg.h | ●●●●● 补丁 | 查看 | 原始文档 | 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,13 +37,20 @@ // CMyStatusbar 消息处理程序 void CMyStatusbar::setBkgnd(COLORREF color) void CMyStatusbar::setBackgroundColor(COLORREF color) { if (m_brBkgnd.GetSafeHandle() != nullptr) { m_brBkgnd.DeleteObject(); } 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); @@ -769,3 +776,22 @@ } 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;