5

Linux のシリアル ポートに接続されているすべての接続デバイスを検出する良い方法はありますか? 私は C++ でプログラミングしていますが、他の例も歓迎します。

すべてのポートを開こうとするだけで、成功したらポートのリストに追加できますが、これはあまり良い解決策ではないようです。

あなたは開発ディレクターに行くことができ、私のシリアルポートはUSBポートなので、どのttyUSB..ファイルが作成されたかを確認できます。ただし、tty0 から tty63 までのファイルは常にこのディレクトリにあるため、これは USB 以外のシリアル ポートでは機能しません。

私の例:

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);
    }
}

ありがとう!

4

2 に答える 2

9

Linux でデバイスを列挙する標準的な方法は、/sysファイル システムを参照することです。この場合、次のことができます。

  1. 内のすべてのファイルを列挙する/sys/class/tty
  2. 各ディレクトリについて、を使用して存在する/sys/class/tty/fooかどうかを確認します。 /sys/class/tty/foo/devicelstat()
    • 存在しない場合は、何らかの種類の仮想 tty デバイス (仮想コンソール ポート、ptmx など) を扱っており、破棄できます。
    • 存在する場合は、シリアル ポートを保持しますfoo

実際のシリアル ポートのリストが残るはずです。

于 2013-03-11T16:24:35.167 に答える
1

これが回答されてから数年が経過したことを考えると、この回答を追加しています。この回答は、Linux の新しいバージョンで機能します。std::filesystemまた、c++17 で導入され た新しいものも使用します。std::filesystem以前のバージョンの c++ では、boost または名前空間std::experimental::filesystem(を使用#include <experimental/filesystem>) で使用できます。ブーストを使用する場合は、コンパイルされたコンポーネントを含める必要があります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;
}
于 2021-01-17T18:23:26.227 に答える