18.7.1.1 uORBManager::getDeviceNodeList()를 통한 활성 토픽 동적 순회
소프트웨어 아키텍처가 아무리 훌륭하더라도, 실제 비행 중에 어떤 데이터가 얼마나 자주 오가고 있는지 눈으로 확인할 수 없다면 문제를 해결할 수 없다. PX4는 커맨드 라인(CLI) 환경에서 리눅스의 top 명령어를 연상케 하는 강력한 uORB 모니터링 툴인 uorb top 을 제공하여 이 시스템의 투명성을 극대화한다.
이 훌륭한 모니터링 시스템의 첫 단추는 현재 시스템에 날아다니고 있는 ‘살아있는’ 모든 토픽(활성 토픽)들의 명단을 동적으로 순회(Traversal)하고 수집하는 것에서부터 시작된다. 그 중추적인 역할을 담당하는 API가 바로 uORBManager::getDeviceNodeList() 이다.
1. 활성 노드 연결 리스트(Linked List)
NuttX 시스템 부팅 이후 orb_advertise를 통해 누군가가 퍼블리셔로 등록을 마친 토픽들은 모두 VFS 상에 uORBDeviceNode 객체로 실체화되어 메모리에 상주하게 된다. uORBManager(내부적으로는 uORBDeviceMaster)는 이 생성된 모든 디바이스 노드들의 포인터를 단순한 단방향 연결 리스트(Singly Linked List) 형태로 유지하고 추적한다.
uorb top 명령어가 실행되면 백그라운드에서는 이 전역 매니저에게 리스트의 첫 시작점(Head Point)을 달라고 다음과 같이 요청한다.
// uorb top 내부 활성 토픽 순회 로직 (슈도코드)
// 1. uORB 매니저로부터 활성 노드의 리스트 헤드를 획득
uORB::DeviceNode::List &node_list = uORB::Manager::get_instance()->getDeviceNodeList();
// 2. 연결 리스트를 순회하며 각 노드 정보(Node Info) 수집
for (auto &node : node_list) {
// node.get_name() : "sensor_accel" 등의 토픽 이름
// node.get_instance() : 다중 인스턴스의 경우 인덱스 번호 (0, 1, 2...)
// node.subscriber_count(): 현재 이 토픽을 듣고 있는 모듈(Subscribers)의 수
// 수집된 정보를 바탕으로 화면 출력 데이터 구조체 업데이트
collect_node_statistics(&node);
}
2. 시스템 보호를 위한 읽기 전용(Read-only) 순회
여기서 구조적으로 매우 중요한 점은, getDeviceNodeList()가 반환하는 리스트 참조(&node_list)가 철저히 읽기 전용이거나 외부에서 원소의 삭제/삽입 로직을 함부로 건드리지 못하도록 캡슐화되어 있다는 사실이다.
비행기 내의 수많은 센서와 내비게이션 스레드들이 쉴새 없이 생성되고 컨텍스트가 전환되는 와중에도 uorb top 프로세스가 이 리스트를 훑을 수 있는 이유는, 이 리스트에 노드가 추가되는 행위 자체(orb_advertise 시점)가 매우 드물게 발생하며, 주로 시스템 초기화 단계나 모듈 구동 시점에 국한되어 있기 때문이다.
만약 이 리스트 순회 중에 누군가 노드를 파괴하려고 한다면 치명적인 세그멘테이션 폴트(Segmentation Fault) 범람이 일어나겠지만, VFS의 참조 카운팅(Reference Counting) 기법 (18.5.1.2절 참조) 덕분에 top 명령어가 노드를 바라보는 그 순간(객체를 참조하는 순간) 생명주기가 철벽처럼 보장된다.
결과적으로 uorb top은 이 getDeviceNodeList() 순회를 정해진 간격(예: 1초에 한 번)마다 반복 호출함으로써, 펌웨어에 하드코딩된 전체 메시지 정의(orb_metadata)를 뒤지는 것이 아니라 현재 이 순간 실제로 RAM 상에서 호흡하며 트래픽을 만들어내고 있는 진짜 활성 토픽들만의 스냅샷 명단을 아주 저렴한 비용(O(N))으로 뽑아내어 터미널 화면으로 끌어올릴 수 있는 것이다.