18.4.1 토픽 광고(`orb_advertise`) 및 노드 할당 시퀀스

18.4.1 토픽 광고(orb_advertise) 및 노드 할당 시퀀스

발행자 파이프라인의 첫 단추는 광고(Advertisement) 행위이다. 일상생활에서 상점을 열기 전 간판을 달고 영업 허가를 받는 것처럼, 센서 모듈이 데이터를 뿜어내기 위해서는 uORB 매니저에게 “내가 이 토픽 이름으로 데이터를 발행할 테니, 통신 파이프를 열어달라“고 정식으로 요청해야 한다. 이 임무를 수행하는 함수가 바로 orb_advertise() 이다.

1. 지연 개설(Lazy Advertisement) 패턴의 도입

초기 통신 아키텍처에서는 모듈이 부팅되자마자 즉시 orb_advertise()를 때려 파이프를 열려고 시도했다. 그러나 수백 개의 모듈이 동시다발적으로 부팅되는 과정에서, 아직 uORB 매니저 싱글톤(18.3.1절)이 채 깨어나기도 전에 광고 요청이 쏟아져 시스템이 크래시(Crash)되는 부팅 레이스 컨디션(Boot Race Condition) 문제가 빈번히 발생했다.

이를 우아하게 회피하기 위해 현대의 C++ uORB::Publication 클래스는 지연 개설(Lazy Advertisement) 패턴을 채택했다.

생성자(Constructor)가 호출되는 시점에는 메타데이터 포인터만 저장해 둘 뿐, 실제 커널 노드 생성은 철저히 미뤄둔다. 그러다가 모듈이 최초로 진짜 데이터를 버퍼에 담아 publish() 메서드를 호출하는 바로 그 찰나의 순간에, orb_advertise()를 동기적으로 가로채어(Intercept) 호출함으로써 가장 안전한 시점에 파이프를 뚫어낸다.

2. orb_advertise() 내부의 4단계 동작 시퀀스

최초의 publish()가 트리거되어 내부 엔진이 orb_advertise()를 호출하면, uORB 지하 세계에서는 다음과 같은 숨 가쁜 노드 할당 시퀀스가 전개된다.

  1. 메타데이터 조회 및 승인: 인자로 넘어온 ORB_ID(topic) 매크로를 통해 등록된 orb_metadata 구조체를 조회한다. 이 구조체 안에는 이 데이터가 메모리를 얼마나 차지할지(o_size) 정확히 적혀 있다 (18.2.3.1절 참조).
  2. uORBDeviceMaster 위임 및 VFS 마운트: 싱글톤 매니저를 통해 uORBDeviceMaster를 호출하고, 가상 파일 시스템(VFS)의 /obj 네임스페이스 트리에 이 토픽을 위한 빈 문자열 디바이스 노드(예: /obj/sensor_gyro0)를 등록(register_driver)한다 (18.3.2절 참조).
  3. 링 버퍼(Ring Buffer) 영구 메모리 할당: 여기가 가장 중요한 물리적 작업이다. uORBDeviceNode 객체가 인스턴스화되면서, 메타데이터의 o_size를 바탕으로 실제 시계열 데이터를 보관할 링 버퍼 메모리 블록을 힙(Heap)에서 영구적으로 할당받아 커널 노드 뒤편에 결속시킨다.
  4. 최초의 데이터 삽입 (초기화): orb_advertise()는 메타데이터뿐만 아니라 최초의 데이터 포인터도 인자로 받는다. 파이프가 개통되자마자 이 초기 데이터를 새로 산 링 버퍼에 밀어 넣어 버퍼의 첫 번째 슬롯을 초기 상태로 채운다.

이 거대한 4단계의 시퀀스가 성공적으로 완료되면, orb_advertise()는 새로 개통된 파이프의 제어권인 핸들(Handle, orb_advert_t 타입, 내부적으로는 uORBDeviceNode 포인터)을 반환한다. 이후부터 발행되는 수만 번의 데이터 통신(publish)은 이 무거운 개통 과정을 모두 건너뛰고 오직 링 버퍼 메모리 고속 복사 로직으로만 진입하게 된다.