LAPTOP-SNT8I5JK\Boounion
2025-05-05 38fdd2e7d1d45a3ffed57fde30031a6a8f04d235
1.获取配方列表,已处理待测试。
已添加4个文件
已修改7个文件
393 ■■■■■ 文件已修改
SourceCode/Bond/Servo/CBonder.cpp 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.cpp 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.h 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageGraph2.cpp 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CRecipeList.cpp 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CRecipeList.h 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CRecipesManager.cpp 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CRecipesManager.h 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Common.h 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj.filters 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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);
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);
    }
}
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;
    };
}
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);
            }
        }
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();
    }
}
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;
    };
}
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;
    }
}
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;
    };
}
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
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" />
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" />