대규모 데이터의 분류와 저장, 검색에 초점을 맞추는 일반적인 정보 시스템과 달리, 임베디드 시스템은 더 큰 시스템 내부에 논리적으로 통합된 부품으로서 연산 자체가 주 목적이 아닌 시스템을 말한다.
대규모이며 수명이 길고, 실시간 응답과 고장시 안전을 보장하는 신뢰성이 필수적이다. 또한 비동기적이고 병렬적인 특성을 가지며 분산된 환경에서도 동작하는 경향이 있다.
응답 속도에 따라 일괄 처리(batch), 대화형(interactive on-line), 실시간 시스템(real-time)으로 분류할 수 있다.
이 때 batch 시스템은 결과가 언제 오는지는 상관하지 않는다. 실시간 시스템(real time)은 time-deadline이 존재하는 시스템을 말한다.
데드라인의 엄격성으로 Hard와 Soft로 구분이 가능하고 실행 속도에 따라 Fast와 Slow로 구분할 수 있다.

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

임베디드는 일반적으로 PC와 달리 물리,전기적으로 가혹한 환경에 노출되는 경우가 많아 이를 견딜 수 있어야한다. 그래서 온도, 전기적 간섭이 강한 공간, 장기 유지보수의 설계까지 반영되어야한다.
임베디드 시스템의 설계자는 시스템이 환경과 상호작용하며 내야하는 성능을 예측해야한다. 정해진 주기에 따라 지속적으로 백그라운드에서 수행되어야하고, 외부의 무작위 이벤트를 즉각 반응해서 처리해야한다.
시스템의 하드웨어나 소프트웨어는 수명 주기 내에 어떤 이유로든 반드시 고장이 발생할 수밖에 없다는 것을 전제로 한다. 따라서 예외 처리 매커니즘을 필수적으로 포함해야한다.
신뢰성있는 소프트웨어(Dependable SW)는 단순히 결함이 없는 상태를 넘어 3가지 핵심 품질 속성을 충족해야한다.

정확성(Correctness)
프로그램이 요구사항 명세서와 일치하는지 나타내는 정적(static)인 속성이다. 오류가 발생하면 부정확한 결과를 보내는 것보다 아무 결과를 내보내지 않고 시스템을 멈추는 것이 낫다는 것을 의미한다.
신뢰성(Reliability)
프로그램이 요구되는 정밀도에 맞춰 의도된 기능을 실제로 얼마나 잘 수행하는지 나타내는 동적(dynamic)인 속성이다. 런타임 중에 고장이 발생하는 빈도를 최소화해서 서비스가 중단 없이 유지되도록 하는 것이 중요하다는 것이다.
안전성(Safety)
시스템이 정상적이거나 비정상적인 상황에서 작동하더라도 인명 피해나 재산상의 손상을 초래하는 위험없이 작동할 수 있는 능력이다. 고장이 나더라도 그것이 치명적인 사고로 이어지지 않도록 방어하는 것이다.
완벽한 소프트웨어는 없으므로 고장이 발생하면 시스템이 어떻게 반응하고 대처할 것인지를 4가지 전략에 따라 동작한다.

