LAPTOP-SNT8I5JK\Boounion
2025-03-03 bf55b2f3083cbfdeb83611b2fa2dd552bf5b0775
SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.cpp
@@ -219,7 +219,8 @@
    if (nRet == 0) {
        m_bConnected.store(true);
        m_enBoardType = enBoardType;
    } else {
    }
    else {
        UpdateLastError(nRet);
        LOG_ERROR(m_strLastError);
    }
@@ -270,7 +271,7 @@
    }
    // 获取版本信息
    short buf[32] = {0};
    short buf[32] = { 0 };
    const short nRet = mdBdVerRead(m_nPath, buf);
    if (nRet != 0) {
        UpdateLastError(nRet);
@@ -428,7 +429,7 @@
        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);
@@ -451,12 +452,13 @@
    // 初始化读取缓冲区
    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);
    }
@@ -481,15 +483,33 @@
        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;
@@ -556,6 +576,7 @@
    // 确保线程安全的最小锁定范围
    {
        std::lock_guard<std::mutex> lock(m_mtx);
        nSize *= sizeof(short);
        nRet = mdSend(m_nPath, CombineStation(station), nDevType, nDevNo, &nSize, pData);
    }
@@ -570,22 +591,35 @@
// 写位数据
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());
}
// 写字数据
@@ -599,7 +633,7 @@
    // 计算需要写入的字节数(每个字占 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);
@@ -616,8 +650,8 @@
    // 计算需要写入的字节数(每个双字占 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);
@@ -640,20 +674,21 @@
        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);
    }
@@ -671,7 +706,8 @@
    // 将 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); // 线程安全保护
@@ -797,7 +833,8 @@
    if (nRet != 0) {
        UpdateLastError(nRet); // 更新错误码
        LOG_ERROR(m_strLastError);
    } else {
    }
    else {
        std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护
        ConvertShortToChar(vecBuffer, vecData);
    }
@@ -854,7 +891,8 @@
    if (nRet != 0) {
        UpdateLastError(nRet);
        LOG_ERROR(m_strLastError);
    } else {
    }
    else {
        std::lock_guard<std::mutex> lock(m_mtx); // 线程安全保护
        ConvertShortToChar(vecBuffer, vecData);
    }
@@ -1022,7 +1060,7 @@
    }
    // 第 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);
@@ -1051,7 +1089,8 @@
    if (it != m_mapError.end()) {
        // 如果找到,直接返回对应语言的错误信息
        m_strLastError = it->second;
    } else {
    }
    else {
        // 如果未找到,处理特殊范围
        m_strLastError = "Unknown error.";
        if (nCode == -28611 || nCode == -28612) {
@@ -1179,13 +1218,17 @@
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;
@@ -1206,10 +1249,12 @@
        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;
    }
@@ -1223,7 +1268,8 @@
    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; // 高字节
        }
    }
@@ -1244,7 +1290,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);    // 高字节
        }
    }
@@ -1273,7 +1320,7 @@
    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位
    }
}