Làm cách nào để đặt lại thiết bị USB bằng tập lệnh?


11

Tôi có modem USB GSM không thuộc tính hoạt động (Huawei E367u-2) Đôi khi, nó được đặt lại (ngắt kết nối / kết nối lại thiết bị USB trong nhật ký) và khi sao lưu, nó có các số ttyUSB khác nhau. Đôi khi khi khởi động, usb_modswitch dường như không bị sa thải. Máy tính là một Raspberry Pi chạy Raspbian.

Tôi có một giải pháp đơn giản cho vấn đề này, cứ sau một phút CRON lại chạy đoạn script sau:

If WVDIAL is not running:
    Run WVDIAL

Tôi muốn thay đổi tập lệnh thành:

If /dev/ttyUSB0 is not present:
    If DevicePresent(12d1:1446):
        ResetDevice(12d1:1446)
    ElseIs DevicePresemt(12d1:1506)
        ResetUSB(12d1:1506)
If WVDIAL is not running:
    Run WVDIAL

Rõ ràng đây là mã giả, nhưng tôi có các dòng sau mà tôi cần phải xâu chuỗi lại với nhau nhưng tôi không thể tìm ra cách:

Điều này tải wvdial nếu nó không chạy:

#! /bin/sh 
# /etc/init.d/wvdial

### BEGIN INIT INFO
# Provides:          TheInternet
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Simple script to start a program at boot
# Description:       A simple script from www.stuffaboutcode.com which will start / stop a program a boot / shutdown.
### END INIT INFO

# If you want a command to always run, put it here

# Carry out specific functions when asked to by the system
case "$1" in
  start)
    echo "Starting GPRS Internet"
    # run application you want to start
    /sbin/start-stop-daemon --start --background --quiet --exec /usr/bin/wvdial internet
    ;;
  stop)
    echo "Stopping GPRS Internet"
    # kill application you want to stop
    /sbin/start-stop-daemon --stop --exec /usr/bin/wvdial 
    ;;
  *)
    echo "Usage: /etc/init.d/noip {start|stop}"
    exit 1
    ;;
esac

exit 0

Điều này cho phép tôi tìm /sysđường dẫn đến một thiết bị nhất định:

