windows driver interrupt continuous read 사용하기

wangki·약 23시간 전

windows driver

목록 보기
10/10

전편에서 interrupt endpoint를 추가하였다. 온도 센서값을 읽어서 kmdf driver와 통신은 성공하였다. application level에서 실시간으로 값을 읽는 것을 구현하였다.


전체 흐름도


KMDF pico driver 구조

중요한 포인트는 어플리케이션에서 Interrupt read 관련 IOCTL 요청을 할 때 받은 reuqest를 바로 완료 처리하지 않고 PendingQueue에 담아준다. 그리고 pico mcu로부터 온도 센서 값을 수신할 때 호출되는 콜백에서 Pending Queue 내부의 request를 꺼내서 완료 처리해 주면 된다.

status = WdfIoQueueRetrieveNextRequest(pDeviceContext->PendingQueue, &request);
if (!NT_SUCCESS(status)) {
    DbgPrint("[picodriverEvtInterruptReadComplete] No pending request, discarding data\n");
    return;
}

// App의 output buffer에 interrupt 데이터 복사
status = WdfRequestRetrieveOutputBuffer(request, NumBytesTransferred, &outBuffer, NULL);
if (!NT_SUCCESS(status)) {
    DbgPrint("[picodriverEvtInterruptReadComplete] WdfRequestRetrieveOutputBuffer failed 0x%x\n", status);
    WdfRequestComplete(request, status);
    return;
}

RtlCopyMemory(outBuffer, WdfMemoryGetBuffer(Buffer, NULL), NumBytesTransferred);
WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, NumBytesTransferred);

위 코드를 참고하면 된다.

결과적으로 어플리케이션 레벨에서 icotl로 요청한 request가 있어야 실시간으로 읽어갈 수 있는 점에서 bulk 통신으로 폴링 방식으로 읽는 방식과 크게 다르지는 않다.

Application 레벨에서는 요청-응답 구조로 Polling과 유사해 보이지만, USB 버스 레벨에서는 디바이스가 준비됐을 때만 전송이 발생하므로 불필요한 버스 점유가 없다는 점에서 본질적으로 다르다.


어플리케이션 구조

어플리케이션 레벨의 동작을 간략히 설명하겠다.
OnInitDialoge에서 interrupt read init을 통해서 DeviceIoCotrol로 비동기 요청을 하고 콜백을 등록을 해준다. 콜백이 호출되면 postmessage를 통해서 gui thread로 메시지를 넘겨준다. 해당 메시지에 연결된 핸들러가 호출이 되면서 ui control을 업데이트해준다.


테스트

pico를 복합장치로 설정했기에 cdc 인터페이스로 시리얼 통신으로 실제 로그를 받아 볼 수 있다. pico에서 보내는 로그와 어플리케이션인 mfc에서 실시간으로 온도 데이터를 수신 테스트를 하였다. 중간에 이미지를 bulk endpoint로 보내서 얼굴 인식하도록 하였고 받은 추론 값으로 블러처리도 진행하였다. interrupt 방식은 문제 없는 것을 확인할 수 있다.


결론

pico mcu를 활용한 프로젝트를 마무리할 예정이다.

  1. mcu 전용으로 만든 model embed
  2. kmdf driver usb 개발
  3. tinyusb를 활용하여 vendor specific, cdc interface로 복합 장치 구현
  4. bulk, interrupt endpoint 통신

이외에도 정말 많은 시간이 들어갔다. led 디버깅을 하면서 불편해 cdc 인터페이스를 추가한 것, driver 개발하며 bosd 발생으로 windbg로 덤프 분석 및 실시간 커널 디버깅 등등 개발에 필요한 지식이 정말 많다는 것을 깨달았다. 프로젝트를 진행하며 https://www.youtube.com/@%EC%9D%B4%EB%B4%89%EC%84%9D-d6u 해당 유튜브 채널이 정말로 도움이 많이 되었다. windows kernel과 driver 개발이 접근하기 쉽지는 않다.

다음 프로젝트로는 실제 가속기를 활용할 예정이다.

위 가속기를 가지고 PCIe driver를 kmdf로 만들 것이다. usb보다 훨씬 난이도가 높다고 한다. 화이팅!

https://github.com/wangki-kyu/pico_usb_vendor
https://github.com/wangki-kyu/pico_driver

0개의 댓글