최근 차량용 소프트웨어 개발 환경에서도 Rust 언어가 점차 관심을 받고 있습니다. 특히 AUTOSAR Classic 플랫폼과의 통합은 Rust 도입을 검토하는 개발자들에게 자주 등장하는 주제입니다. 이번 글에서는 Foreign Function Interface(FFI)를 활용한 Rust와 AUTOSAR Classic의 통합 방법을 단계별로 살펴보겠습니다.
1. AUTOSAR Classic의 기본 구조
AUTOSAR Classic 환경에서 애플리케이션은 RTE(Run-Time Environment)를 통해 동작합니다. 구조를 단순히 표현하면, 상위에는 소프트웨어 컴포넌트(SWC)와 Runnable이 있고, 그 아래에 RTE가 있으며, 그 밑으로는 BSW(Basic Software), OS, 드라이버 계층이 위치합니다.
즉, RTE는 C로 작성된 애플리케이션 코드를 호출하는 중간 계층 역할을 합니다. 일반적으로 Application Runnable은 C 함수 형태로 등록되며, RTE는 이를 직접 호출합니다. 예를 들어, RTE는 “MyRunnable”이라는 C 함수를 실행하도록 구성됩니다.
그렇다면, 이 함수를 Rust 쪽으로 옮길 수 있을까요?
정답은 가능하다는 것입니다. 단, Rust 함수가 C ABI(Application Binary Interface) 형식으로 외부에 노출되어야 합니다. 이 방식이 바로 FFI 기반 통합의 출발점입니다.
2. 첫 번째 패턴 – RTE에서 Rust를 호출하는 방식 (Forward Call)
이 방식은 현실적으로 가장 많이 쓰이고, 구현 난이도도 낮습니다. RTE가 생성될 때 MyRunnable 같은 C 함수를 호출하도록 설계되어 있는데,
이 함수를 Rust에서 대신 구현하는 개념입니다.
이를 위해 Rust에서는 함수를 C 스타일로 export하고, RTE 측에서는 외부 함수로 선언해 호출하도록 구성합니다.
이 접근법을 적용하면, RTE가 기존과 동일한 방식으로 Runnable을 실행하면서 실제 로직은 Rust 내부에서 수행할 수 있습니다. 즉, RTE에서 Rust 함수로의 정방향 호출(Forward Call) 이 가능합니다.
이 방법은 AUTOSAR의 구조적 제약을 위배하지 않으며, 기존 C 기반 설계를 유지하면서도 Rust의 장점을 일부 활용할 수 있다는 점에서 가장 안전하고 실무적으로도 검증된 통합 방식입니다.
3. 두 번째 패턴 – Rust에서 RTE를 호출하는 방식 (Inversion Call)
두 번째 방식은 방향이 반대입니다. 즉, Rust 코드가 실행 중일 때, RTE에서 제공하는 API를 직접 호출하는 구조입니다.
이 접근은 가능하지만, 좀 더 주의가 필요합니다. Rust 코드가 RTE의 클라이언트가 되는 형태이기 때문입니다. 이를 위해 Rust에서는 RTE가 제공하는 C 함수를 외부 선언으로 불러와야 합니다. Rust 코드 내에서는 해당 함수들을 “unsafe” 블록에서 호출해야 하며, 이 호출이 실제로 RTE의 C 라이브러리와 올바르게 링크되어야 합니다.
정리하자면, Rust가 AUTOSAR의 API를 직접 호출할 수는 있지만, FFI 특성상 메모리 안정성이 완전히 보장되지 않으므로 빌드 단계에서 링크 순서나 ABI 호환성을 철저히 관리해야 합니다.
4. 정리
두 가지 방식은 각각 장단점이 분명합니다.
RTE에서 Rust를 호출하는 방식은 상대적으로 구현이 간단하며, AUTOSAR의 기존 구조와 완전히 호환됩니다. Runnable을 Rust 함수로 대체할 수 있고, 별도의 구조 변경이 필요하지 않습니다.
반면, Rust에서 RTE API를 호출하는 역방향 방식은 더 많은 제어와 유연성을 제공하지만, unsafe 블록 사용과 링크 관리 등 개발 난이도가 다소 높습니다. AUTOSAR 구조 자체를 변경하는 것은 아니지만, 실수 시 런타임 오류나 빌드 불일치 문제가 발생할 수 있습니다.