| | |
| | | m_ullStartTime = 0; |
| | | m_ullRunTime = 0; |
| | | m_state = MASTERSTATE::READY; |
| | | m_curveMode = CurveMode::Production; |
| | | m_pActiveRobotTask = nullptr; |
| | | m_nLastError = ER_CODE_NOERROR; |
| | | m_isCompareMapsBeforeProceeding = FALSE; |
| | |
| | | LOGE("连接CC-Link失败."); |
| | | } |
| | | else { |
| | | LOGI("连接CC-Link成功."); |
| | | BoardVersion version{}; |
| | | int nRet = m_cclink.GetBoardVersion(version); |
| | | if (nRet == 0) { |
| | | LOGD("版本信息:%s.", version.toString().c_str()); |
| | | } |
| | | else { |
| | | LOGE("获取CC-Link版本信息失败."); |
| | | } |
| | | |
| | | BoardStatus status; |
| | | nRet = m_cclink.GetBoardStatus(status); |
| | | if (nRet == 0) { |
| | | LOGD("状态:%s.", status.toString().c_str()); |
| | | } |
| | | else { |
| | | LOGE("获取CC-Link状态失败."); |
| | | } |
| | | LOGI("连接CC-Link成功."); |
| | | BoardVersion version{}; |
| | | int nRet = m_cclink.GetBoardVersion(version); |
| | | if (nRet == 0) { |
| | | LOGD("版本信息:%s.", version.toString().c_str()); |
| | | } |
| | | else { |
| | | LOGE("获取CC-Link版本信息失败."); |
| | | } |
| | | |
| | | |
| | | // 初始化添加各子设备 |
| | | CLoadPort* pPort1, * pPort2, * pPort3, * pPort4; |
| | | CBonder* pBonder1, * pBonder2; |
| | | CEFEM* pEfem; |
| | | CArm* pArm; |
| | | CArmTray* pArmTray1, * pArmTray2; |
| | | CFliper* pFliper; |
| | | CVacuumBake* pVacuumBake; |
| | | CAligner* pAligner; |
| | | CBakeCooling* pBakeCooling; |
| | | CMeasurement* pMeasurement; |
| | | |
| | | pPort1 = addLoadPort(0); |
| | | pPort2 = addLoadPort(1); |
| | | pPort3 = addLoadPort(2); |
| | | pPort4 = addLoadPort(3); |
| | | pEfem = addEFEM(); |
| | | pArm = addArm(); |
| | | pArmTray1 = addArmTray(0); |
| | | pArmTray2 = addArmTray(1); |
| | | pFliper = addFliper(); |
| | | pVacuumBake = addVacuumBake(); |
| | | pAligner = addAligner(); |
| | | pBonder1 = addBonder(0); |
| | | pBonder2 = addBonder(1); |
| | | pBakeCooling = addBakeCooling(); |
| | | pMeasurement = addMeasurement(); |
| | | |
| | | ASSERT(pEfem); |
| | | ASSERT(pFliper); |
| | | ASSERT(pVacuumBake); |
| | | ASSERT(pAligner); |
| | | ASSERT(pBonder1); |
| | | ASSERT(pBonder2); |
| | | ASSERT(pBakeCooling); |
| | | ASSERT(pMeasurement); |
| | | |
| | | pEfem->setPort(0, pPort1); |
| | | pEfem->setPort(1, pPort2); |
| | | pEfem->setPort(2, pPort3); |
| | | pEfem->setPort(3, pPort4); |
| | | pEfem->setFliper(pFliper); |
| | | pEfem->setAligner(pAligner); |
| | | pEfem->setArmTray(0, pArmTray1); |
| | | pEfem->setArmTray(1, pArmTray2); |
| | | pPort1->setArm(pArm); |
| | | pPort2->setArm(pArm); |
| | | pPort3->setArm(pArm); |
| | | pPort4->setArm(pArm); |
| | | pArmTray1->setArm(pArm); |
| | | pArmTray2->setArm(pArm); |
| | | pFliper->setArm(pArm); |
| | | pVacuumBake->setArm(pArm); |
| | | pAligner->setArm(pArm); |
| | | pBonder1->setArm(pArm); |
| | | pBonder2->setArm(pArm); |
| | | pBakeCooling->setArm(pArm); |
| | | pMeasurement->setArm(pArm); |
| | | |
| | | connectEquipments(); |
| | | |
| | | |
| | | |
| | | // 读缓存数据 |
| | | const ULONGLONG boot_cache_begin = GetTickCount64(); |
| | | const ULONGLONG boot_read_begin = GetTickCount64(); |
| | | readCache(); |
| | | LOGI("[BOOT][MASTER] readCache finished, cost=%llu ms", (unsigned long long)(GetTickCount64() - boot_read_begin)); |
| | | |
| | | const ULONGLONG boot_state_begin = GetTickCount64(); |
| | | loadState(); |
| | | LOGI("[BOOT][MASTER] loadState finished, cost=%llu ms", (unsigned long long)(GetTickCount64() - boot_state_begin)); |
| | | if (m_listener.onControlJobChanged) { |
| | | notifyControlJobChanged(); |
| | | BoardStatus status; |
| | | nRet = m_cclink.GetBoardStatus(status); |
| | | if (nRet == 0) { |
| | | LOGD("状态:%s.", status.toString().c_str()); |
| | | } |
| | | |
| | | LOGI("[BOOT][MASTER] cache/state loaded, cost=%llu ms (since init %llu ms)", |
| | | (unsigned long long)(GetTickCount64() - boot_cache_begin), |
| | | (unsigned long long)(GetTickCount64() - boot_master_begin)); |
| | | |
| | | |
| | | // 定时器 |
| | | g_pMaster = this; |
| | | 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); |
| | | |
| | | |
| | | // 曲线服务 |
| | | CreateDAQBridgeServer(); |
| | | |
| | | |
| | | LOGI("<Master>初始化完成."); |
| | | LOGI("[BOOT][MASTER] init finished, total cost=%llu ms", |
| | | (unsigned long long)(GetTickCount64() - boot_master_begin)); |
| | | return 0; |
| | | else { |
| | | LOGE("获取CC-Link状态失败."); |
| | | } |
| | | } |
| | | |
| | | |
| | | // 初始化添加各子设备 |
| | | CLoadPort* pPort1, * pPort2, * pPort3, * pPort4; |
| | | CBonder* pBonder1, * pBonder2; |
| | | CEFEM* pEfem; |
| | | CArm* pArm; |
| | | CArmTray* pArmTray1, * pArmTray2; |
| | | CFliper* pFliper; |
| | | CVacuumBake* pVacuumBake; |
| | | CAligner* pAligner; |
| | | CBakeCooling* pBakeCooling; |
| | | CMeasurement* pMeasurement; |
| | | |
| | | pPort1 = addLoadPort(0); |
| | | pPort2 = addLoadPort(1); |
| | | pPort3 = addLoadPort(2); |
| | | pPort4 = addLoadPort(3); |
| | | pEfem = addEFEM(); |
| | | pArm = addArm(); |
| | | pArmTray1 = addArmTray(0); |
| | | pArmTray2 = addArmTray(1); |
| | | pFliper = addFliper(); |
| | | pVacuumBake = addVacuumBake(); |
| | | pAligner = addAligner(); |
| | | pBonder1 = addBonder(0); |
| | | pBonder2 = addBonder(1); |
| | | pBakeCooling = addBakeCooling(); |
| | | pMeasurement = addMeasurement(); |
| | | |
| | | ASSERT(pEfem); |
| | | ASSERT(pFliper); |
| | | ASSERT(pVacuumBake); |
| | | ASSERT(pAligner); |
| | | ASSERT(pBonder1); |
| | | ASSERT(pBonder2); |
| | | ASSERT(pBakeCooling); |
| | | ASSERT(pMeasurement); |
| | | |
| | | pEfem->setPort(0, pPort1); |
| | | pEfem->setPort(1, pPort2); |
| | | pEfem->setPort(2, pPort3); |
| | | pEfem->setPort(3, pPort4); |
| | | pEfem->setFliper(pFliper); |
| | | pEfem->setAligner(pAligner); |
| | | pEfem->setArmTray(0, pArmTray1); |
| | | pEfem->setArmTray(1, pArmTray2); |
| | | pPort1->setArm(pArm); |
| | | pPort2->setArm(pArm); |
| | | pPort3->setArm(pArm); |
| | | pPort4->setArm(pArm); |
| | | pArmTray1->setArm(pArm); |
| | | pArmTray2->setArm(pArm); |
| | | pFliper->setArm(pArm); |
| | | pVacuumBake->setArm(pArm); |
| | | pAligner->setArm(pArm); |
| | | pBonder1->setArm(pArm); |
| | | pBonder2->setArm(pArm); |
| | | pBakeCooling->setArm(pArm); |
| | | pMeasurement->setArm(pArm); |
| | | |
| | | connectEquipments(); |
| | | |
| | | |
| | | |
| | | // 读缓存数据 |
| | | const ULONGLONG boot_cache_begin = GetTickCount64(); |
| | | const ULONGLONG boot_read_begin = GetTickCount64(); |
| | | readCache(); |
| | | LOGI("[BOOT][MASTER] readCache finished, cost=%llu ms", (unsigned long long)(GetTickCount64() - boot_read_begin)); |
| | | |
| | | const ULONGLONG boot_state_begin = GetTickCount64(); |
| | | loadState(); |
| | | LOGI("[BOOT][MASTER] loadState finished, cost=%llu ms", (unsigned long long)(GetTickCount64() - boot_state_begin)); |
| | | if (m_listener.onControlJobChanged) { |
| | | notifyControlJobChanged(); |
| | | } |
| | | |
| | | LOGI("[BOOT][MASTER] cache/state loaded, cost=%llu ms (since init %llu ms)", |
| | | (unsigned long long)(GetTickCount64() - boot_cache_begin), |
| | | (unsigned long long)(GetTickCount64() - boot_master_begin)); |
| | | |
| | | |
| | | // 定时器 |
| | | g_pMaster = this; |
| | | 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); |
| | | |
| | | |
| | | // 曲线服务 |
| | | CreateDAQBridgeServer(); |
| | | |
| | | |
| | | LOGI("<Master>初始化完成."); |
| | | LOGI("[BOOT][MASTER] init finished, total cost=%llu ms", |
| | | (unsigned long long)(GetTickCount64() - boot_master_begin)); |
| | | return 0; |
| | | } |
| | | |
| | | void CMaster::setCurveMode(CurveMode mode) |
| | | { |
| | | if (m_curveMode == mode) { |
| | | return; |
| | | } |
| | | m_curveMode = mode; |
| | | if (m_pCollector != nullptr) { |
| | | const uint32_t mids[] = { |
| | | MID_Bonder1, MID_Bonder2, |
| | | MID_VacuumBakeA, MID_VacuumBakeB, |
| | | MID_BakeCoolingA, MID_BakeCoolingB |
| | | }; |
| | | for (uint32_t mid : mids) { |
| | | if (mode == CurveMode::EmptyChamber) { |
| | | m_pCollector->batchStart(mid, "EMPTY_CHAMBER", 30 * 60 * 1000ULL); // 空腔模式:启动采样批次 |
| | | } |
| | | else { |
| | | m_pCollector->batchStop(mid); |
| | | m_pCollector->buffersClear(mid); // 切回生产模式,清掉空腔数据 |
| | | } |
| | | } |
| | | } |
| | | LOGI("<Master>CurveMode=%s", mode == CurveMode::EmptyChamber ? "EmptyChamber" : "Production"); |
| | | } |
| | | |
| | | CurveMode CMaster::getCurveMode() const |
| | | { |
| | | return m_curveMode; |
| | | } |
| | | |
| | | int CMaster::term() |
| | | { |
| | |
| | | m_state == MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER || |
| | | m_state == MASTERSTATE::RUNNING_BATCH || |
| | | m_state == MASTERSTATE::STARTING); |
| | | if (!allowSvLog) { |
| | | const bool allowCurve = allowSvLog || (m_curveMode == CurveMode::EmptyChamber); |
| | | if (!allowCurve) { |
| | | return; |
| | | } |
| | | CSVData* pSVData = (CSVData*)pData; |
| | |
| | | auto& dataTypes = CServoUtilsTool::getEqDataTypes(); |
| | | auto& bonderTypes = dataTypes[MID_Bonder1]; |
| | | for (size_t i = 0; i < bonderTypes.size(); ++i) { |
| | | m_pCollector->buffersSetChannelName(MID_Bonder1, i + 1, bonderTypes[i].c_str()); |
| | | m_pCollector->buffersSetChannelName(MID_Bonder2, i + 1, bonderTypes[i].c_str()); |
| | | m_pCollector->buffersSetChannelName(MID_Bonder1, (UINT)i + 1, bonderTypes[(UINT)i].c_str()); |
| | | m_pCollector->buffersSetChannelName(MID_Bonder2, (UINT)i + 1, bonderTypes[(UINT)i].c_str()); |
| | | } |
| | | |
| | | auto& vacuumbakeTypes = dataTypes[MID_VacuumBakeA]; |
| | | for (size_t i = 0; i < vacuumbakeTypes.size(); ++i) { |
| | | m_pCollector->buffersSetChannelName(MID_VacuumBakeA, i + 1, vacuumbakeTypes[i].c_str()); |
| | | m_pCollector->buffersSetChannelName(MID_VacuumBakeB, i + 1, vacuumbakeTypes[i].c_str()); |
| | | m_pCollector->buffersSetChannelName(MID_VacuumBakeA, (UINT)i + 1, vacuumbakeTypes[(UINT)i].c_str()); |
| | | m_pCollector->buffersSetChannelName(MID_VacuumBakeB, (UINT)i + 1, vacuumbakeTypes[(UINT)i].c_str()); |
| | | } |
| | | |
| | | auto& coolingTypes = dataTypes[MID_BakeCoolingA]; |
| | |
| | | m_pCollector->buffersSetChannelName(MID_BakeCoolingA, i + 1, coolingTypes[i].c_str()); |
| | | m_pCollector->buffersSetChannelName(MID_BakeCoolingB, i + 1, coolingTypes[i].c_str()); |
| | | } |
| | | |
| | | if (m_curveMode == CurveMode::EmptyChamber) { |
| | | const uint32_t mids[] = { |
| | | MID_Bonder1, MID_Bonder2, |
| | | MID_VacuumBakeA, MID_VacuumBakeB, |
| | | MID_BakeCoolingA, MID_BakeCoolingB |
| | | }; |
| | | for (uint32_t mid : mids) { |
| | | m_pCollector->batchStart(mid, "EMPTY_CHAMBER", 10 * 60 * 1000ULL); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |