19.7.3.2. 발행자가 전송한 모사 데이터와 구독자가 수신한 데이터의 일치성 검증
PX4_INFO 매크로라는 전지전능한 디버깅 무기를 확보했다면, 이제 이 무기를 퍼블리셔(발행자)와 구독자(Subscriber) 양쪽 진영의 심장부에 꽂아 넣고, 우리가 짠 다중 인스턴스 VFS 파이프라인이 단 1비트의 데이터 오염도 없이 데이터를 전송해 내는지 검증하는 **‘크로스-체크 무결성(Cross-check Integrity) 검사’**를 수행할 차례이다.
데이터를 보내는 쪽(퍼블리셔 데몬)에서 쏜 숫자와, 받는 쪽(구독자 데몬)이 씹어먹은 숫자가 리눅스 NSH 콘솔 터미널 화면 위에서 완벽한 거울상(Mirror)으로 일치하지 않는다면, 이는 중간에 위치한 uORB 커널 락(Lock) 메커니즘이 무너졌거나 당신의 C++ 구조체 캐스팅에 치명적인 메모리 침범 버그가 숨어있다는 명백한 파멸의 징조이다.
1. 무결성 핑퐁(Ping-Pong) 테스트 아키텍처 타설
테스트의 논리는 극도로 잔혹하고 단순하다. 퍼블리셔는 자신이 orb_publish를 때리기 직전에 자기가 만들어낸 가짜(Mock) 데이터를 콘솔에 크게 소리쳐 외치고, 반대편의 구독자는 큐에서 깨어나 copy로 데이터를 빼먹자마자 자신이 받은 고깃덩어리를 보란 듯이 똑같이 소리쳐 외친다.
1.1 퍼블리셔(발행자) 데몬의 타격점
퍼블리셔의 메인 while 루프 안, 데이터를 링커에 쑤셔 넣는 바로 그 지점(orb_publish) 직전에 아래와 같이 로깅 레이더를 심는다.
// 퍼블리셔: 가짜(Mock) 테스트 데이터를 무작위로 생성 (예: 루프 카운터 값 활용)
sensor_data.temperature = 25.0f + (float)(_loop_counter % 100) * 0.1f;
sensor_data.timestamp = hrt_absolute_time();
// [무결성 검증 레이더 A] 내가 링 버퍼에 던질 원본 데이터를 영구 박제한다.
PX4_INFO("[PUB] Instance %d | Sending Temp: %.2f | TS: %llu",
my_sensor_instance, (double)sensor_data.temperature, sensor_data.timestamp);
// 실제 파이프라인 송출 타격
orb_publish(ORB_ID(sensor_test_data), sensor_pub_fd, &sensor_data);
1.2 구독자(Subscriber) 데몬의 타격점
반대편 블록, 구독자 클래스의 Run() 콜백 메서드 내부에서 while (updated()) 루프를 돌며 데이터를 빨아들인 직후를 타격점으로 잡는다.
// 구독자: 인터럽트에 깨어나 링 버퍼의 스냅샷을 딥카피로 빼앗아 온다.
_sensor_sub.copy(&received_data);
// [무결성 검증 레이더 B] 내가 방금 파이프 구멍에서 꺼낸 날 것의 데이터를 증명한다.
PX4_INFO("[SUB] Extracted | Received Temp: %.2f | TS: %llu | Latency: %llu us",
(double)received_data.temperature,
received_data.timestamp,
hrt_absolute_time() - received_data.timestamp);
2. SITL 터미널 교차 검증: 스케줄러의 무결성 증명
이 두 레이더가 심어진 코드를 빌드하고 시뮬레이터(make px4_sitl jmavsim)를 띄운 뒤, NSH 콘솔에서 px4_uorb_example start &를 치는 순간 터미널 창은 두 데몬이 미친 듯이 주고받는 텍스트 파도로 융단 폭격 당하게 된다.
아래는 완벽하게 성공한 100% 무결점 시스템 통신에서만 나타나는 기적 같은 이상적인 텍스트 덤프(Dump)이다.
px4> px4_uorb_example start &
[px4_uorb_example] [PUB] Instance 0 | Sending Temp: 25.10 | TS: 10450210
[px4_uorb_example] [SUB] Extracted | Received Temp: 25.10 | TS: 10450210 | Latency: 12 us
[px4_uorb_example] [PUB] Instance 0 | Sending Temp: 25.20 | TS: 10460225
[px4_uorb_example] [SUB] Extracted | Received Temp: 25.20 | TS: 10460225 | Latency: 15 us
[px4_uorb_example] [PUB] Instance 0 | Sending Temp: 25.30 | TS: 10470233
[px4_uorb_example] [SUB] Extracted | Received Temp: 25.30 | TS: 10470233 | Latency: 11 us
...
당신은 이 무자비하게 쏟아지는 로그 위에서 정확히 세 가지 지표를 매의 눈으로 심문해야 한다.
- 데이터 일치성 (Data Parity): PUB에서 찍힌
25.20이면 SUB도25.20인가? 부동소수점 오차나 쓰레기 값(Garbage)이 섞이지 않았는가? - 타임스탬프 동기화 (Timestamp Sync): 링커를 거쳐 나오는 동안 데이터가 섞여서 과거의 TS 값이 역전되어 튀어나오지 않는가?
- 지연 시간 (Latency): 보내진 시간과 받는 루프 안의 현재 시간 차이(
Latency)가 수십 US(마이크로초) 이내의 미친듯한 칼날 같은 스케줄링 간격으로 유지되는가? 만약 수만 US(밀리초 단위)로 벌어져 있다면 당신의Run()콜백 로직에 무거운 비즈니스 에러가 껴있어 큐가 밀리고 있다는 심각한 경고이다.
이 터미널 화면의 텍스트 교차 동기화 리포트는, 당신이 짠 uORB 구독 데몬이 PX4의 가혹한 리얼타임 스케줄링(RTOS) 환경을 단 하나의 오차도 없이 견뎌내고 있음을 방증하는 가장 완벽한 수학적 승리 증명서이다.