如何使用脚本重置USB设备?


11

我有一个不支持alwasys工作属性的USB GSM调制解调器(Huawei E367u-2)有时会重置(USB设备在日志中断开连接/重新连接),当它恢复时,它具有不同的ttyUSB编号。有时在启动时,usb_modswitch似乎没有被解雇。该计算机是运行Raspbian的Raspberry Pi。

我对此有一个简单的解决方案,CRON每分钟都会运行以下脚本:

If WVDIAL is not running:
    Run WVDIAL

我想将脚本更改为:

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

显然,这是伪代码,但是我需要将以下几行内容串在一起,但我不知道如何做:

如果未运行,则会加载wvdial:

#! /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

这使我可以找到/sys特定设备的路径:

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

如果您知道正确的/ sys路径,这将重置USB设备:

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

因此,我需要将最后两节和一个测试字符串/dev/ttyUSB0放入“如果您希望命令始终运行。请放在此处”部分下的部分中。

更新1

usbreset尽管可以正常工作,但却无法完成任务。只有回显0到1才能authroized正确模拟设备断开/重新连接。
这就是将设备或usb_modeswitch引导回生活的诀窍。因此,我设法将以下内容凑在一起:

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

我认为因此现在要做的就是将其放入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 usbreset失败与华为调制解调器,调制解调器无法恢复并且在重新启动时冻结。我目前正在解决相同的问题,并且可能很快就会有一个可以正常工作的解决方案。
2014年

我知道这不是您想听到的,但是在我使用的烟斗引起了此问题的严重后果之后,我从乐购(Tesco)买了一部华为E3131(10英镑)。它是一根棍子中的路由器,您只需将其插入,即可获得带有NAT'd IP的eth1,然后就完成了。它甚至具有用于配置的Web界面。如果需要,可以将其切换为普通PPP模式。@tohecz
RoboJ1M 2014年

好吧,告诉我有没有便宜的4G,而你是我的英雄!:)(是的,我目前使用4G资费和3G调制解调器,并且使用没有ARM驱动程序的4G调制解调器。)
2014年


在Unix&Linux SE上查看此相关问题
德米特里·格里戈里耶夫

Answers:


2

我制作了一个简单的bash脚本来重置特定的USB设备。

#!/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

您可以通过此C程序重置USB总线。 https://gist.github.com/x2q/5124616

从github下载C代码

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

将C代码编译为usbreset

cc usbreset.c -o usbreset

授予程序执行权限

chmod +x usbreset

通过lsusb命令列出您的USB设备

lsusb

您应该在输出中看到USB设备条目,并检查要重置的设备。

总线002设备003:ID 0fe9:9010 DVICO

使用参数运行usbreset程序

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

仍然需要将其放到脚本中。类似于: x = lsusb | grep xxxx:yyyy /usr/sbin/usbreset $x。可悲的是,我们似乎无法在评论中
添加

我在init.d脚本(wvdialer)中需要它。目前,CRON每分钟运行一次,如果不存在,则会重新加载wvdial(使用start-stop-daemon)。但是,如果ttyUSB0不存在,它将无法启动。现在由于种种原因,有时只是需要重新开始使用棒子。因此,在该脚本中,我需要If ttyUSB0 is not present reset the USB stick
RoboJ1M 2013年

1
使用lsusb命令获取更多信息?例子; lsusb -d xxxx:yyyy然后检查您的USB调制解调器是否在那里,如果它没有调用usbreset。
gurcanozturk

2

您可以使用pyusb重置设备:

首先安装pyusb:

sudo pip install pyusb

然后创建此脚本并运行它:

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

使idVendor和适应idProduct您要重置的设备(您可以通过找到ID lsusb


0

非常感谢!此C代码非常有效。这是我用来识别USB设备的简单shell脚本

#!/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

重置我的华为调制解调器并不总是有效。因为无论如何我都在使用systemd服务进行拨号,所以我添加了一些线路,这些线路可以完全断开所有 USB设备的电源,并在5分钟后重新启动树莓:-)

[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'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.