2010-11-16 23 views
9

Estamos haciendo un dispositivo y tiene 8 puertos serie. Se ejecuta en el kernel de Monta Vista Pro5. Y estamos trabajando en C.¿Cómo encontrar qué dispositivo está conectado a un puerto serie USB en Linux usando C?

Supongamos: Un dispositivo se conecta a ttyUSB0, ttyUSB1 y ttyUSB2. El siguiente dispositivo se conecta a ttyUSB3 y otro a ttyUSB4. ¿Cómo puedo saber qué dispositivo se conecta a qué puerto? es decir, ttyUSB0 o ttyUSB1 más o menos. ¿Hay alguna forma de consultar directamente el dispositivo y encontrar el puerto al que está conectado? O, en C, abre ttyUSB0, indaga de alguna manera y obtén alguna respuesta sobre qué dispositivo es?

Una forma bastante complicada: hacer una estadística de, digamos/dev/ttyUSB0. Obtener el número de dispositivo. Y busque esto en/proc/bus/usb/devices y encuentre la identificación del proveedor o algo para identificar el dispositivo.

O: ¿Hay alguna manera de reservar ttyUSB0, ttyUSB1 y ttyUSB2 para un dispositivo, ttyUSB3 para otro y así sucesivamente cuando están enchufadas? De esta forma sabré qué dispositivo está conectado a qué puerto.

Ayuda por favor ..... :)

Gracias de antemano. Nubin Stanley

+0

Vamos a ver si tengo ese derecho. Lo que intenta hacer es hacer coincidir los nodos/dev/ttyUSBx con el dispositivo/proc/bus/usb en el sistema host? ¿O está intentando identificar un dispositivo en serie que está conectado a un adaptador usbserial? – thkala

+0

stat'ing/dev/ solo obtendrá las versiones principales y secundarias del dispositivo.Esos no están de ninguna manera conectados a los identificadores de proveedor/producto/dispositivo. – thkala

+0

Entonces, ¿tiene un dispositivo con algunos IC usbserial (por ejemplo, de FTDI) y necesita identificarlo? ¿Ha establecido ids de proveedor/producto y número de serie en el chip usbserial? – thkala

Respuesta

0

La mejor manera de hacer esto es sería utilizar libusb, pero si eso no le da suficiente información acerca de sus dispositivos (que puede que no), entonces usted tendrá que usar el sistema de archivos /proc que el núcleo pone a disposición, específicamente /proc/bus/usb/.

Tiene una lectura de this information en /proc/bus/usb: en particular en /proc/bus/usb/devices. Pero como dices, ¡esto es un poco hacky!

+0

Actualmente estoy trabajando en libusb. Pero, de nuevo, no sé si me daría alguna indicación sobre a qué puerto está conectado un dispositivo ... Supongamos que consulto mi dispositivo usando libusb, de alguna manera tengo que descubrir 'x' en/dev/ttyUSB para que sepa que el dispositivo en particular es/dev/ttyUSB0 o ttyUSB1 más o menos :) – stanzlavos

9

Puede utilizar las reglas de udev para crear enlaces simbólicos sólo para su dispositivo:

(estas reglas van en /etc/udev/rules.d/-name.rules - vistazo a la documentación de udev

KERNEL=="ttyUSB*", ATTRS{idVendor}=="<vendorid>", MODE="0666", SYMLINK+="mydev" 

tiene que especificar su identificador de proveedor y/o identificación del producto para su dispositivo. a continuación, estos dispositivos estarán disponibles en/dev/mydev en el ejemplo anterior.

también puede utilizar otros parámetros para crear apropiada enlaces simbólicos únicos para su uso. Consulte la página de manual de udev.

+0

Lo que sugirió me ayudaría a obtener un enlace único a mi dispositivo. Pero eso no es lo que quiero. – stanzlavos

+0

Se han conectado 3 dispositivos aleatorios que ocupan ttyUSB0, ttyUSB1 y ttyUSB2. Ahora el problema es que no sé qué dispositivos están conectados a qué puerto. Necesito una forma de averiguar qué dispositivo está conectado a ttyUSB0 o ttyUSB1 o ttyUSB2 :) – stanzlavos

+0

He respondido a su pregunta: "¿Hay alguna manera de reservar ttyUSB0, ttyUSB1 y ttyUSB2 para un dispositivo, ttyUSB3 para otro ... ". Si desea reservar entradas de dispositivos en un dispositivo, necesita conocer los detalles de ese dispositivo. Por supuesto, si son dispositivos aleatorios, esto no ayudará. – rsmoorthy

1

Este código de Python parece encontrar el número/dev/ttyUSB para la identificación del vendedor y la identificación del producto. No es difícil traducirlo a C. Analizar la salida de hwinfo --usb puede hacer el truco, también. El regx es:

"\s\sVendor:\susb\s0x([0-9a-f]{4}).*?\s\sDevice:\susb\s0x([0-9a-f]{4}).*?\s\sDevice\sFile:\s/dev/ttyUSB([0-9]+)" 
import glob 
import os 
import re 

def find_usb_tty(vendor_id = None, product_id = None) : 
    tty_devs = [] 

    for dn in glob.glob('/sys/bus/usb/devices/*') : 
     try  : 
      vid = int(open(os.path.join(dn, "idVendor")).read().strip(), 16) 
      pid = int(open(os.path.join(dn, "idProduct")).read().strip(), 16) 
      if ((vendor_id is None) or (vid == vendor_id)) and ((product_id is None) or (pid == product_id)) : 
       dns = glob.glob(os.path.join(dn, os.path.basename(dn) + "*")) 
       for sdn in dns : 
        for fn in glob.glob(os.path.join(sdn, "*")) : 
         if re.search(r"\/ttyUSB[0-9]+$", fn) : 
          #tty_devs.append("/dev" + os.path.basename(fn)) 
          tty_devs.append(os.path.join("/dev", os.path.basename(fn))) 
         pass 
        pass 
       pass 
      pass 
     except (ValueError, TypeError, AttributeError, OSError, IOError) : 
      pass 
     pass 

    return tty_devs 

print find_usb_tty() 
3

Aquí está mi código, basado en Alex Robinson, pero sin global "excepto":

import os 
from os.path import join 

def find_tty_usb(idVendor, idProduct): 
    """find_tty_usb('067b', '2302') -> '/dev/ttyUSB0'""" 
    # Note: if searching for a lot of pairs, it would be much faster to search 
    # for the enitre lot at once instead of going over all the usb devices 
    # each time. 
    for dnbase in os.listdir('/sys/bus/usb/devices'): 
     dn = join('/sys/bus/usb/devices', dnbase) 
     if not os.path.exists(join(dn, 'idVendor')): 
      continue 
     idv = open(join(dn, 'idVendor')).read().strip() 
     if idv != idVendor: 
      continue 
     idp = open(join(dn, 'idProduct')).read().strip() 
     if idp != idProduct: 
      continue 
     for subdir in os.listdir(dn): 
      if subdir.startswith(dnbase+':'): 
       for subsubdir in os.listdir(join(dn, subdir)): 
        if subsubdir.startswith('ttyUSB'): 
         return join('/dev', subsubdir) 
Cuestiones relacionadas