소프트웨어 오류란 오작동을 일으키는 프로그램의 요소들을 총괄한 내용인데, 크게 3가지 범주로 나눌 수 있다.
시스템 설계 오류
설계자가 시스템이 작동할 물리적 환경이나 동작 시간에 대해 잘못된 가정을 내렸을 때 발생하는 치명적 오류이다.
설계 및 코딩 오류
개념을 실제 컴퓨터 코드로 번역하는 과정에서 발생한다. 우리가 흔히 생각하는 개발 중에 일어나는 오류들이 거의 대부분 여기에 포함된다. 소프트웨어가 고객의 의도나 의미를 잘못 이해한 의미론적 오류, 우발적 무한루프, 데드락 등의 논리적 오류, 0으로 나누기나 오버플로우 등의 알고리즘적 오류 등으로 구성된다.
환경적 요인
소프트웨어가 정상적인 환경에서 작동할 때 발생하는 하드웨어의 오작동, 사람의 실수, 예상치 못한 외부 간섭 등 예측 불가능한 오류이다. 이는 설계 단계에서 완벽하게 제거할 수 없기에 심층 분석으로 문제 발생 가능성을 최소화 해야한다.
나쁜 소프트웨어가 만들어지는 원인은 경영진 또는 상관에게 문제가 있거나 설계가 부족한 상황, 전문성 결여, 문서화 부족, 프로토타이핑 부재 등의 여러 문제들을 꼽을 수 있다.
그럼 반면 좋은 소프트웨어 개발의 기본은 무엇일까 1) 우선 명확한 요구사항이 정의되어야 한다. 사용자가 무엇을 원하는지 잘 파악하는것이 중요하다는 것이다. 그리고 2)설계를 할 때 목표 달성이 가능한 수준이어야하고, 3)관리에 있어서 유연한 프로젝트 조직으로 구성이 되어야한다. 마지막으로 4)테스트가 쉽게 이뤄지도록 설계와 검증된 방법을 사용하는 것이 필요하다.
이식성과 재사용성 또한 좋은 소프트웨어 하면 빠질 수 없는데, 검증된 컴포넌트를 사용해서 작업을 하면 설계, 코딩, 디버깅 시간 및 비용이 감소하고 신뢰성을 높일 수 있다. 이식성과 재사용성을 고려하면 소프트웨어가 더욱 효율적으로 구성될 수 있다.
우리는 기본적으로 오류에 대해 회피를 해야한다. 오류를 회피한다는게 무슨말이냐, 오류 회피는 기본적으로 잘못된 값이 들어오거나 잘못된 접속이 발생했을 때 큰 문제가 발생하지 않으면 가능한 회피하는 방향으로 움직이는 것이다. 이러한 오류 회피를 실질적인 프로그래밍에 접목하면 "방어적 프로그래밍"이 된다.
방어적 프로그래밍은 예상치 못한 입력에도 소프트웨어가 계속 수행을 보장할 수 있도록 한 프로그래밍 기법이다. 방어적 프로그래밍은 목표가 존재하는데 오류가 발생했을 때, 도입 자체를 방지하고, 발생 시 감지는 필수적이며 마지막으로 시스템의 반응을 제어한다.
방어적 프로그래밍이 모토로 이끄는 문장이 있는데 "Garbage in, nothing out"이라고 하며, 좋은 프로그램은 잘못된 값이 들어오면 이를 아무것도 내보내지 않는 방식으로 방어해야한다.
단언문이란 개발 중에 프로그램이 예상대로 작동하는지 스스로 확인하도록 하는 코드이다. 복잡한 프로그램에서 잘못된 인터페이스나 코드 수정시에 발생한 오류를 빠르게 찾아내는 데에 유용하다. 주로 절대 발생하면 안되는 조건에만 사용한다.
그리고 Assertion 내에는 실행코드를 넣으면 안된다. 만약 넣게되면 그 코드가 배포 등을 했을 경우 무시될 가능성이 존재하기 때문이다. 그리고 마지막으로 사전 조건과 사후 조건을 문서화하고 검증할 때도 사용한다.
오류를 처리하는 기법은 여러가지가 있는데 아래에 간결하게 정리해보면 다음과 같다.
강건성과 정확성이 있다. 여기서 강건성이란, 소프트웨어가 중단되지 않고 어떻게든 작동하도록 하는 것을 말한다. 설령 기능적으로 성능이 저하되더라도 실행시키는 것에 의미를 둔다. 반대로 정확성이란 소프트웨어가 고장이나 에러가 발생하면 심각한 문제를 초래할 가능성이 높기에 부정확한 결과보다 아예 결과 자체를 반환하지 않는 것을 말한다.
소프트웨어는 그 종류에 따라서 강건성을 더 중요시할수도, 정확성을 중요시할수도 있다. 만약 에어백이나 방사선 치료기와 같이 조금의 문제도 발생해서는 안되는 기기에는 정확성을 요할 것이고, 그냥 우리가 자주 쓰는 유튜브나 서비스 프로그램들은 강건성에 힘을 더 주어서 중단되지 않고 이어가는 것을 중요시해야한다.

Exception은 코드가 스스로 처리하지 못하는 예기치 않은 예외 이벤트를 마주쳤을 때, 이를 자신을 호출한 코드쪽으로 전달하는 특정 매커니즘이다. 언어에 따라서 예외처리를 하는 표현의 방식은 다르다는 점을 유의해서 접근해야한다.
이렇게 임베디드 시스템와 관련된 내용을 알아보았다.