개념
모듈 25 레슨 4가 멈춘 자리
모듈 25 레슨 4는 ISO 26262 Part 6의 구조 커버리지 권고를 경향 으로만 보여주고, 실제 칸 값은 원문으로 확인하라고 적었다. 모듈 3 레슨 7에서는 구문·분기·MC/DC를 코드로 직접 계산했다. 이 레슨은 두 레슨 사이의 빈칸 — "그래서 ASIL C 프로젝트의 단위 검증 보고서에는 무엇이 들어가야 하는가" — 를 채운다.
레슨 1에서 61508-3의 표를 읽었다면 Part 6은 훨씬 쉽다. 표기만 다르고 구조가 같다.
| 61508-3 | ISO 26262 | 뜻 |
|---|---|---|
| HR | ++ | 강력 권고 |
| R | + | 권고 |
| --- | o | 권고도 반대도 없음 |
| SIL 1~4 | ASIL A~D | 등급 |
Part 6에서 검증을 다루는 절
ISO 26262-6:2018에서 시험과 직접 닿는 절은 넷이다.
8 소프트웨어 단위 설계와 구현 코딩 가이드라인·설계 원칙
9 소프트웨어 단위 검증 ← 단위 검증 방법, 케이스 도출, 단위 구조 커버리지
10 소프트웨어 통합과 검증 ← 통합 검증 방법, 아키텍처 구조 커버리지
11 임베디드 소프트웨어 시험 목표 하드웨어에서의 소프트웨어 시험9절과 10절은 같은 틀을 반복한다. 방법 표(무엇으로 검증하는가), 케이스 도출 표 (케이스를 어떻게 뽑는가), 구조 커버리지 표(얼마나 덮었는가 — 완전성 확인). 이 세 표가 한 세트다.
단위 검증 방법 — 정적 검증과 시험이 한 표에
2018판의 단위 검증 방법 표는 정적 검증과 동적 시험을 한 표에 모았다. 항목을 묶어 보면 이렇다.
| 묶음 | 방법 |
|---|---|
| 리뷰 | 워크스루, 짝 프로그래밍, 인스펙션 |
| 분석 | 준정형·정형 검증, 제어 흐름 분석, 데이터 흐름 분석, 정적 코드 분석, 추상 해석 기반 정적 분석 |
| 시험 | 요구사항 기반 시험, 인터페이스 시험, 고장 주입 시험, 자원 사용량 평가, 모델과 코드 간 백투백 비교 시험 |
해설 자료들이 공통으로 강조하는 칸은 이렇다. 요구사항 기반 시험과 인터페이스 시험은 모든 ASIL에서 강력 권고 이고, 고장 주입 시험은 ASIL이 오를수록 권고 강도가 올라가 높은 ASIL에서 강력 권고가 된다. 나머지 칸의 정확한 값은 규격 원문 표로 확정한다.
여기서 "모든 ASIL에서 요구사항 기반 시험이 강력 권고" 라는 사실이 이 레슨 전체의 전제가 된다. 뒤에서 볼 구조 커버리지는 요구사항 기반 시험을 대신하는 것이 아니라 검산하는 것 이기 때문이다.
케이스 도출 방법 — 모듈 3의 기법이 규격 항목이 된다
케이스 도출 표에는 요구사항 분석, 동등 분할의 생성·분석, 경계값 분석, 지식·경험 기반 오류 추정 이 올라와 있다. 요구사항 분석은 모든 등급에서 강력 권고이고, 동등 분할과 경계값 분석은 대체로 ASIL B 이상에서 강력 권고로 올라가는 구조로 해설된다.
이 표가 증거에 주는 요구는 명확하다. 케이스마다 어느 기법으로 도출했는지 가 기록되어 있어야 한다.
| 케이스 ID | 요구사항 ID | 도출 기법 | 입력 | 기대 결과 | 비고 |
|---|---|---|---|---|---|
| UT-BRK-014 | SWR-BRK-032 | 경계값 분석 | 휠 속도 = 3.99 km/h | ABS 비활성 | 활성 임계 4.0 직전 |
| UT-BRK-015 | SWR-BRK-032 | 경계값 분석 | 휠 속도 = 4.00 km/h | ABS 활성 | 임계값 |
| UT-BRK-021 | SWR-BRK-040 | 오류 추정 | 센서 값 NaN | 안전 상태 요청 | 과거 결함 DR-221 |"도출 기법" 칸이 비어 있는 케이스 목록은 규격 관점에서 왜 이 케이스가 충분한지 설명하지 못하는 목록 이다. 모듈 3에서 기법을 배운 이유가 여기서 증거 칸 하나로 돌아온다.
구조 커버리지 — 단위와 아키텍처, 두 층
단위 수준(표 9).
| 방법 | ASIL A | ASIL B | ASIL C | ASIL D |
|---|---|---|---|---|
| 1a 구문 커버리지 | ++ | ++ | + | + |
| 1b 분기 커버리지 | + | ++ | ++ | ++ |
| 1c MC/DC | + | + | + | ++ |
모듈 25에서 본 대로, ASIL C·D에서 구문 커버리지가 + 로 내려가는 것은 요구가 약해진 것이
아니라 분기 커버리지가 구문을 사실상 포함하기 때문 이다. 레슨 1의 61508-3 B.2와 비교하면
차이도 보인다. 61508-3은 SIL 4에서만 MC/DC가 HR이었고, 26262도 ASIL D에서만 ++ 다. 두
계보가 "조건 하나하나의 독립적 영향을 증명하라"는 요구를 최상위 등급에 둔다 는 점에서
일치한다.
아키텍처 수준(표 12). 통합 검증에서는 코드 줄이 아니라 구성 요소 사이의 연결 을 본다.
| 방법 | ASIL A | ASIL B | ASIL C | ASIL D |
|---|---|---|---|---|
| 1a 함수 커버리지 | + | + | ++ | ++ |
| 1b 호출 커버리지 | + | + | ++ | ++ |
두 기준은 이름이 비슷해 자주 헷갈린다.
함수 커버리지 각 함수가 적어도 한 번 호출되었는가
호출 커버리지 각 호출 지점(call site)이 적어도 한 번 실행되었는가
void control() {
if (mode == NORMAL) update(sensor); ← 호출 지점 ①
else update(fallback); ← 호출 지점 ②
}update() 가 ①에서 한 번만 호출돼도 함수 커버리지는 100%다. 그러나 ②는 실행되지 않았다.
대체 입력(fallback)으로 update를 부르는 경로 가 통합 시험에서 한 번도 확인되지 않은
상태다. 기능안전에서 fallback 경로는 정확히 사고가 나는 자리이므로, ASIL C·D에서 호출
커버리지를 강력 권고하는 이유가 여기서 보인다.
커버리지는 "측정"이 아니라 "완전성 확인"이다
26262의 구조 커버리지 요구에는 목적이 붙어 있다. 검증의 완전성을 평가하고 단위 시험의 목표가 달성되었다는 증거를 제공하기 위해 요구사항 커버리지를 확인하고 구조 커버리지를 측정한다. 그리고 달성한 구조 커버리지가 불충분하다고 판단되면, 추가 케이스를 명세하거나 다른 방법에 근거한 논거를 제시 해야 한다.
이 문장의 순서가 증거의 순서다.
1. 요구사항 기반으로 케이스를 도출한다 (케이스 도출 표)
2. 실행한다 (방법 표)
3. 요구사항 커버리지를 확인한다 모든 요구사항에 케이스가 있는가
4. 구조 커버리지를 측정한다 위 케이스들이 코드를 얼마나 밟았는가
5. 불충분하면 → 요구사항 누락인가 (1로 돌아감)
→ 방어·죽은 코드인가 (레슨 1 의 네 부류 분류)
→ 근거로 닫는다4에서 5로 넘어갈 때 커버리지 숫자를 맞추려고 요구사항에 없는 케이스를 끼워 넣으면 안 된다. 그렇게 채운 100%는 "요구사항 기반 시험이 완전하다"는 주장을 오히려 무너뜨린다. 모듈 3 레슨 7에서 "커버리지 80%라는 숫자를 믿으면 안 되는 이유"를 봤는데, 규격 환경에서는 숫자가 아니라 미도달의 이유가 증거 다.
시험 환경 — 호스트에서 돌린 결과는 어디까지 믿을 수 있는가
단위 시험은 대개 개발 PC(호스트)에서 돌린다. 그런데 제품은 목표 마이크로컨트롤러(타깃)에서 돈다. 26262는 시험 환경이 목표 환경과 가능한 한 가깝기 를 요구하고, 차이가 있다면 그 차이가 결과에 주는 영향을 분석하도록 한다.
| 환경 | 무엇이 같은가 | 무엇이 다를 수 있는가 |
|---|---|---|
| 호스트 네이티브 | 소스 코드 논리 | 컴파일러, 정수 크기·엔디언, 부동소수점, 최적화 |
| 모델 기반(MIL) | 알고리즘 설계 | 코드 자체가 없음 |
| 소프트웨어 인 더 루프(SIL) | 생성·작성 코드 | 타깃 컴파일러와 CPU |
| 프로세서 인 더 루프(PIL) | 타깃 컴파일러와 CPU | 주변 하드웨어, 실시간 부하 |
| 하드웨어 인 더 루프(HIL) | 실제 ECU | 차량 전체의 물리 |
실무에서 가장 흔한 함정은 정수 크기 다. 호스트에서 int 가 32비트인데 타깃에서 16비트라면,
경계값 시험의 기대 결과 자체가 달라진다. 호스트 결과를 증거로 쓰려면 타깃과 호스트의
자료형 차이 분석 이 증거 묶음에 들어가야 한다.
두 번째 함정은 계측(instrumentation) 이다. 커버리지 도구는 코드에 측정용 코드를 끼워 넣는다. 그러면 실행 시간과 메모리가 달라지고, 타이밍에 민감한 코드는 계측 빌드에서만 다르게 동작할 수 있다. 그래서 흔히 계측 빌드로 커버리지를 재고, 비계측 빌드로 같은 케이스를 다시 돌려 결과가 같은지 확인한다. 이 두 번의 실행 기록이 "커버리지를 잰 코드와 출하 코드가 같게 동작한다"는 논거가 된다.
MC/DC 증거의 모양 — 독립 쌍 표
ASIL D에서 MC/DC를 주장하려면 커버리지 도구의 퍼센트 한 줄로는 부족하다. 판정마다 각 조건이 결과를 독립적으로 바꾼다는 것 을 보여주는 표가 증거의 표준 형태다.
판정 D-17: if (speed_valid && (brake_req || aeb_req))
케이스 speed_valid brake_req aeb_req 결과
T1 1 1 0 1
T2 0 1 0 0 ← T1 과 비교: speed_valid 만 바뀜 → 결과 바뀜
T3 1 0 0 0 ← T1 과 비교: brake_req 만 바뀜 → 결과 바뀜
T4 1 0 1 1 ← T3 과 비교: aeb_req 만 바뀜 → 결과 바뀜
독립 쌍 speed_valid: (T1,T2) brake_req: (T1,T3) aeb_req: (T3,T4)
조건 3개 → 케이스 4개 (조건 수 + 1)모듈 3 레슨 7에서 이 계산을 연습했다. 규격 증거로서 추가되는 것은 두 가지다. 판정 ID가 코드 위치와 연결 되어 있어야 하고, 각 케이스가 요구사항에서 도출된 케이스와 같은 것 이어야 한다. MC/DC를 맞추려고 따로 만든 케이스가 요구사항 추적을 갖지 못하면, 앞 절의 "숫자를 맞추려고 끼워 넣은 케이스" 문제가 그대로 생긴다.
단축 평가(short-circuit)가 있는 언어에서는 뒤 조건이 평가되지 않는 케이스 가 독립 쌍으로 인정되는지 도구마다 처리가 다르다. 어떤 방식의 MC/DC를 측정했는지 도구 설정과 함께 적는다.
단위 검증 증거 묶음
ASIL C 모듈 하나의 단위 검증에 대해 시험소나 평가자가 기대하는 묶음은 대체로 이렇다.
| 산출물 | 담기는 것 |
|---|---|
| 단위 검증 명세 | 방법 표에서 채택한 방법과 미채택 근거, 케이스 목록(도출 기법 포함) |
| 요구사항 ↔ 케이스 추적표 | 요구사항 커버리지 100% 확인 |
| 실행 기록 | 빌드 식별(해시), 환경(호스트/SIL/PIL), 도구 버전, 케이스별 결과 |
| 구조 커버리지 리포트 | 분기 커버리지(ASIL C ++), 판정별 상세 |
| 미도달 분석표 | 레슨 1의 네 부류 분류와 근거 |
| 환경 차이 분석 | 호스트·타깃 자료형·컴파일러 차이, 계측/비계측 결과 대조 |
| 정적 분석 결과 | 코딩 가이드라인(레슨 4·5의 MISRA) 준수 요약 |
마지막 줄이 다음 레슨들로 이어진다. 26262의 8절은 코딩 가이드라인을 요구하고, 실무에서 그 가이드라인은 대부분 MISRA C다.
실무에서 왜 필요한가
자동차 전장 프로젝트에서 단위 검증은 일정의 가장 큰 덩어리이고, 동시에 재작업이 가장 많이 나는 곳 이다. 재작업의 원인은 대부분 시험 실패가 아니라 증거 형식이다. 도출 기법이 기록되지 않은 케이스, 호스트에서만 돌리고 자료형 차이 분석이 없는 결과, 미도달 근거가 없는 97% 커버리지 리포트 — 모두 심사에서 되돌아온다.
이 레슨의 표를 프로젝트 초기에 단위 검증 계획서 템플릿 으로 고정해 두면 재작업이 크게 준다. 특히 "커버리지를 요구사항 기반 시험의 완전성 확인으로 쓴다"는 원칙을 개발팀과 먼저 합의해야 한다. 이 합의가 없으면 개발자는 커버리지 숫자를 올리기 위한 테스트를 쓰고, QA는 그 테스트의 추적성을 나중에 복원하느라 시간을 쓴다.
통합 단계에서는 호출 커버리지가 실제 결함을 찾는다. 대체 입력·열화 모드로 들어가는 호출 지점은 정상 시나리오 시험에서 거의 밟히지 않고, 그 경로의 결함은 현장에서 가장 비싸다.