From 91edce4c65f08dd2f4981c55427d0a78daeb8ee6 Mon Sep 17 00:00:00 2001 From: cyy_mac Date: Thu, 26 Mar 2026 18:55:36 +0800 Subject: [PATCH] uart fix --- .../transporter_driver/uart_transporter.cpp | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/rm_hardware_driver/rm_serial_driver/src/transporter_driver/uart_transporter.cpp b/src/rm_hardware_driver/rm_serial_driver/src/transporter_driver/uart_transporter.cpp index d086797..17e8777 100644 --- a/src/rm_hardware_driver/rm_serial_driver/src/transporter_driver/uart_transporter.cpp +++ b/src/rm_hardware_driver/rm_serial_driver/src/transporter_driver/uart_transporter.cpp @@ -27,9 +27,51 @@ #include #include /*PPSIX 终端控制定义*/ #include /*Unix 标准函数定义*/ +#include /*目录操作*/ +#include /*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; } // 恢复串口为阻塞状态