C ++ linux检测所有串口

时间:2013-03-11 15:46:30

标签: c++ ubuntu serial-port

有没有一种很好的方法来检测连接在Linux上串行端口上的所有连接设备?我用C ++编程,但也欢迎其他例子。

您可以尝试打开每个端口,当它成功时,将其添加到端口列表中,但这似乎不是一个非常好的解决方案。

您可以进入开发人员,因为我的串口是USB端口,我可以检查哪些ttyUSB ..文件已经制作完成。但是这不适用于非USB串行端口,因为tty0到tty63的文件总是在这个目录中。

我的例子:

std::string port;
int fd 
std::vector<std::string>> list;
for(int i = 0; i < 256; ++i)
{
    port.clear();
    port.append("/dev/ttyUSB");
    port.append(std::to_string(i));
    fd = open(port.c_str(), O_RDWR | O_NOCTTY | O_DELAY);
    if(fd != -1)
    {
        list.push_back(port);
    }
}

谢谢!

2 个答案:

答案 0 :(得分:7)

在Linux中枚举设备的标准方法是浏览/sys文件系统。在这种情况下,您可以执行以下操作:

  1. 枚举/sys/class/tty
  2. 中的所有文件
  3. 对于每个目录/sys/class/tty/foo,使用/sys/class/tty/foo/device检查lstat()是否存在。
    • 如果它不存在,那么你正在处理某种虚拟tty设备(虚拟控制台端口,ptmx等......),你可以丢弃它。
    • 如果存在,则保留串口foo
  4. 您应该留下实际串口的列表。

答案 1 :(得分:0)

鉴于自从回答这个问题已经过去了很多年,我正在添加这个答案。此答案适用于更高版本的 linux。它还使用了 c++17 中引入的新 std::filesystemstd::filesystem 在早期版本的 c++ 中可以通过 boost 或在命名空间 std::experimental::filesystem 中使用(使用 #include <experimental/filesystem>)。如果使用 boost,则必须包含已编译的组件 system

此示例还计算出符号链接指向的位置并返回其规范名称。

#include <iostream>
#include <string>
#include <boost/filesystem.hpp>
#include <boost/asio.hpp>

using std::cout;
namespace fs = boost::filesystem;

std::vector<std::string> get_available_ports() {
    std::vector<std::string> port_names;

    fs::path p("/dev/serial/by-id");
    try {
      if (!exists(p)) {
        throw std::runtime_error(p.generic_string() + " does not exist");
      } else {
        for (fs::directory_entry &de : fs::directory_iterator(p)) {
          if (is_symlink(de.symlink_status())) {
            fs::path symlink_points_at = read_symlink(de);
            fs::path canonical_path = fs::canonical(symlink_points_at, p);
            port_names.push_back(canonical_path.generic_string());
          }
        }
      }
    } catch (const fs::filesystem_error &ex) {
      cout << ex.what() << '\n';
      throw ex;
    }
    std::sort(port_names.begin(), port_names.end());
    return port_names;
}