기술나눔

Windows USB 장치 드라이버 개발 - USB 대역폭

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

이 문서에서는 USB 대역폭을 신중하게 관리하는 방법에 대한 지침을 설명합니다. 각 USB 클라이언트 드라이버는 사용하는 USB 대역폭을 최소화하고 사용되지 않은 대역폭을 사용 가능한 대역폭 풀로 최대한 빨리 반환하는 역할을 합니다.

여기서 우리는 USB 2.0의 속도가 480Mbps, 12Mbps, 1.5Mbps라고 생각하는데, 이는 각각 고속, 최고 속도, 저속에 해당합니다. 그러나 사실 USB 2.0의 대역폭은 매우 좁습니다. 이 글의 전제에 따르면 USB 3.0은 대역폭 문제를 완화하지만 대역폭 문제는 상한이 부족한 것이 아니라 히비스커스 스케줄링 문제이다.

USB 드라이버에서 대역폭 부족 오류가 발생하는 이유는 무엇입니까?

USB 버스의 대역폭 경쟁은 하드웨어와 소프트웨어를 포함한 다양한 소스에서 비롯됩니다. USB 클라이언트 드라이버에 사용 가능한 대역폭의 양을 정확하게 예측하는 것은 어렵습니다. USB 호스트 컨트롤러가 작동하려면 일정량의 대역폭이 필요합니다. 필요한 양은 컨트롤러가 고속인지 여부에 따라 다릅니다. 시스템마다 다릅니다. 고속으로 작동하는 USB 허브는 때때로 고속 업스트림 포트와 다운스트림 저속 장치 간의 트랜잭션을 변환해야 하며, 이 변환 프로세스는 대역폭을 소비합니다. 그러나 트랜잭션 변환에 대역폭이 필요한지 여부는 연결된 장치의 유형과 장치 트리의 토폴로지에 따라 다릅니다.

대역폭 리소스에 대한 가장 심각한 압력은 일반적으로 대역폭을 독점하는 USB 클라이언트 드라이버에서 발생합니다. 시스템은 선착순으로 대역폭을 할당합니다. 로드된 첫 번째 USB 드라이버가 사용 가능한 모든 대역폭을 요청하는 경우 로드된 후속 USB 드라이버는 해당 장치에 대한 대역폭을 허용하지 않습니다. 시스템이 장치를 구성하거나 열거할 수 없습니다. 열거 실패의 이유가 명확하지 않기 때문에 사용자 경험이 좋지 않습니다.

때때로 클라이언트 드라이버는 고속 인터럽트 전송을 통해 사용 가능한 대역폭을 소모합니다. 그러나 가장 일반적인 시나리오는 클라이언트 드라이버가 지속적인 전송에 너무 많은 대역폭을 할당하고 적시에 이를 해제하지 못하는 것입니다. 시스템은 이를 요청한 드라이버가 다른 끝점을 열어 해당 끝점을 닫거나 대역폭이 할당된 장치가 제거될 때까지 할당된 대역폭을 유지합니다. 시스템은 대량 전송에 대해 보장된 대역폭을 할당하지 않으므로 대량 전송은 열거 오류의 원인이 되지 않습니다. 그러나 대량 전송 장치의 성능은 일반(지속적인 대기 및 중단) 전송을 위해 장치에 할당된 대역폭의 양에 따라 달라집니다.

USB 2.0 사양에서는 기본 인터페이스 설정에서 대역폭이 0인 엔드포인트를 갖는 상수 장치가 필요합니다. 이렇게 하면 기능 드라이버가 기본이 아닌 인터페이스를 열 때까지 장치에 대해 대역폭이 예약되지 않습니다. 이는 장치 구성 중 과도한 대역폭 요청으로 인한 열거 실패를 방지하는 데 도움이 됩니다. 클라이언트 드라이버가 장치를 구성한 후 과도한 대역폭을 할당하는 것을 방지하지 못하므로 다른 장치가 제대로 작동하지 못하게 됩니다.

적절한 대역폭 관리의 핵심은 지속적인 전송을 수행하는 시스템의 모든 USB 장치가 지속적인 끝점을 포함하는 각 인터페이스에 대해 여러 대체(Alt) 설정을 제공해야 하며 클라이언트 드라이버는 이러한 Alt 설정을 현명하게 사용해야 한다는 것입니다. 클라이언트 드라이버는 대역폭이 가장 높은 인터페이스 설정을 먼저 요청해야 합니다. 요청이 실패하면 클라이언트 드라이버는 요청이 성공할 때까지 점점 더 작은 대역폭으로 인터페이스 설정을 요청해야 합니다.

