SW 공학 및 테스팅 (8) - Embedded SW & Dependable SW

Charlie·2026년 4월 11일

SE&Testing

목록 보기
8/8

Embedded Software

대규모 데이터의 분류와 저장, 검색에 초점을 맞추는 일반적인 정보 시스템과 달리, 임베디드 시스템은 더 큰 시스템 내부에 논리적으로 통합된 부품으로서 연산 자체가 주 목적이 아닌 시스템을 말한다.

대규모이며 수명이 길고, 실시간 응답고장시 안전을 보장하는 신뢰성이 필수적이다. 또한 비동기적이고 병렬적인 특성을 가지며 분산된 환경에서도 동작하는 경향이 있다.

응답 속도에 따른 분류

응답 속도에 따라 일괄 처리(batch), 대화형(interactive on-line), 실시간 시스템(real-time)으로 분류할 수 있다.

이 때 batch 시스템은 결과가 언제 오는지는 상관하지 않는다. 실시간 시스템(real time)은 time-deadline이 존재하는 시스템을 말한다.

실시간 시스템의 임계성

데드라인의 엄격성으로 Hard와 Soft로 구분이 가능하고 실행 속도에 따라 Fast와 Slow로 구분할 수 있다.

임베디드 시스템 특징

임베디드 시스템을 설계할 때, 3가지의 특성을 중심으로 고려해야하는데 환경, 성능, 고장 모드 이렇게 3가지로 이뤄진다. 이 3가지 모두를 고려할 수 있어야 한다.

1. Environmental Aspects

임베디드는 일반적으로 PC와 달리 물리,전기적으로 가혹한 환경에 노출되는 경우가 많아 이를 견딜 수 있어야한다. 그래서 온도, 전기적 간섭이 강한 공간, 장기 유지보수의 설계까지 반영되어야한다.

2. Performance Aspect

임베디드 시스템의 설계자는 시스템이 환경과 상호작용하며 내야하는 성능을 예측해야한다. 정해진 주기에 따라 지속적으로 백그라운드에서 수행되어야하고, 외부의 무작위 이벤트를 즉각 반응해서 처리해야한다.

3. Failure and their effects

시스템의 하드웨어나 소프트웨어는 수명 주기 내에 어떤 이유로든 반드시 고장이 발생할 수밖에 없다는 것을 전제로 한다. 따라서 예외 처리 매커니즘을 필수적으로 포함해야한다.

Dependable Software

3가지 품질 속성

신뢰성있는 소프트웨어(Dependable SW)는 단순히 결함이 없는 상태를 넘어 3가지 핵심 품질 속성을 충족해야한다.

  • 정확성(Correctness)
    프로그램이 요구사항 명세서와 일치하는지 나타내는 정적(static)인 속성이다. 오류가 발생하면 부정확한 결과를 보내는 것보다 아무 결과를 내보내지 않고 시스템을 멈추는 것이 낫다는 것을 의미한다.

  • 신뢰성(Reliability)
    프로그램이 요구되는 정밀도에 맞춰 의도된 기능을 실제로 얼마나 잘 수행하는지 나타내는 동적(dynamic)인 속성이다. 런타임 중에 고장이 발생하는 빈도를 최소화해서 서비스가 중단 없이 유지되도록 하는 것이 중요하다는 것이다.

  • 안전성(Safety)
    시스템이 정상적이거나 비정상적인 상황에서 작동하더라도 인명 피해나 재산상의 손상을 초래하는 위험없이 작동할 수 있는 능력이다. 고장이 나더라도 그것이 치명적인 사고로 이어지지 않도록 방어하는 것이다.

고장 발생 시 시스템 동작 전략

