요구사항 분석 → CANdb·CANoe·Panel 환경 구성 → 수동 검증 → CAPL 자동 검증 → 정적·동적 검증 → 결함 분석 및 재확인
CODE
교육 당시 CAPL 원본 발췌와 한계
최신 수신 프레임을 확인한 뒤에 측정 타이머를 시작하도록 동기화 유틸리티를 분리했습니다. 아래는 보관된 Battery_Percent_Low.can 발췌입니다. 무한 대기 가능성, timeout 무기록 종료, 9ms 보정과 주석 불일치를 포함한 교육 당시 코드입니다.
기준 프레임 동기화 — 기대한 신호 값이 실제로 수신된 것을 확인한 뒤에만 1ms 주기 타이머를 기동합니다.
void waitBattReference(int timeoutMs , int data)
{
if (TestWaitForMessage(BATT_01_10ms, timeoutMs) == 1)
{
TestGetWaitEventMsgData(battRef_msg);
if (battRef_msg.Batt_Percent == data){
testWaitForTimeout(9);
setTimerCyclic(t_1ms ,1);
}
else{
while(1){
if (TestWaitForMessage(BATT_01_10ms, timeoutMs) == 1){
TestGetWaitEventMsgData(battRef_msg);
if (battRef_msg.Batt_Percent == data){
testWaitForTimeout(9);
setTimerCyclic(t_1ms ,1);
break;
}
}
}
}
}
}
전수 조합 판정 — Batt_Percent 0~100 × Ignition 0/1 × Engine 0/1을 모두 돌면서, 검출을 기대하는 조합과 기대하지 않는 조합을 각각 다른 기준으로 판정합니다.
/* 14,15 + IGN=1 + ENG=1 일 때만 fault level 2 기대 */
expectFault = (i == 1 && j == 1 && battPercent <= 15);
waitBattReference(20, battPercent);
while(time_cnt_ms <= 5100)
{
@sysvar::UDS::Send_msg = 1;
if(TestWaitForMessage(Fault_sts_Rsp, 20) == 1)
{
TestGetWaitEventMsgData(faultRsp_msg);
if(expectFault)
{
if(faultRsp_msg.BATT_Percent_Err_sts == 2)
{
if(time_cnt_ms >= 4900 && time_cnt_ms <= 5100)
{
faultDetectedInWindow = 1;
break;
}
else
{
timingError = 1;
TestStepFail("1.4",
"Fault detected out of time window when IGN=%d, ENG=%d, Batt_Percent=%d, time=%dms",
i, j, battPercent, time_cnt_ms);
break;
}
}
}
else
{
/* fault를 기대하지 않는 모든 경우는 0 유지가 정상 */
if(faultRsp_msg.BATT_Percent_Err_sts != 0)
{
unexpectedStateDetected = 1;
TestStepFail("1.5",
"Unexpected state detected when IGN=%d, ENG=%d, Batt_Percent=%d, Err_sts=%d, time=%dms",
i, j, battPercent, faultRsp_msg.BATT_Percent_Err_sts, time_cnt_ms);
break;
}
}
}
}
대기 실패와 측정 기준을 분리하는 개선 설계
원본 저장소에 기록한 후속 설계입니다. 아래는 의사코드이며 CAPL 컴파일·CANoe 실행 검증 전입니다.
deadline = monotonicNow + totalTimeout
while monotonicNow < deadline:
frame = waitMessage(deadline - monotonicNow)
if frame is timeout: return TIMEOUT
if frame.value == expected: return OK(frame.timestamp)
return TIMEOUT
reference = waitReference(expected, totalTimeout)
if reference is TIMEOUT:
record TEST_ERROR("기준 프레임 미수신")
stop current case
if no valid status response before deadline:
record TEST_ERROR("상태 응답 미수신")
stop current case
elapsed = firstFaultResponse.timestamp - reference.timestamp
전체 대기시간을 제한하고 성공·실패를 반환합니다. 무응답을 정상 미검출로 판정하지 않습니다. 원본의 “14,15일 때만” 주석은 Batt_Percent ≤ 15 조건과 다르므로 수정 대상입니다.
시간 측정의 범위
Steering 소스에도 9ms 대기(주석: IVS controller 보정값)와 최대 20ms 응답 대기가 있습니다. 보정의 교정 근거와 전체 측정 불확도는 확보하지 못했습니다. 1ms 카운터 분해능과 986~993ms의 관측 산포는 측정 정확도 보증이 아닙니다.
후속 검증에서는 자극 프레임과 첫 상태 2 응답의 시각 차이를 기록하고, 요청·응답 관측 지연을 별도로 평가해야 합니다. 50±10ms 경계의 합격 판정은 이 검증 이후에 가능합니다.
Detection·Recovery·Clear 시나리오 자동화
CAN Signal·System Variable 기반 기대값 판정
경계값과 선행 조건 조합 입력
판정은 TestStepPass·TestStepFail로 기록해 조건과 실제 값을 함께 남김
TEST
4건정적 검토 항목
11건동적 결함
CAPL입력 조합 반복 시험
대표 테스트와 실제 판정
테스트
요구 기준
실제 결과
판정
Batt Percent 경계값
15% 조건 반영
15%에서 Fault 미검출
FAIL
IGN Cycle
50 Cycle 경계
Off-by-One 동작 확인
FAIL
Steering Timing
50±10ms
986~993ms
FAIL
대표 검출 결과
7개 고장 시나리오 중 보관 소스는 CAPL 6종·testcase 선언 24개입니다. Batt Percent 시나리오는 101 × Ignition 2 × Engine 2 = 404조합을 대상으로 했습니다. 작은 정수 입력 공간에서 경계값과 선행조건 누락을 함께 확인한 범위이며 전체 시스템 전수 시험은 아닙니다.
정적 검토 4건: Signal Length·Description 불일치와 값 표기 개선 2건. 127과 0x7F는 같은 값이며 값 자체의 오류는 아닙니다.
동적 결함 11건: 경계값, 선행 조건, Recovery, Timing 오류
Batt Percent 15% 경계값과 IGN 50 Cycle Off-by-One 확인
Steering Timing 요구사항 50±10ms 대비 스크립트 관측 986~993ms
Batt Voltage 회복: raw 14400~15000에서 회복 실패를 관측했습니다. 단위·스케일 해석 오류는 원인 가설이며 DBC와 raw 15 회복 증거의 추가 확인이 필요합니다.
결함별 실제 판정 화면
동적 결함 11건 가운데 10건은 CAPL 테스트 리포트의 판정 행을 그대로 남겼습니다. 각 행에는 입력 조건과 관측값이 함께 기록됩니다. Brake·Accel·Vehicle 독립 검출 결함 1건은 캡처가 없어 문서로만 정리했습니다.
BB-DEF-S01: Ignition의 Off/On/Error 세 상태를 1bit로 정의해 상태 수와 표현 범위가 충돌했습니다. 최소 2bit가 필요합니다. BB-DEF-S04: Brake_Err_sts 설명이 Accel을 지칭해 신호명과 설명이 불일치했습니다. 원본 요구사항 이미지는 교육 자료 보호를 위해 재게시하지 않습니다.
6개 스크립트 / 7개 모듈 / 24 testcase의 관계
보관된 스크립트별 testcase 선언은 Batt Percent 5개, Charging 6개, Voltage 7개, Ignition 1개, Engine 1개, Steering 4개로 합계 24개입니다. 화면에는 Brake_Error를 포함해 7개 모듈이 있지만 해당 모듈의 소스는 보관 자료에 없습니다. 24개는 함수 선언 수이며 입력 조합 수와 다릅니다.
DEMO
실제 CANoe 프로젝트 구성과 자동화 시험, Panel·Trace, 결함 결과 화면입니다.