Files
vision_sjtu_19/armor/include/serialManager.hpp
2026-03-28 04:54:33 +08:00

126 lines
3.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef SERIAL_MANAGER_HPP
#define SERIAL_MANAGER_HPP
#include "serialComm.hpp"
#include <thread>
#include <atomic>
#include <mutex>
#include <cstdio>
#include <chrono>
class SerialManager {
private:
SerialComm m_serial;
std::thread m_connectionThread;
std::atomic<bool> m_isConnected;
std::atomic<bool> m_shouldStop;
std::mutex m_serialMutex;
int m_retryIntervalMs;
// 后台重连线程函数
void connectionThreadFunc() {
printf("[I][SerialMgr]: RETRY\n");
while (!m_shouldStop.load()) {
if (!m_isConnected.load()) {
std::lock_guard<std::mutex> lock(m_serialMutex);
if (m_serial.findFirstTtyUSB() && m_serial.openPort()) {
m_isConnected.store(true);
} else {
printf("[W][SerialMgr]: Failed, retry in %dms\n", m_retryIntervalMs);
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(m_retryIntervalMs));
}
printf("[I][SerialMgr]: EXIT\n");
}
public:
// 构造函数retryIntervalMs - 重试间隔(毫秒)
SerialManager(int retryIntervalMs = 500)
: m_isConnected(false)
, m_shouldStop(false)
, m_retryIntervalMs(retryIntervalMs) {
}
~SerialManager() {
stop();
}
// 启动管理器(开始后台重连)
void start() {
if (!m_connectionThread.joinable()) {
m_shouldStop.store(false);
m_connectionThread = std::thread(&SerialManager::connectionThreadFunc, this);
printf("[I][SerialMgr]: START\n");
}
}
// 停止管理器
void stop() {
if (m_connectionThread.joinable()) {
m_shouldStop.store(true);
m_connectionThread.join();
std::lock_guard<std::mutex> lock(m_serialMutex);
m_serial.closePort();
m_isConnected.store(false);
printf("[I][SerialMgr]: STOP\n");
}
}
// 检查是否已连接
bool isConnected() const {
return m_isConnected.load();
}
// 发送数据(线程安全)
bool sendData(const char* data, size_t length) {
if (!m_isConnected.load()) {
return false;
}
std::lock_guard<std::mutex> lock(m_serialMutex);
if (!m_serial.sendData(data, length)) {
// 发送失败,标记为断开
m_isConnected.store(false);
printf("[W][SerialMgr]: Failed, mark DISCONNECT\n");
return false;
}
return true;
}
// 发送数据(字节数组)
bool sendData(const uint8_t* data, size_t length) {
return sendData(reinterpret_cast<const char*>(data), length);
}
// 接收数据(线程安全)
int receiveData(uint8_t* buffer, size_t maxLength) {
if (!m_isConnected.load()) {
return -1;
}
std::lock_guard<std::mutex> lock(m_serialMutex);
return m_serial.receiveData(buffer, maxLength);
}
// 接收数据(字符数组)
int receiveData(char* buffer, size_t maxLength) {
return receiveData(reinterpret_cast<uint8_t*>(buffer), maxLength);
}
// 获取端口名
const char* getPortName() const {
return m_serial.getPortName();
}
};
#endif // SERIAL_MANAGER_HPP