19.6.2.2. ORB_MULTI_MAX_INSTANCES 제한 및 초과 시 예외 처리 로직
orb_advertise_multi() 함수가 알아서 빈 방을 척척 찾아내어 링 버퍼를 동적으로 할당해 주는 마법 같은 다중 인스턴스 생태계는 개발자에게 무한한 쾌감을 주지만, 픽스호크 마더보드의 메인 램(RAM) 크기는 보통 1MB~2MB 남짓에 불과한 극도로 메마르고 척박한 물리적 사막이다.
단일한 센서 스키마(예: vehicle_gps_position)를 1개 복제하여 새로운 링 버퍼 인스턴스 꼬리를 만들 때마다, 커널은 피눈물을 흘리며 힙(Heap) 메모리의 몇십~몇백 바이트를 영구 할당해야만 한다. 만약 미친 개발자가 while 무한 루프 안에서 실수로 orb_advertise_multi()를 천 번 연속으로 때려버린다면, 순식간에 픽스호크의 전역 메모리가 완전히 고갈(OOM: Out Of Memory)되어 기체 메인 모터가 서고 그대로 추락해 버릴 것이다.
이러한 치명적인 메모리 폭주와 악의적인 스레드의 메모리 점유 공격(Denial of Service)을 OS 커널 차원에서 차단하기 위해, PX4 uORB 코어 아키텍트는 **ORB_MULTI_MAX_INSTANCES**라는 절대적인 거시적 바리케이드를 커널 헤더 깊숙한 곳에 하드코딩으로 세워두었다.
1. ORB_MULTI_MAX_INSTANCES: 커널의 물리적 부동산 한계선
PX4 소스코드 트리 안의 uORB/uORB.h 헤더를 뜯어보면, 단일 토픽 이름 밑에 최대로 생성될 수 있는 자식 인스턴스 링 버퍼의 최대 개수가 보통 4 (또는 최신 버전에서는 성능에 따라 다름)로 엄격히 제한(Lock)되어 있는 것을 목격할 수 있다.
즉 커널은 0번, 1번, 2번, 3번 방까지만 기쁜 마음으로 지어주고, 당신의 5번째 예비 센서 데몬이 뒤늦게 부팅되어 4번 방을 달라고 청원하면 가차 없이 nullptr 에러를 뱉어버리며 할당을 완전 거부한다.
따라서 최고 수준의 비행 제어 데몬 아키텍트라면, 단순히 “내가 당연히 0번~3번 방 중 하나를 먹겠지“라는 낭만적인 망상 코딩을 버리고, 이 거대한 ORB_MULTI_MAX_INSTANCES 한계선에 부딪혀 내 데몬이 방을 배정받지 못했을 때 어떻게 얌전하고 우아하게 죽음을 맞이할 것인가(Graceful Degradation)에 대한 예외 처리(Exception Handling) 로직을 반드시 19.6.2.1 단원의 orb_advertise_multi() 직후 하단에 강제 타설해야 한다.
2. 인스턴스 할당 한계 초과 시의 치명적 예외 파싱 아키텍처
#include <uORB/uORB.h>
int my_sensor_instance = ORB_MULTI_UNASSIGNED;
sensor_test_data_s init_data{};
// 1. [운명의 주사위] 커널을 향해 다중 인스턴스 방 배정을 청원
orb_advert_t sensor_pub_fd = orb_advertise_multi(ORB_ID(sensor_test_data), &init_data, &my_sensor_instance, ORB_PRIO_DEFAULT);
// 2. [가장 강력한 블로킹 방어선] 할당 자체의 실패 (메모리 고갈, 커널 스케줄러 락 등)
if (sensor_pub_fd == nullptr) {
// 3. 대체 왜 실패했는가? 그 끔찍한 원인을 추적 분기한다.
if (my_sensor_instance >= ORB_MULTI_MAX_INSTANCES) {
// [원인 A] 시스템에 허용된 최대 4개의 토픽 인스턴스(0,1,2,3) 방이 이미
// 나보다 먼저 부팅된 다른 잡동사니 센서 데몬들에게 모조리 점령당해 알박기(Occupied) 된 상태이다!
PX4_ERR("FATAL: Maximum uORB instances (%d) reached for sensor_test_data! "
"No room for this 5th sensor daemon. Shutting down gracefully.", ORB_MULTI_MAX_INSTANCES);
// 4. [페일세이프 자살] 이 데몬 스크립트가 여기서 강제로 무한 루프를 타면 null 포인터 예외(Segfault)로
// VFS 전체가 찢어지므로, 즉시 얌전하게 return -1 을 때려 스스로 데몬 스레드를 자연사(Terminate)시킨다.
return PX4_ERROR;
} else {
// [원인 B] 방 개수가 꽉 찬 것도 아닌데 nullptr이 떴다면,
// 이는 시스템 힙 메모리(SRAM) 자체가 100% 꽉 차서 OOM(Out of Memory)이 터졌거나 uORB 디바이스 드라이버가 붕괴된 것이다.
PX4_ERR("FATAL: Unknown kernel memory allocation error during orb_advertise_multi.");
return PX4_ERROR;
}
}
// 5. 이 끔찍한 ORB_MULTI_MAX_INSTANCES의 철벽 방어선을 무사히 뚫고 내려왔다면...
PX4_INFO("Survival Confirmed! I successfully conquered Instance Room #%d", my_sensor_instance);
이렇듯 커널의 최대 인스턴스 제한 한계선을 두려워하고 그 벽에 머리를 부딪혔을 때의 예외 출구를 미리 정교하게 파놓는 방어 플로우(Defensive Flow)야말로, 공중에서 절대로 커널 패닉을 일으키지 않는 군사/항공 우주급 무결점 펌웨어 아키텍처 코딩의 가장 빛나는 정수이다.