예를 들어 웹캠 장치에 다음 인터페이스가 있다고 가정합니다.

인터페이스 0(기본 인터페이스 설정: 기본 설정에는 일정한 대역폭이 0이 아닌 엔드포인트가 없습니다)

Const 끝점 1: 최대 패킷 크기 = 0바이트

Const 끝점 2: 최대 패킷 크기 = 0바이트

인터페이스 0 Alt 설정 1

Const 끝점 1: 최대 패킷 크기 = 256바이트

Const Endpoint 2: 최대 패킷 크기 = 256바이트

인터페이스 0 대체 설정 2

Const 끝점 1: 최대 패킷 크기 = 512바이트

Const 끝점 2: 최대 패킷 크기 = 512바이트

웹캠 드라이버는 초기화 시 기본 인터페이스 설정을 사용하도록 웹캠을 구성합니다. 기본 설정에는 일정한 대역폭이 없으므로 초기화 중에 기본 설정을 사용하면 일정한 대역폭 요청 실패로 인해 웹캠이 열거되지 못하는 위험을 피할 수 있습니다.

클라이언트 드라이버가 지속적인 등시성 전송을 수행할 준비가 되면 Alt 설정 2의 패킷 크기가 가장 크기 때문에 Alt 설정 2를 사용해야 합니다. 요청이 실패하면 드라이버는 Alt 설정 1을 사용하여 두 번째 시도를 할 수 있습니다. Alt 설정 1은 더 적은 대역폭을 필요로 하기 때문에 첫 번째 요청이 실패하더라도 이 요청은 성공할 수 있습니다. 여러 Alt 설정을 사용하면 운전자가 포기하기 전에 여러 번 시도할 수 있습니다.

웹캠이 유휴 상태가 되면 기본 설정을 다시 선택하여 할당된 대역폭을 사용 가능한 대역폭 풀로 되돌릴 수 있습니다.

사용자는 Windows 장치 관리자에서 컨트롤러 속성을 확인하여 USB 컨트롤러가 할당한 대역폭의 양을 확인할 수 있습니다. 컨트롤러의 속성을 선택하고 고급 탭을 살펴보세요. 이 수치는 USB 허브가 트랜잭션 변환을 위해 할당하는 대역폭의 양을 나타내지는 않습니다.

USB 컨트롤러 대역폭 사용량을 보고하는 장치 관리자 기능이 Windows XP에서 제대로 작동하지 않습니다.

USB 전송 및 패킷 크기
최대 전송 크기

최대 전송 크기는 USB 드라이버 스택에 하드 코딩된 제한을 지정합니다. 시스템 리소스 제한으로 인해 이러한 한도 미만의 전송 크기는 실패할 수 있습니다. 이러한 유형의 오류를 방지하고 모든 Windows 버전과의 호환성을 보장하려면 USB 전송에 큰 전송 크기를 사용하지 마십시오.

USBD_PIPE_INFORMATION 구조의 MaximumTransferSize 멤버는 더 이상 사용되지 않습니다. USB 드라이버 스택은 복합 장치와 비복합 장치에 대한 MaximumTransferSize 값을 무시합니다.

Windows 2000에서 USB 드라이버 스택은 MaximumTransferSize를 USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE로 초기화합니다. 클라이언트 드라이버는 장치를 구성할 때 더 작은 값을 설정할 수 있습니다. 복합 장치의 경우 기능별 클라이언트 드라이버는 기본이 아닌 인터페이스 설정에서만 파이프의 MaximumTransferSize를 변경할 수 있습니다.

USB 전송 크기는 다음으로 제한됩니다.

MaximumTransferSize를 사용하여 전송 크기를 제한해도 장치에서 소비하는 대역폭에는 직접적인 영향을 미치지 않습니다. 클라이언트 드라이버는 인터페이스 설정을 변경하거나 USBD_PIPE_INFORMATION의 MaximumPacketSize 멤버에 설정된 최대 패킷 크기를 제한해야 합니다.

최대 패킷 크기

최대 패킷 크기는 엔드포인트 설명자의 wMaxPacketSize 필드에 의해 정의됩니다. 클라이언트 드라이버는 장치에 대한 선택 인터페이스 요청에서 USB 패킷 크기를 조정할 수 있습니다. 이 값을 변경해도 장치의 wMaxPacketSize는 변경되지 않습니다.

