| | |
| | | if (nRet == 0) { |
| | | m_bConnected.store(true); |
| | | m_enBoardType = enBoardType; |
| | | } else { |
| | | } |
| | | else { |
| | | UpdateLastError(nRet); |
| | | LOG_ERROR(m_strLastError); |
| | | } |
| | |
| | | } |
| | | |
| | | // 获取版本信息 |
| | | short buf[32] = {0}; |
| | | short buf[32] = { 0 }; |
| | | const short nRet = mdBdVerRead(m_nPath, buf); |
| | | if (nRet != 0) { |
| | | UpdateLastError(nRet); |
| | |
| | | return ERROR_CODE_NOT_CONNECTED; |
| | | } |
| | | |
| | | short buf[6] = {0}; |
| | | short buf[6] = { 0 }; |
| | | const short nRet = mdBdSwRead(m_nPath, buf); |
| | | if (nRet != 0) { |
| | | UpdateLastError(nRet); |
| | |
| | | |
| | | // 初始化读取缓冲区 |
| | | vecData.clear(); |
| | | vecData.resize(nSize); |
| | | vecData.resize(nSize, 0); |
| | | |
| | | // 确保线程安全的最小锁定范围 |
| | | { |
| | | std::lock_guard<std::mutex> lock(m_mtx); |
| | | short* pData = vecData.data(); |
| | | nSize *= sizeof(short); |
| | | nRet = mdReceive(m_nPath, CombineStation(station), nDevType, nDevNo, &nSize, pData); |
| | | } |
| | | |
| | |
| | | return nRet; |
| | | } |
| | | |
| | | // 计算需要读取的字节大小(按位对齐为字节数) |
| | | if (nDevNo % 8 != 0) { |
| | | nRet = -2; |
| | | UpdateLastError(nRet); |
| | | return nRet; |
| | | } |
| | | |
| | | const short nDevType = CalculateDeviceType(station, enDevType); |
| | | const auto nSize = static_cast<short>((nBitCount + 7) / 8); // 向上取整 |
| | | std::vector<short> vecTempBuffer((nSize + 1) / 2, 0); // 临时缓冲区,字节对齐 |
| | | const auto nSize = static_cast<short>((static_cast<int>(nBitCount) + 15) / 16); // 计算需要读取的字数量(向上取整) |
| | | |
| | | std::vector<short> vecTempBuffer(nSize, 0); |
| | | nRet = ReadData(station, nDevType, nDevNo, nSize, vecTempBuffer); |
| | | |
| | | if (nRet == 0) { |
| | | std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护 |
| | | ConvertShortToUint8(vecTempBuffer, vecData); |
| | | vecData.clear(); |
| | | |
| | | // 将字数据解析为位数据 |
| | | for (short nIdx = 0; nIdx < nSize; ++nIdx) { |
| | | const short nCurrentValue = vecTempBuffer[nIdx]; |
| | | // 遍历当前 short 中的每一位 |
| | | for (int bitIdx = 0; bitIdx < 16; ++bitIdx) { |
| | | bool bBit = (nCurrentValue & (1 << bitIdx)) != 0; |
| | | vecData.push_back(bBit); |
| | | if (vecData.size() >= nBitCount) { |
| | | return nRet; // 如果已经读取完所需的位数,提前退出 |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | return nRet; |
| | |
| | | // 确保线程安全的最小锁定范围 |
| | | { |
| | | std::lock_guard<std::mutex> lock(m_mtx); |
| | | nSize *= sizeof(short); |
| | | nRet = mdSend(m_nPath, CombineStation(station), nDevType, nDevNo, &nSize, pData); |
| | | } |
| | | |
| | |
| | | // 写位数据 |
| | | int CPerformanceMelsec::WriteBitData(const StationIdentifier& station, const DeviceType enDevType, const short nDevNo, const BitContainer& vecData) { |
| | | // 验证站点参数和数据有效性 |
| | | const int nRet = ValidateStationAndData(station, vecData); |
| | | int nRet = ValidateStationAndData(station, vecData); |
| | | if (nRet != 0) { |
| | | UpdateLastError(nRet); |
| | | return nRet; |
| | | } |
| | | |
| | | // 计算需要写入的字节数(位数据需要按 8 位对齐为字节数) |
| | | const short nDevType = CalculateDeviceType(station, enDevType); |
| | | const auto nSize = static_cast<short>((vecData.size() + 7) / 8); |
| | | std::vector<short> vecBuffer(vecData.size() / 2 + vecData.size() % 2, 0); |
| | | { |
| | | std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护 |
| | | ConvertUint8ToShort(vecData, vecBuffer); |
| | | if (nDevNo % 8 != 0) { |
| | | nRet = -2; |
| | | UpdateLastError(nRet); |
| | | return nRet; |
| | | } |
| | | |
| | | return WriteData(station, nDevType, nDevNo, nSize, vecBuffer.data()); |
| | | const short nDevType = CalculateDeviceType(station, enDevType); |
| | | const auto nSize = static_cast<short>((static_cast<int>(vecData.size()) + 15) / 16); // 计算需要写入的字数量(向上取整) |
| | | |
| | | // 准备临时缓冲区来存储转换后的 16 位数据 |
| | | std::vector<short> vecTempBuffer(nSize, 0); |
| | | { |
| | | std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护 |
| | | // 将位数据按字打包到临时缓冲区 |
| | | for (int i = 0; i < vecData.size(); ++i) { |
| | | if (vecData[i]) { |
| | | // 使用 & 0xFFFF 保证不会超过 16 位,防止溢出 |
| | | vecTempBuffer[i / 16] |= static_cast<short>((1 << (i % 16)) & 0xFFFF); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return WriteData(station, nDevType, nDevNo, nSize, vecTempBuffer.data()); |
| | | } |
| | | |
| | | // 写字数据 |
| | |
| | | |
| | | // 计算需要写入的字节数(每个字占 2 字节) |
| | | const short nDevType = CalculateDeviceType(station, enDevType); |
| | | const auto nSize = static_cast<short>(vecData.size() * sizeof(uint16_t)); |
| | | const auto nSize = static_cast<short>(vecData.size()); |
| | | const auto pData = const_cast<short*>(reinterpret_cast<const short*>(vecData.data())); |
| | | |
| | | return WriteData(station, nDevType, nDevNo, nSize, pData); |
| | |
| | | |
| | | // 计算需要写入的字节数(每个双字占 4 字节) |
| | | const short nDevType = CalculateDeviceType(station, enDevType); |
| | | const auto nSize = static_cast<short>(vecData.size() * sizeof(uint32_t)); |
| | | std::vector<short> vecBuffer(vecData.size() * 2, 0); |
| | | const auto nSize = static_cast<short>(vecData.size() * sizeof(short)); |
| | | std::vector<short> vecBuffer(nSize, 0); |
| | | { |
| | | std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护 |
| | | ConvertUint32ToShort(vecData, vecBuffer); |
| | |
| | | return ERROR_CODE_INVALID_PARAM; |
| | | } |
| | | |
| | | vecData.resize(nSize); |
| | | long nActualSize = (nSize + 1) / 2; |
| | | std::vector<short> vecBuffer(nActualSize, 0); |
| | | nSize = nSize % 2 != 0 ? nSize + 1 : nSize; |
| | | std::vector<short> vecBuffer(nSize / 2, 0); |
| | | |
| | | { |
| | | std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护 |
| | | nRet = mdReceiveEx(m_nPath, station.nNetNo, station.nStNo, nDevType, nDevNo, &nActualSize, vecBuffer.data()); |
| | | nRet = mdReceiveEx(m_nPath, station.nNetNo, station.nStNo, nDevType, nDevNo, &nSize, vecBuffer.data()); |
| | | } |
| | | |
| | | if (nRet != 0) { |
| | | UpdateLastError(nRet); |
| | | LOG_ERROR(m_strLastError); |
| | | } else { |
| | | } |
| | | else { |
| | | std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护 |
| | | vecData.resize(nSize); |
| | | ConvertShortToChar(vecBuffer, vecData); |
| | | } |
| | | |
| | |
| | | |
| | | // 将 vecData 转换为 short 类型的缓冲区 |
| | | long nSize = static_cast<long>(vecData.size()); |
| | | std::vector<short> vecBuffer((nSize + 1) / 2, 0); |
| | | nSize = nSize % 2 != 0 ? nSize + 1 : nSize; |
| | | std::vector<short> vecBuffer(nSize / 2, 0); |
| | | |
| | | { |
| | | std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护 |
| | |
| | | if (nRet != 0) { |
| | | UpdateLastError(nRet); // 更新错误码 |
| | | LOG_ERROR(m_strLastError); |
| | | } else { |
| | | } |
| | | else { |
| | | std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护 |
| | | ConvertShortToChar(vecBuffer, vecData); |
| | | } |
| | |
| | | if (nRet != 0) { |
| | | UpdateLastError(nRet); |
| | | LOG_ERROR(m_strLastError); |
| | | } else { |
| | | } |
| | | else { |
| | | std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护 |
| | | ConvertShortToChar(vecBuffer, vecData); |
| | | } |
| | |
| | | } |
| | | |
| | | // 第 0 个元素存储数量,最大支持 64 个事件 |
| | | std::array<short, 65> eventno = {0}; |
| | | std::array<short, 65> eventno = { 0 }; |
| | | eventno[0] = static_cast<short>(vecEventNumbers.size()); |
| | | std::copy(vecEventNumbers.begin(), vecEventNumbers.end(), eventno.begin() + 1); |
| | | |
| | |
| | | if (it != m_mapError.end()) { |
| | | // 如果找到,直接返回对应语言的错误信息 |
| | | m_strLastError = it->second; |
| | | } else { |
| | | } |
| | | else { |
| | | // 如果未找到,处理特殊范围 |
| | | m_strLastError = "Unknown error."; |
| | | if (nCode == -28611 || nCode == -28612) { |
| | |
| | | BoardType CPerformanceMelsec::FindBoardTypeByChannel(const int nChannel) { |
| | | if (nChannel >= MELSECNET_CHANNEL(1) && nChannel <= MELSECNET_CHANNEL(4)) { |
| | | return BoardType::MELSECNET_H; |
| | | } else if (nChannel >= CC_LINK_CHANNEL(1) && nChannel <= CC_LINK_CHANNEL(4)) { |
| | | } |
| | | else if (nChannel >= CC_LINK_CHANNEL(1) && nChannel <= CC_LINK_CHANNEL(4)) { |
| | | return BoardType::CC_LINK_VER_2; |
| | | } else if (nChannel >= CC_LINK_IE_CONTROL_CHANNEL(1) && nChannel <= CC_LINK_IE_CONTROL_CHANNEL(4)) { |
| | | } |
| | | else if (nChannel >= CC_LINK_IE_CONTROL_CHANNEL(1) && nChannel <= CC_LINK_IE_CONTROL_CHANNEL(4)) { |
| | | return BoardType::CC_LINK_IE_CONTROL; |
| | | } else if (nChannel >= CC_LINK_IE_FIELD_CHANNEL(1) && nChannel <= CC_LINK_IE_FIELD_CHANNEL(4)) { |
| | | } |
| | | else if (nChannel >= CC_LINK_IE_FIELD_CHANNEL(1) && nChannel <= CC_LINK_IE_FIELD_CHANNEL(4)) { |
| | | return BoardType::CC_LINK_IE_FIELD; |
| | | } else if (nChannel >= CC_LINK_IE_TSN_CHANNEL(1) && nChannel <= CC_LINK_IE_TSN_CHANNEL(4)) { |
| | | } |
| | | else if (nChannel >= CC_LINK_IE_TSN_CHANNEL(1) && nChannel <= CC_LINK_IE_TSN_CHANNEL(4)) { |
| | | return BoardType::CC_LINK_IE_TSN; |
| | | } |
| | | return BoardType::UNKNOWN; |
| | |
| | | enDevType == DeviceType::LSB || enDevType == DeviceType::LSW) { |
| | | // 网络号加偏移 |
| | | nDevType += station.nNetNo; |
| | | } else if (enDevType == DeviceType::ER) { |
| | | } |
| | | else if (enDevType == DeviceType::ER) { |
| | | // 文件寄存器的块号加偏移 |
| | | nDevType += 0; |
| | | } else if (enDevType == DeviceType::SPG) { |
| | | } |
| | | else if (enDevType == DeviceType::SPG) { |
| | | // 起始 I/O No. ÷ 16 的值 |
| | | nDevType += 0 / 16; |
| | | } |
| | |
| | | for (size_t i = 0; i < vecChar.size(); i++) { |
| | | if (i % 2 == 0) { |
| | | vecShort[i / 2] = static_cast<unsigned char>(vecChar[i]); // 低字节 |
| | | } else { |
| | | } |
| | | else { |
| | | vecShort[i / 2] |= static_cast<unsigned char>(vecChar[i]) << 8; // 高字节 |
| | | } |
| | | } |
| | |
| | | for (size_t i = 0; i < vecUint8.size(); i++) { |
| | | if (i % 2 == 0) { |
| | | vecShort[i / 2] = static_cast<short>(vecUint8[i]); // 低字节 |
| | | } else { |
| | | } |
| | | else { |
| | | vecShort[i / 2] |= static_cast<short>(vecUint8[i] << 8); // 高字节 |
| | | } |
| | | } |
| | |
| | | vecUint32.resize((vecShort.size() + 1) / 2, 0); // 每两个 short 合并为一个 uint32_t |
| | | for (size_t i = 0; i < vecUint32.size(); i++) { |
| | | vecUint32[i] = (static_cast<uint32_t>(static_cast<uint16_t>(vecShort[i * 2 + 1])) << 16) | // 高16位 |
| | | static_cast<uint32_t>(static_cast<uint16_t>(vecShort[i * 2])); // 低16位 |
| | | static_cast<uint32_t>(static_cast<uint16_t>(vecShort[i * 2])); // 低16位 |
| | | } |
| | | } |
| | | |