126 lines
3.4 KiB
C++
126 lines
3.4 KiB
C++
#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
|