요청된 URB 내에 파이프의 USBD_PIPE_INFORMATION 구조가 있습니다. 이 구조에서는,

  • USBD_PIPE_INFORMATION 구조의 MaximumPacketSize 멤버를 수정합니다. 현재 인터페이스 설정에 대해 장치 펌웨어에 정의된 wMaxPacketSize보다 작거나 같은 값으로 설정하십시오.
  • PipeFlags 멤버 USBD_PIPE_INFORMATION 구조에서 USBD_PF_CHANGE_MAX_PACKET 플래그를 설정합니다.
전송 버퍼의 최대 패킷 크기 제한을 읽습니다.

클라이언트 드라이버가 읽기 요청을 발행할 때 전송 버퍼는 최대 패킷 크기의 배수여야 합니다. 드라이버가 최대 패킷 크기보다 적은 데이터를 요구하더라도 여전히 전체 패킷을 요청해야 합니다. 장치가 최대 크기보다 작은 패킷(짧은 패킷)을 전송하면 전송이 완료됩니다.

이전 컨트롤러에서는 클라이언트 드라이버가 이 동작을 재정의할 수 있습니다. 데이터 전송 URB의 TransferFlags 멤버에서 클라이언트 드라이버는 USBD_SHORT_TRANSFER_OK 플래그를 설정해야 합니다. 이 플래그를 사용하면 장치가 wMaxPacketSize보다 작은 패킷을 보낼 수 있습니다.

xHCI 호스트 컨트롤러에서 USBD_SHORT_TRANSFER_OK는 벌크 엔드포인트와 인터럽트 엔드포인트를 무시합니다. EHCI 컨트롤러에서 짧은 패킷을 전송해도 오류 조건이 발생하지 않습니다.

EHCI 호스트 컨트롤러에서는 대량 및 인터럽트 엔드포인트에 대해 USBD_SHORT_TRANSFER_OK가 무시됩니다.

UHCI 및 OHCI 호스트 컨트롤러에서 대량 또는 인터럽트 전송에 대해 USBD_SHORT_TRANSFER_OK가 설정되지 않은 경우 짧은 패킷 전송은 엔드포인트를 중지하고 전송 오류 코드를 반환합니다.

짧은 패킷을 사용하여 쓰기 전송을 구분합니다.

USB 드라이버 스택 드라이버는 장치에서 읽을 때와 장치에 쓸 때 패킷 크기에 다른 제한을 적용합니다. 일부 클라이언트 드라이버는 장치를 관리하기 위해 소량의 제어 데이터를 자주 전송해야 합니다. 이 경우 데이터 전송을 균일한 크기의 패킷으로 제한하는 것은 비현실적입니다. 따라서 데이터를 쓰는 동안 드라이버 스택은 엔드포인트의 최대 크기보다 작은 패킷에 특별한 의미를 할당하지 않습니다. 이를 통해 클라이언트 드라이버는 장치로의 대용량 전송을 최대 크기 이하의 여러 URB로 나눌 수 있습니다.

드라이버는 최대 크기보다 작은 패킷으로 전송을 종료하거나 길이가 0인 패킷을 사용하여 전송 종료를 구분해야 합니다. 드라이버가 wMaxPacketSize보다 작은 패킷을 보낼 때까지 전송이 완료되지 않습니다. 전송 크기가 정확히 최대값의 배수인 경우 드라이버는 전송을 명시적으로 종료하기 위해 길이가 0으로 구분된 패킷을 보내야 합니다.

USB 사양에서 요구하는 대로 클라이언트 드라이버는 길이가 0인 패킷을 사용하여 데이터 전송을 구분하는 역할을 합니다. USB 드라이버 스택은 이러한 패킷을 자동으로 생성하지 않습니다.

wMaxPacketSize보다 작은 패킷을 사용하여 별도의 USB 데이터 전송

호환 USB 2.0 및 USB 1.1 드라이버는 최대 크기 패킷(wMaxPacketSize)을 전송한 다음 최대 크기보다 작은 패킷으로 전송을 종료하거나 길이가 0인 패킷을 사용하여 전송 끝을 구분해야 합니다. 드라이버가 wMaxPacketSize보다 작은 패킷을 보낼 때까지 전송이 완료되지 않습니다. 전송 크기가 정확히 최대값의 배수인 경우 드라이버는 전송을 명시적으로 종료하기 위해 길이가 0으로 구분된 패킷을 보내야 합니다.

장치 드라이버는 USB 사양에서 요구하는 대로 길이가 0인 패킷을 사용하여 데이터 전송을 구분하는 역할을 합니다. 시스템 USB 스택은 이러한 패킷을 자동으로 생성하지 않습니다.