This commit is contained in:
cyy_mac
2026-03-26 18:55:36 +08:00
parent 45c4526218
commit 91edce4c65

View File

@@ -27,9 +27,51 @@
#include <sys/types.h>
#include <termios.h> /*PPSIX 终端控制定义*/
#include <unistd.h> /*Unix 标准函数定义*/
#include <dirent.h> /*目录操作*/
#include <cctype> /*isdigit*/
namespace fyt::serial_driver {
// 自动搜索匹配的串口设备
static std::string find_ttyacm_device(const std::string& device_path) {
if (device_path.find("/dev/ttyACM") == 0) {
// 先尝试直接打开指定设备O_RDWR | O_NOCTTY | O_NDELAY
int test_fd = open(device_path.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
if (test_fd >= 0) {
close(test_fd);
return device_path;
}
// 指定设备不可用,搜索所有 ttyACM* 设备
DIR* dir = opendir("/dev");
if (dir) {
struct dirent* entry;
int max_num = -1;
std::string found_path;
while ((entry = readdir(dir)) != nullptr) {
// 匹配 ttyACM 开头,且后面是数字
if (strncmp(entry->d_name, "ttyACM", 6) == 0 && isdigit(entry->d_name[6])) {
std::string full_path = std::string("/dev/") + entry->d_name;
// 检查是否是有效字符设备
struct stat st;
if (stat(full_path.c_str(), &st) == 0 && S_ISCHR(st.st_mode)) {
// 提取数字部分
int num = atoi(entry->d_name + 6);
if (num > max_num) {
max_num = num;
found_path = full_path;
}
}
}
}
closedir(dir);
if (!found_path.empty()) {
return found_path;
}
}
}
return device_path;
}
bool UartTransporter::setParam(int speed, int flow_ctrl, int databits, int stopbits, int parity) {
// 设置串口数据帧格式
int speed_arr[] = {B115200, B19200, B9600, B4800, B2400, B1200, B300};
@@ -147,9 +189,10 @@ bool UartTransporter::open() {
if (is_open_) {
return true;
}
fd_ = ::open(device_path_.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
std::string actual_path = find_ttyacm_device(device_path_);
fd_ = ::open(actual_path.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
if (-1 == fd_) {
error_message_ = "can't open uart device: " + device_path_;
error_message_ = "can't open uart device: " + actual_path;
return false;
}
// 恢复串口为阻塞状态