Share via


DMA 채널 개체

참고 항목

Microsoft는 다양하고 포괄적인 환경을 지원합니다. 이 문서에는 바이어스 없는 통신에 대한 Microsoft 스타일 가이드에서 제외로 인식하는 용어에 대한 참조가 포함되어 있습니다. 단어 또는 구는 현재 소프트웨어에 표시되므로 일관성을 위해 이 문서에서 사용됩니다. 언어를 제거하도록 소프트웨어가 업데이트되면 이 문서가 정렬되도록 업데이트됩니다.

PortCls 시스템 드라이버는 WaveCyclic 및 WavePci 미니포트 드라이버의 이점을 위해 IDmaChannel 및 IDmaChannelSlave 인터페이스를 구현합니다. IDmaChannel 은 DMA 채널과 연결된 DMA 버퍼 및 버퍼 사용 매개 변수를 나타냅니다. 또한 WaveCyclic 미니포트 드라이버는 IDmaChannelSlave를 사용하여 하위 디바이스에 대한 DMA 채널을 관리합니다. IDmaChannelSlave는 IDmaChannel에서 상속됩니다. DMA 작업을 제어하는 방법에 대한 자세한 내용은 어댑터 개체 및 DMA를 참조하세요.

IDmaChannel 개체는 다음을 캡슐화합니다.

  • 마스터 또는 하위 디바이스에 대한 DMA 채널

  • 채널과 연결된 데이터 버퍼

  • 채널을 사용하는 방법을 설명하는 정보

포트 및 미니포트 드라이버는 DMA 채널 개체를 사용하여 DMA 채널 사용과 관련된 정보를 전달합니다. 일반적으로 미니포트 드라이버는 초기화 중 또는 스트림을 만드는 동안 DMA 채널 집합을 할당합니다. 새 스트림을 만드는 동안 미니포트 드라이버는 스트림에 사용할 DMA 채널 개체를 포트 드라이버에 알려줍니다.

마스터 또는 하위 디바이스에 대한 DMA 채널 개체를 만들 수 있습니다.

  • 하위 디바이스에는 기본 제공 DMA 하드웨어 기능이 없으며 시스템 DMA 컨트롤러를 사용하여 디바이스에 필요한 데이터 전송을 수행해야 합니다.

  • 마스터 디바이스는 자체 버스 마스터 DMA 하드웨어를 사용하여 시스템 버스에서 데이터 전송을 수행합니다.

하위 DMA 채널 개체를 사용하는 WaveCyclic 디바이스의 예는 이전 버전의 Microsoft WDK(Windows 드라이버 키트)의 Sb16 샘플 오디오 드라이버를 참조하세요. 마스터 DMA 채널 개체는 포트와 미니포트 드라이버 간에 DMA 채널에 대한 정보를 공유하기 위한 백보드에 지나지 않습니다. 마스터 및 하위 디바이스에 대한 자세한 내용은 어댑터 개체 소개를 참조 하세요.

마스터 또는 하위 디바이스에 대한 DMA 채널 개체는 다음을 노출합니다.

  • 어댑터 개체

  • 드라이버와 DMA 하드웨어에서 공유할 수 있는 단일 공통 버퍼

  • 쿼리 및 변경할 수 있는 버퍼 크기 값

어댑터 개체는 PDO(물리적 디바이스 개체)에 대한 DMA 어댑터 구조입니다. 미니포트 드라이버가 다음 방법 중 하나를 호출하여 DMA 채널 개체를 만들 때 어댑터 개체가 자동으로 만들어집니다.

IPortWavePci::NewMasterDmaChannel

IPortWaveCyclic::NewMasterDmaChannel

IPortWaveCyclic::NewSlaveDmaChannel

IDmaChannel::GetAdapterObject 메서드를 사용하여 어댑터 개체에 대한 포인터를 가져올 수 있습니다.

어댑터 드라이버는 PcNewDmaChannel 함수를 호출하여 DMA 채널 개체를 만들 수도 있지만 호출자가 디바이스 개체 및 기타 컨텍스트 정보를 명시적으로 지정해야 하므로 이 함수는 IPortWaveXxx::NewXxxDmaChannel 호출보다 사용하기가 더 어렵습니다.

하위 디바이스에 대한 DMA 채널의 경우 IDmaChannel::TransferCount 메서드는 IDmaChannelSlave::Start 호출에 지정된 최대 전송 크기(MapSize 매개 변수)를 반환합니다. 또한 어댑터 개체는 DMA 디바이스를 조작하고 쿼리하는 몇 가지 방법을 제공합니다. 이러한 메서드는 마스터 DMA 채널에 의미가 없습니다.

