From ab612c6fa43c9ae172572d187bf40da0386434d2 Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期三, 19 二月 2025 15:38:46 +0800
Subject: [PATCH] 1.增加CStep类,用于处理相似的CC-Link读取数据,回复等逻辑;

---
 SourceCode/Bond/Servo/DevicePropertyDlg.h   |   28 ++++
 SourceCode/Bond/Servo/Servo.vcxproj         |    2 
 SourceCode/Bond/Servo/DevicePropertyDlg.cpp |   79 +++++++++++
 SourceCode/Bond/Servo/Servo.vcxproj.filters |    2 
 SourceCode/Bond/Servo/CStep.h               |   35 +++++
 SourceCode/Bond/Servo/CEquipment.cpp        |   53 +++++++
 SourceCode/Bond/Servo/CMaster.cpp           |    8 +
 SourceCode/Bond/Servo/CEquipment.h          |    8 +
 SourceCode/Bond/Servo/CStep.cpp             |  159 ++++++++++++++++++++++
 9 files changed, 371 insertions(+), 3 deletions(-)

diff --git a/SourceCode/Bond/Servo/CEquipment.cpp b/SourceCode/Bond/Servo/CEquipment.cpp
index 5fe849f..33156a2 100644
--- a/SourceCode/Bond/Servo/CEquipment.cpp
+++ b/SourceCode/Bond/Servo/CEquipment.cpp
@@ -20,6 +20,11 @@
 
 	CEquipment::~CEquipment()
 	{
+		for (auto item : m_mapStep) {
+			delete item.second;
+		}
+		m_mapStep.clear();
+
 		DeleteCriticalSection(&m_criticalSection);
 	}
 
@@ -29,14 +34,37 @@
 		m_listener.onCimStateChanged = listener.onCimStateChanged;
 	}
 
+	CStep* CEquipment::getStep(unsigned int addr)
+	{
+		auto iter = m_mapStep.find(addr);
+		if (iter == m_mapStep.end()) return nullptr;
+		return iter->second;
+	}
+
+	int CEquipment::addStep(unsigned int addr, CStep* pStep)
+	{
+		auto iter = m_mapStep.find(addr);
+		if (iter != m_mapStep.end()) return -1;
+		m_mapStep[addr] = pStep;
+		return 0;
+	}
+
 	void CEquipment::init()
 	{
-
+		CStep* pStep = new CStep();
+		if (addStep(0x360, pStep) == 0) {
+			pStep->init();
+		}
+		else {
+			delete pStep;
+		}
 	}
 
 	void CEquipment::term()
 	{
-
+		for (auto item : m_mapStep) {
+			item.second->term();
+		}
 	}
 
 	void CEquipment::setID(int nID)
@@ -196,6 +224,27 @@
 		if (!equalBool(m_bVCREnable[0], bFlag)) {
 			m_bVCREnable[0] = bFlag;
 		}
+
+
+		// 以下根据信号做流程处理
+
+		// Equipment Mode Change Report
+		index = 0x360;
+		bFlag = isBitOn(pszData, size, ++index);
+		static int i;
+		i++;
+		if (i > 10) bFlag = TRUE;
+		if (i > 15) bFlag = FALSE;
+		if (i > 110) bFlag = TRUE;
+		if (i > 115) bFlag = FALSE;
+		//if (i == 12) bFlag = FALSE;
+		CStep* pStep = getStep(0x360);
+		if (pStep != nullptr) {
+			pStep->onSignal(bFlag);
+		}
+
+
+
 	}
 
 	BOOL CEquipment::isBitOn(const char* pszData, size_t size, int index)
diff --git a/SourceCode/Bond/Servo/CEquipment.h b/SourceCode/Bond/Servo/CEquipment.h
index 90774cd..765467c 100644
--- a/SourceCode/Bond/Servo/CEquipment.h
+++ b/SourceCode/Bond/Servo/CEquipment.h
@@ -1,6 +1,9 @@
 #pragma once
 #include "Log.h"
 #include "CCLinkIEControl.h"
