스크립트를 사용하여 USB 장치를 재설정하는 방법은 무엇입니까?

스크립트를 사용하여 USB 장치를 재설정하는 방법은 무엇입니까?

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따라서 마지막 두 섹션을 함께 연결하고 "명령이 항상 실행되도록 하려면 여기에 입력하세요" 주석 아래 섹션에 테스트를 추가해야 합니다 .

  • 어떻게 해야 하나요?
  • 더 좋은 방법이 있나요?

답변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이 있는 경우에도 도움이 될 수 있습니다.

유용한 답변라즈베리파이 공식

관련 정보