
[고급 기술]
호스트에서 테스트를 하기 위한 몇 가지 기술들을 더 알아봅시다. 첫 번째, 테스트용 시뮬레이터 소프트웨어가 어떤 일을 자동으로 수행하게 만들면 유용할 때가 많습니다. 가령 지하 유류 저장 탱크 모니터 시스템을 위한 하드웨어 독립적인 코드가 데이터 한 줄을 프린터에 보낸다고 할 때, 테스트용 시뮬레이터 소프트웨어는 그 줄을 가로채고, 하드웨어 독립적인 코드에 다음 줄을 인쇄할 준비가 되었다고 말을 해야 합니다. 앞의 권고들로부터 합리적으로 생각해보면, 테스트용 시뮬레이터 소프트웨어는 스크립트에 있는 명령어에 대한 응답에 의해서만 프린터 인터럽트 루틴을 호출해야 합니다. 하지만 단순히 시스템이 보고서를 제대로 만드는지 아닌지만 확인하고 싶었다면 전체 보고서를 출력하기 위해 계속 테스트용 시뮬레이터가 프린터 인터럽트를 호출하도록 명령하는 것은 번거로운 일입니다. 하드웨어 독립적인 코드가 한 줄을 프린터에 보낼 때마다, 테스트용 시뮬레이터 코드가 자동으로 프린터 인터럽트 루틴을 호출하도록 만들면 편리할 겁니다.
하지만, 어떤 시간에는 이런 테스트용 시뮬레이터 기능을 끄길 원할 수도 있습니다. 문서 요청들을 큐에 저장하는 소프트웨어를 테스트하려면, 테스트용 시뮬레이터 소프트웨어는 프린터 인터럽트 루틴을 호출하지 않게 하여 하드웨어 독립적인 코드가 프린터에 다음 줄들을 인쇄하지 않도록 현재의 문서를 지연시키면서 또 다른 문서의 인쇄를 요청하는 버튼 인터럽트 루틴을 호출해야 합니다. 따라서 테스트용 시뮬레이터 코드는 프린터 인터럽트 루틴을 자동으로 호출할지 말지를 결정하는 스위치를 가지고 있어야만 하는 것이죠.
이와 유사한 예시들이 많이 있습니다. 무선 바코드 스캐너에서 하드웨어 독립적인 코드가 전파 송신 장치에 프레임 데이터를 보낼 때, 테스트용 시뮬레이터 코드는 데이터를 가로채고, 프레임 데이터가 보내졌음을 나타내기 위한 인터럽트 루틴을 자동으로 호출해야 합니다. 하드웨어 독립적인 장치가 200 마이크로세컨드의 짧은 타이머를 설정할 때마다 매번 스크립트 명령으로 테스트용 시뮬레이터 소프트웨어가 설정하도록 하는 대신 자동으로 설정하도록 할 수도 있습니다. 시스템이 테스트용 시뮬레이터가 가로챌만한 데이터를 생성하는 순간마다 테스트용 시뮬레이터가 자동으로 응답을 하게 만들어서 테스트를 더 편하게 만들 수 있습니다.
서로 간에 통신을 해야 하는 여러 시스템을 가지고 있는 프로젝트를 수행하는 경우에 테스트용 시뮬레이터가 여러 개의 하드웨어 독립적인 코드의 개체를 가지도록 하고 개체들 사이에서 중개 역할을 하도록 하는 기술을 생각해 봐야 합니다. 가령 무선 바코드 스캐너를 위해서 테스트용 시뮬레이터 소프트웨어는 여러 개의 스캐너를 위한 하드웨어 독립적인 코드 개체들과 현금 출납기를 위한 하드웨어 독립적인 코드 개체들을 가져야만 합니다. 각각의 하드웨어 독립적인 코드에게 테스트용 시뮬레이터 소프트웨어는 전파 송수신 하드웨어처럼 보이고, 타깃 하드웨어에 있는 실제 전파 송수신 하드웨어처럼 데이터를 보내거나 받아야 합니다.
한 예를 들어봅시다. 무선 바코드 스캐너 a는 데이터 프레임을 보내고 테스트용 시뮬레이터 소프트웨어는 데이터를 가로챕니다. 테스트용 시뮬레이터 소프트웨어는 또한 모든 하드웨어가 독립적인 코드의 개체들이 무선 전파 장치를 제어하기 위해서 함수를 호출할 때마다 정보를 가로채기 때문에, 어떤 개체가 무선 전파 장치를 켰는지 어떤 주파수를 가지고 있는지를 알고 있습니다. 테스트용 시뮬레이터 소프트웨어는 무선 전파 장치가 켜져 있고, 가로챈 주파수와 같은 개체들의 프레임 수신 인터럽트 루틴들을 호출합니다. 무선 전파 장치를 껐거나 다른 주파수로 설정한 개체들은 프레임 데이터를 받지 못합니다. 추가적으로 간섭을 테스트하기 위해 하나 아니면 그 이상의 장치들이 데이터를 받지 못하게 테스트용 시뮬레이터 소프트웨어를 프로그래밍하는 것도 가능합니다. 이런 방법으로 테스트용 시뮬레이터 소프트웨어는 각각의 개체들이 서로 똑바로 통신을 하는지를 점검할 수 있는 것입니다.
[반론과 제한 사항 그리고 단점]
엔지니어들은 종종 임베디드 시스템 코드를 호스트 시스템에서 테스트하는 것에 대해서 반대하곤 합니다. 1, 임베디드 시스템 코드는 상당히 하드웨어 의존적인 것이기 때문에 그렇다고 합니다. 코드는 대부분을 하드웨어에 의존하는 임베디드 시스템이 있는 것이 사실이긴 하고, 많은 임베디드 시스템이 어느 정도의 하드웨어 의존적인 코드를 가지고 있는 것도 사실이긴 하지만, 임베디드 시스템의 코드 대부분은 하드웨어와 직접적인 연관을 갖지 않습니다. 코드들은 대부분 마이크로프로세서와 상호작용을 합니다. 텔레그래프 소프트웨어 블록을 보여주는 한 에씨에서도 볼 수 있듯이, 소프트웨어의 많은 부분이 하드웨어 독립적입니다. 이는 적절한 테스트용 시뮬레이터 소프트웨어를 이용해서 호스트에서 테스트될 수 있다는 것을 의미합니다.
더해서 테스트용 시뮬레이션 코드를 작성해서 얻는 장점보다 더 많은 문제를 야기시킬 수 있다는 반대를 하기도 합니다. 이런 반대에는 두 가지 답변을 줄 수가 있겠군요. 처음은 비록 버그의 수가 적다고 하더라도 실험실에서 버그를 찾는 것은 상당히 많은 시간을 필요로 하는 일이기 때문에 테스트용 시뮬레이션 코드를 작성하는 것은 가치가 있다는 겁니다. 두 번째는 시뮬레이션 코드를 작성하는 것은 생각보다 그다지 큰일이 아니라는 것이지요. 테스트용 시뮬레이션 코드는 1. 스크립트 파일을 읽어서 스크립트 파일의 명령어를 하드웨어 독립적인 소프트웨어의 호출로 변경시켜 주는 명령어 해석기, 2. 출력을 가로채고 재구성하고 출력 파일에 써넣는 코드로 구성되어 있습니다. 이런 코드를 작성하는 노력은 대부분의 임베디드 시스템 소프트웨어를 작성하는데 드는 노력에 비해서 상대적으로 무시할 만큼 작습니다. 스크립트 파일을 작성하는데 시간이 필요하긴 하겠지만, 스크립트 파일을 작성하는 것은 같은 일을 하는 이벤트들을 실험실에서 테스트해보는 것보다 시간이 적게 듭니다.
다른 반대 의견은 이런 방법을 적용하기 위해서 호스트 시스템에서 돌아가는 RTOS버전을 구해야 한다는 겁니다. 이건 상대적으로 사소한 일인데요. 하나, 많은 RTOS 제조 회사들은 윈도나 도스 또는 유닉스에서 실행되는 버전을 제공하기 때문에, 사용하는 호스트에서 돌아가는 ROTS 버전을 구할 수 있는 RTOS를 선택해서 이런 문제를 간단히 해결 가능합니다. 둘, 만약에 RTOS를 감싸는 쉘을 만들었을 경우, 코드를 상대적으로 쉽게 호스트에서 돌아가는 RTOS에 맞도록 포팅하거나, 심지어 호스트 운영체제의 능력에 맞도록 포딩이 가능하다는 겁니다. 붙여보자면 대부분의 테스트용 시뮬레이터 소프트웨어 하드웨어 독립적인 소프트웨어와 통합하는 가장 일반적인 방법은 테스트용 시뮬레이터 소프트웨어를 RTOS에서 낮은 우선순위의 태스크로 만드는 것입니다.
호스트에서 테스트를 하는 것에 대한 또 다른 반대의견은 호스트에서 중요한 소프트웨어 특징을 테스트해 볼 수 없다는 얘기입니다. 아래 내용을 포함하니 살펴보도록 합시다.
- 하드웨어와 소프트웨어의 상호 작용 : UART를 위한 데이터를 잘못된 주소에 쓰는 경우 타깃 하드웨어 없이는 문제를 발견하기 힘듦.
- 응답성과 작업 처리량 : 만약 코드가 다른 종류의 C 컴파일러로 컴파일되고 다른 속도와 다른 인터럽트 지연시간을 갖는 다른 마이크로프로세서에서 실행된다고 하면, 응답성과 작업 처리량은 변하게 됨.
- 공유 데이터 문제 : 공유 데이터 문제는 인터럽트가 걸린 태스크 코드가 인터럽트를 금지시켜야 했거나, 세마포어를 가졌어야 했는데 그러지 못한 난처한 순간에 인터럽트가 발생했을 때 생김. 이런 문제는 호스트에서는 거의 발견하기 어려움.
- 이식성의 문제 : 호스트 시스템과 타깃 시스템은 많은 차이점을 가지고 있음. 가령 호스트 시스템이 MSB가 메모리의 첫 번지에 저장되는 형태인 빅엔디언이고 타깃 시스템이 LSB가 메모리의 첫 번지에 저장되는 리틀엔디언이라면, 호스트에서는 볼 수 없었던 문제가 타깃에서는 발생할 수 있습니다. 이런 문맥에서 int의 크기나 구조체의 구성 방법 그리고 다양한 번지 지정 방법 등이 문제를 일으킬 수 있음.
이 얘기는 완전히 맞는 말입니다. 이런 내용을 호스트에서 테스트해보는 것은 불가능합니다. 호스트에서 사전에 테스트해서 발견할 수도 있는 버그가 있는 코드를 가지고 이런 문제들을 다루고 싶은가요? 아니면 이런 문제들을 더 안정된 버전의 코 드위에서 걱정하고 싶은가요?
호스트에서 코드를 테스트하는 일은 만능열쇠가 아닙니다. 그러나 테스트 절차에 의해서 미리 반복적으로 코드의 많은 부분을 테스트할 수 있다는 것은 약간의 힘듦을 감수할 가치가 있다는 것을 명심해둡시다.
참고)
디버깅을 위한 호스트 시스템에서의 테스팅1 - 테스팅의 목적과 기본
드디어 새로운 파트로 넘어왔습니다. 이번에는 고객에게 선적할 때 제대로 동작하도록 하기 위한 임베디드 시스템 소프트웨어를 테스트하고 디버깅하는 방법을 위주로 이어나갈 예정입니다. ��
ppojjaknews.tistory.com
디버깅을 위한 호스트 시스템에서의 테스팅2 - 인터럽트 루틴 호출 / 스크립트, 출력 파일
이어서 계속 테스팅 얘기를 해볼게요. [인터럽트 루틴의 호출] 언젠가 언급했듯이 대부분의 임베디드 시스템은 인터럽트가 발생해서 인터럽트 루틴이 실행되는 것으로 뭔가를 합니다. 따라서 ��
ppojjaknews.tistory.com
'IT > 임베디드 시스템' 카테고리의 다른 글
임베디드 소프트웨어 디버깅 장비1 - 전압계/저항계, 오실로스코프 (0) | 2020.07.01 |
---|---|
디버깅 테크닉 - 명령어 시뮬레이션 & assert 매크로 (0) | 2020.06.25 |
디버깅을 위한 호스트 시스템에서의 테스팅2 - 인터럽트 루틴 호출 / 스크립트, 출력 파일 (0) | 2020.06.23 |
디버깅을 위한 호스트 시스템에서의 테스팅1 - 테스팅의 목적과 기본 (0) | 2020.06.22 |
타깃 시스템에 임베디드 시스템 올리는 방법 (0) | 2020.06.20 |
댓글