+#include "CStep.h"
+#include <map>
+
 
 namespace SERVO {
 #define BLOCK_BUFFER_MAX			1024
@@ -52,6 +55,8 @@
 		MemoryBlock& getReadBitBlock();
 		void setWriteBitBlock(unsigned int start, unsigned int end);
 		MemoryBlock& getWriteBitBlock();
+		int addStep(unsigned int addr, CStep* pStep);
+		CStep* getStep(unsigned int addr);
 		virtual void init();
 		virtual void term();
 		virtual void onTimer(UINT nTimerid);
@@ -97,6 +102,9 @@
 		BOOL m_bLocalAlarm;
 		BOOL m_bAutoRecipeChange;
 		BOOL m_bVCREnable[VCR_MAX];
+
+	private:
+		std::map<unsigned int, CStep*> m_mapStep;
 	};
 }
 
diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index e2d3f3c..51f34a6 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/SourceCode/Bond/Servo/CMaster.cpp
@@ -38,7 +38,6 @@
 		// 	cclink
 		if (m_cclink.Connect(CC_LINK_IE_CONTROL_CHANNEL(1)) != 0) {
 			LOGE("连接CC-Link失败.");
-			return -1;
 		}
 		else {
 			LOGI("连接CC-Link成功.");
@@ -71,6 +70,8 @@
 			pEquipment->setReadBitBlock(0x4000, 0x45ff);
 			pEquipment->setStation(1, 2);
 			addEquipment(pEquipment);
+
+			pEquipment->init();
 			LOGE("已添加“EFEM(ROBOT)”.");
 		}
 		/*
@@ -96,6 +97,11 @@
 
 	int CMaster::term()
 	{
+		LOGI("<Master>正在结束程序.");
+		for (auto item : m_listEquipment) {
+			item->term();
+		}
+
 		return 0;
 	}
 
diff --git a/SourceCode/Bond/Servo/CStep.cpp b/SourceCode/Bond/Servo/CStep.cpp
new file mode 100644
index 0000000..6f98ac8
--- /dev/null
+++ b/SourceCode/Bond/Servo/CStep.cpp
@@ -0,0 +1,159 @@
+#include "stdafx.h"
+#include "CStep.h"
+
+
+namespace SERVO {
+#define TIMEOUT			15
+
+	unsigned __stdcall StepWorkThreadFunction(LPVOID lpParam)
+	{
+		CStep* pScale = (CStep*)lpParam;
+		return pScale->WorkingProc();
+	}
+
+	CStep::CStep()
+	{
+		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;
+		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);
+	}
+
+	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();
+				TRACE("m_nCurStep:%d\n", m_nCurStep);
+
+
+				// 2.给对方写ON
+				nextStep();
+				TRACE("m_nCurStep:%d\n", m_nCurStep);
+
+
+				// 3.等待对方OFF
+				nextStep();
+				TRACE("m_nCurStep:%d\n", m_nCurStep);
+				int nStep3Ret = ::WaitForSingleObject(m_hSignalOff, TIMEOUT * 1000);
+				if (nStep3Ret == WAIT_TIMEOUT) {
+					timeout();
+					goto RESET;
+				}
+				ResetEvent(m_hSignalOff);
+
+
+				// 4.给对方写OFF
+				nextStep();
+				TRACE("m_nCurStep:%d\n", m_nCurStep);
+
+
+				// 5.对接CIM等
+				nextStep();
+				TRACE("m_nCurStep:%d\n", m_nCurStep);
+
+
+				// 6.完成
+				nextStep();
+				TRACE("m_nCurStep:%d\n", m_nCurStep);
+			}
+		}
+
+		if (hEvent != nullptr) {
+			CloseHandle(hEvent);
+		}
+
+		// _endthreadex(0);
+		TRACE("CStep::WorkingProc 线程退出\n");
+		return 0;
+	}
+
+	void CStep::onSignal(BOOL bSignal)
+	{
+		TRACE(">>>>>>>>>>>>>>>>>>>> setSignal:%s\n", bSignal ? "ON" : "OFF");
+		Lock();
+		if (m_nCurStep == 0 && bSignal) {
+			SetEvent(m_hSignalOn);
+		}
+		else if (m_nCurStep == 3 && !bSignal) {
+			SetEvent(m_hSignalOff);
+		}
+
+		Unlock();
+	}
+
+	void CStep::resetStep()
+	{
+		Lock();
+		m_nCurStep = 0;
+		Unlock();
+	}
+
+	void CStep::nextStep()
+	{
+		Lock();
+		m_nCurStep++;
+		Unlock();
+	}
+
+	void CStep::timeout()
+	{
+		TRACE(">>>>>>>>>>>>>>>> timeout:%d\n", m_nCurStep);
+	}
+}
+
diff --git a/SourceCode/Bond/Servo/CStep.h b/SourceCode/Bond/Servo/CStep.h
new file mode 100644
index 0000000..6c4bb0f
--- /dev/null
+++ b/SourceCode/Bond/Servo/CStep.h
@@ -0,0 +1,35 @@
+#pragma once
+
+
+namespace SERVO {
+	class CStep
+	{
+	public:
+		CStep();
+		virtual ~CStep();
+
+	public:
+		unsigned WorkingProc();
+		virtual void init();
+		virtual void CStep::term();
+		virtual void onSignal(BOOL bSignal);
+
+	protected:
+		inline void Lock() { EnterCriticalSection(&m_criticalSection); }
+		inline void Unlock() { LeaveCriticalSection(&m_criticalSection); }
+		inline void nextStep();
+		inline void resetStep();
+		void timeout();
+
+	private:
+		CRITICAL_SECTION m_criticalSection;
+		std::string strName;
+		HANDLE m_hWorkThreadHandle;
+		unsigned m_nWordThreadAddr;
+		HANDLE m_hWorkStop;
+		HANDLE m_hSignalOn;
+		HANDLE m_hSignalOff;
+		int m_nCurStep;
+	};
+}
+
diff --git a/SourceCode/Bond/Servo/DevicePropertyDlg.cpp b/SourceCode/Bond/Servo/DevicePropertyDlg.cpp
new file mode 100644
index 0000000..8a115d2
--- /dev/null
+++ b/SourceCode/Bond/Servo/DevicePropertyDlg.cpp
@@ -0,0 +1,79 @@
+锘�// CDevicePropertyDlg.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "stdafx.h"
+#include "Servo.h"
+#include "afxdialogex.h"
+#include "DevicePropertyDlg.h"
+
+// CDevicePropertyDlg 瀵硅瘽妗�
+
+IMPLEMENT_DYNAMIC(CDevicePropertyDlg, CDialogEx)
+
+CDevicePropertyDlg::CDevicePropertyDlg(CWnd* pParent /*=nullptr*/, int nDeviceID /*=0*/)
+	: CDialogEx(IDD_DIALOG_DEVICE_PROPERTY, pParent), m_nDeviceID(nDeviceID)
+{
+
+}
+
+CDevicePropertyDlg::~CDevicePropertyDlg()
+{
+}
+
+void CDevicePropertyDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+	DDX_Control(pDX, IDC_LIST_DEVICE_PROPERTY, m_listDeviceProperties);
+}
+
+
+BEGIN_MESSAGE_MAP(CDevicePropertyDlg, CDialogEx)
+END_MESSAGE_MAP()
+
+
+// CDevicePropertyDlg 娑堟伅澶勭悊绋嬪簭
+
+
+BOOL CDevicePropertyDlg::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+	// TODO:  鍦ㄦ娣诲姞棰濆鐨勫垵濮嬪寲
+	SERVO::CEquipment* pEquipment = theApp.m_model.m_master.getEquipment(m_nDeviceID);
+	if (nullptr == pEquipment) {
+		LOGI("<璁惧ID锛�%d>鑾峰彇璁惧灞炴�уけ璐ャ��", m_nDeviceID);
+		return FALSE;
+	}
+
+	// 淇敼瀵硅瘽妗嗘爣棰�
+	std::string strDeviceName = pEquipment->getName();
+	SetWindowText(CString(strDeviceName.c_str()));
+
+	// 鑾峰彇鎵�鏈夎澶囧睘鎬�
+	std::vector<std::pair<std::string, std::string>> properties;
+	//pEquipment->getProperties(properties);
+
+	// 鑾峰彇ListCtrl鐨勫鎴峰尯鍩�
+	CRect rect;
+	m_listDeviceProperties.GetClientRect(&rect);  
+	int nTotalWidth = rect.Width();
+
+	int nColumnWidth = 150;
+	m_listDeviceProperties.InsertColumn(0, _T("鍚嶇О"), LVCFMT_LEFT, nColumnWidth);
+	m_listDeviceProperties.InsertColumn(1, _T("鍊�"), LVCFMT_LEFT, nColumnWidth);
+
+	// 閬嶅巻瀹瑰櫒涓殑鎵�鏈夊睘鎬у苟杈撳嚭
+	int nItem = 0;
+	for (const auto& property : properties) {
+		// 鎻掑叆璁惧灞炴��
+		m_listDeviceProperties.InsertItem(nItem, property.first.c_str());
+		m_listDeviceProperties.SetItemText(nItem, 1, property.second.c_str());
+		++nItem;
+	}
+
+	// 璁剧疆绗簩鍒楀搴�
+	m_listDeviceProperties.SetColumnWidth(1, nTotalWidth - nColumnWidth);
+
+	return TRUE;  // return TRUE unless you set the focus to a control
+	// 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
+}
diff --git a/SourceCode/Bond/Servo/DevicePropertyDlg.h b/SourceCode/Bond/Servo/DevicePropertyDlg.h
new file mode 100644
index 0000000..39bdec3
--- /dev/null
+++ b/SourceCode/Bond/Servo/DevicePropertyDlg.h
@@ -0,0 +1,28 @@
+锘�#pragma once
+#include "afxdialogex.h"
+
+
+// CDevicePropertyDlg 瀵硅瘽妗�
+
+class CDevicePropertyDlg : public CDialogEx
+{
+	DECLARE_DYNAMIC(CDevicePropertyDlg)
+
+public:
+	CDevicePropertyDlg(CWnd* pParent = nullptr, int nDeviceID = 0);   // 鏍囧噯鏋勯�犲嚱鏁�
+	virtual ~CDevicePropertyDlg();
+
+// 瀵硅瘽妗嗘暟鎹�
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_DIALOG_DEVICE_PROPERTY };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 鏀寔
+	virtual BOOL OnInitDialog();
+	DECLARE_MESSAGE_MAP()
+
+private:
+	int m_nDeviceID;
+	CListCtrl m_listDeviceProperties;
+};
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj b/SourceCode/Bond/Servo/Servo.vcxproj
index 667194d..1668acb 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj
+++ b/SourceCode/Bond/Servo/Servo.vcxproj
@@ -200,6 +200,7 @@
     <ClInclude Include="CBonder.h" />
     <ClInclude Include="CCLinkPerformance\CCLinkIEControl.h" />
     <ClInclude Include="CCLinkPerformance\PerformanceMelsec.h" />
