PCAN_USBBUSX 到 /dev/pcanusbX 之间的映射

PCAN_USBBUSX 到 /dev/pcanusbX 之间的映射

我有 Ubuntu 服务器(22.04.2 LTS),连接了多个 PCAN 设备,
CAN 驱动程序信息:

$ modinfo pcan
filename:       /lib/modules/6.5.0-26-generic/misc/pcan.ko
license:        GPL
version:        Release_20240116_n
description:    Driver for PEAK-System CAN interfaces
author:         [email protected]
author:         [email protected]
srcversion:     9B91AA025C2BA6422309BBB
alias:          usb:v0C72p0014d*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v0C72p0013d*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v0C72p0011d*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v0C72p0012d*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v0C72p000Dd*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v0C72p000Cd*dc*dsc*dp*ic*isc*ip*in*
alias:          pci:v0000001Cd0000001Asv*sd*bc*sc*i*
alias:          pci:v0000001Cd00000019sv*sd*bc*sc*i*
alias:          pci:v0000001Cd00000018sv*sd*bc*sc*i*
alias:          pci:v0000001Cd00000017sv*sd*bc*sc*i*
alias:          pci:v0000001Cd00000016sv*sd*bc*sc*i*
alias:          pci:v0000001Cd00000014sv*sd*bc*sc*i*
alias:          pci:v0000001Cd00000013sv*sd*bc*sc*i*
alias:          pci:v0000001Cd00000010sv*sd*bc*sc*i*
alias:          pci:v0000001Cd0000000Asv*sd*bc*sc*i*
alias:          pci:v0000001Cd00000002sv*sd*bc*sc*i*
alias:          pci:v0000001Cd00000009sv*sd*bc*sc*i*
alias:          pci:v0000001Cd00000008sv*sd*bc*sc*i*
alias:          pci:v0000001Cd00000007sv*sd*bc*sc*i*
alias:          pci:v0000001Cd00000006sv*sd*bc*sc*i*
alias:          pci:v0000001Cd00000005sv*sd*bc*sc*i*
alias:          pci:v0000001Cd00000004sv*sd*bc*sc*i*
alias:          pci:v0000001Cd00000003sv*sd*bc*sc*i*
alias:          pci:v0000001Cd00000001sv*sd*bc*sc*i*
depends:        i2c-algo-bit
retpoline:      Y
name:           pcan
vermagic:       6.5.0-26-generic SMP preempt mod_unload modversions 
parm:           fdusemsi: 0=INTA; 1=MSI (not shared); 2=MSI (shared) (def=0) (byte)
parm:           fdirqcl: PCIe FD IRQ Count Limit (default=16) (uint)
parm:           fdirqtl: PCIe FD IRQ Time Limit (default=10) (uint)
parm:           usemsi: 0=INTA; 1=MSI (not shared); 2=MSI (shared) (def=0) (byte)
parm:           fast_fwd: set fast forward option in USB device (def=0) (ushort)
parm:           irqmaxloop: max loops in ISR per CAN (0=default def=6) (uint)
parm:           irqmaxrmsg: max msgs read per Rx IRQ (0=default def=8) (uint)
parm:           type:type of PCAN interface (isa, sp, epp) (array of charp)
parm:           io:io-port address for either PCAN-ISA, PC/104 or Dongle (array of ulong)
parm:           irq:interrupt number for either PCAN-ISA, PC/104 or Dongle (array of byte)
parm:           btr0btr1:initial bitrate (BTR0BTR1 format) for all channels (ushort)
parm:           bitrate:initial nominal bitrate for all channels (charp)
parm:           dbitrate:initial data bitrate for all CAN-FD channels (charp)
parm:           rxqsize: size of the Rx FIFO of a channel (def=2000) (ushort)
parm:           rxqprealloc:allocate Rx FIFO once at probe time (byte)
parm:           txqsize: size of the Tx FIFO of a channel (def=500) (ushort)
parm:           txqprealloc:allocate Tx FIFO once at probe time (byte)
parm:           dmamask: [24..64] (def=64) (ushort)
parm:           deftsmode: default ts mode (ushort)
parm:           defblperiod: default bus load msg period (def=500 ms.) (ushort)
parm:           drvclkref: driver clock reference (def=0) (ushort)
parm:           txqhiwat: Tx fifo hi-water ratio [5000..10000] def=10000) (short)

连接设备列表:

