From 38fdd2e7d1d45a3ffed57fde30031a6a8f04d235 Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期一, 05 五月 2025 18:02:20 +0800
Subject: [PATCH] 1.获取配方列表,已处理待测试。
---
SourceCode/Bond/Servo/CPageGraph2.cpp | 14 +
SourceCode/Bond/Servo/Servo.vcxproj | 4
SourceCode/Bond/Servo/Servo.vcxproj.filters | 4
SourceCode/Bond/Servo/CRecipesManager.cpp | 187 ++++++++++++++++++++++++++
SourceCode/Bond/Servo/CEquipment.cpp | 11 +
SourceCode/Bond/Servo/CRecipeList.cpp | 81 +++++++++++
SourceCode/Bond/Servo/CEquipment.h | 3
SourceCode/Bond/Servo/CBonder.cpp | 2
SourceCode/Bond/Servo/CRecipeList.h | 27 +++
SourceCode/Bond/Servo/CRecipesManager.h | 42 ++++++
SourceCode/Bond/Servo/Common.h | 18 ++
11 files changed, 389 insertions(+), 4 deletions(-)
diff --git a/SourceCode/Bond/Servo/CBonder.cpp b/SourceCode/Bond/Servo/CBonder.cpp
index 5276f30..1652925 100644
--- a/SourceCode/Bond/Servo/CBonder.cpp
+++ b/SourceCode/Bond/Servo/CBonder.cpp
@@ -188,7 +188,9 @@
[&](int code, const char* pszData, size_t size) -> int {
if (code == ROK && pszData != nullptr && size > 0) {
// 此处解释配方数据
+ return decodeRecipeListReport(pszData, size);
}
+ return -1;
});
pStep->setName(STEP_EQ_MASTER_RECIPE_LIST);
pStep->setWriteSignalDev(m_nIndex == 0 ? 0x34b : 0x64b);
diff --git a/SourceCode/Bond/Servo/CEquipment.cpp b/SourceCode/Bond/Servo/CEquipment.cpp
index aaf7662..054457f 100644
--- a/SourceCode/Bond/Servo/CEquipment.cpp
+++ b/SourceCode/Bond/Servo/CEquipment.cpp
@@ -887,11 +887,15 @@
}
LOGI("<CEquipment-%s>正在请求单元<%d>主配方列表", m_strName.c_str(), unitNo);
- pStep->writeShort(unitNo, [&](int code) -> int {
+ if (m_recipesManager.syncing() != 0) {
+ return -2;
+ }
+ pStep->writeShort(unitNo, [&, unitNo](int code) -> int {
if (code == WOK) {
LOGI("<CEquipment-%s>请求单元<%d>主配方列表成功,正在等待数据.", m_strName.c_str(), unitNo);
}
else {
+ //m_recipesManager.syncFailed();
LOGI("<CEquipment-%s>请求单元<%d>主配方列表失败,code:%d", m_strName.c_str(), unitNo, code);
}
@@ -899,4 +903,9 @@
});
return 0;
}
+
+ int CEquipment::decodeRecipeListReport(const char* pszData, size_t size)
+ {
+ return m_recipesManager.decodeRecipeListReport(pszData, size);
+ }
}
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/CEquipment.h b/SourceCode/Bond/Servo/CEquipment.h
index e16140a..1e6d326 100644
--- a/SourceCode/Bond/Servo/CEquipment.h
+++ b/SourceCode/Bond/Servo/CEquipment.h
@@ -26,6 +26,7 @@
#include <map>
#include <list>
#include "CGlass.h"
+#include "CRecipesManager.h"
namespace SERVO {
@@ -149,6 +150,7 @@
BOOL isBitOn(const char* pszData, size_t size, int index);
inline BOOL equalBool(BOOL b1, BOOL b2);
void addGlassToList(CGlass* pGlass);
+ int decodeRecipeListReport(const char* pszData, size_t size);
protected:
EquipmentListener m_listener;
@@ -178,6 +180,7 @@
CCCLinkIEControl* m_pCclink;
std::map<unsigned int, CStep*> m_mapStep;
int m_nBaseAlarmId;
+ CRecipesManager m_recipesManager;
};
}
diff --git a/SourceCode/Bond/Servo/CPageGraph2.cpp b/SourceCode/Bond/Servo/CPageGraph2.cpp
index 4d81345..7ead0b6 100644
--- a/SourceCode/Bond/Servo/CPageGraph2.cpp
+++ b/SourceCode/Bond/Servo/CPageGraph2.cpp
@@ -176,8 +176,10 @@
}
}
*/
+
+
// 娴嬭瘯娓呴櫎Cim Message
-
+ /*
if (pEquipment->getID() == EQ_ID_Bonder1
|| pEquipment->getID() == EQ_ID_Bonder2) {
static int msgId = 0; msgId++;
@@ -188,7 +190,7 @@
pEquipment->clearCimMessage(msgId, 2);
}
}
-
+ */
// 娴嬭瘯璁剧疆鏃堕棿
/*
@@ -221,8 +223,8 @@
pEquipment->setEqMode((ii % 5) + 1);
}
*/
+
/*
- SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData;
SERVO::CGlass* pGlass = pEquipment->getFrontGlass();
if (pGlass != nullptr) {
std::string strDescription;
@@ -234,6 +236,12 @@
}
}
*/
+
+
+ // 璇锋眰涓婚厤鏂瑰垪琛�
+ if (pEquipment != nullptr) {
+ pEquipment->masterRecipeListRequest(0);
+ }
}
diff --git a/SourceCode/Bond/Servo/CRecipeList.cpp b/SourceCode/Bond/Servo/CRecipeList.cpp
new file mode 100644
index 0000000..4d8e7d0
--- /dev/null
+++ b/SourceCode/Bond/Servo/CRecipeList.cpp
@@ -0,0 +1,81 @@
+#include "stdafx.h"
+#include "CRecipeList.h"
+#include "Common.h"
+#include "ToolUnits.h"
+
+
+namespace SERVO {
+ CRecipeList::CRecipeList()
+ {
+ m_nToatlGroupCount = 0;
+ m_nCurrentGroupCount = 0;
+ }
+
+ CRecipeList::CRecipeList(int unitNo)
+ {
+ m_nUnitNo = unitNo;
+ }
+
+ CRecipeList::~CRecipeList()
+ {
+
+ }
+
+ int CRecipeList::getUnitNo()
+ {
+ return m_nUnitNo;
+ }
+
+ int CRecipeList::addRecipePacket(int totalGroup, int currentGroup, const char* pszData, size_t size)
+ {
+ if (m_nToatlGroupCount == 0) m_nToatlGroupCount = totalGroup;
+ if (m_nToatlGroupCount != totalGroup) {
+ reset();
+ return MRLRC_GROUP_COUNT_NG;
+ }
+ if (m_nCurrentGroupCount + 1 > currentGroup) {
+ return MRLRC_DUPLICATION_GROUP_COUNT_NG;
+ }
+ if (m_nCurrentGroupCount + 1 < currentGroup) {
+ return ORDER_BY_GROUP_COUNT_NG;
+ }
+ m_nCurrentGroupCount++;
+
+ for (int i = 0; i < size; i += 4) {
+ int index = CToolUnits::toInt16(&pszData[i]);
+ short id = CToolUnits::toInt16(&pszData[i + 2]);
+ addRecipe(index, id);
+ }
+
+ if (m_nCurrentGroupCount == m_nToatlGroupCount) {
+ return MRLRC_CURRENT_RECIPE_COMPLETE;
+ }
+
+
+ return MRLRC_CONTINUE;
+ }
+
+ int CRecipeList::addRecipe(int index, short id)
+ {
+ for (auto item : m_ids) {
+ if (item.second == id) {
+ return -1;
+ }
+ }
+
+ m_ids[index] = id;
+ return 0;
+ }
+
+ std::map<int, short>& CRecipeList::getIds()
+ {
+ return m_ids;
+ }
+
+ void CRecipeList::reset()
+ {
+ m_nToatlGroupCount = 0;
+ m_nCurrentGroupCount = 0;
+ m_ids.clear();
+ }
+}
diff --git a/SourceCode/Bond/Servo/CRecipeList.h b/SourceCode/Bond/Servo/CRecipeList.h
new file mode 100644
index 0000000..7cb4577
--- /dev/null
+++ b/SourceCode/Bond/Servo/CRecipeList.h
@@ -0,0 +1,27 @@
+#pragma once
+#include <map>
+
+
+namespace SERVO {
+ class CRecipeList
+ {
+ public:
+ CRecipeList();
+ CRecipeList(int unitNo);
+ virtual ~CRecipeList();
+
+ public:
+ int getUnitNo();
+ int addRecipePacket(int totalGroup, int currentGroup, const char* pszData, size_t size);
+ int addRecipe(int index, short id);
+ std::map<int, short>& getIds();
+ void reset();
+
+ private:
+ int m_nUnitNo;
+ int m_nToatlGroupCount;
+ int m_nCurrentGroupCount;
+ std::map<int, short> m_ids;
+ };
+}
+
diff --git a/SourceCode/Bond/Servo/CRecipesManager.cpp b/SourceCode/Bond/Servo/CRecipesManager.cpp
new file mode 100644
index 0000000..34bac63
--- /dev/null
+++ b/SourceCode/Bond/Servo/CRecipesManager.cpp
@@ -0,0 +1,187 @@
+#include "stdafx.h"
+#include "CRecipesManager.h"
+#include "ToolUnits.h"
+#include "Common.h"
+
+
+namespace SERVO {
+ unsigned __stdcall TimeoutCheckWorkThreadFunction(LPVOID lpParam)
+ {
+ CRecipesManager* pRecipesManager = (CRecipesManager*)lpParam;
+ return pRecipesManager->TimeoutCheckWorkingProc();
+ }
+
+ CRecipesManager::CRecipesManager()
+ {
+ m_nSyncStatus = SS_NONE;
+ m_nTotalMasterRecipeCount = 0;
+ m_nWordThreadAddr = 0;
+ m_hWorkStop = nullptr;
+ m_hWorkThreadHandle = nullptr;
+ m_nTimeoutCount = 0;
+ ::InitializeCriticalSection(&m_cs);
+ }
+
+ CRecipesManager::~CRecipesManager()
+ {
+ // 等待超时检测线程退出
+ if (m_hWorkStop != nullptr) {
+ SetEvent(m_hWorkStop);
+ if (m_hWorkThreadHandle != NULL) {
+ WaitForSingleObject(m_hWorkThreadHandle, INFINITE);
+ CloseHandle(m_hWorkThreadHandle);
+ m_hWorkThreadHandle = NULL;
+ }
+ CloseHandle(m_hWorkStop);
+ m_hWorkStop = NULL;
+ }
+
+
+ // 清理数据
+ lock();
+ for (auto item : m_mapRecipes) {
+ delete item.second;
+ }
+ for (auto item : m_mapRecipesTemp) {
+ delete item.second;
+ }
+ unlock();
+ ::DeleteCriticalSection(&m_cs);
+ }
+
+ int CRecipesManager::syncing()
+ {
+ lock();
+ if (m_nSyncStatus == SS_SYNCING) {
+ unlock();
+ return -1;
+ }
+
+ m_nSyncStatus = SS_SYNCING;
+ m_nTimeoutCount = 0;
+ unlock();
+
+
+ if (m_hWorkStop == nullptr) {
+ m_hWorkStop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+ m_hWorkThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::TimeoutCheckWorkThreadFunction, this,
+ 0, &m_nWordThreadAddr);
+ }
+
+ return 0;
+ }
+
+ void CRecipesManager::syncFailed()
+ {
+ lock();
+ m_nSyncStatus = SS_FAILED;
+ m_nTimeoutCount = 0;
+ unlock();
+ }
+
+ int CRecipesManager::decodeRecipeListReport(const char* pszData, size_t size)
+ {
+ int index = 0;
+ int unitNo, reportType, totalMasterRecipeCount;
+ int toatlGroupCount, currentGroupCount;
+ const char* pszIdsData;
+
+ unitNo = CToolUnits::toInt16(&pszData[index]);
+ index += 2;
+
+ pszIdsData = &pszData[index];
+ index += (250 * 2);
+
+ reportType = CToolUnits::toInt16(&pszData[index]);
+ index += 2;
+
+ totalMasterRecipeCount = CToolUnits::toInt16(&pszData[index]);
+ index += 2;
+
+ toatlGroupCount = CToolUnits::toInt16(&pszData[index]);
+ index += 2;
+
+ lock();
+ if (m_nTotalMasterRecipeCount == 0) m_nTotalMasterRecipeCount = toatlGroupCount;
+ if (m_nTotalMasterRecipeCount != toatlGroupCount) {
+ return MRLRC_MASTER_RECIPE_LIST_COUNT_NG;
+ }
+ m_nTimeoutCount = 0;
+ unlock();
+
+ currentGroupCount = CToolUnits::toInt16(&pszData[index]);
+ index += 2;
+
+
+ // 找到对应CRecipeList, 找不到则新建
+ lock();
+ CRecipeList* pRecipeList = getRecipeListFromTemp(unitNo);
+ if (pRecipeList == nullptr) {
+ pRecipeList = new CRecipeList(unitNo);
+ m_mapRecipesTemp[unitNo] = pRecipeList;
+ }
+ unlock();
+ ASSERT(pRecipeList);
+
+
+ // 这里暂时只处理reportType=4,即Request from EAS
+ if (reportType == 4) {
+ int nRet = pRecipeList->addRecipePacket(toatlGroupCount, currentGroupCount, pszIdsData, 250 * 2);
+ if (MRLRC_CURRENT_RECIPE_COMPLETE == nRet) {
+ lock();
+ if (m_nTotalMasterRecipeCount == m_mapRecipesTemp.size()) {
+ for (auto item : m_mapRecipes) {
+ delete item.second;
+ }
+ m_mapRecipes = m_mapRecipesTemp;
+ m_mapRecipesTemp.clear();
+ m_nSyncStatus = SS_COMPLETE;
+ unlock();
+ return MRLRC_OK;
+ }
+ unlock();
+ }
+ else if (MRLRC_CONTINUE == nRet) {
+ return MRLRC_CONTINUE;
+ }
+ }
+
+
+ return MRLRC_OK;
+ }
+
+ CRecipeList* CRecipesManager::getRecipeListFromTemp(int unitNo)
+ {
+ auto iter = m_mapRecipesTemp.find(unitNo);
+ if (iter == m_mapRecipesTemp.end()) return nullptr;
+ return iter->second;
+ }
+
+ unsigned CRecipesManager::TimeoutCheckWorkingProc()
+ {
+ while (1) {
+ int nRet = WaitForSingleObject(m_hWorkStop, 1000);
+ if (nRet == WAIT_OBJECT_0) {
+ ResetEvent(m_hWorkStop);
+ break;
+ }
+
+ lock();
+ if (m_nSyncStatus == SS_SYNCING) {
+ m_nTimeoutCount++;
+ if (m_nTimeoutCount > 10) {
+ m_nSyncStatus = SS_TIMEOUT;
+ unlock();
+ TRACE("CRecipesManager::TimeoutCheckWorkingProc 超时退出\n");
+ }
+ }
+
+ unlock();
+ }
+
+ // _endthreadex(0);
+ TRACE("CRecipesManager::TimeoutCheckWorkingProc 线程退出\n");
+ return 0;
+ }
+
+}
diff --git a/SourceCode/Bond/Servo/CRecipesManager.h b/SourceCode/Bond/Servo/CRecipesManager.h
new file mode 100644
index 0000000..489e2a5
--- /dev/null
+++ b/SourceCode/Bond/Servo/CRecipesManager.h
@@ -0,0 +1,42 @@
+#pragma once
+#include <map>
+#include "CRecipeList.h"
+
+
+#define SS_NONE 0
+#define SS_SYNCING 1
+#define SS_COMPLETE 2
+#define SS_TIMEOUT 3
+#define SS_FAILED 4
+
+namespace SERVO {
+ class CRecipesManager
+ {
+ public:
+ CRecipesManager();
+ virtual ~CRecipesManager();
+
+ public:
+ unsigned TimeoutCheckWorkingProc();
+ int syncing();
+ void syncFailed();
+ int decodeRecipeListReport(const char* pszData, size_t size);
+ CRecipeList* getRecipeListFromTemp(int unitNo);
+
+ public:
+ inline void lock() { ::EnterCriticalSection(&m_cs); };
+ inline void unlock() { ::LeaveCriticalSection(&m_cs); };
+
+ private:
+ HANDLE m_hWorkThreadHandle;
+ unsigned m_nWordThreadAddr;
+ HANDLE m_hWorkStop;
+ int m_nTimeoutCount;
+ CRITICAL_SECTION m_cs; // 同步锁
+ int m_nSyncStatus;
+ int m_nTotalMasterRecipeCount;
+ std::map<int, CRecipeList*> m_mapRecipes;
+ std::map<int, CRecipeList*> m_mapRecipesTemp;
+ };
+}
+
diff --git a/SourceCode/Bond/Servo/Common.h b/SourceCode/Bond/Servo/Common.h
index c8ae7ab..5314223 100644
--- a/SourceCode/Bond/Servo/Common.h
+++ b/SourceCode/Bond/Servo/Common.h
@@ -279,3 +279,21 @@
#define CASSETTE_PROCCESS_COMPLETED 7
+/*
+ Master Recipe List Return Code Block Description
+ 1 OK : Recipe List Received Result is all ok
+ 2 Continue : Equipment still has to send the master recipe list to EAS because EAS is not yet received all master recipe list.
+ 3 Master Recipe list Count NG : Total Group Count is same as Current Group Count but it’s different with Total Master Recipe List Count.
+ 4 Group Count NG : Total Group Count is different with Current Group Count but it’s same with Total Master Recipe Count.
+ 5 Duplication Group Count NG : Current Group Count is duplicate with previous group count.Equipment has to send the next group count to EAS.
+ 6 Order by Group Count NG : Group Count is not sent order by next group count to EAS.Group Count has to send by order the next group count
+*/
+#define MRLRC_CURRENT_RECIPE_COMPLETE 0
+#define MRLRC_OK 1
+#define MRLRC_CONTINUE 2
+#define MRLRC_MASTER_RECIPE_LIST_COUNT_NG 3
+#define MRLRC_GROUP_COUNT_NG 4
+#define MRLRC_DUPLICATION_GROUP_COUNT_NG 5
+#define ORDER_BY_GROUP_COUNT_NG 6
+
+
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj b/SourceCode/Bond/Servo/Servo.vcxproj
index bd2f2f6..1f07ff6 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj
+++ b/SourceCode/Bond/Servo/Servo.vcxproj
@@ -248,6 +248,8 @@
<ClInclude Include="CPin.h" />
<ClInclude Include="CReadStep.h" />
<ClInclude Include="CEqCurrentRecipeChangeStep.h" />
+ <ClInclude Include="CRecipeList.h" />
+ <ClInclude Include="CRecipesManager.h" />
<ClInclude Include="CSample.h" />
<ClInclude Include="CStep.h" />
<ClInclude Include="CVacuumBake.h" />
@@ -337,6 +339,8 @@
<ClCompile Include="CPin.cpp" />
<ClCompile Include="CReadStep.cpp" />
<ClCompile Include="CEqCurrentRecipeChangeStep.cpp" />
+ <ClCompile Include="CRecipeList.cpp" />
+ <ClCompile Include="CRecipesManager.cpp" />
<ClCompile Include="CSample.cpp" />
<ClCompile Include="CStep.cpp" />
<ClCompile Include="CVacuumBake.cpp" />
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj.filters b/SourceCode/Bond/Servo/Servo.vcxproj.filters
index 339a1a7..7e9e760 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj.filters
+++ b/SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -95,6 +95,8 @@
<ClCompile Include="CEqCurrentRecipeChangeStep.cpp" />
<ClCompile Include="CEqWriteStep.cpp" />
<ClCompile Include="CEqReadStep.cpp" />
+ <ClCompile Include="CRecipesManager.cpp" />
+ <ClCompile Include="CRecipeList.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AlarmManager.h" />
@@ -188,6 +190,8 @@
<ClInclude Include="CEqCurrentRecipeChangeStep.h" />
<ClInclude Include="CEqWriteStep.h" />
<ClInclude Include="CEqReadStep.h" />
+ <ClInclude Include="CRecipesManager.h" />
+ <ClInclude Include="CRecipeList.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Servo.rc" />
--
Gitblit v1.9.3