마이크로초 지터 감소(실시간 커널 사용)

마이크로초 지터 감소(실시간 커널 사용)

5.15.44 raspi 커널과 라이브 패치가 적용된 Gentoo를 실행하는 Raspberry Pi 4B가 있습니다. 코어는 CONFIG_PREEMPT_RT(놀랍게도) , CONFIG_HZ_PERIODIC, CPU_FREQ_DEFAULT_GOV_PERFORMANCE(머리로는 기억나지 않는 몇 가지 다른 옵션)로 구성되어 있으며, Raspi 자체는 1,800GHz 클럭 속도로 실행됩니다.

제가 해결하고 싶은 문제는 다음과 같습니다.

외부 장치를 Raspi의 GPIO 핀에 연결했습니다. 이 장치는 입력 및 출력에 1핀을 사용합니다. 입출력의 경우 4us(마이크로초)마다 1비트를 전송하여 통신이 이루어집니다. 낮은 비트(0)는 3us의 낮은 신호, 1us의 높은 신호로 나누어집니다. 높은 비트(1)는 1us의 낮은 신호와 3us의 높은 신호로 나누어집니다.

외부 장치는 주기적으로 000000001 시퀀스를 raspi에 보냅니다(약 36us 소요). 그 후 64비트 응답이 예상됩니다. 외부 장치에서 데이터를 읽기 위해 현재 핀 상태를 읽고 프로그램이 시작된 이후의 시간을 마이크로초 단위로 인쇄하는 작은 프로그램을 C++로 작성했습니다.

다음은 프로그램이 전송되는 값 0의 비트를 읽는 예입니다.

Pin State: 0 | Time Dif: 7365.79
Pin State: 0 | Time Dif: 7365.92
Pin State: 0 | Time Dif: 7366.05
Pin State: 0 | Time Dif: 7366.36
Pin State: 0 | Time Dif: 7366.49
Pin State: 0 | Time Dif: 7366.62
Pin State: 0 | Time Dif: 7366.75
Pin State: 0 | Time Dif: 7366.88
Pin State: 0 | Time Dif: 7367.01
Pin State: 0 | Time Dif: 7367.14
Pin State: 0 | Time Dif: 7367.27
Pin State: 0 | Time Dif: 7367.4
Pin State: 0 | Time Dif: 7367.55
Pin State: 0 | Time Dif: 7367.68
Pin State: 0 | Time Dif: 7367.81
Pin State: 0 | Time Dif: 7367.94
Pin State: 0 | Time Dif: 7368.07
Pin State: 0 | Time Dif: 7368.2
Pin State: 0 | Time Dif: 7368.33
Pin State: 0 | Time Dif: 7368.46
Pin State: 0 | Time Dif: 7368.61
Pin State: 0 | Time Dif: 7368.74
Pin State: 0 | Time Dif: 7368.86
Pin State: 0 | Time Dif: 7368.99
Pin State: 0 | Time Dif: 7369.12
Pin State: 0 | Time Dif: 7369.25
Pin State: 0 | Time Dif: 7369.38
Pin State: 0 | Time Dif: 7369.51
Pin State: 0 | Time Dif: 7369.66
Pin State: 0 | Time Dif: 7369.79
Pin State: 1 | Time Dif: 7369.92
Pin State: 1 | Time Dif: 7370.05
Pin State: 1 | Time Dif: 7370.18
Pin State: 1 | Time Dif: 7370.31
Pin State: 1 | Time Dif: 7370.44

(이것은 인쇄 중이라는 점에 유의해야 합니다.뒤쪽에프로그램은 이 값을 읽는 동안이 아니라 실행을 완료했습니다)

여태까지는 그런대로 잘됐다. 그러나 제가 파악하지 못한 작은 문제가 하나 있습니다. 때때로 프로그램은 몇 마이크로초를 건너뜁니다. 이는 여러 비트의 정보가 손실된다는 의미이므로 이 사용 사례에서는 큰 문제입니다.

Pin State: 0 | Time Dif: 7384.2
Pin State: 0 | Time Dif: 7384.33
Pin State: 1 | Time Dif: 7390.4
Pin State: 1 | Time Dif: 7390.53

여기에서 볼 수 있듯이 거의 6마이크로초가 빨라졌으며 이는 1.5비트의 정보가 손실된 것입니다. 단지 장치에서 폴링 요청을 받는 것이라면 별 문제가 아니지만 장치에 정보를 보내는 경우 모든 것이 엉망이 될까봐 걱정됩니다(장치는 어떤 종류의 오류 수정도 수행하지 않습니다). .

이제 내 질문은 이런 일이 발생하지 않도록 하는 방법입니다. 특정 우선순위로 프로세스를 설정하거나 실행할 수 있는 커널 구성이 있습니까? 나는 시도했지만 chrt -rr 99 <program>성공하지 못했습니다. 어떤 도움이라도 대단히 감사하겠습니다.

답변1

SCHED_RR 프로그램을 예약하는 올바른 선택을 하셨습니다.

RT 패치를 사용하여 IRQ를 SCHED_RR과 함께 스레드 가능하게 하여 GPIO와 관련된 IRQ 스레드의 우선 순위를 높이고 싶습니다.

궁극적으로 "프로그램"을 하나의 코어에 고정하고 GPIO IRQ 스레드를 다른 코어에 고정한 다음 다른 코어가 관리 작업을 수행하도록 해야 합니다.

기다리는 시간 때문에 값을 인쇄하는 것을 잊어버릴 수도 있습니다. 나중에 사용할 수 있도록 일부 tmpfs 파일에 기록해 두세요.

관련 정보