首页 > 解决方案 > 如何关联 PCI 卡总线/功能或 VENDEV 和从 Linux C/C++ 安装的 /dev/ttySn

问题描述

我正在编写一个测试程序来验证我们广泛的 PCI、PCI Express、M.2(和相关总线)单端口和多端口卡系列的串行端口操作。

如何确定 /dev/ttyS{n} 是由哪个 PCI 卡在 Linux 上以编程方式 (CPP) 创建的。

例如,8 端口 RS232 卡安装在 Linux PC 中,Linux 内核驱动程序成功安装 8 个 /dev/ttyS 设备,用户运行我的程序,我的程序必须通过 8 个端口中的每一个以多个波特率发送/接收串行数据.

哪 8 个端口来自被测单元(“UUT”)?

好吧,一个Linux机器有/dev/ttyS0到/dev/ttyS31,/dev/ttyS0到/dev/ttyS3来自主板。在这个系统上,UUT 的 8 个端口安装为 /dev/ttyS4 到 /dev/ttyS11 ——但它可以/将在不同的系统/Linux 映像上使用不同的 ttyS 编号。

我可以lspci -n |grep $VEND:找到卡(“04:00.0 0700: VEND:DEVI”),手动获取前 7 个字节(04:00.0)并dmesg | grep 04:00.0 | grep ttyS获取该卡的端口列表......但我想从在“CPP”程序中。

我可以

for (const auto & entry : fs::directory_iterator("/dev/"))
    if (entry.path().filename().string().compare(0,4, "ttyS") == 0 )
        list.push_back( entry.path() );

获取此系统上所有 32 个 /dev/ttyS 设备的列表,但不知道哪些来自 UUT。

更糟糕的是,有些卡是 1、2、4 或 8 端口。更糟糕的是,可以同时安装多个多端口卡。

那么:如何以编程方式确定创建任何给定 /dev/ttyS 的 VENDEV?(C/CPP; gcc C++17)

涉及 libpci 的东西?( #include <pci/pci.h>)

`root@systemname:/proc/tty/driver# cat serial
serinfo:1.0 driver revision:
0: uart:16550A port:000003F8 irq:4 tx:0 rx:0
...
4: uart:ST16650 port:00003000 irq:18 tx:0 rx:0
5: uart:ST16650 port:00003008 irq:18 tx:0 rx:0
6: uart:ST16650 port:00003010 irq:18 tx:0 rx:0
7: uart:ST16650 port:00003018 irq:18 tx:0 rx:0
8: uart:ST16650 port:00003020 irq:18 tx:0 rx:0
9: uart:ST16650 port:00003028 irq:18 tx:0 rx:0
10: uart:ST16650 port:00003030 irq:18 tx:0 rx:0
11: uart:ST16650 port:00003038 irq:18 tx:0 rx:0
12: uart:unknown port:00000000 irq:0
...
31: uart:unknown port:00000000 irq:0`

我可以

struct pci_access *pciAccess;
struct pci_dev *dev;
pciAccess = pci_alloc(); 
pci_init(pciAccess);                                 
pci_scan_bus(pciAccess);                             
for (dev = pciAccess->devices; dev; dev = dev->next) 
{
    pci_fill_info(dev, PCI_FILL_IDENT); 
    if (dev->vendor_id == VENDOR_ID_UUT)
    {
        printf("%04x:%02x:%02x.%d vendor=%04x device=%04x  base0=%lx\n",
            dev->domain, dev->bus, dev->dev, dev->func, dev->vendor_id, dev->device_id,
            (long)dev->base_addr[0]&0xFFF0);
    }
}
pci_cleanup(pciAccess);

但它仍然没有让我以编程方式选择与检测到的卡关联的 8 个 ttyS 设备。

我真的需要壳setserial和解析输出吗?

标签: c++clinuxserial-port

解决方案


推荐阅读