~ $ ls /dev/* | grep -P "pcan\d+"
/dev/pcan32
/dev/pcan33
/dev/pcan34
/dev/pcan35
/dev/pcan36
/dev/pcan37
/dev/pcan38
/dev/pcan39

udevadm一台设备的信息:

~ $ udevadm info --query=all --name=/dev/pcan32
P: /devices/pci0000:00/0000:00:14.0/usb2/2-13/2-13.3/2-13.3.1/2-13.3.1.1/2-13.3.1.1:1.0/pcan/pcanusb32
N: pcanusb32
L: 0
S: pcan-usb/0/can0
S: pcan32
S: U3-PCAN-1
E: DEVPATH=/devices/pci0000:00/0000:00:14.0/usb2/2-13/2-13.3/2-13.3.1/2-13.3.1.1/2-13.3.1.1:1.0/pcan/pcanusb32
E: DEVNAME=/dev/pcanusb32
E: MAJOR=238
E: MINOR=32
E: SUBSYSTEM=pcan
E: USEC_INITIALIZED=1453865341559
E: DEVLINKS=/dev/pcan-usb/0/can0 /dev/pcan32 /dev/U3-PCAN-1

但是,当使用 python-can 检测可用设备时,我得到以下信息:

In [1]: from can.interface import detect_available_configs

In [2]: print("\n".join(map(str, detect_available_configs('pcan'))))
{'interface': 'pcan', 'channel': 'PCAN_USBBUS1', 'supports_fd': False, 'controller_number': 0, 'device_features': 0, 'device_id': 0, 'device_name': 'PCAN-USB', 'device_type': 5, 'channel_condition': 1}
{'interface': 'pcan', 'channel': 'PCAN_USBBUS2', 'supports_fd': True, 'controller_number': 0, 'device_features': 3, 'device_id': 0, 'device_name': 'PCAN-USB FD', 'device_type': 5, 'channel_condition': 1}
{'interface': 'pcan', 'channel': 'PCAN_USBBUS3', 'supports_fd': False, 'controller_number': 0, 'device_features': 0, 'device_id': 0, 'device_name': 'PCAN-USB', 'device_type': 5, 'channel_condition': 1}
{'interface': 'pcan', 'channel': 'PCAN_USBBUS4', 'supports_fd': False, 'controller_number': 0, 'device_features': 0, 'device_id': 0, 'device_name': 'PCAN-USB', 'device_type': 5, 'channel_condition': 1}
{'interface': 'pcan', 'channel': 'PCAN_USBBUS5', 'supports_fd': False, 'controller_number': 0, 'device_features': 0, 'device_id': 1, 'device_name': 'PCAN-USB', 'device_type': 5, 'channel_condition': 1}
{'interface': 'pcan', 'channel': 'PCAN_USBBUS6', 'supports_fd': False, 'controller_number': 0, 'device_features': 0, 'device_id': 0, 'device_name': 'PCAN-USB', 'device_type': 5, 'channel_condition': 1}
{'interface': 'pcan', 'channel': 'PCAN_USBBUS7', 'supports_fd': False, 'controller_number': 0, 'device_features': 0, 'device_id': 0, 'device_name': 'PCAN-USB', 'device_type': 5, 'channel_condition': 1}
{'interface': 'pcan', 'channel': 'PCAN_USBBUS8', 'supports_fd': False, 'controller_number': 0, 'device_features': 0, 'device_id': 0, 'device_name': 'PCAN-USB', 'device_type': 5, 'channel_condition': 1}

我如何知道每个/dev/pcanX映射到哪个PCAN_USBBUSX
因为在 Linux 系统中,第一个设备获取第一个索引,第二个设备获取第二个索引,依此类推……,

我可以假设第一个 pcan 设备(在我的例子中/dev/pcan32)被映射到PCAN_USBBUS1
,第二个设备/dev/pcan33被映射到PCAN_USBBUS2吗?
ETC...

我需要一个方法来确定每个/dev/pcan<X>映射到哪个PythonPCAN_USBBUS<X>

答案1

我创建了一个Python脚本,也许可以解决这个问题:


from can.interface import detect_available_configs
import glob
import os

can_devices: list[dict[str, str]] = detect_available_configs('pcan')

def get_devices() -> tuple[tuple[str, int, str], ...]:
    devices = sorted(
        glob.glob('/dev/pcan-usb*/*/*'),
        key=lambda x: int(os.readlink(x)[-2:])
    )
    links = sorted(
        # U*-PCAN-* is a symlink to /dev/pcan-usb* that was created by udev rules
        # based on the physical connection of the device
        # e.g.:
        # KERNEL=="pcanusb*", ATTRS{devpath}=="13.2.4.1.2", MODE="0660", SYMLINK+="U4-PCAN-1"
        # KERNEL=="pcanusb*", ATTRS{devpath}=="13.2.4.1.3", MODE="0660", SYMLINK+="U4-PCAN-2"
        glob.glob('/dev/U*-PCAN-*'),
        key=lambda x: int(os.readlink(x)[-2:])
    )
    return tuple((i, int(i.split('/')[3]), j) for i, j in zip(devices, links))

shift = 0
for index, (dev, can_index, link) in enumerate(get_devices()):
    if can_index + shift < index:
        shift += 1

    # can_devices[can_index + shift]['link'] = link
    can_devices[can_index + shift].update({
        'link': link,
        'device': dev,
        'dev': os.readlink(dev).replace('../..', '/dev')
    })

print("\n".join(map(str, can_devices)))

结果,我得到以下结果:

{'interface': 'pcan', 'channel': 'PCAN_USBBUS1', 'supports_fd': False, 'controller_number': 0, 'device_features': 0, 'device_id': 0, 'device_name': 'PCAN-USB', 'device_type': 5, 'channel_condition': 1, 'link': '/dev/U3-PCAN-1', 'device': '/dev/pcan-usb/0/can0', 'dev': '/dev/pcanusb32'}
{'interface': 'pcan', 'channel': 'PCAN_USBBUS2', 'supports_fd': True, 'controller_number': 0, 'device_features': 3, 'device_id': 0, 'device_name': 'PCAN-USB FD', 'device_type': 5, 'channel_condition': 1, 'link': '/dev/U3-PCAN-2', 'device': '/dev/pcan-usb_fd/0/can0', 'dev': '/dev/pcanusbfd33'}
{'interface': 'pcan', 'channel': 'PCAN_USBBUS3', 'supports_fd': False, 'controller_number': 0, 'device_features': 0, 'device_id': 0, 'device_name': 'PCAN-USB', 'device_type': 5, 'channel_condition': 1, 'link': '/dev/U4-PCAN-1', 'device': '/dev/pcan-usb/1/can0', 'dev': '/dev/pcanusb34'}
{'interface': 'pcan', 'channel': 'PCAN_USBBUS4', 'supports_fd': False, 'controller_number': 0, 'device_features': 0, 'device_id': 0, 'device_name': 'PCAN-USB', 'device_type': 5, 'channel_condition': 1, 'link': '/dev/U4-PCAN-2', 'device': '/dev/pcan-usb/2/can0', 'dev': '/dev/pcanusb35'}
{'interface': 'pcan', 'channel': 'PCAN_USBBUS5', 'supports_fd': False, 'controller_number': 0, 'device_features': 0, 'device_id': 1, 'device_name': 'PCAN-USB', 'device_type': 5, 'channel_condition': 1, 'link': '/dev/U2-PCAN-1', 'device': '/dev/pcan-usb/3/can0', 'dev': '/dev/pcanusb36'}
{'interface': 'pcan', 'channel': 'PCAN_USBBUS6', 'supports_fd': False, 'controller_number': 0, 'device_features': 0, 'device_id': 0, 'device_name': 'PCAN-USB', 'device_type': 5, 'channel_condition': 1, 'link': '/dev/U2-PCAN-2', 'device': '/dev/pcan-usb/4/can0', 'dev': '/dev/pcanusb37'}
{'interface': 'pcan', 'channel': 'PCAN_USBBUS7', 'supports_fd': False, 'controller_number': 0, 'device_features': 0, 'device_id': 0, 'device_name': 'PCAN-USB', 'device_type': 5, 'channel_condition': 1, 'link': '/dev/U1-PCAN-1', 'device': '/dev/pcan-usb/5/can0', 'dev': '/dev/pcanusb38'}
{'interface': 'pcan', 'channel': 'PCAN_USBBUS8', 'supports_fd': False, 'controller_number': 0, 'device_features': 0, 'device_id': 0, 'device_name': 'PCAN-USB', 'device_type': 5, 'channel_condition': 1, 'link': '/dev/U1-PCAN-2', 'device': '/dev/pcan-usb/6/can0', 'dev': '/dev/pcanusb39'}

请有人告诉我我的方法是否正确。
10 倍:)

相关内容