+    <ClInclude Include="CStep.h" />
     <ClInclude Include="DevicePropertyDlg.h" />
     <ClInclude Include="CEFEM.h" />
     <ClInclude Include="CEquipment.h" />
@@ -230,6 +231,7 @@
     <ClCompile Include="CBonder.cpp" />
     <ClCompile Include="CCLinkPerformance\CCLinkIEControl.cpp" />
     <ClCompile Include="CCLinkPerformance\PerformanceMelsec.cpp" />
+    <ClCompile Include="CStep.cpp" />
     <ClCompile Include="DevicePropertyDlg.cpp" />
     <ClCompile Include="CEFEM.cpp" />
     <ClCompile Include="CEquipment.cpp" />
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj.filters b/SourceCode/Bond/Servo/Servo.vcxproj.filters
index 71c9a87..b6912df 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj.filters
+++ b/SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -36,6 +36,7 @@
     <ClCompile Include="CEFEM.cpp" />
     <ClCompile Include="ToolUnits.cpp" />
     <ClCompile Include="DevicePropertyDlg.cpp" />
+    <ClCompile Include="CStep.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="AlarmManager.h" />
@@ -70,6 +71,7 @@
     <ClInclude Include="CEFEM.h" />
     <ClInclude Include="ToolUnits.h" />
     <ClInclude Include="DevicePropertyDlg.h" />
+    <ClInclude Include="CStep.h" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="Servo.rc" />

--
Gitblit v1.9.3