SerCx2 Custom-Receive 트랜잭션
일부 직렬 컨트롤러 하드웨어는 직렬 컨트롤러에서 데이터를 읽기 위해 PIO 또는 시스템 DMA 이외의 데이터 전송 메커니즘을 구현할 수 있습니다. 직렬 컨트롤러 드라이버는 사용자 지정 수신 트랜잭션을 지원하여 SerCx2에서 이 데이터 전송 메커니즘을 사용할 수 있도록 할 수 있습니다.
사용자 지정 수신 트랜잭션을 시작하기 위해 SerCx2는 드라이버의 EvtSerCx2CustomReceiveTransactionStart 이벤트 콜백 함수를 호출하고 읽기(IRP_MJ_READ) 요청 및 트랜잭션에 대한 읽기 버퍼에 대한 설명을 매개 변수로 제공합니다. 이 호출에서 함수는 트랜잭션을 시작하고 를 반환합니다. 그런 다음 드라이버는 트랜잭션을 완료하고 읽기 요청을 완료할 책임이 있습니다.
사용자 지정 수신 개체 만들기
SerCx2가 직렬 컨트롤러 드라이버의 EvtSerCx2CustomReceiveTransactionXxx** 함수를 호출하려면 먼저 드라이버가 SerCx2CustomReceiveTransactionCreate 메서드를 호출하여 이러한 함수를 SerCx2에 등록해야 합니다. 이 메서드는 입력 매개 변수로 드라이버의 EvtSerCx2CustomReceiveTransaction Xxx** 함수에 대한포인터를 포함하는 SERCX2_CUSTOM_RECEIVE_TRANSACTION_CONFIG 구조체에 대한 포인터를 허용합니다.
드라이버는 다음 두 함수를 구현해야 합니다.
옵션으로 드라이버는 다음 세 가지 함수 중 어느 것 또는 전부를 구현할 수 있습니다.
- EvtSerCx2CustomReceiveTransactionEnableNewDataNotification
- EvtSerCx2CustomReceiveTransactionInitialize
- EvtSerCx2CustomReceiveTransactionCleanup
SerCx2CustomReceiveTransactionCreate 메서드는 사용자 지정 수신 개체를 만들고 호출 드라이버에 이 개체에 SERCX2CUSTOMRECEIVETRANSACTION 핸들을 제공합니다. 드라이버의 EvtSerCx2CustomReceiveTransactionXxx** 함수는 모두 이 핸들을 첫 번째 매개 변수로 사용합니다. 다음 SerCx2 메서드는 이 핸들을 첫 번째 매개 변수로 사용합니다.
- SerCx2CustomReceiveTransactionNewDataNotification
- SerCx2CustomReceiveTransactionReportProgress
- SerCx2CustomReceiveTransactionInitializeComplete
- SerCx2CustomReceiveTransactionCleanupComplete
하드웨어 초기화 및 클린
일부 직렬 컨트롤러 드라이버는 사용자 지정 수신 트랜잭션을 시작할 때 직렬 컨트롤러 하드웨어를 초기화하거나 트랜잭션이 끝날 때 직렬 컨트롤러의 하드웨어 상태를 클린 수 있습니다.
드라이버가 EvtSerCx2CustomReceiveTransactionInitialize 이벤트 콜백 함수를 구현하는 경우 SerCx2는 트랜잭션을 시작하기 전에 이 함수를 호출하여 직렬 컨트롤러를 초기화합니다. 구현된 경우 EvtSerCx2CustomReceiveTransactionInitialize 함수는 SerCx2CustomReceiveTransactionInitializeComplete 메서드를 호출하여 드라이버가 직렬 컨트롤러 초기화를 완료할 때 SerCx2에 알려야 합니다.
드라이버가 EvtSerCx2CustomReceiveTransactionCleanup 이벤트 콜백 함수를 구현하는 경우 SerCx2는 트랜잭션이 종료된 후 하드웨어 상태를 클린 위해 이 함수를 호출합니다. 구현된 경우 EvtSerCx2CustomReceiveTransactionInitialize 함수는 SerCx2CustomReceiveTransactionCleanupComplete 메서드를 호출하여 드라이버가 직렬 컨트롤러 정리를 완료할 때 SerCx2에 알려야 합니다.
새 데이터 알림
옵션으로 직렬 컨트롤러 드라이버는 EvtSerCx2CustomReceiveTransactionEnableNewDataNotification 이벤트 콜백 함수를 구현할 수 있습니다. 구현된 경우 SerCx2는 이 함수를 사용하여 사용자 지정 수신 트랜잭션으로 처리되는 읽기 요청을 처리하는 동안 발생하는 간격 제한 시간을 효율적으로 관리합니다.
직렬 컨트롤러에서 받은 두 개의 연속 바이트 사이의 간격이 클라이언트에서 지정한 최대 시간을 초과하는 경우 간격 제한 시간이 발생합니다. 주변 장치 드라이버가 SerCx2에 읽기 요청을 보낸 후에는 직렬로 연결된 주변 장치에서 하나 이상의 데이터를 수신할 때까지 간격 제한 시간이 발생할 수 없습니다. 읽기 요청의 도착과 주변 장치에서 데이터의 첫 번째 바이트 수신 사이의 시간은 첫 번째 바이트가 수신된 후 읽기 요청에 대한 나머지 데이터를 수신하는 데 필요한 시간보다 훨씬 길 수 있습니다. 자세한 내용은 SERIAL_TIMEOUTS 참조하세요.
SerCx2는 구현된 경우 EvtSerCx2CustomReceiveTransactionEnableNewDataNotification 함수를 호출하여 새 데이터 알림을 사용하도록 설정합니다. 이 알림을 사용하도록 설정하고 직렬 컨트롤러가 주변 장치에서 하나 이상의 새 데이터를 받거나 수신 FIFO에 이미 데이터가 있는 경우 직렬 컨트롤러 드라이버는 SerCx2CustomReceiveTransactionNewDataNotification 메서드를 호출하여 SerCx2에 알립니다.
가능한 간격 제한 시간을 검색하기 위해 SerCx2는 EvtSerCx2CustomReceiveTransactionQueryProgress 이벤트 콜백 함수를 주기적으로 호출하여 이전 간격 동안 데이터가 수신되었는지 여부를 검사. SerCx2가 데이터의 첫 번째 바이트 수신을 검색하는 방법은 직렬 컨트롤러 드라이버가 EvtSerCx2CustomReceiveTransactionEnableNewDataNotification 함수를 구현하는지 여부에 따라 달라집니다. 이 함수가 구현되면 SerCx2는 함수를 호출하여 새 데이터 알림을 사용하도록 설정하고, 데이터의 첫 번째 바이트가 수신될 때 드라이버에 의해 알림을 받습니다. 그렇지 않으면 SerCx2는 EvtSerCx2CustomReceiveTransactionQueryProgress 함수를 주기적으로 호출하여 첫 번째 바이트의 수신을 감지하고 이러한 호출을 위해 프로세서를 주기적으로 절전 모드 해제해야 할 수 있습니다. 따라서 EvtSerCx2CustomReceiveTransactionEnableNewDataNotification 함수를 구현하는 드라이버는 프로세서가 자주 절전 모드를 해제할 필요가 없으므로 전력 소비를 줄일 수 있습니다.
SerCx2는 사용자 지정 수신 트랜잭션에 대해 보류 중인 새 데이터 알림을 명시적으로 취소하지 않습니다. 그러나 직렬 컨트롤러 드라이버는 알림을 사용하도록 설정하고 드라이버가 다음 이유 중 하나로 연결된 읽기 요청을 완료해야 하는 경우 새 데이터 알림을 암시적으로 취소해야 할 수 있습니다.
- 읽기 요청 시간이 초과되거나 취소됩니다.
- 직렬 컨트롤러가 D0 디바이스 전원 상태를 종료하여 저전력 상태로 들어가려고 합니다.
드라이버는 일반적으로 WdfRequestComplete 와 같은 메서드를 호출하여 요청을 완료합니다. 드라이버는 요청이 완료된 후 SerCx2CustomReceiveTransactionNewDataNotification 을 호출해서는 안 됩니다.
요청 개체 액세스
사용자 지정 수신 트랜잭션을 시작하기 위해 SerCx2는 드라이버의 EvtSerCx2CustomReceiveTransactionStart 함수를 호출하고 연결된 읽기 요청(WDFREQUEST 개체 핸들에 캡슐화됨)을 이 함수에 매개 변수로 전달합니다. 드라이버는 트랜잭션이 완료되면 WdfRequestComplete 와 같은 메서드를 호출하여 이 요청을 완료해야 합니다. 요청을 즉시 완료할 수 없는 한 EvtSerCx2CustomReceiveTransactionStart 함수가 반환되기 전에 드라이버는 WdfRequestMarkCancelableEx 와 같은 메서드를 호출하여 요청을 취소 가능으로 표시해야 합니다.
직렬 컨트롤러 드라이버는 WdfRequestRetrieveOutputBuffer 와 같은 메서드를 사용하여 읽기 요청의 데이터 버퍼에 액세스하면 안됩니다. 대신 드라이버는 EvtSerCx2CustomReceiveTransactionStart 함수에 전달된 Mdl, Offset 및 Length 매개 변수 값을 사용하여 이 버퍼에 액세스해야 합니다.
사용자 지정 수신 트랜잭션 중에 드라이버는 요청 개체에 연결된 컨텍스트에서 트랜잭션에 대한 정보를 저장해야 할 수 있습니다. 이 경우 드라이버의 EvtDriverDeviceAdd 이벤트 콜백 함수는 WdfDeviceInitSetRequestAttributes 메서드를 호출하여 요청 개체에 사용할 특성을 설정할 수 있습니다. 이러한 특성에는 요청 컨텍스트에 사용할 이름 및 할당 크기가 포함됩니다. 이 호출에 지정된 요청 특성은 드라이버가 SerCx2InitializeDevice 메서드 호출에서 지정하는 요청 특성과 일치해야 합니다. 이러한 특성은 드라이버가 SerCx2InitializeDevice에 전달하는 SERCX2_CONFIG 구조체의 RequestAttributes 멤버에 지정됩니다. 자세한 내용은 SERCX2_CONFIG 참조하세요.
직렬 컨트롤러 드라이버가 사용자 지정 수신 트랜잭션을 시작할 때 수신하는 읽기 요청의 경우 드라이버 프레임워크에서 할당한 요청 컨텍스트는 초기화되지 않습니다. 드라이버는 모범 사례로 RtlZeroMemory 루틴을 호출하여 이 요청 컨텍스트를 모든 0으로 초기화해야 합니다.