From e937700184e21d263b771921b269fbdda341dfc4 Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期二, 27 五月 2025 14:39:40 +0800
Subject: [PATCH] 1.master调试线程实现,状态,运行时间等;
---
SourceCode/Bond/Servo/CMyStatusbar.h | 4
SourceCode/Bond/Servo/CMaster.cpp | 131 ++++++++++++++++++++++++++++++++
SourceCode/Bond/Servo/CMyStatusbar.cpp | 11 ++
SourceCode/Bond/Servo/CMaster.h | 28 +++++++
SourceCode/Bond/Servo/Model.cpp | 4 +
SourceCode/Bond/Servo/ServoDlg.cpp | 46 +++++++++--
SourceCode/Bond/Servo/Common.h | 1
SourceCode/Bond/Servo/ServoDlg.h | 2
8 files changed, 210 insertions(+), 17 deletions(-)
diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index 79e3277..9cdef60 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/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);
+ }
+ }
}
diff --git a/SourceCode/Bond/Servo/CMaster.h b/SourceCode/Bond/Servo/CMaster.h
index 2a0286b..be53515 100644
--- a/SourceCode/Bond/Servo/CMaster.h
+++ b/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;
};
}
diff --git a/SourceCode/Bond/Servo/CMyStatusbar.cpp b/SourceCode/Bond/Servo/CMyStatusbar.cpp
index 1d85905..d85b341 100644
--- a/SourceCode/Bond/Servo/CMyStatusbar.cpp
+++ b/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) {
diff --git a/SourceCode/Bond/Servo/CMyStatusbar.h b/SourceCode/Bond/Servo/CMyStatusbar.h
index 283ca03..3ac6fee 100644
--- a/SourceCode/Bond/Servo/CMyStatusbar.h
+++ b/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;
diff --git a/SourceCode/Bond/Servo/Common.h b/SourceCode/Bond/Servo/Common.h
index 361ce0d..8b7e4c0 100644
--- a/SourceCode/Bond/Servo/Common.h
+++ b/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 */
diff --git a/SourceCode/Bond/Servo/Model.cpp b/SourceCode/Bond/Servo/Model.cpp
index 959277e..c991c64 100644
--- a/SourceCode/Bond/Servo/Model.cpp
+++ b/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"));
diff --git a/SourceCode/Bond/Servo/ServoDlg.cpp b/SourceCode/Bond/Servo/ServoDlg.cpp
index 69a0d76..6ce2bf0 100644
--- a/SourceCode/Bond/Servo/ServoDlg.cpp
+++ b/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;
}
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/ServoDlg.h b/SourceCode/Bond/Servo/ServoDlg.h
index 774cb22..a281b1c 100644
--- a/SourceCode/Bond/Servo/ServoDlg.h
+++ b/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;
--
Gitblit v1.9.3