다음을 통해 공유


SerCx2-Managed 직렬 포트에서 데이터 읽기

직렬 컨트롤러(또는 UART)에는 일반적으로 수신 FIFO가 포함됩니다. 이 FIFO는 직렬 포트에 연결된 주변 장치에서 받은 데이터의 하드웨어 제어 버퍼링을 제공합니다. 수신 FIFO에서 데이터를 읽기 위해 이 디바이스의 주변 장치 드라이버는 읽기(IRP_MJ_READ) 요청을 직렬 포트로 보냅니다.

직렬 포트가 주변 장치 드라이버가 데이터를 읽을 수 있는 것보다 빠르게 데이터를 계속 수신하는 경우 수신 FIFO가 오버플로될 수 있습니다. 오버플로로 인한 데이터 손실을 방지하려면 주변 장치 드라이버는 일반적으로 하드웨어 흐름 제어를 사용하도록 직렬 포트를 구성해야 합니다. 흐름 제어를 사용하면 직렬 컨트롤러 하드웨어는 수신 FIFO가 거의 가득 찼을 때 주변 장치 디바이스에 데이터 전송을 중지하도록 자동으로 신호를 보냅니다. 일반적으로 SerCx2에서 관리되는 직렬 포트는 하드웨어 흐름 제어를 사용해야 합니다. 자세한 내용은 흐름 제어 세부 정보를 참조하세요.

그러나 흐름 제어를 사용하여 주변 장치 디바이스가 너무 오랫동안 데이터를 전송하지 못하게 하거나 디바이스가 계속 올바르게 작동하지 않을 수 있습니다. 예를 들어 디바이스가 이 버퍼에서 직렬 포트로 데이터를 너무 오래 보내지 못하는 경우 주변 디바이스에 오버플로할 수 있는 내부 데이터 버퍼가 있을 수 있습니다.

이 페이지에서

비동기 읽기 요청 사용

잘못된 작업과 가능한 데이터 손실을 방지하기 위해 주변 장치 드라이버는 직렬 컨트롤러의 수신 FIFO에서 적시에 데이터를 읽습니다. 일반적으로 데이터를 수신하기 전에 주변 장치 드라이버는 향후 주변 장치에서 데이터가 도착할 것으로 예상하여 비동기 읽기 요청을 직렬 포트로 보냅니다. 이 읽기 요청은 수신 FIFO에서 데이터를 읽을 수 있을 때까지 SerCx2 I/O 큐에서 보류 상태로 유지됩니다.

대부분의 하드웨어 플랫폼에서 주변 장치 드라이버에는 한 번에 두 개 이상의 읽기 요청이 보류 중일 필요가 없습니다. 드문 경우이지만 데이터가 수신된 후 읽기 요청을 처리하는 데 너무 오래 걸리는 경우 드라이버에 두 개 이상의 미해결 읽기 요청이 필요할 수 있으며, 이로 인해 결과 데이터 백업으로 인해 주변 장치에서 데이터가 손실되거나 잘못 동작할 수 있습니다.

주변 장치 드라이버에 보류 중인 이러한 읽기 요청이 한 번에 하나만 있다고 가정하면 이 요청에서 필요한 데이터 버퍼 크기는 주로 주변 디바이스의 알려진 동작에 따라 달라집니다. 예를 들어 드라이버가 디바이스에서 예상할 데이터 바이트 수를 미리 알고 있는 경우 드라이버는 요청의 버퍼 크기를 이 바이트 수로 설정합니다. 읽기 요청은 버퍼가 수신 FIFO의 데이터로 채워지는 즉시 완료됩니다. 이에 대한 응답으로 드라이버는 비동기적으로 새 읽기 요청을 보내 다음 데이터 블록을 기다릴 수 있습니다.

그러나 주변 장치 드라이버는 주변 장치에서 예상되는 데이터의 양을 미리 알지 못할 수 있습니다. 이 경우 드라이버는 읽기 요청의 데이터 버퍼를 적절한 크기로 설정한 다음 간격 제한 시간을 사용하여 주변 장치에서 데이터의 끝을 식별합니다. 읽기 버퍼에 적합한 크기를 선택하려면 주변 장치 작동 방식에 대한 자세한 지식이 필요할 수 있습니다. 읽기 버퍼가 너무 작은 경우 드라이버는 데이터 읽기를 완료하기 위해 하나 이상의 추가 읽기 요청을 보내야 합니다.

간격 시간 제한 세부 정보

