USB GSMモデムがありますが、常に動作するわけではなく(Huawei E367u-2)、時にはリセットされ(ログからUSBデバイスの接続が切断されて再接続されます)、戻ってくると別のttyUSB番号があります。時には起動時にusb_modeswitch
解雇されないようです。コンピュータはRaspbianを実行するRaspberry Piです。
これには簡単な解決策があります。cron
毎分、次のスクリプトを実行します(疑似コード)。
If WVDIAL is not running:
Run WVDIAL
スクリプトを次のように変更したいと思います。
If /dev/ttyUSB0 is not present:
If DevicePresent(12d1:1446):
ResetDevice(12d1:1446)
ElseIf DevicePresent(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
したがって、最後の2つのセクションを一緒にリンクし、「コマンドが常に実行されるようにするには、ここに入力してください」コメントの下のセクションにテストを追加する必要があります。
- どうすればいいですか?
- もっと良い方法がありますか?
答え1
私はあなたが基本的にそこにいると思います:
#!/bin/sh
for X in /sys/bus/usb/devices/*
do
if [ -e "$X/idVendor" ] && [ -e "$X/idProduct" ] \
&& [ 12d1 = $(cat "$X/idVendor") ] && [ 1446 = $(cat "$X/idProduct") ]
then
echo 0 >"$X/authorized"
# might need a small sleep here
echo 1 >"$X/authorized"
fi
done
これはユーザーが行ったようにすべてのデバイスで繰り返され、Vendor:Product IDと一致するものが見つかるたびにユーザーに適切なリセットを適用します。
ちなみに、あなたはこのwatchdog
プログラムをあなたの仕事に代わるものとして考えたいかもしれませんcron
。
答え2
コマンドラインを使用するにはリセットしてください。
以下を別の名前で保存してください。usbreset.c
/* usbreset -- send a USB port reset to a USB device */
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/usbdevice_fs.h>
int main(int argc, char **argv)
{
const char *filename;
int fd;
int rc;
if (argc != 2) {
fprintf(stderr, "Usage: usbreset device-filename\n");
return 1;
}
filename = argv[1];
fd = open(filename, O_WRONLY);
if (fd < 0) {
perror("Error opening output file");
return 1;
}
printf("Resetting USB device %s\n", filename);
rc = ioctl(fd, USBDEVFS_RESET, 0);
if (rc < 0) {
perror("Error in ioctl");
return 1;
}
printf("Reset successful\n");
close(fd);
return 0;
}
端末で次のコマンドを実行します。
コンパイラ:
$ cc usbreset.c -o usbreset Get the Bus and Device ID of the USB device you want to reset:
$ lsusb
Bus 002 Device 003: ID 0fe9:9010 DVICO
Make our compiled program executable:
$ chmod +x usbreset Execute the program with sudo privilege; make necessary substitution for <Bus> and <Device> ids as found by running the lsusb command:
$ sudo ./usbreset /dev/bus/usb/002/003
その他
#!/usr/bin/env python
import os
import sys
from subprocess import Popen, PIPE
import fcntl
driver = sys.argv[-1]
print "resetting driver:", driver
USBDEVFS_RESET= 21780
try:
lsusb_out = Popen("lsusb | grep -i %s"%driver, shell=True, bufsize=64, stdin=PIPE, stdout=PIPE, close_fds=True).stdout.read().strip().split()
bus = lsusb_out[1]
device = lsusb_out[3][:-1]
f = open("/dev/bus/usb/%s/%s"%(bus, device), 'w', os.O_WRONLY)
fcntl.ioctl(f, USBDEVFS_RESET, 0)
except Exception, msg:
print "failed to reset device:", msg
私の場合はcp210xドライバ(lsmod | grep usbserialでわかります)なので、上記のコードスニペットをReset_usb.pyとして保存して次のことができます。
sudo python reset_usb.py cp210x
システムにacコンパイラがインストールされていませんが、Pythonがある場合にも役立ちます。
便利な答えラズベリーパイの公式