IDmaChannel::AllocateBufferIDmaChannel::FreeBuffer 는 DMA 채널 개체와 연결된 단일 공통 버퍼를 관리하는 데 사용됩니다. 개체에 의해 할당된 버퍼는 드라이버(커널 가상 메모리 주소 포함) 및 DMA 디바이스(실제 메모리 주소 포함)에서 모두 액세스할 수 있도록 보장됩니다. 또한 버퍼는 물리적으로 연속됩니다. 일반적으로 가장 좋은 전략은 물리적으로 연속된 메모리가 가장 많을 때 미니포트 드라이버 초기화 중에 DMA 버퍼를 할당하는 것입니다. IDmaChannel::AllocatedBufferSize는 IDmaChannel::AllocateBuffer 호출에 지정된 대로 버퍼의 크기를 반환합니다.

IDmaChannel::MaximumBufferSize 는 사용할 수 있는 실제 최대 버퍼 크기를 나타냅니다. 할당된 크기가 페이지 크기의 짝수 배수가 아닌 경우 할당된 크기를 초과할 수 있습니다. DMA 디바이스가 할당된 크기의 전송을 지원할 수 없는 경우 할당된 크기보다 작을 수 있습니다. IDmaChannel::BufferSizeIDmaChannel::SetBufferSize 는 DMA 전송에 사용할 버퍼의 크기를 쿼리하고 설정하는 데 사용됩니다. 버퍼가 할당되면 버퍼 크기가 최대 버퍼 크기로 설정됩니다. 초기화 후 포트 드라이버와 미니포트 드라이버 모두 버퍼 크기를 변경하거나 현재 값을 검색할 수 있습니다. 미니포트 드라이버는 IDmaChannel::BufferSize결과를 사용하여 DMA 채널이 시작될 때 DMA 작업의 전송 크기를 결정합니다. IDmaChannel::SystemAddressIDmaChannel::P hysicalAddress 는 각각 버퍼의 가상 및 물리적 주소를 가져오는 데 사용됩니다.

IDmaChannel::CopyToIDmaChannel::CopyFrom 은 DMA 버퍼에서 샘플 데이터를 복사합니다. WaveCyclic 포트 드라이버는 이러한 메서드를 호출하여 애플리케이션 버퍼와 미니포트 드라이버의 순환 버퍼 간에 오디오 데이터를 복사합니다.

DMA 버퍼가 스트리밍된 데이터를 전송하는 데 반드시 사용되는 것은 아닙니다. WavePci 포트 드라이버의 경우 스트리밍된 데이터는 분산/수집 매핑 목록으로 미니포트 드라이버에 전달되거나 검색됩니다. 그러나 미니포트 드라이버는 어댑터 드라이버와 통신하기 위한 공유 메모리 공간으로 DMA 버퍼를 계속 사용할 수 있습니다.

포트 드라이버는 미니포트 드라이버에 DMA 채널을 만드는 데 사용할 수 있는 함수를 제공합니다. 포트 드라이버에 대한 설명에서 달리 명시하지 않는 한 포트 드라이버에서 할당된 DMA 개체를 반드시 사용할 필요는 없습니다. 포트 드라이버에는 필요한 메서드를 지원하는 IDmaChannel 인터페이스에 대한 포인터가 필요합니다. 각 포트 드라이버에 대한 설명서에서 포트 드라이버에 필요한 DMA 채널 메서드 목록을 확인합니다.

일반적으로 가장 쉬운 방법은 포트 드라이버가 구현하는 DMA 채널 할당 함수를 사용하는 것입니다. 드물게 미니포트 드라이버 개발자는 특정 어댑터의 특별한 요구 사항을 충족하기 위해 자체 DMA 채널 개체를 구현해야 할 수 있습니다. 이 경우 새 개체를 구현해야 하는 경우도 있습니다. 또한 미니포트 드라이버의 스트림 개체가 IDmaChannel 인터페이스를 노출하고 DMA 채널 메서드 자체를 구현하는 것으로 충분합니다.

IDmaChannel 인터페이스는 다음 메서드를 지원합니다.

IDmaChannel::AllocateBuffer

IDmaChannel::AllocatedBufferSize

IDmaChannel::BufferSize

IDmaChannel::CopyFrom

IDmaChannel::CopyTo

IDmaChannel::FreeBuffer

IDmaChannel::GetAdapterObject

IDmaChannel::MaximumBufferSize

IDmaChannel::P hysicalAddress

IDmaChannel::SetBufferSize

IDmaChannel::SystemAddress

IDmaChannel::TransferCount

IDmaChannelSlave 인터페이스는 다음 메서드를 추가하여 IDmaChannel을 확장합니다.

IDmaChannelSlave::ReadCounter

IDmaChannelSlave::Start

IDmaChannelSlave::Stop

IDmaChannelSlave::WaitForTC