읽기 및 쓰기 요청에 대한 제한 시간 매개 변수를 설정하기 위해 주변 장치 드라이버는 직렬 포트에 IOCTL_SERIAL_SET_TIMEOUTS 요청을 보낼 수 있습니다. 읽기 제한 시간은 이 요청의 ReadIntervalTimeout, ReadTotalTimeoutMultiplierReadTotalTimeoutConstant 매개 변수 값에 의해 제어됩니다. ReadIntervalTimeout 은 수신 트랜잭션에서 두 개의 연속 바이트 사이에 허용되는 최대 시간 간격을 지정합니다. ReadTotalTimeoutMultiplierReadTotalTimeoutConstant가 모두 0이고 읽기 요청이 직렬 포트로 전송될 때 직렬 컨트롤러의 수신 FIFO가 비어 있는 경우 이 요청은 포트가 하나 이상의 새 데이터를 수신할 때까지 시간 초과(SerCx2 I/O 큐에서 보류 중인 상태로 유지)되지 않습니다. 자세한 내용은 SERIAL_TIMEOUTS.

SoC(System on a Chip) 통합 회로의 직렬 포트는 초당 몇 메가비트 이상의 최고 속도로 주변 장치에서 데이터를 수신할 수 있습니다. 이 디바이스의 주변 장치 드라이버 개발자는 간격 제한 시간 값( ReadIntervalTimeout 매개 변수에 지정된 대로)을 밀리초 이하로 설정하려고 할 수 있지만 이 값은 원하는 효과가 없을 수 있습니다. 간격 제한 시간을 검색하는 데 사용되는 타이머의 정확도는 시스템 클록의 세분성에 의해 제한되기 때문입니다.

예를 들어 시스템 클록 기간이 15밀리초이고 드라이버가 ReadIntervalTimeout 값을 1밀리초로 설정하는 경우 0에서 15밀리초가 조금 넘는 범위의 바이트 대 바이트 간격이 시간 초과를 트리거할 수 있습니다. 경우에 따라 이 설정으로 인해 주변 장치에서 데이터 전송 중간에 시간 초과가 발생할 수 있습니다. 이 전송이 완료된 후에만 시간 제한이 발생할 수 있도록 드라이버는 ReadIntervalTimeout 을 15밀리초보다 약간 큰 값으로 설정할 수 있습니다. 예를 들어 ReadIntervalTimeout 이 20밀리초로 설정된 경우 30밀리초의 바이트 대 바이트 간격이 안정적으로 시간 제한을 트리거하고 15밀리초 이하의 간격은 시간 초과를 트리거하지 않습니다.

타이머 정확도가 시스템 클록에 따라 달라지는 방법에 대한 자세한 내용은 타이머 정확도를 참조하세요.

흐름 제어 세부 정보

SerCx2 관리 직렬 포트를 사용하는 주변 장치 드라이버는 수신 FIFO가 오버플로되지 않도록 하드웨어 흐름 제어를 사용하도록 이러한 포트를 구성해야 합니다. 보류 중인 읽기 요청이 없는 경우 SerCx2는 수신 FIFO의 용량을 초과하는 수신 데이터의 소프트웨어 버퍼링을 제공하지 않습니다. 이 FIFO를 오버플로할 수 있으면 데이터가 손실됩니다.

하드웨어 흐름 제어를 사용하도록 설정하기 위해 주변 장치 드라이버는 직렬 포트에 대한 핸드셰이크 및 흐름 제어 설정을 위한 IOCTL_SERIAL_SET_HANDFLOW 요청을 보낼 수 있습니다. 또는 드라이버가 IOCTL_SERIAL_APPLY_DEFAULT_CONFIGURATION 요청을 보내 하드웨어 흐름 제어를 포함하는 기본 하드웨어 설정 집합을 사용하도록 직렬 포트를 구성할 수 있습니다. IOCTL_SERIAL_SET_HANDFLOW 요청은 SERIAL_HANDFLOW 구조를 사용하여 흐름 제어 설정을 설명합니다. IOCTL_SERIAL_APPLY_DEFAULT_CONFIGURATION 요청에는 공급업체에서 지정한 데이터 형식의 유사한 정보가 포함될 수 있습니다.

주변 장치 드라이버가 IOCTL_SERIAL_SET_HANDFLOW 요청을 사용하여 하드웨어 흐름 제어를 사용하도록 설정하는 경우 드라이버는 이 요청의 SERIAL_HANDFLOW 구조에서 다음 플래그를 설정해야 합니다.

  • 구조체의 ControlHandShake 멤버에 있는 SERIAL_CTS_HANDSHAKE 플래그입니다. 이 플래그를 사용하면 직렬 포트가 수신 작업에 흐름 제어를 사용할 수 있습니다.
  • FlowReplace 멤버의 SERIAL_RTS_CONTROL 및 SERIAL_RTS_HANDSHAKE 플래그입니다. 이러한 플래그를 사용하면 직렬 포트가 전송 작업에 흐름 제어를 사용할 수 있습니다.