완벽한 소프트웨어는 없으므로 고장이 발생하면 시스템이 어떻게 반응하고 대처할 것인지를 4가지 전략에 따라 동작한다.

  • Fail-operational (운영 유지): 고장이 발생한 상황에서도 전체 서비스를 온전히 유지하며 작동하는 방식이다.
  • Fail-soft (성능 저하 운영): 고장이 존재할 때 시스템의 성능이나 서비스 수준은 어느 정도 저하되더라도, 동작 자체는 계속해서 유지하는 방식이다.
  • Fail-hard (즉시 중단): 고장이 발생하면 전체 시스템을 즉시 완전히 멈추게(Halt) 하는 방식이다.
  • Fail-safe (안전 중심 중단): 정상적인 시스템 운영을 복구하려고 노력하는 대신, 고장으로 인해 발생할 수 있는 위험이나 피해를 제한하고 최소화하는 데 목적을 두는 방식이다.

Software Error

소프트웨어 오류의 3가지 범주

소프트웨어 오류란 오작동을 일으키는 프로그램의 요소들을 총괄한 내용인데, 크게 3가지 범주로 나눌 수 있다.

시스템 설계 오류
설계자가 시스템이 작동할 물리적 환경이나 동작 시간에 대해 잘못된 가정을 내렸을 때 발생하는 치명적 오류이다.

설계 및 코딩 오류
개념을 실제 컴퓨터 코드로 번역하는 과정에서 발생한다. 우리가 흔히 생각하는 개발 중에 일어나는 오류들이 거의 대부분 여기에 포함된다. 소프트웨어가 고객의 의도나 의미를 잘못 이해한 의미론적 오류, 우발적 무한루프, 데드락 등의 논리적 오류, 0으로 나누기나 오버플로우 등의 알고리즘적 오류 등으로 구성된다.

환경적 요인
소프트웨어가 정상적인 환경에서 작동할 때 발생하는 하드웨어의 오작동, 사람의 실수, 예상치 못한 외부 간섭 등 예측 불가능한 오류이다. 이는 설계 단계에서 완벽하게 제거할 수 없기에 심층 분석으로 문제 발생 가능성을 최소화 해야한다.

좋은 소프트웨어 설계를 위한 원칙

나쁜 소프트웨어가 만들어지는 원인은 경영진 또는 상관에게 문제가 있거나 설계가 부족한 상황, 전문성 결여, 문서화 부족, 프로토타이핑 부재 등의 여러 문제들을 꼽을 수 있다.

그럼 반면 좋은 소프트웨어 개발의 기본은 무엇일까 1) 우선 명확한 요구사항이 정의되어야 한다. 사용자가 무엇을 원하는지 잘 파악하는것이 중요하다는 것이다. 그리고 2)설계를 할 때 목표 달성이 가능한 수준이어야하고, 3)관리에 있어서 유연한 프로젝트 조직으로 구성이 되어야한다. 마지막으로 4)테스트가 쉽게 이뤄지도록 설계와 검증된 방법을 사용하는 것이 필요하다.

이식성과 재사용성 또한 좋은 소프트웨어 하면 빠질 수 없는데, 검증된 컴포넌트를 사용해서 작업을 하면 설계, 코딩, 디버깅 시간 및 비용이 감소하고 신뢰성을 높일 수 있다. 이식성과 재사용성을 고려하면 소프트웨어가 더욱 효율적으로 구성될 수 있다.

Defensive Programming

오류 회피와 방어적 프로그래밍

우리는 기본적으로 오류에 대해 회피를 해야한다. 오류를 회피한다는게 무슨말이냐, 오류 회피는 기본적으로 잘못된 값이 들어오거나 잘못된 접속이 발생했을 때 큰 문제가 발생하지 않으면 가능한 회피하는 방향으로 움직이는 것이다. 이러한 오류 회피를 실질적인 프로그래밍에 접목하면 "방어적 프로그래밍"이 된다.

방어적 프로그래밍은 예상치 못한 입력에도 소프트웨어가 계속 수행을 보장할 수 있도록 한 프로그래밍 기법이다. 방어적 프로그래밍은 목표가 존재하는데 오류가 발생했을 때, 도입 자체를 방지하고, 발생 시 감지는 필수적이며 마지막으로 시스템의 반응을 제어한다.

