libusb-1.0의 대략적인 사용법

19276 단어 USBlibusbtech
libusb는 USB 장치를 처리하는 프로그램을 무의식적으로 쓸 수 있는 C의 라이브러리다.현재 버전 1.0 시스템의 개발은 여전히 계속되고 있지만 버전 0.1 시스템과 호환되지 않는다.하지만 온라인에 공개된 프로그램과 튜토리얼에는 버전 0.1 클래스도 많았고, 예컨대 데비안"libusb-dev" 라는 이름으로 설치할 수 있는 패키지는 0.1 계열이다 플랫폼도 있어 2021년 4월이면 조금 혼란스러울 것 같았다.
또 2021년 4월libusb-1.0의 Debian에 있는 가방의 이름은'libusb-1.0-0-dev'입니다까지다.
libusb-1.0의 사용법은 갑자기 API를 봐도 잘 모르겠어요.USB 규격을 한 손에 들고 "Modules" 부분부터 문서를 읽으면 알 것 같다.

프로그램 전체 프로세스


libub에서는 이러한 느낌의 절차로 특정 USB 장치를 조작하는 프로그램을 작성합니다.
  • libub 초기화(세션 열기)
  • 연결된 장치 목록 가져오기
  • 목록에서 관심 있는 장치를 찾아 엽니다
  • .
  • 켜진 장치에서 무엇을 하는가(메시지 교환)
  • 켜진 장치 끄기
  • 폐기 장치 목록
  • 세션 닫기
  • 다음은 각자의 구체적인 설명이다.

    libub 초기화 (세션 열기)

    libusb_init()의 함수를 초기화합니다.
    libusb_context *context;
    libusb_init (&context);
    
    libub는 한 과정에서 여러 개의libub를 연결하여 한 응용 프로그램에서 여러 개의 USB와 교환을 처리할 수 있도록 합니다.이때 각 상태는 구조체형의 변수libusb_context로 관리된다.이 변수로 구분되는libub의 한 실체는'세션'이며, 세션을 식별하는 변수를'상하문'이라고 부른다.libusb_init() 함수도 컨텍스트(위치를 가리키는 포인터)를 매개변수로 지정합니다.
    그러나 보통 프로그램에서 여러 개의libub를 동시에 사용하지 않기 때문에 이러한 상황을 위해 기본적인 상하문을 준비했습니다.libusb_init()의 매개변수를 매개변수NULL로 지정하면 기본 컨텍스트에서 세션이 열립니다.
    libusb_init (NULL);
    

    연결 장치 목록 가져오기


    libub 세션을 초기화한 후 USB 포트에 연결된 장치를 찾습니다.이를 위해, 먼저 설비의 일람을 얻는다.함수libusb_get_device_list()를 사용합니다.libusb_get_device_list() 함수의 첫 번째 매개 변수에 상하문을 지정합니다.두 번째 매개변수에서 스토리지 디바이스 목록의 정렬을 지정합니다.libub에서는 각 USB 장치가 구조체형libusb_device으로 표시되기 때문에 이 바늘을 저장하는 배열을 지정합니다.libusb_get_device_list() 함수의 반환값은 획득한 장치의 수량입니다.실패 후 -1 되돌아오다.
    위에서 말한 바와 같이 기본 상하문에서 이러한 방식으로 장치 목록을 얻을 수 있다.
    libusb_device **list;
    int cnt = libusb_get_device_list(NULL, &list);
    

    장치 목록에서 관심 있는 장치를 찾아서 열기

    libusb_get_device_list() 함수에서 가져온 장치 목록에서 응용 프로그램에서 작업할 USB 장치만 찾아 열 수 있도록 장치 목록을 검색합니다.스캔 시 대상 장치를 식별할 때 USB 사양에 명시된 장치 스크립트 정보를 사용합니다.
    장치 스크립트는 설명서 섹션 9.6.1에 명시된 USB 2.0(1.0 및 1.1 포함)이나 USB 3.0에 대한 일반 정보를 나타냅니다.libub에서 구조libusb_device_descriptor로 표시합니다.이 구조의 필드는 다음과 같은 내용을 참조할 수 있다.
  • http://libusb.sourceforge.net/api-1.0/structlibusb__device__descriptor.html
  • libusb_device_descriptor의 필드에서 디바이스를 식별하는 데 사용할 수 있는 필드는 다음과 같습니다.또 USB-IF란'USB 임플리멘터스 포름'을 뜻하며, 어쨌든 USB 규격을 정하는 단체다.
    필드
    설명
    idVendor
    UV-IF에서 지정된 식별자(Vendor ID
    idProduct
    Vendor ID를 보유한 공급업체가 제품에 할당한 ID(Product ID)
    iManufacturer
    협력업체 설명에 대한 문자열
    iProduct
    제품 설명 문자열
    장치를 식별하기 위해 획득한 장치 목록에 포함된 각 장치에 대한 스크립트를 추출하고 해당 필드의 값을 읽고 조사할 수 있습니다.스크립트를 꺼낼 때libusb_get_device_descriptor의 함수를 준비했기 때문에 기본적으로 다음과 같은 절차에 따라 진행한다.
    struct libusb_device_descriptor desc;
    libusb_device_handle *handle;
    
    for (i = 0; i < cnt; i++) {
      libusb_device *dev = list[i];
      libusb_get_device_descriptor(device, &desc);
      libusb_open(devive, &handle)
    
      /* handle と desc を使って何かする */
      ...
    }
    
    위에서 libusb_device_handle 유형의 변수handle에 대한 지침이 나왔는데 이것은 설비 처리 프로그램이라고 불리며 설비의 실제 입출력 작업 등의 대상이 되었다.장치 목록으로 얻은 것은 libusb_device 유형 변수의 지침으로 괴롭힘을 당할 수 있지만 내부 구조를 참고할 수 없습니다.스크립트를 참조할 때 포인터를 libusb_device 유형의 변수에 가리키는 libusb_open() 유형의 변수를 얻어야 한다.
    그렇다면 libusb_device_handle 유형의 변수는 무엇 때문에 설비의 참고 계수기의 역할을 하는가.장치 목록을 얻을 때 참고 카운터가 '1' 으로 분배되어 프로그래머를 늘리거나 줄일 수 있습니다.참조 카운터가 0인 장치가 세션에서 버려집니다.
    참고로 Vendor ID와 Product ID를 지정하여 장치 프로세서libusb_device를 단숨에 얻는 함수도 있다.컨텍스트, Vendor ID 및 Product ID를 매개변수로 지정하면 유형 변수의 포인터가 반환값libusb_open_device_with_vid_pid()으로 지정됩니다.
    int vendorId, productId;
    libusb_device_handle *handle;
    
    handle = libusb_open_device_with_vid_pid(NULL, vendorId, productId)
    

    열려 있는 장치에서 무엇을 합니까 (정보 교환)


    장치 처리 프로그램과 스크립트를 받은 후에 마침내 그 장치로 하고 싶은 일을 적었다.예를 들어 libusb_device_handle를 표준 출력에 표시하면 전체적으로 이렇다.
    #include <stdio.h>
    #include <libusb-1.0/libusb.h>
    
    main () {
      libusb_device **list;
      struct libusb_device_descriptor desc;
      libusb_device_handle *handle;
      int i, ret;
      unsigned char text[512];
    
      /* 初期化 */
      libusb_init (NULL); 
      
      /* デバイスの一覧を取得 */
      int cnt = libusb_get_device_list(NULL, &list); //
      
      /* 一覧を走査して関心のあるデバイスを開く */
      for (i = 0; i < cnt; i++) {
        libusb_device *dev = list[i];
        libusb_get_device_descriptor(device, &desc);
        ret = libusb_open(devive, &handle)
      
        /* handle と desc を使って何かする */
        if (ret == 0) {
          libusb_get_string_descriptor_ascii(
              handle, desc.iProduct, text, sizeof(text));
          printf ("%s\n", text);
        }
      }
    
      /* クロージング */
      ...
    }
    
    iProduct는 ASCII를 통해 문자열을 꺼낸 스크립트를 표시하는 얻기 어려운libub의 함수입니다.USB 규격에서는 libusb_get_string_descriptor_ascii()iProduct 같은 문자열의 스크립트가 UTF-16LE에 저장되어 다른 바이트 문자도 사용할 수 있지만 그래도 ASCII를 이용한다C 언어로 직접 출력하거나 장치를 확인하기 위해 문자열을 비교하는 것은 매우 번거롭다.이 함수를 사용하면 가져온 바이트 문자열을 ASCII 문자열로 직접 처리할 수 있습니다.
    또한 상기에서 주의해야 할 것은 iManufacturer의 반환값 오류 처리이다.더 나은 오류 처리를 하는 것이 좋겠지만, 우선 libusb_open() 장치가 연결되고 권한과 메모리가 분배된 경우 (즉, 되돌아오는 값은 libusb_open() 장치 제어점이 활성화된 경우)여기서만 오류 처리를 하지 않으면 장치 처리 프로그램의 함수 (상기 예에서 0 를 사용하여 기본적으로 신호가 발생합니다.

    탈의실


    기본적으로 다음 순서에 따라 끝난다.
  • 켜진 장치 끄기
  • 디바이스 목록 지우기
  • 세션 닫기
  • 그러나 실행하는 함수는 libusb_get_string_descriptor_ascii()libusb_free_device_list() 두 개일 수 있다.이는 libusb_exit()의 두 번째 매개 변수libusb_free_device_list()에 설정1을 통해 상기 1과 2를 동시에 진행할 수 있으나 두 번째 매개 변수에 설정1 이외의 매개 변수를 설정해도 이 정도의 응용에서 특별히 문제 없이 끝나지 않아 잘 모르겠기 때문이다.libusb_device형 변수의 참조 계수기는 줄어들지 않고 계속 살아있다면 무슨 문제가 발생할 수 있다...libusb_exit()에서 상하문을 지정해야 하기 때문에 다른 상하문의 세션을 중지하지 않습니다.물론 기본 상하문NULL을 사용해도 된다.
    전체적으로 이런 느낌.
    #include <stdio.h>
    #include <libusb-1.0/libusb.h>
    
    main () {
      libusb_device **list;
      struct libusb_device_descriptor desc;
      libusb_device_handle *handle;
      int i, ret;
      unsigned char text[512];
    
      /* 初期化 */
      libusb_init (NULL); 
      
      /* デバイスの一覧を取得 */
      int cnt = libusb_get_device_list(NULL, &list); //
      
      /* 一覧を走査して関心のあるデバイスを開く */
      for (i = 0; i < cnt; i++) {
        libusb_device *dev = list[i];
        libusb_get_device_descriptor(device, &desc);
        ret = libusb_open(devive, &handle)
      
        /* handle と desc を使って何かする */
        if (ret == 0) {
          libusb_get_string_descriptor_ascii(
              handle, desc.iProduct, text, sizeof(text));
          printf ("%s\n", text);
        }
      }
    
      /* クロージング */
      libusb_free_device_list(list, 1);
      libusb_exit(NULL);
      return 0;
    }
    
    'handle과 desc를 사용하여 무엇을 하는가'부분에서 더 많은 일을 해야 한다libusb_control_transfer()libusb_bulk_transfer() 등 함수를 사용한다.이러한 함수는 USB 장치 설치에 따라 사용되며 여기서 생략됩니다.

    컴파일 및 실행


    다음은 Debian이 자체 제작 V-USB 장치를 가리킬 때의 예입니다.
    $ gcc -O -Wall libusb-sample.c -lusb-1.0
    $ ./a.out
    
    
    Template
    
    $
    
    "Template"는 V-USB로 디바이스를 제작할 때 기본적으로 사용되는 값iProduct입니다.설정iProduct된 장치가 예기치 않게 적습니다.

    좋은 웹페이지 즐겨찾기