对反复使用的字符串再次使用时要清零!

博客指出,在再次使用反复用过的字符串时要进行清零操作,还提及了读取串口的变量字符串相关情况。

对反复使用的字符串再次使用时要清零!

如果再读串口的变量字符串等

int ALModbus::ModbusWriteString(int addr, string value, string& m_strErr) { // 1. 验证连接状态 if (mb == nullptr) { m_strErr = "错误: Modbus 连接未初始化"; return -1; } // 2. 检查连接是否仍然有效 int socket_fd = modbus_get_socket(mb); if (socket_fd < 0) { m_strErr = "错误: Modbus 连接已断开 (Bad file descriptor)"; return -2; } // 3. 计算字符串所需寄存器总数 int strLen = static_cast<int>(value.length()); // 针对超长字符串的优化 if (strLen > 600) { // 增加响应超间 (默认值通常是 500ms,增加到 2000ms) modbus_set_response_timeout(mb, 2, 0); // 2秒 } // 精确计算寄存器数量 (每个寄存器存储2个字符) int totalRegisters = (strLen + 1) / 2; // 4. 处理空字符串的特殊情况 if (strLen == 0) { // 写入一个空寄存器表示空字符串 uint16_t emptyReg = 0; int written = modbus_write_registers(mb, addr, 1, &emptyReg); if (written != 1) { m_strErr = "写入空字符串失败: " + std::string(modbus_strerror(errno)); return -1; } return 1; } // 5. Modbus 写入限制 - 针对超长字符串减小每次写入量 int MAX_REGISTERS = strLen > 600 ? 50 : 125; // 长字符串使用更小的块大小 // 6. 分块写入 int currentAddr = addr; int remaining = totalRegisters; int charsProcessed = 0; // 已处理的字符数 int retryCount = 0; const int MAX_RETRIES = 2; while (remaining > 0) { // 计算本次写入的寄存器数量 int writeCount = min(remaining, MAX_REGISTERS); std::vector<uint16_t> registers(writeCount, 0); // 填充数据到寄存器 for (int i = 0; i < writeCount * 2 && charsProcessed < strLen; ++i) { char currentChar = value[charsProcessed++]; int regIndex = i / 2; int charPos = i % 2; if (charPos == 0) // 高字节 { registers[regIndex] = static_cast<uint16_t>(static_cast<uint8_t>(currentChar)) << 8; } else // 低字节 { registers[regIndex] |= static_cast<uint8_t>(currentChar); } } // 处理奇数长度字符串的最后一个字符 if (charsProcessed == strLen && strLen % 2 != 0) { // 最后一个字符只填充了高字节,低字节保持0(已初始化) } // 写入Modbus寄存器(带重试机制) int written = -1; for (retryCount = 0; retryCount <= MAX_RETRIES; retryCount++) { written = modbus_write_registers(mb, currentAddr, writeCount, registers.data()); // 成功写入,跳出重试循环 if (written == writeCount) break; // 如果是连接错误,尝试重新连接 int err = errno; if (err == ECONNRESET || err == ETIMEDOUT || err == EBADF) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 尝试重新连接 modbus_close(mb); if (modbus_connect(mb) == -1) { // 重连失败,跳出循环 break; } } else { // 其他错误,不重试 break; } } // 检查写入结果 if (written != writeCount) { int err = errno; const char* errMsg = modbus_strerror(err); m_strErr = "Modbus 写入失败 [" + std::to_string(err) + "]: " + errMsg; // 添加具体错误信息 if (err == EMBBADDATA) { m_strErr += " (发送数据无效)"; } else if (err == EMBXILADD) { m_strErr += " (寄存器地址无效)"; } else if (err == EMBXILVAL) { m_strErr += " (寄存器值无效)"; } return -1; } // 写入后验证(仅当字符串较短才启用) if (strLen <= 600) { std::vector<uint16_t> readback(writeCount); int read = modbus_read_registers(mb, currentAddr, writeCount, readback.data()); if (read != writeCount) { m_strErr = "写入后读取失败: " + std::string(modbus_strerror(errno)); return -1; } for (int i = 0; i < writeCount; ++i) { if (readback[i] != registers[i]) { m_strErr = "写入后验证失败: 寄存器 " + std::to_string(currentAddr + i) + " 期望值 " + std::to_string(registers[i]) + " 实际值 " + std::to_string(readback[i]); return -1; } } } // 更新地址和剩余寄存器数量 currentAddr += writeCount; remaining -= writeCount; // 对于长字符串,添加短暂延迟以避免拥堵 if (strLen > 600) { std::this_thread::sleep_for(std::chrono::milliseconds(20)); } } return 1; // 成功 }这个重新写入,要舍弃上一次所有值
09-16
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值