방어적 프로그래밍이 모토로 이끄는 문장이 있는데 "Garbage in, nothing out"이라고 하며, 좋은 프로그램은 잘못된 값이 들어오면 이를 아무것도 내보내지 않는 방식으로 방어해야한다.

단언문(Assertion)의 활용과 가이드 라인

단언문이란 개발 중에 프로그램이 예상대로 작동하는지 스스로 확인하도록 하는 코드이다. 복잡한 프로그램에서 잘못된 인터페이스나 코드 수정시에 발생한 오류를 빠르게 찾아내는 데에 유용하다. 주로 절대 발생하면 안되는 조건에만 사용한다.

그리고 Assertion 내에는 실행코드를 넣으면 안된다. 만약 넣게되면 그 코드가 배포 등을 했을 경우 무시될 가능성이 존재하기 때문이다. 그리고 마지막으로 사전 조건과 사후 조건을 문서화하고 검증할 때도 사용한다.

Exception Handling

오류처리 기법

오류를 처리하는 기법은 여러가지가 있는데 아래에 간결하게 정리해보면 다음과 같다.

  • 중립적인 값 반환 : 안전한 값을 반환하는 방식이다.
  • 다음의 유효한 데이터로 대체 : 손상된 기록을 건너뛰고 다음 값을 넣는다.
  • 이전과 동일한 응답 반환 : 이전에 출력한 값을 이어서 출력하는 형태이다.
  • 가장 가까운 합법적 값으로 대체 : 최대/최소 허용치로 값을 조정한다.
  • 파일에 경고 메세지 기록 : 메세지만 남기고 계속 수행한다.
  • 에러 코드 반환 : 예외 처리를 통해서 오류의 발생을 알린다.
  • 에러 처리 루틴/객체 호출 : 중앙 집중식이며 코드를 재사용할 때 종속성을 계속 호출해야한다.
  • 에러 발생 위치에 바로 메세지 표시 : 흔히 단순히 생각하는 출력구문을 이용하는 것이다.
  • 가장 적합한 최소한의 방법으로 처리 : 유연성은 높지만 시스템 전체의 정확성/강건성은 못 맞출 수 있다.
  • 시스템 종료 : 안전 필수 애플리케이션에서 유용하다.

딜레마 : 강건성(Robustness) vs 정확성

강건성과 정확성이 있다. 여기서 강건성이란, 소프트웨어가 중단되지 않고 어떻게든 작동하도록 하는 것을 말한다. 설령 기능적으로 성능이 저하되더라도 실행시키는 것에 의미를 둔다. 반대로 정확성이란 소프트웨어가 고장이나 에러가 발생하면 심각한 문제를 초래할 가능성이 높기에 부정확한 결과보다 아예 결과 자체를 반환하지 않는 것을 말한다.

소프트웨어는 그 종류에 따라서 강건성을 더 중요시할수도, 정확성을 중요시할수도 있다. 만약 에어백이나 방사선 치료기와 같이 조금의 문제도 발생해서는 안되는 기기에는 정확성을 요할 것이고, 그냥 우리가 자주 쓰는 유튜브나 서비스 프로그램들은 강건성에 힘을 더 주어서 중단되지 않고 이어가는 것을 중요시해야한다.

프로그래밍 언어 수준의 예외처리


Exception은 코드가 스스로 처리하지 못하는 예기치 않은 예외 이벤트를 마주쳤을 때, 이를 자신을 호출한 코드쪽으로 전달하는 특정 매커니즘이다. 언어에 따라서 예외처리를 하는 표현의 방식은 다르다는 점을 유의해서 접근해야한다.



이렇게 임베디드 시스템와 관련된 내용을 알아보았다.

profile
찬찬히 써내려가는 개발일지

0개의 댓글