Các lệnh để mô phỏng các loại bỏ và gắn lại một thiết bị ngoại vi USB?


8

Tôi sử dụng chuyển động trên Raspberry Pi và đôi khi nguồn cấp dữ liệu máy ảnh bị treo. Máy ảnh được gắn vật lý, và thật khó xử khi tháo cáp và cắm lại, vì vậy tôi đã tự hỏi:

Có cách nào để đạt được hiệu quả tương tự theo chương trình không?


Xin chào - Bạn có thể chấp nhận câu trả lời không: D có vẻ như một số câu trả lời ở đây đã giúp nhiều người trong tình huống của bạn .. tự hỏi liệu nó có giúp bạn không?
Piotr Kula

Câu trả lời:


8

Câu hỏi hay và ý kiến ​​hay. Shuckle gợi ý một số mã đặt lại bus USB cho thiết bị, điều này có thể làm sáng tỏ một số vấn đề. Xem diễn đàn chính thức:

http://www.raspberrypi.org/phpBB3/viewtopic.php?p=219980#p219980

Tôi trích dẫn mã c của anh ấy, mà tôi chưa thử nghiệm:

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/usbdevice_fs.h>

void main(int argc, char **argv)
{
    const char *filename;
    int fd;

    if (argc < 2) {
        printf("Give USB device name as parameter\n");
        exit(1);
    }
    filename = argv[1];
    fd = open(filename, O_WRONLY);
    if (fd == -1) {
        perror("USB device open failed");
        exit(2);
    }
    if (ioctl(fd, USBDEVFS_RESET, 0) == -1) {
        perror("USBDEVFS_RESET device ioctl failed");
        exit(3);
    }
    close(fd);
}

Sau đó, bạn sử dụng mã này bằng cách nói, về cơ bản:

usbreset /dev/bus/usb/001/004

Bạn có thể lấy số xe buýt từ lsusb:

$ lsusb
...
Bus 001 Device 004: ID 046d:092f Logitech, Inc. QuickCam Express Plus
Bus 001 Device 006: ID 046d:0825 Logitech, Inc. Webcam C270

Bây giờ bạn đã khiến tôi tò mò về việc liệu điều đó có khắc phục được sự cố với Express Plus cũ hay không, tôi sẽ sớm thử điều đó!


Cảm ơn bạn đã trả lời tuyệt vời, tôi chắc chắn sẽ kiểm tra nó! Hãy cho chúng tôi biết nếu nó khắc phục sự cố liên quan đến Express Plus của bạn. :-)
Christian Neverdal

Nó không khắc phục được sự cố của tôi, nhưng đoạn mã được nêu ở trên dường như đặt lại xe buýt và ngăn máy ảnh bị kẹt trong trạng thái bị hỏng. Ngoài ra, các bản cập nhật firmware tiếp tục cải thiện hiệu suất USB cho các máy ảnh nghi vấn này. ** Nhà ngoại cảm Linux 3.6.11+ # 414 PREEMPT Thu ngày 18 tháng Tư 02:00:59 BST 2013 armv6l GNU / Linux **
Tai Viinikka

5

Bạn có thể làm cho các thiết bị USB biến mất bằng sysfs. Tôi đã thử nghiệm điều này với bộ thu USB Logitech Unifying. Mặc dù lsusbđược liệt kê thiết bị, các phím bấm không được xử lý khi thiết bị được gỡ bỏ bằng phương pháp này.

  1. Xác định ID được liên kết với thiết bị USB của bạn bằng cách sử dụng dmesg. Chẳng hạn, sau khi cắm bộ thu USB vào, tôi lấy 1-1.2làm ID:

    usb 1-1.2: new full-speed USB device number 4 using dwc_otg
    usb 1-1.2: New USB device found, idVendor=046d, idProduct=c52b
    usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
    usb 1-1.2: Product: USB Receiver
    usb 1-1.2: Manufacturer: Logitech
    
  2. Tháo và lắp lại thiết bị:

    sudo sh -c 'echo 1-1.2 > /sys/bus/usb/drivers/usb/unbind'
    sudo sh -c 'echo 1-1.2 > /sys/bus/usb/drivers/usb/bind'
    
  3. Lợi nhuận!

Bạn cũng có thể thành công bằng cách viết unbind và ràng buộc trình điều khiển cho trình điều khiển máy ảnh của bạn. Sử dụng ls -l /dev/bus/[DRIVER]/devicesđể xác định trình điều khiển.

(Lấy cảm hứng từ một câu trả lời trên Unix.SE )


4

Theo tinh thần chia sẻ, tôi đã sửa đổi usbresetmã được cung cấp, trong câu trả lời của Tai ở trên, để chấp nhận các tham số như bạn nhận được lsusb(ngoài ra). Bằng cách đó, nó có thể được gọi một cách thuận tiện bằng cách

DEVNUMS=`lsusb | grep -i webcam | tr -d : | awk '{print $2, $4;}'`
/home/xyz/cam/usbreset $DEVNUMS

mà biến, ví dụ, thành

/home/xyz/cam/usbreset 001 018

Mã ở cuối

Tôi thấy trình điều khiển webcam Pi USB bị hỏng thường xuyên, nhưng đây là một cách để khôi phục nó. Nó là dễ nhất để làm cho thực thi được su root.

void main(int argc, char **argv)
{
    char devicename[1024];
    const char *filename = devicename;
    int fd;

    if ( 2 > argc || 3 < argc ) {
        printf("Give USB device name as parameter\n");
        exit(1);
    }

    if ( 2 == argc ) 
        filename = argv[1];
    else
        sprintf( devicename, "/dev/bus/usb/%s/%s", argv[1], argv[2] );

    printf( "Resetting USB device '%s'\n", filename );

    fd = open(filename, O_WRONLY);
    if (fd == -1) {
        perror("USB device open failed");
        exit(2);
    }
    if (ioctl(fd, USBDEVFS_RESET, 0) == -1) {
        // Don't care!  It usually does, when we need to reset it.
        //perror("USBDEVFS_RESET device ioctl failed");
        //exit(3);
    }
    close(fd);
}

1

Bạn có thể thử bỏ gắn và gắn ổ USB?

$ sudo mount /dev/sda1 /path/to/usb
$ sudo umount /path/to/usb

Dòng đầu tiên là tạo / path / to / usb điểm gắn của cổng usb tại / dev / sda1 (bạn sẽ phải kiểm tra xem cổng nào được kết nối với mỗi lần bạn cắm nó).

Dòng thứ hai đang ngắt kết nối cổng thông qua bí danh


1
Tôi nghĩ OP có nghĩa là được gắn kết vật lý và kết quả là khó có thể rút phích cắm. :)
Tai Viinikka

Vâng, vật lý gắn kết. (Và nhân tiện, đây không phải là ổ USB, đó là máy ảnh.)
Christian Neverdal
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.