for X in /sys/bus/usb/devices/*; do
    echo "$X"
    cat "$X/idVendor" 2>/dev/null
    cat "$X/idProduct" 2>/dev/null
    echo
done

Và điều này đặt lại một thiết bị USB nếu bạn biết đường dẫn / sys chính xác:

echo 0 > /sys/bus/usb/devices/1-1.2.1.1/authorized
echo 1 > /sys/bus/usb/devices/1-1.2.1.1/authorized

Vì vậy, tôi cần xâu chuỗi 2 phần cuối cùng và kiểm tra /dev/ttyUSB0vào một phần nằm trong phần "Nếu bạn muốn một lệnh luôn chạy. Đặt nó ở đây"

CẬP NHẬT 1

usbreset, mặc dù hoạt động, không thực hiện công việc. Chỉ lặp lại 0 0 thành authroizedmô phỏng chính xác một thiết bị ngắt kết nối / kết nối lại.
Đây là những gì mà thủ thuật khởi động thiết bị hoặc usb_modeswitch trở lại. Vì vậy, tôi đã xoay sở để cùng nhau giải quyết vấn đề này:

echo "Searching for $1"
devPath=`lsusb | grep $1 | sed -r 's/Bus ([0-9]{3}) Device ([0-9]{3}).*/bus\/usb\/\1\/\2/g;'`
echo "Found $1 @ $devPath"
echo "Searching for sysPath"
for sysPath in /sys/bus/usb/devices/*; do
    echo "$sysPath/uevent"
    devName=`cat "$sysPath/uevent" | grep $devPath`
    #echo devName=$devName
    if [ ! -z $devName ] 
    then
        break
    fi
done
if [ ! -z  $devName ] 
then
    echo "Found $1 @ $sysPath, Resetting"
    echo "echo 0 > $sysPath/authorized"
    echo 0 > $sysPath/authorized
    echo "echo 1 > $sysPath/authorized"
    echo 1 > $sysPath/authorized
else
    echo "Could not find $1"
fi

Tôi nghĩ do đó tất cả những gì tôi phải làm bây giờ là đưa cái này vào tập lệnh init.d:

if ttyUSB0 not present
    if 12d1:1446 present
        /usr/sbin/resetdevicebyauthorized 12d1:1446
    else if 12d1:1506 present
        /usr/sbin/resetdevicebyauthorized 12d1:1506
    fi
fi

1
+1 usbresetkhông thành công với modem Huawei, modem không thể phục hồi và đóng băng khi khởi động lại. Tôi hiện đang giải quyết vấn đề tương tự và có thể sớm có giải pháp hoạt động hoàn chỉnh.
yo

Tôi biết đó không phải là những gì bạn muốn nghe, nhưng sau khi chiếc gậy tôi đang sử dụng gây ra vấn đề này, tôi đã chọn một chiếc Huawei E3131 với giá từ Tesco (£ 10). Đó là một bộ định tuyến trong một thanh, bạn chỉ cần cắm nó vào và bạn nhận được eth1 với IP của NAT và bạn đã hoàn thành. Nó thậm chí có một giao diện web cho cấu hình. Và nó có thể được chuyển sang chế độ PPP bình thường nếu bạn cần. @tohecz
RoboJ1M

Chà, nói cho tôi biết nếu có một chiếc 4G rẻ như vậy, và bạn là người hùng của tôi! :) (Hiện tại tôi có gói cước 4G và modem 3G, vâng, và với modem 4G không có trình điều khiển ARM.)
yo '


Kiểm tra câu hỏi liên quan này trên Unix & Linux SE.
Dmitry Grigoryev

Câu trả lời:


2

tôi đã tạo một tập lệnh bash đơn giản để thiết lập lại thiết bị USB cụ thể.

#!/bin/bash
#type lsusb to find "vendor" and "product" ID in terminal
 set -euo pipefail
 IFS=$'\n\t'

        #edit the below tow lines of vendor and product values using lsusb result
        dev=$(lsusb -t | grep usbdevicename | grep 'If 1' | cut -d' ' -f13|cut -d"," -f1)
        #VENDOR=05a3
        #PRODUCT=9230
        VENDOR=$(lsusb -s $dev | cut -d' ' -f6 | cut -d: -f1)
        PRODUCT=$(lsusb -s $dev | cut -d' ' -f6 | cut -d: -f2)

        for DIR in $(find /sys/bus/usb/devices/ -maxdepth 1 -type l); do
          if [[ -f $DIR/idVendor && -f $DIR/idProduct &&
                $(cat $DIR/idVendor) == $VENDOR && $(cat $DIR/idProduct) == $PRODUCT ]]; then
            echo 0 > $DIR/authorized
            sleep 0.5
            echo 1 > $DIR/authorized
          fi
        done

9

Bạn có thể thiết lập lại USB bus thông qua chương trình C này. https://gist.github.com/x2q/5124616

Tải xuống mã C từ github

wget -c --no-check-certificate https://gist.githubusercontent.com/x2q/5124616/raw/3f6e5f144efab2bc8e9d02b95b8301e1e0eab669/usbreset.c -O usbreset.c

Biên dịch mã C dưới dạng usbreset

cc usbreset.c -o usbreset

Cấp quyền thực thi cho chương trình

chmod +x usbreset

Liệt kê các thiết bị USB của bạn thông qua lệnh lsusb

lsusb

Bạn sẽ thấy các mục thiết bị USB trong đầu ra của mình và kiểm tra thiết bị bạn muốn đặt lại.

Xe buýt 002 Thiết bị 003 : ID 0fe9: 9010 DVICO

Chạy chương trình usbreset với các đối số

sudo ./usbreset /dev/bus/usb/002/003

Vẫn cần phải đặt nó cùng nhau thành một kịch bản. Một cái gì đó như : x = lsusb | grep xxxx:yyyy /usr/sbin/usbreset $x. Đáng buồn thay, có vẻ như chúng ta không thể đặt ngắt dòng trong một nhận xét
RoboJ1M

Tôi cần nó trong tập lệnh init.d của tôi ( wvdialer). Hiện tại CRON chạy nó mỗi phút và nó tải lại wvdial nếu nó không xuất hiện (sử dụng start-stop-daemon). Nhưng nó sẽ không bắt đầu nếu ttyUSB0 không có ở đó. Bây giờ vì nhiều lý do, cây gậy đôi khi cần phải sống lại. Vì vậy, trong kịch bản đó tôi cầnIf ttyUSB0 is not present reset the USB stick
RoboJ1M

1
Sử dụng lệnh lsusb để có thêm thông tin? Thí dụ ; lsusb -d xxxx: yyyy sau đó kiểm tra xem modem USB của bạn có ở đó không, nếu nó không gọi usbreset.
gurcanozturk

2

Bạn có thể sử dụng pyusb để đặt lại thiết bị:

Đầu tiên cài đặt pyusb:

sudo pip install pyusb

Sau đó tạo tập lệnh này và chạy nó:

#!/usr/bin/python
from usb.core import find as finddev
dev = finddev(idVendor=0x1234, idProduct=0x5678)
dev.reset()

Điều chỉnh idVendoridProductphù hợp với thiết bị bạn muốn đặt lại (bạn có thể tìm id qua lsusb)


0

Cảm ơn bạn rất nhiều! Mã C này hoạt động rất tốt. Đây là tập lệnh shell đơn giản tôi đã làm để xác định thiết bị USB

#!/bin/bash
USBNAME=webcam
LSUSB=$(lsusb | grep --ignore-case $USBNAME)
FOLD="/dev/bus/usb/"$(echo $LSUSB | cut --delimiter=' ' --fields='2')"/"$(echo $LSUSB | cut --delimiter=' ' --fields='4' | tr --delete ":")
echo $LSUSB
echo $FOLD
sudo ./usbreset $FOLD

0

Đặt lại modem Huawei của tôi không phải lúc nào cũng hoạt động. Vì tôi đang quay số bằng một dịch vụ systemd, tôi đã thêm một số dòng hoàn toàn không cấp nguồn cho tất cả các thiết bị USB và khởi động lại mâm xôi sau 5 phút :-)

[Unit]
Description=GSM Internet
Requires=network.target
# If unable to start within 12hrs, unpower all USB and reboot
StartLimitIntervalSec=43200
StartLimitBurst=300
OnFailure=unpower-usb-reboot.service

[Service]
Type=forking
User=root
ExecStartPre=/bin/ls /dev/serial/by-id/usb-HUAWEI_Technology_HUAWEI_Mobile-if00-port0
ExecStart=/usr/bin/pon
RemainAfterExit=yes
ExecStop=/usr/bin/poff
Restart=always
RestartSec=120

[Install]
WantedBy=multi-user.target
[Unit]
Description=Unpowers all USB and reboots
[Service]
User=root
ExecStart=/bin/sh -c 'echo 0 > /sys/devices/platform/soc/20980000.usb/buspower; sleep 5m; shutdown -r now'
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.