이전 글에서 F190 DID를 DCM에 등록하고 Generate까지 수행했다면, 이제 구조는 준비된 상태다.
(이전 글 참고: https://jjongday.tistory.com/155)
하지만 이 단계에서 CANoe로 0x22 F190 요청을 보내도 대부분 다음과 같은 상황을 만나게 된다.
요청은 정상적으로 들어오나 응답이 없거나, 빈 값이 나온다.
이유는 단순하다.
DCM은 데이터를 직접 만들지 않기 때문이다
AUTOSAR 구조에서 DCM의 역할은 “요청을 해석하는 것”까지다.
실제 데이터는 반드시 SWC에서 생성되어야 한다.
이번 글에서는 F190 요청이 들어왔을 때 DCM이 어떤 흐름으로 SWC를 호출하는지,
그리고 그에 맞게 SWC에서 무엇을 구현해야 하는지를 연결해서 설명한다.
1. Generate 이후 상태를 먼저 이해해야 한다
Generate를 수행하면 RTE 레벨에서 두 개의 함수가 생성된다.
FUNC(Std_ReturnType, RTE_CODE) Rte_Call_Dcm_DataServices_Data_F190_Vehicle_Identification_Number_ConditionCheckRead(VAR(Dcm_OpStatusType, AUTOMATIC) OpStatus, P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, RTE_APPL_DATA) ErrorCode)
{
Rte_CallHook_Dcm_DataServices_Data_F190_Vehicle_Identification_Number_ConditionCheckRead_Start(OpStatus, ErrorCode);
RTE_UNUSED(OpStatus);
RTE_UNUSED(ErrorCode);
Rte_CallHook_Dcm_DataServices_Data_F190_Vehicle_Identification_Number_ConditionCheckRead_Return(OpStatus, ErrorCode);
/* Return RTE_E_UNCONNECTED */
return RTE_E_UNCONNECTED;
}
FUNC(Std_ReturnType, RTE_CODE) Rte_Call_Dcm_DataServices_Data_F190_Vehicle_Identification_Number_ReadData(VAR(Dcm_OpStatusType, AUTOMATIC) OpStatus, P2VAR(uint8, AUTOMATIC, RTE_APPL_DATA) Data)
{
Rte_CallHook_Dcm_DataServices_Data_F190_Vehicle_Identification_Number_ReadData_Start(OpStatus, Data);
RTE_UNUSED(OpStatus);
RTE_UNUSED(Data);
Rte_CallHook_Dcm_DataServices_Data_F190_Vehicle_Identification_Number_ReadData_Return(OpStatus, Data);
/* Return RTE_E_UNCONNECTED */
return RTE_E_UNCONNECTED;
}
이 함수들은 단순히 “자동 생성된 코드”가 아니다.
실제로 DCM이 요청을 처리할 때 호출하는 진입 지점(entry point)이다.
하지만 이 시점의 함수 내부를 보면 다음과 같은 형태다.
return RTE_E_UNCONNECTED;
이 의미는 명확하다.
아직 SWC와 연결된 실제 구현이 존재하지 않는다.
즉, DCM은 호출할 준비는 되어 있지만 실제로 값을 가져올 대상이 없는 상태다.
그래서 이 단계에서는 요청이 들어와도 응답이 만들어지지 않는다.
2. 왜 함수가 두 개인가 (구조를 이해해야 한다)
처음 보면 가장 헷갈리는 부분이 이거다.
“왜 Read 함수 하나면 되는데 두 개가 있지?”
이건 USE_DATA_ASYNCH_CLIENT_SERVER 구조의 특징이다.
DCM은 데이터를 바로 읽지 않는다.
먼저 “이 요청이 가능한지”를 확인하고, 그 다음에 데이터를 읽는다.
흐름은 이렇게 나뉜다.
ConditionCheckRead → ReadData
ConditionCheckRead의 역할
이 함수는 데이터를 읽기 전에 호출된다.
여기서 하는 일은 단순하다.
- 지금 이 DID를 읽어도 되는 상태인가?
- 세션이 맞는가?
- 특정 조건이 충족되었는가?
즉, "읽어도 되는지 판단하는 단계"다.
이 단계에서 E_NOT_OK를 반환하면 DCM은 ReadData를 아예 호출하지 않는다.
3. SWC 구현 (Port / Runnable / RTE 연결)
이전 단계에서 RTE 함수는 생성되었지만, 실제로는 아직 동작하지 않는다.
DCM이 호출할 대상(SWC)이 아직 연결되지 않았기 때문이다
AUTOSAR에서 함수 호출은 직접 연결되는 것이 아니라, Port와 Interface를 통해 연결된다.
즉, 아래 구조가 완성되어야 한다.
DCM → RTE → Port → SWC Runnable → 실제 코드
3.1 Client-Server Interface 확인
USE_DATA_ASYNCH_CLIENT_SERVER를 사용한 경우,
F190 DID에 대해 다음 두 개의 Operation이 생성된다.
- ConditionCheckRead
- ReadData
이 두 Operation은 하나의 Client-Server Interface로 묶여 있다.
이 Interface를 SWC에서 받아야 한다.
6.2 SWC에 Port 추가
SWC(APP)에서 Ports 탭으로 이동하여 Provide Port(P-Port)를 하나 생성한다.
이때 Interface는 DCM 설정 과정에서 생성된 DataServices Client-Server Interface를 선택한다.
AUTOSAR 구조에서 DCM은 Client 역할을 하고, SWC는 데이터를 제공하는 Server 역할을 수행하기 때문에,
SWC에서는 반드시 Provide Port(Server)로 설정해야 한다.
이 설정을 통해 DCM에서 호출한 Operation이 SWC로 전달될 수 있는 연결 구조가 만들어진다.
그 이후 ConditionCheckRead와 ReadData Operation에 대해
Enable Provided ComSpec을 활성화하고 Queue Length를 1로 설정한다.
이는 Client-Server 호출 시 요청을 정상적으로 처리하기 위한 설정으로,
환경에 따라 기본값으로 동작할 수도 있지만 명시적으로 설정하는 것이 안정적이다.

