기록
[GPT가 알려주는] service & system 구조 파악 (dds 포팅 시도 중) 본문
좋아, 지금 보여준 이 작은 tree 구조만 두고 “얘네가 서로 무슨 관계인지”부터 딱 정리해볼게.
(실제로 뭐가 빠졌는지보다, 레이어 구조가 먼저 이해되면 나머지는 그냥 패턴 맞추기라 훨씬 쉬워짐.)
1. 제일 위: vendor/ivi/services/* = 안드로이드 서비스 레이어
vendor/ivi/services
├── canservice
│ ├── can
│ │ ├── aidl
│ │ ├── Android.bp
│ │ ├── lib
│ │ └── service
│ ├── can_service.mk
│ └── sepolicy/...
└── ddsservice
├── dds
│ ├── aidl
│ ├── Android.bp
│ ├── lib
│ └── service
├── dds_service.mk
└── sepolicy/...
여기의 공통점
- aidl/
- 앱이 사용할 Binder 인터페이스 정의 (ICanService, IDdsService 같은 것들)
- lib/
- AIDL을 감싸는 Java 래퍼 (CanManager, DdsManager)
- 앱이 직접 쓰는 클라이언트 라이브러리
- service/
- 실제로 돌아가는 프로세스 소스
- 빌드되면 /vendor/bin/can_svc, /vendor/bin/dds_svc 같은 바이너리가 되는 애들
- 여기 Android.bp 에 cc_binary { name: "can_svc" ... } 같은 게 있음
- *_service.mk
- “이 모듈들을 PRODUCT에 포함시켜라”라고 상위 빌드에 알려주는 make 스크립트
- sepolicy/
- can_svc, dds_svc에 대한 SELinux 설정
👉 한 줄로 말하면:
vendor/ivi/services/* = 앱 ↔ (밑단 엔진) 사이를 Binder(AIDL)로 이어주는 안드로이드 서비스 계층
2. 중간: vendor/ivi/system/ccs/{j1939, dds} = CCS 엔진(HAL/daemon) 레이어
vendor/ivi/system/ccs
├── j1939
│ ├── Android.bp
│ ├── build
│ ├── include
│ ├── ipc
│ ├── j1939_service.mk
│ ├── j1939_service.rc
│ ├── service.cpp
│ └── src
└── dds
├── Android.bp
├── build
├── dds_module.mk
├── dds_module.rc
├── include
├── ipc
├── lib
├── module.cpp
└── src
여긴 CAN/dDS 자체가 아니라, **“CCS 내부에서 CAN + DDS 프로토콜을 관리하는 엔진”**이라고 보면 돼.
j1939 쪽
- ipc/1.0/*.hal
- HIDL HAL 인터페이스 (IJ1939.hal 등)
- src/, service.cpp
- J1939 메인 로직, HAL 구현
- j1939_service.mk
- 이 모듈(j1939 엔진)을 빌드 타깃에 올리는 make 파일
- j1939_service.rc
- init에 등록되는 서비스 정의
- /vendor/etc/init/j1939_service.rc 로 가서
service j1939_service /vendor/bin/j1939_service 이런 식으로 데몬 띄움
👉 즉:
system/ccs/j1939 = “J1939 전용 네이티브 데몬 + HAL”
dds 쪽
- ipc/1.0/*.hal
- IDDS.hal, IDDSCallback.hal = DDS용 HIDL 인터페이스
- lib/
- libfastdds.so, libfastcdr.so 같은 Fast-DDS 라이브러리
- src/, module.cpp
- DDSHal, DDSManager, Fast-DDS 연동 로직
- dds_module.mk
- DDS 모듈(엔진)을 빌드 타깃에 올리는 make 파일
- dds_module.rc
- init에서 DDS 네이티브 모듈을 띄우는 서비스 정의
- /vendor/etc/init/dds_module.rc 로 가서
service dds_module /vendor/bin/dds_module 같은 데몬 정의 예상
👉 즉:
system/ccs/dds = “DDS 전용 네이티브 엔진 + Fast-DDS 라이브러리 + HAL”
j1939와 DDS의 차이점은 이름만 다르고, 역할 구조는 거의 똑같다고 보면 된다.
3. 세 레이어를 한 번에 보면 이렇게 됨
CAN 쪽 흐름:
- 커널:
- CONFIG_CAN=y, CONFIG_CAN_VCAN=y → vcan0 인터페이스 생김
- CCS 엔진 (vendor/ivi/system/ccs/j1939)
- J1939 HAL + 서비스 데몬 (j1939_service.cpp, j1939_service.rc)
- 안드로이드 서비스 (vendor/ivi/services/canservice)
- can_svc (Binder 서비스) + AIDL + Java CanManager
DDS 쪽 흐름:
- 커널:
- DDS는 커널 모듈이 아니라 유저 공간에서 Fast-DDS 라이브러리를 쓰는 구조
- CCS 엔진 (vendor/ivi/system/ccs/dds)
- Fast-DDS + DDSHal + DDSManager + dds_module.rc (네이티브 데몬)
- 안드로이드 서비스 (vendor/ivi/services/ddsservice)
- dds_svc (Binder 서비스) + AIDL + Java DdsManager
4. “구조파악”만 놓고 보면 핵심 요약
- services/*service
- AIDL + Java 라이브러리 + Binder 서비스 프로세스
- 앱이 직접 붙는 창구
- system/ccs/{j1939, dds}
- CCS 내부 엔진 (J1939/DDS 프로토콜 처리)
- HIDL HAL + 네이티브 데몬 + Fast-DDS 같은 라이브러리
- *_service.mk, *_module.mk, *.rc
- *.mk → “이걸 빌드/PRODUCT에 넣어라”
- *.rc → “부팅할 때 이 이름으로 데몬/서비스를 시작해라”
여기까지가 “디렉토리/파일이 어떤 층에 있는지” 구조 설명이고,
지금 보드에서 DDS가 안 보이는 이유는 이 구조 중에서:
- DDS쪽 mk / bp / PRODUCT_PACKAGES / rc 가
CAN / J1939처럼 상위 product에 아직 제대로 연결이 안 돼 있다
(그래서 소스는 다 있는데, 빌드/이미지/부팅 경로에 안 올라오는 것)
이라는 걸 뒤에 이어서 맞추는 단계야.
일단 이 그림이 조금이라도 잡혔는지만 말해주면,
그 다음엔 “CAN이랑 1:1로 맞춰서 DDS도 어디에 뭐를 추가해야 하는지”를 딱 짚어서 diff 형식으로 정리해줄게.
오케이. joo가 헷갈리던 이유 = 3개의 레이어(계층)가 서로 겹쳐 보이기 때문이야.
이걸 완전 단순한 그림으로 다시 그려줄게.
Android 시스템은 항상 아래처럼 구성되어 있어:
🎯 전체 구조를 그림으로 보면 이렇게야
[1] 앱(App) 레벨
┌────────────────────────────┐
│ Android App (Java/Kotlin)│
│ ex) Cluster UI, Diagnostics│
└────────────────────────────┘
│
▼ (AIDL / Binder IPC)
[2] Android Service 레벨 (vendor/ivi/services/*)**
┌────────────────────────────────────────┐
│ vendor/ivi/services/canservice │
│ vendor/ivi/services/ddsservice │
│ │
│ - AIDL (ICanService.aidl, IDds.aidl) │
│ - 서비스 프로세스 (can_svc, dds_svc) │
│ - Java Manager (CanManager, DdsManager)│
└────────────────────────────────────────┘
│
▼ (HAL IPC: HIDL/AIDL)
➡ App ↔ HAL 사이의 브릿지 역할
➡ 앱이 서비스에 붙어서 “can 보내줘”, “dds publish 해줘” 같은 명령을 호출함.
[3] CCS Native Engine 레벨 (vendor/ivi/system/ccs/*)**
┌───────────────────────────────────────────────┐
│ vendor/ivi/system/ccs/j1939 │
│ vendor/ivi/system/ccs/dds │
│ │
│ - HAL 구현체 (DDSHal.cpp, J1939Hal.cpp) │
│ - Native Engine (DDSManager, J1939Manager) │
│ - Fast-DDS 라이브러리 │
│ - 데몬 실행 (dds_module, j1939_service) │
│ - *.rc: init 시 자동 실행되는 네이티브 데몬 │
└───────────────────────────────────────────────┘
│
▼ (Kernel API / Socket CAN / Fast-DDS Transport)
➡ 실제 로직이 돌아가는 엔진(진짜 뇌)
➡ DDS는 여기서 Fast-DDS를 사용해 subscribe/publish 처리함
➡ J1939도 여기서 CAN 프레임 파싱/조립/브로드캐스트 처리
[4] 커널 레벨(Linux Kernel)
┌────────────────────────────────────┐
│ Linux Kernel │
│ │
│ - CAN 드라이버(vcan, mcan 등) │
│ - 네트워크 소켓 API │
│ - 시스템 콜 (select, epoll...) │
└────────────────────────────────────┘
➡ DDS는 커널 모듈이 아님
➡ CAN은 커널 드라이버(vcan0 등)가 필요함
✨ 최종 전체 구조를 한눈에 보면…
┌─────────────────────────────────────────────────────────┐
│ Android App │
│ (Java/Kotlin → DdsManager) │
└─────────────────────────────────────────────────────────┘
│ AIDL
▼
┌─────────────────────────────────────────────────────────┐
│ vendor/ivi/services/ddsservice │
│ dds_svc (Binder Service, AIDL 인터페이스) │
└─────────────────────────────────────────────────────────┘
│ HIDL/AIDL
▼
┌─────────────────────────────────────────────────────────┐
│ vendor/ivi/system/ccs/dds (Native Engine) │
│ DDSHal.cpp / DDSManager / Fast-DDS Library │
│ dds_module.rc → dds_module 데몬 실행 │
└─────────────────────────────────────────────────────────┐
│
▼
┌─────────────────────────────────────────────────────────┐
│ Linux Kernel (Socket, Netlink) │
└─────────────────────────────────────────────────────────┘
CAN은 거의 동일한 구조인데, 엔진이 DDS 대신 J1939 엔진일 뿐이야.
📌 다시 정리해주면:
계층 역할 예시 폴더
| App | UI/비즈니스 로직 | (앱 apk) |
| Android Service(services) | 앱이 붙는 Binder 서비스 | vendor/ivi/services/ddsservice |
| CCS Native Engine(system/ccs) | DDS/J1939 실제 처리 로직 | vendor/ivi/system/ccs/dds |
| Kernel | CAN 드라이버, 소켓 제공 | CONFIG_CAN=y |
📷 이해를 돕는 직관적인 버전 (진짜 쉽게)
앱 입장에서 보면:
앱 → ddsservice → DDSEngine → Fast-DDS 네트워크
앱 → canservice → J1939Engine → CAN 드라이버(vcan0)
만약 이것도 헷갈린다면?
joo가 지금까지 본 tree는 그냥 위 그림의 디렉토리 버전일 뿐이야.
내가 원하면
- 더 단순한 버전
- 실제 실행 파일이 어디 떨어지는지
- CAN과 DDS가 서로 어떻게 데이터가 움직이는지 "시퀀스 다이어그램"
까지도 그림으로 만들어줄게.
원하는 방향이 뭐야?
- 전체 구조를 더 단순하게 다시 그려줄까?
- 아니면 DDS가 왜 지금 보드에 “전혀 안 올라왔는지” 분석부터 할까?
'잡동사니 > GPT가 알려주는' 카테고리의 다른 글
| [GPT가 알려주는] JVM 언어란? (0) | 2025.12.05 |
|---|---|
| [GPT가 알려주는] JniLib란? (0) | 2025.12.05 |
| [GPT가 알려주는] X86 vs Arm64 (0) | 2025.12.04 |
| [GPT가 알려주는] AIDL과 HIDL (0) | 2025.12.04 |
| [GPT가 알려주는] AOSP랑 Soong (0) | 2025.11.27 |