#if defined(WIN32) #include // #include "stdafx.h" #endif #include #include #include #include #include "ModbusEx_LnS.h" #include "se_log.h" #include "daq/daq_utl.h" extern CRdbTable DEF_DCDLL RDB_Chan; unsigned int CRC_16(unsigned char * pSendBuf, int len)//CRC检验码 { unsigned short wCrc = 0xFFFF; for(int i=0; i>= 1; wCrc ^= 0xA001; } else wCrc >>= 1; } } return wCrc; } CModbusExLnS::CModbusExLnS() { // #ifdef LOG_WIN // m_logger = new Logger("ModbusExLnS", "ModbusExLnS.log"); // // m_logger->WriteLineSeparator("Create a new class instance. ", 2); // #endif m_bExitMe = false; m_b_InitBuff = 0; m_bufValueHasReady = 0; m_bufYC = NULL; m_bufYX = NULL; m_TxDataMaxLen = 1042; m_FrameObjNum_Max = 512; m_FrameDINum_Max = m_FrameObjNum_Max * DINumberPerBlock; resetIniParam(&m_iniConfig); } CModbusExLnS::~CModbusExLnS() { if (m_iniConfig.rtuConfArray != NULL) { delete [] m_iniConfig.rtuConfArray; } m_bExitMe = true; if (m_bufYX != NULL) delete [] m_bufYX; if (m_bufYC != NULL) delete [] m_bufYC; #ifdef LOG_WIN delete m_logger; #endif } void CModbusExLnS::Init( S_PROTOCOLCFG * pcfg ) { // #ifdef LOG_WIN // m_logger->WriteFmtStrWithTime_L3("[Init] : "); // #endif PRawCtrl = pcfg->PRawCtrl; pRxBuf = pcfg->pRxBuf; pTxBuf = pcfg->pTxBuf; pCmdMem = pcfg->pCmdMem; pRtu = pcfg->pRtu; pLink = pcfg->pLink; pTable = pcfg->pTable; pZfDataCtrl = pcfg->pZfDataCtrl; sint32 buflen = pRxBuf->GetReadableSize(); pRxBuf->Move(buflen); buflen = pTxBuf->GetReadableSize(); pTxBuf->Move(buflen); #ifdef LOG_WIN char logfilename[32] = {0}; sprintf(logfilename, "S_rtu%d_chan%d.log", pLink->GetRtuNo(), pLink->GetChanNo()); m_logger = new Logger("ModbusExLnS", logfilename); m_logger->WriteLineSeparator("Create a new class instance. ", 2); #endif readIni(); initBuffer(); initStation(); m_hThreadGetData = SE_CreateThread( (PTHREAD_FUNC_DEF)GetData, (void *)this); } void CModbusExLnS::initStation() { // #ifdef LOG_WIN // m_logger->WriteFmtStrWithTime_L3("[initStation] : "); // #endif m_flagSendType = 3; m_nSendFrameNo = 0; m_nSendSeqNo = 0; m_nYXFrameCount = 0; m_nYCFrameCount = 0; pLink->SetCommStatus(CMST_NORMAL); } void CModbusExLnS::readIni() { // #ifdef LOG_WIN // m_logger->WriteFmtStrWithTime_L3("[readIni] : "); // #endif char *home = getenv("SEROOT"); if (NULL == home) { PrintLog(LOG_ERROR, "环境变量SEROOT未设置"); return; } char filename[256] = {0}; #if defined(__unix) sprintf(filename, "%s%s", home, "/cfg/ModbusExLns.ini"); #else sprintf(filename, "%s%s", home, "\\cfg\\ModbusExLns.ini"); #endif CReadConf readconf; char sSection[7]; sint32 rtu_no = 0; uint32 zfRtu_start = 0; uint32 zfRtu_count = 0; int nTotalRtuNum = readconf.ReadLong("GENERAL", "rtuCount", filename, "1"); for (sint32 rtu_i=0; rtu_iGetRtuNo()) break; } m_logger->WriteFmtStrWithTime_L3("[readIni] : local rtu no %d, zf rtu number %d", rtu_no, zfRtu_count); if (rtu_no <= 0) { PrintLog(LOG_ERROR, "RTU未配置"); return; } if (zfRtu_count <= 0) { PrintLog(LOG_ERROR, "被转发的RTU数量无配置"); return; } m_iniConfig.totalRtus = zfRtu_count; m_iniConfig.bufType = (uint8)readconf.ReadLong("GENERAL", "buffType", filename, "0"); m_iniConfig.rtuConfArray = new IniRtuParam[zfRtu_count]; for (uint32 zfrtu_i=0; zfrtu_irtuNo = readconf.ReadLong(sSection, "rtuNo", filename, "0"); pRtuPara->totalYX = readconf.ReadLong(sSection, "yx", filename, "0"); pRtuPara->totalYC = readconf.ReadLong(sSection, "yc", filename, "0"); pRtuPara->totalYxBlock = (pRtuPara->totalYX + DINumberPerBlock - 1) / DINumberPerBlock; } setFrameProperty(m_iniConfig.bufType); } // sint32 CModbusExLnS::RxProc() { if ( (m_flagSendType & 0x3) == 0) m_flagSendType = 0x3; #if 1 sint32 count = RDB_Chan.GetRcdCount(); if( count>DEF_DCV_MAX_CHANNUM ) count = DEF_DCV_MAX_CHANNUM; S_RDB_Chan * pChan = (S_RDB_Chan * )RDB_Chan.GetRcdAddr(0); sint32 chanNo = pLink->GetChanNo(); for (int i=0; iRegisterFrm( FRAME_RX_SUC ); // pLink->SetCommStatus(CMST_NORMAL); return 1; } // sint32 CModbusExLnS::TxProc() { // m_logger->WriteFmtStrWithTime_L3("[TxProc] : "); if (m_b_InitBuff == 0) { if (NULL != m_bufYX) { delete [] m_bufYX; m_bufYX = NULL; } #ifdef LOG_WIN m_logger->WriteFmtStrWithTime_L3("[TxProc] : m_iniConfig.yxBytes = %d, m_iniConfig.ycBytes = %d", m_iniConfig.totalBytesYx, m_iniConfig.totalBytesYc); #endif if (m_iniConfig.totalBytesYx > 0) m_bufYX = new uint8[m_iniConfig.totalBytesYx]; if (NULL == m_bufYX) return 0; memset(m_bufYX, 0, m_iniConfig.totalBytesYx); if (m_iniConfig.totalBytesYc > 0) m_bufYC = new uint8[m_iniConfig.totalBytesYc]; if (NULL == m_bufYC) return 0; memset(m_bufYC, 0, m_iniConfig.totalBytesYc); m_b_InitBuff = 1; while (TRUE) { if (m_bufValueHasReady == 1) break; if (m_bExitMe) return 1; SeSleep(10); } } else { if (NULL == m_bufYX) return 0; if (NULL == m_bufYC) return 0; } // m_logger->WriteFmtStrWithTime_L3("[TxProc] : send data ..."); if ( (m_flagSendType & 0x1) == 0x1) { if (procSendDI() == 1) return 1; } if ( (m_flagSendType & 0x2) == 0x2) { if (procSendAI() == 1) return 1; } return 1; } void CModbusExLnS::appToLink(uint8 nDataType) { BYTE * p = m_sendData.databuf; int len = m_sendData.trailP - m_sendData.headP; unsigned int crcValue = CRC_16(p, len); *m_sendData.trailP++ = crcValue % 0x100; *m_sendData.trailP++ = crcValue / 0x100; len = m_sendData.trailP - m_sendData.headP; #ifdef LOG_WIN if (m_logger->IfLogData()) { if (nDataType == 1) m_logger->WriteFmtStrWithTime_L3(_T("发送报文 (字节数 %d) : DI第%d帧"), len, m_nYXFrameCount); else if (nDataType == 3) m_logger->WriteFmtStrWithTime_L3(_T("发送报文 (字节数 %d) : AI第%d帧"), len, m_nYCFrameCount); TCHAR strLog[MaxCodeLen] = {0}; uint32 real_len = MaxCodeLen - TimeHead; uint32 code_line = 1; _tcscpy(strLog, "\n0001: "); int code_index; for (code_index=0; code_index= real_len-1) { m_logger->WriteFmtStrWithTime_L3(strLog); memset(strLog, 0, sizeof(TCHAR)*MaxCodeLen); _stprintf(strLog, _T("\n%04d: "), ++code_line); } TCHAR tmpStr[12] = {0}; if ( (code_index+1)/32 > 0 && (code_index+1)%32 == 0) { if ( (code_index+1) % (MaxLine*MaxLineCodeNum) == 0 ) _stprintf(tmpStr, _T("%02X \n"), *(p+code_index)); else _stprintf(tmpStr, _T("%02X \n%04d: "), *(p+code_index), ++code_line); } else _stprintf(tmpStr, _T("%02X "), *(p+code_index)); _tcscat(strLog, tmpStr); } m_logger->WriteFmtStrWithTime_L3(strLog); } #endif // pLink->RegisterFrmCode(RAW_CODEDIR_DOWN, (char *)p, len); pTxBuf->Write(p, len); // pLink->SetCommStatus(CMST_NORMAL); pLink->RegisterFrm( FRAME_TX_SUC ); return; } // index base 0 // 不同的RTU点在同一个帧发送,每个帧尽量满额 sint32 CModbusExLnS::procSendDI() { if (NULL == m_bufYX || NULL == m_iniConfig.rtuConfArray) { PrintLog(LOG_ERROR, "RTU未配置"); m_flagSendType &= 0xFE; m_nSendFrameNo = 0; return 0; } #ifdef LOG_WIN if (m_nSendFrameNo == 0) { m_timeBeginYX = GetTickCount(); } #endif // save DI into buffer uint8 *buf = new uint8[m_TxDataMaxLen]; if (NULL == buf) return 0; uint32 nPreCopied = m_nSendFrameNo * m_FrameObjNum_Max * 2; uint8 * dataSrc = m_bufYX + nPreCopied; uint32 nCopySize = ( (uint32)(m_nSendFrameNo + 1) >= m_iniConfig.totalFramesYx ) ? (m_iniConfig.totalBytesYx - nPreCopied) : (m_FrameObjNum_Max * 2); memcpy(buf, dataSrc, nCopySize); // DATA_HEAD DATA_HEAD dataHead; dataHead.HeadLo = 0xEB; dataHead.HeadHi = 0x90; dataHead.SysID = FixSysID_Ans; dataHead.PacketNoLo = m_nSendSeqNo % 256; dataHead.PacketNoHi = m_nSendSeqNo / 256; uint16 framelen = nCopySize + 8; dataHead.LenLo = framelen % 256; dataHead.LenHi = framelen / 256; bool bFinishedCycle = false; if ( (uint32)(m_nSendFrameNo + 1) >= m_iniConfig.totalFramesYx ) bFinishedCycle = true; if (bFinishedCycle) dataHead.FollowupFlag = 0; else dataHead.FollowupFlag = 1; // DATA_BODY_HEAD DATA_BODY_HEAD dataBodyHead; dataBodyHead.DataType = ReqTypeID_DI; uint32 nMaxCount = nCopySize * 8; dataBodyHead.DataCountLB = nMaxCount & 0xFF; dataBodyHead.DataCountMB = (nMaxCount >> 8) & 0xFF; dataBodyHead.DataCountHB = (nMaxCount >> 16) & 0xFF; dataBodyHead.DataStAddrLB = nPreCopied & 0xFF; dataBodyHead.DataStAddrMB = (nPreCopied >> 8) & 0xFF; dataBodyHead.DataStAddrHB = (nPreCopied >> 16) & 0xFF; // uint8 *ptr = m_sendData.databuf; m_sendData.headP = m_sendData.trailP = ptr; memcpy(ptr, (BYTE *)&dataHead, DataHeadLen); ptr += DataHeadLen; memcpy(ptr, (BYTE *)&dataBodyHead, DataBodyHeadLen); ptr += DataBodyHeadLen; memcpy(ptr, (BYTE *)buf, nCopySize); ptr += nCopySize; m_sendData.trailP = ptr; appToLink(1); m_nSendSeqNo = (m_nSendSeqNo + 1) % 0xFFFF; #ifdef LOG_WIN m_nYXFrameCount++; #endif delete [] buf; if (bFinishedCycle) { m_flagSendType &= 0xFE; m_nSendFrameNo = 0; #ifdef LOG_WIN DWORD curTick = GetTickCount(); DWORD spendTick = GetTickCount() - m_timeBeginYX; m_logger->WriteFmtStrWithTime_L3(_T("[procSendDI] : 遥信 发送完毕,耗时: %us(%ums), 发送帧数: %d"), spendTick/1000, spendTick, m_nYXFrameCount); m_nYXFrameCount = 0; #endif } else m_nSendFrameNo++; return 1; } /* // 不同的RTU在不同帧 sint32 CModbusExLnS::procSendDI() { if (NULL == m_bufYX || NULL == m_iniConfig.rtuConfArray) { PrintLog(LOG_ERROR, "RTU未配置"); m_flagSendType &= 0xFE; m_nSendFrameNo = 0; return 0; } // get start RTU uint32 nRtuNo = 0; uint32 nCalcFrames = 0; // total frames have been sent (not include current RTU) uint32 nTotalFramesRTU = 0; // total frames of current RTU uint32 nDI_byte_start = 0; // start address of current frame (:= 0~0xFFFFFF) LPIniRtuParam p_zfRtu = NULL; while ( nRtuNo < m_iniConfig.totalRtus) { p_zfRtu = m_iniConfig.rtuConfArray + nRtuNo; nTotalFramesRTU = (p_zfRtu->totalYxBlock + MaxObjPerFrame_DI - 1) / MaxObjPerFrame_DI; if (m_nSendFrameNo < nCalcFrames + nTotalFramesRTU)//SendFrameNo : index base from 0 break; nCalcFrames += nTotalFramesRTU; nDI_byte_start += (p_zfRtu->totalYxBlock * 2); nRtuNo++; } if (nRtuNo >= m_iniConfig.totalRtus || NULL == p_zfRtu) { PrintLog(LOG_ERROR, "RTU配置数超出,请检查配置文件,当前RTU %d", nRtuNo+1); m_flagSendType &= 0xFE; m_nSendFrameNo = 0; return 0; } uint32 nRtuFrameNo = m_nSendFrameNo - nCalcFrames; // get frame number which has been sent in current RTU nDI_byte_start += (MaxObjPerFrame_DI * 2 * nRtuFrameNo); uint32 nRtuPointStart = (MaxObjPerFrame_DI * DINumberPerBlock) * nRtuFrameNo; // get from which DI start #ifdef LOG_WIN if (m_nSendFrameNo == 0) { m_timeBeginYX = GetTickCount(); } #endif // re-calculate max DI uint32 nRetPoint = p_zfRtu->totalYX - nRtuPointStart; uint32 nMaxPoint = (MaxObjPerFrame_DI * DINumberPerBlock); // max DI of current frame nMaxPoint = nRetPoint < nMaxPoint ? nRetPoint : nMaxPoint; // save DI into buffer uint8 buf[1024] = {0}; uint32 nCopySize = (nMaxPoint + 7) / 8; uint8 *dataSrc = m_bufYX + nDI_byte_start; memcpy(buf, dataSrc, nCopySize); // DATA_HEAD DATA_HEAD dataHead; dataHead.HeadLo = 0xEB; dataHead.HeadHi = 0x90; dataHead.SysID = FixSysID_Ans; dataHead.PacketNoLo = m_nSendSeqNo % 256; dataHead.PacketNoHi = m_nSendSeqNo / 256; uint16 nBlock = (nMaxPoint+DINumberPerBlock-1) / DINumberPerBlock; uint16 framelen = nBlock * 2 + 8; dataHead.LenLo = framelen % 256; dataHead.LenHi = framelen / 256; bool bFinishedCycle = false; // if ( (nRtuNo >= m_iniConfig.totalRtus-1) && (nRtuFrameNo >= nTotalFramesRTU-1) ) // bFinishedCycle = true; // m_logger->WriteFmtStrWithTime_L3("[procSendDI] : nDI_byte_start = %d, nCopySize = %d, m_iniConfig.totalBytesYx = %d", // nDI_byte_start, nCopySize, m_iniConfig.totalBytesYx); if ( (nDI_byte_start + (nMaxPoint+15)/16*2) >= m_iniConfig.totalBytesYx) bFinishedCycle = true; if (bFinishedCycle) dataHead.FollowupFlag = 0; else dataHead.FollowupFlag = 1; dataHead.DataType = ReqTypeID_DI; // uint8 *ptr = m_sendData.databuf; m_sendData.headP = m_sendData.trailP = ptr; memcpy(ptr, (BYTE *)&dataHead, DataHeadLen); ptr += DataHeadLen; uint32 nMaxCount = nMaxPoint; *ptr++ = nMaxCount & 0xFF; *ptr++ = (nMaxCount >> 8) & 0xFF; *ptr++ = (nMaxCount >> 16) & 0xFF; *ptr++ = nDI_byte_start & 0xFF; *ptr++ = (nDI_byte_start >> 8) & 0xFF; *ptr++ = (nDI_byte_start >> 16) & 0xFF; memcpy(ptr, (BYTE *)buf, nBlock*2); ptr += nBlock * 2; m_sendData.trailP = ptr; appToLink(1); m_nSendSeqNo = (m_nSendSeqNo + 1) % 0xFFFF; #ifdef LOG_WIN m_nYXFrameCount++; #endif if (bFinishedCycle) { m_flagSendType &= 0xFE; m_nSendFrameNo = 0; #ifdef LOG_WIN DWORD curTick = GetTickCount(); DWORD spendTick = GetTickCount() - m_timeBeginYX; m_logger->WriteFmtStrWithTime_L3(_T("[procSendDI] : 遥信 发送完毕,耗时: %us(%ums), 发送帧数: %d"), spendTick/1000, spendTick, m_nYXFrameCount); m_nYXFrameCount = 0; #endif } else m_nSendFrameNo++; return 1; } */ // 不同的RTU点在同一个帧发送,每个帧尽量满额 sint32 CModbusExLnS::procSendAI() { if (NULL == m_bufYC || NULL == m_iniConfig.rtuConfArray) { PrintLog(LOG_ERROR, "RTU未配置"); m_flagSendType &= 0xFD; m_nSendFrameNo = 0; return 0; } #ifdef LOG_WIN if (m_nSendFrameNo == 0) { m_timeBeginYC = GetTickCount(); } #endif // save AI into buffer uint8 *buf = new uint8[m_TxDataMaxLen]; if (NULL == buf) return 0; uint32 nPreCopied = m_nSendFrameNo * m_FrameObjNum_Max * 2; uint8 * dataSrc = m_bufYC + nPreCopied; uint32 nCopySize = ( (uint32)(m_nSendFrameNo + 1) >= m_iniConfig.totalFramesYc ) ? (m_iniConfig.totalBytesYc - nPreCopied) : (m_FrameObjNum_Max * 2); memcpy(buf, dataSrc, nCopySize); // DATA_HEAD DATA_HEAD dataHead; dataHead.HeadLo = 0xEB; dataHead.HeadHi = 0x90; dataHead.SysID = FixSysID_Ans; dataHead.PacketNoLo = m_nSendSeqNo % 256; dataHead.PacketNoHi = m_nSendSeqNo / 256; uint16 framelen = nCopySize + 8; dataHead.LenLo = framelen % 256; dataHead.LenHi = framelen / 256; bool bFinishedCycle = false; if ( (uint32)(m_nSendFrameNo + 1) >= m_iniConfig.totalFramesYc ) bFinishedCycle = true; if (bFinishedCycle) dataHead.FollowupFlag = 0; else dataHead.FollowupFlag = 1; // DATA_BODY_HEAD DATA_BODY_HEAD dataBodyHead; dataBodyHead.DataType = ReqTypeID_AI; uint32 nMaxPoint = nCopySize / 2; dataBodyHead.DataCountLB = nMaxPoint & 0xFF; dataBodyHead.DataCountMB = (nMaxPoint >> 8) & 0xFF; dataBodyHead.DataCountHB = (nMaxPoint >> 16) & 0xFF; uint32 nInfoAddrStart = nPreCopied / 2; dataBodyHead.DataStAddrLB = nInfoAddrStart & 0xFF; dataBodyHead.DataStAddrMB = (nInfoAddrStart >> 8) & 0xFF; dataBodyHead.DataStAddrHB = (nInfoAddrStart >> 16) & 0xFF; // uint8 *ptr = m_sendData.databuf; m_sendData.headP = m_sendData.trailP = ptr; memcpy(ptr, (BYTE *)&dataHead, DataHeadLen); ptr += DataHeadLen; memcpy(ptr, (BYTE *)&dataBodyHead, DataBodyHeadLen); ptr += DataBodyHeadLen; memcpy(ptr, (BYTE *)buf, nMaxPoint*2); ptr += nCopySize; m_sendData.trailP = ptr; PrintLog(LOG_INFORMATION, "发送DI响应帧"); appToLink(3); m_nSendSeqNo = (m_nSendSeqNo + 1) % 0xFFFF; #ifdef LOG_WIN m_nYCFrameCount++; #endif delete [] buf; if (bFinishedCycle) { m_flagSendType &= 0xFD; m_nSendFrameNo = 0; #ifdef LOG_WIN DWORD curTick = GetTickCount(); DWORD spendTick = curTick - m_timeBeginYC; m_logger->WriteFmtStrWithTime_L3(_T("[procSendAI] : 遥测 发送完毕,耗时: %us(%ums), 发送帧数: %d"), spendTick/1000, spendTick, m_nYCFrameCount); m_nYCFrameCount = 0; spendTick = curTick - m_timeBeginYX; m_logger->WriteFmtStrWithTime_L3(_T("[procSendAI] : ------>>> 所有数据 发送完毕,耗时: %us(%ums) <<<------"), spendTick/1000, spendTick); m_timeBeginYX = m_timeBeginYC = 0; #endif } else m_nSendFrameNo++; return 1; } /* // 不同的RTU在不同帧 sint32 CModbusExLnS::procSendAI() { if (NULL == m_bufYC || NULL == m_iniConfig.rtuConfArray) { PrintLog(LOG_ERROR, "RTU未配置"); m_flagSendType &= 0xFD; m_nSendFrameNo = 0; return 0; } // get start RTU uint32 nRtuNo = 0; uint32 nCalcFrames = 0; // total frames have been sent (not include current RTU) uint32 nTotalFramesRTU = 0; // total frames of current RTU uint32 nInfoAddrStart = 0; // start address of current frame (:= 0~0xFFFFFF) LPIniRtuParam p_zfRtu = NULL; while (nRtuNo < m_iniConfig.totalRtus) { p_zfRtu = m_iniConfig.rtuConfArray + nRtuNo; nTotalFramesRTU = p_zfRtu->totalYcFrame; if (m_nSendFrameNo < nCalcFrames + nTotalFramesRTU)//SendFrameNo : index base from 0 break; nCalcFrames += nTotalFramesRTU; nInfoAddrStart += p_zfRtu->totalYC; nRtuNo++; } if (nRtuNo >= m_iniConfig.totalRtus || NULL == p_zfRtu) { PrintLog(LOG_ERROR, "AI点超出,请检查配置文件,当前RTU %d", nRtuNo+1); m_flagSendType &= 0xFD; m_nSendFrameNo = 0; return 0; } uint32 nRtuFrameNo = m_nSendFrameNo - nCalcFrames; // get frame number which has been sent in current RTU nInfoAddrStart += MaxObjPerFrame_AI * nRtuFrameNo; uint32 nMaxPoint = MaxObjPerFrame_AI; // max DI of current frame uint32 nRtuPointStart = nMaxPoint * nRtuFrameNo; // get from which DI start #ifdef LOG_WIN if (m_nSendFrameNo == 0) { m_timeBeginYC = GetTickCount(); } #endif // re-calculate max DI uint32 nRetPoint = p_zfRtu->totalYC - nRtuPointStart; nMaxPoint = nRetPoint < nMaxPoint ? nRetPoint : nMaxPoint; // save AI into buffer uint8 buf[1024] = {0}; uint32 nCopySize = nMaxPoint * 2; uint8 * dataSrc = m_bufYC + nInfoAddrStart * 2; memcpy(buf, dataSrc, nCopySize); // DATA_HEAD DATA_HEAD dataHead; dataHead.HeadLo = 0xEB; dataHead.HeadHi = 0x90; dataHead.SysID = FixSysID_Ans; dataHead.PacketNoLo = m_nSendSeqNo % 256; dataHead.PacketNoHi = m_nSendSeqNo / 256; uint16 framelen = nMaxPoint * 2 + 8; dataHead.LenLo = framelen % 256; dataHead.LenHi = framelen / 256; bool bFinishedCycle = false; // m_logger->WriteFmtStrWithTime_L3("[procSendAI] : m_iniConfig.totalRtus = %d, nRtuNo = %d, nRtuFrameNo = %d, nTotalFramesRTU = %d", // m_iniConfig.totalRtus, nRtuNo, nRtuFrameNo, nTotalFramesRTU); // if ( (nRtuNo >= m_iniConfig.totalRtus-1) && (nRtuFrameNo >= nTotalFramesRTU-1) ) // bFinishedCycle = true; if ( (nInfoAddrStart*2 + nCopySize) >= m_iniConfig.totalBytesYc) bFinishedCycle = true; if (bFinishedCycle) dataHead.FollowupFlag = 0; else dataHead.FollowupFlag = 1; dataHead.DataType = ReqTypeID_AI; // uint8 *ptr = m_sendData.databuf; m_sendData.headP = m_sendData.trailP = ptr; memcpy(ptr, (BYTE *)&dataHead, DataHeadLen); ptr += DataHeadLen; *ptr++ = nMaxPoint & 0xFF; *ptr++ = (nMaxPoint >> 8) & 0xFF; *ptr++ = (nMaxPoint >> 16) & 0xFF; *ptr++ = nInfoAddrStart & 0xFF; *ptr++ = (nInfoAddrStart >> 8) & 0xFF; *ptr++ = (nInfoAddrStart >> 16) & 0xFF; memcpy(ptr, (BYTE *)buf, nMaxPoint*2); ptr += nMaxPoint * 2; m_sendData.trailP = ptr; PrintLog(LOG_INFORMATION, "发送DI响应帧"); appToLink(3); m_nSendSeqNo = (m_nSendSeqNo + 1) % 0xFFFF; #ifdef LOG_WIN m_nYCFrameCount++; #endif if (bFinishedCycle) { m_flagSendType &= 0xFD; m_nSendFrameNo = 0; #ifdef LOG_WIN DWORD curTick = GetTickCount(); DWORD spendTick = curTick - m_timeBeginYC; m_logger->WriteFmtStrWithTime_L3(_T("[procSendAI] : 遥测 发送完毕,耗时: %us(%ums), 发送帧数: %d"), spendTick/1000, spendTick, m_nYCFrameCount); m_nYCFrameCount = 0; spendTick = curTick - m_timeBeginYX; m_logger->WriteFmtStrWithTime_L3(_T("[procSendAI] : ------>>> 所有数据 发送完毕,耗时: %us(%ums) <<<------"), spendTick/1000, spendTick); m_timeBeginYX = m_timeBeginYC = 0; #endif } else m_nSendFrameNo++; return 1; } */ void CModbusExLnS::resetIniParam(LPIniConfig pParam) { memset(pParam, 0, sizeof(IniConfig)); } void CModbusExLnS::initBuffer() { if (NULL == m_iniConfig.rtuConfArray) return; for (uint32 zfrtu_i=0; zfrtu_iWriteFmtStrWithTime_L3("[initBuffer] : m_iniConfig.yxBytes 1= %d, pRtuPara->totalYxBlock = %d", m_iniConfig.yxBytes, pRtuPara->totalYxBlock); m_iniConfig.totalBytesYx += pRtuPara->totalYxBlock * 2; // m_logger->WriteFmtStrWithTime_L3("[initBuffer] : m_iniConfig.yxBytes 2= %d", m_iniConfig.yxBytes); m_iniConfig.totalBytesYc += pRtuPara->totalYC * 2; } uint32 nMaxBytesPerFrame = m_FrameObjNum_Max * 2; m_iniConfig.totalFramesYx = (m_iniConfig.totalBytesYx + nMaxBytesPerFrame - 1) / nMaxBytesPerFrame; m_iniConfig.totalFramesYc = (m_iniConfig.totalBytesYc + nMaxBytesPerFrame - 1) / nMaxBytesPerFrame; } sint32 CModbusExLnS::procWriteBuffer_DI() { if (m_bufYX == NULL) return 0; uint32 yx_startNo_inBuff = 0; for (uint32 rtu_i=0; rtu_itotalYxBlock * 2; uint32 byteIndex, bitIndex; for (uint16 yx_i = 0; yx_itotalYX; yx_i++) { uint8 btVal = 0; PRawCtrl->GetAYx(pRtuPara->rtuNo, yx_i, &btVal); uint32 curYxNo_inBuff = yx_startNo_inBuff + yx_i; byteIndex = curYxNo_inBuff/DINumberPerBlock * 2 + curYxNo_inBuff%DINumberPerBlock / 8; bitIndex = curYxNo_inBuff % 8; if (btVal == 1) { *(m_bufYX+byteIndex) |= (1 << bitIndex); } else { *(m_bufYX+byteIndex) &= ~(1 << bitIndex); } } } return 1; } sint32 CModbusExLnS::procWriteBuffer_AI() { if (m_bufYC == NULL) return 0; uint32 yc_startNo_inBuff = 0; for (uint32 rtu_i=0; rtu_itotalYC; yc_i++) { float32 fVal = 0.0f; PRawCtrl->GetAYc(pRtuPara->rtuNo, yc_i, &fVal); byteIndex = (yc_startNo_inBuff + yc_i) * 2; *(m_bufYC+byteIndex) = ((sint32)fVal) % 256; *(m_bufYC+byteIndex+1) = ((sint32)fVal) / 256; } yc_startNo_inBuff += pRtuPara->totalYC; } return 1; } void CModbusExLnS::GetData(void * pClass) { if (NULL == pClass) return; CModbusExLnS * pThis = (CModbusExLnS *)pClass; while (TRUE) { if (pThis->m_b_InitBuff == 1) break; if (pThis->m_bExitMe) return; SeSleep(1); } while (TRUE) { if (pThis->m_bExitMe) break; pThis->procWriteBuffer_DI(); // pThis->m_logger->WriteFmtStrWithTime_L3("[GetData] : call procWriteBuffer_AI"); pThis->procWriteBuffer_AI(); if (pThis->m_bufValueHasReady == 0) pThis->m_bufValueHasReady = 1; SeSleep(1); } } void CModbusExLnS::setFrameProperty(uint8 bufType) { if (bufType <= 0 || bufType > 6) return; uint32 nDataBuffLen = (uint32)(1 << bufType) * 1024; m_TxDataMaxLen = nDataBuffLen + sizeof(DATA_HEAD) + sizeof(DATA_BODY_HEAD) + 2; m_FrameObjNum_Max = nDataBuffLen / 2; m_FrameDINum_Max = m_FrameObjNum_Max * DINumberPerBlock; } //////////////////////////////////////////////////////////////// #if defined(WIN32) extern "C" __declspec(dllexport) #else extern "C" #endif CProtocol *CreateProtocol(char *defpara) { return (CProtocol*)(new CModbusExLnS()); }