3.3 Runnable 생성
SWC(APP)에서 Runnable 탭으로 이동하여 ConditionCheckRead Runnable과 ReadData Runnable을 생성한다.
ConditionCheckRead Runnable
- Short Name: DID_F190_Vehicle_Identification_Number_ConditionCheck
- Symbol: DID_F190_Vehicle_Identification_Number_ConditionCheck (실제 함수 이름)
- Can Be Invoked Concurrently: true 설정 (필수 아님)
- RTE Event: Operation Invoked Event에 ConditionCheckRead 추가

ReadData Runnable
- Short Name: DID_F190_Vehicle_Identification_Number_ReadData
- Symbol: DID_F190_Vehicle_Identification_Number_ReadData (실제 함수 이름)
- Can Be Invoked Concurrently: true 설정 (필수 아님)
- RTE Event: Operation Invoked Event에 ReadData 추가

Symbol은 실제 SWC 코드에서 구현해야 하는 함수 이름으로 사용된다.
각 Runnable은 앞에서 생성한 Port의 Operation과 연결해야 하며,
이를 위해 RTE Event에서 Operation Invoked Event를 선택하여 해당 Operation을 매핑한다.
4. EcuComposition에서 연결 (mapping)
SWC에서 Port와 Runnable까지 생성했다면, 이제 DCM과 SWC를 실제로 연결해야 한다.
AUTOSAR에서는 모듈 간 연결이 자동으로 되는 것이 아니라,
EcuComposition에서 명시적으로 연결(mapping)해야 한다.

5. 하모나이즈 수행 후 Generate
모든 설정이 완료되면 먼저 Harmonize를 수행하여 설정 간 연결 상태를 정리한다.
Port 연결, Interface 참조, Runnable 매핑과 같은 설정들이 정합성 있게 구성된다.
이후 Generate를 수행한다.
Generate를 수행하면 다음이 생성된다.
- RTE 코드
- DCM 설정 코드
- Port / Runnable 연결 코드
6. SWC 코드 구현
이제 실제 코드가 연결된다.
이제 RTE에서 연결된 함수에 실제 로직을 작성한다.
ConditionCheckRead와 ReadData를 구현해야 하며, 특히 ReadData에서 VIN 데이터를 채워야 한다.
이 단계가 빠지면 요청은 들어오지만 응답은 나오지 않는다
ConditionCheckRead
FUNC(Std_ReturnType, SWC_Diag_Dcm_CODE)DID_F190_Vehicle_Identification_Number_ConditionCheck
(
VAR(Dcm_OpStatusType, AUTOMATIC) OpStatus,
P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, RTE_APPL_DATA) ErrorCode
)
{
(void)OpStatus;
(void)ErrorCode;
/* 항상 읽기 허용 */
return E_OK;
}
ReadData
#define VIN_LENGTH 17U
typedef struct
{
uint8 VIN[VIN_LENGTH];
} DidF190Type;
extern DidF190Type gDidData_F190;
FUNC(Std_ReturnType, SWC_Diag_Dcm_CODE)DID_F190_Vehicle_Identification_Number_ReadData
(
VAR(Dcm_OpStatusType, AUTOMATIC) OpStatus,
P2VAR(uint8, AUTOMATIC, RTE_APPL_DATA) Data
)
{
(void)OpStatus;
if (Data == NULL_PTR)
{
return E_NOT_OK;
}
(void)memcpy(Data, gDidData_F190.VIN, VIN_LENGTH);
return E_OK;
}
7. Build
이제 SWC 구현까지 완료되었다면, 전체 프로젝트를 Build하여 실제 실행 가능한 바이너리를 생성한다.
이 단계는 단순히 컴파일을 통과하는 과정이 아니라,
지금까지 구성한 DCM ↔ RTE ↔ SWC 연결이 정상적으로 동작 가능한 상태인지 확인하는 중요한 단계다.
'mobilgene > DCM' 카테고리의 다른 글
| [DCM] Security Access 설정 방법 (DcmDspSecurityRow 실무 설정) (0) | 2026.05.28 |
|---|---|
| [DCM] F190 VIN 응답 확인 (CANoe로 0x22 F190 테스트 및 디버깅 방법) (0) | 2026.05.06 |
| [DCM] DID 0xF190 설정부터 응답까지 (mobilgene 실무 전체 과정) (0) | 2026.05.06 |
| [DCM] DcmDsp > Did / Did Info / Data / Data Info 설정 방법 (실무) (5) | 2026.04.19 |
| [DCM] DCM 전체 구조 이해하기 (DSL, DSD, DSP 설명 포함) (0) | 2026.04.19 |