본문 바로가기

Electron

[펌] 노이즈에 강한 프로그래밍


MCU에는 여러가지 메모리가 있는데, 쓰임새에 따라 다르게 부릅니다.

PC (프로그램 카운터) : 프로그램 메모리중 현재 실행할 번지를 가지고 있음.
SP (스택 포인터) : 스택 저장 지점을 가지고 있음.
레지스터 : ALU에서 사용하는 데이터를 가지고 있음.
I/O (페리퍼럴) 레지스터 : I/O등 페리퍼럴의 셋팅상태등을 가지고 있음. 

다양한 쓰임새가 있지만, 이 모든것은 그냥 플립플롭으로 구성된 메모리입니다.  
노이즈에 의해서 차별대우를 받지 않는 그냥 평범한 메모리인 것입니다.
이중 어떠한 메모리도 노이즈의 공격으로 부터 자유롭지 않습니다.
심지어 PC (프로그램 카운터) 조차도 노이즈로 인해 내용이 파괴될수 있습니다.

I/O 레지스터의 내용이 노이즈로 인해 바뀐다면, 그냥 I/O상태가 바뀌는 것이지만,
PC (프로그램 카운터)의 내용이 바뀐다면, 그결과는 매우 치명적입니다.
갑자기 알 수 없는 번지로 점프(GOTO)하게 되고 맙니다.

하필 그번지에 니모닉이 아닌, 데이터가 들어 있다면, 프로그램은 삼천포로 빠지게 됩니다.
데이터는 의도되지 않는 숫자이기때문에 어떤식으로 실행될지는 아무도 알 수 없습니다.
심지어 MCU를 설계한 사람 조차도 말입니다.

 "노이즈에 의해 PC(프로그램카운터)의 내용이 바뀔수 있다" 는 가정하에, 프로그램을 짜야합니다. 

이런 상황을 피하기 위한 가장 좋은 방법은 와치독 타이머를 활용하는 것입니다.
이에 대해서는 앞서 자세히 포스팅했으니 참조하시기 바랍니다. (와치독타이머 사용법)
와치독 타이머는 프로그램이 엉뚱한곳에서 계속 무한루프를 도는 것을 막아줍니다.  
**
그럼 I/O레지스터가 잘못되는 것은 어떻게 처리해야 할까요?

I/O레지스터도 노이즈의 공격대상이 될 수 있습니다.
그래서 루프구조로 프로그램을 짜야합니다. 루프안에서 중요한 I/O레지스터는 계속 셋팅값을 유지시켜주어야 합니다. 

DDRA = 0xff;
while (1) {
    input_proc();
    output_proc();
}

이런식으로 PORTA의 입출력상태를 결정하는 명령어를 루프 바깥에 두지 마시고,

while (1) {
    DDRA = 0xff;
    input_proc();
    output_proc();
}

이런식으로 루프 안에 두십시오. 

I/O제어도 마찬가지입니다. 설령 노이즈에 의해서 출력값이 바뀐다 하더라도,
정상적으로 루프를 한바퀴 더 돌고 나면, 원래값으로 돌아올 수 있도록 프로그램하십시오.

사실 PLC (프로그래머블 로직 콘트롤러)가 노이즈에 강한 이유가 여기에도 있습니다.
PLC는 루프구조로 되어 있어, 모든 프로그램이 수마이크로초~수밀리초 간격으로 반복해서 실행합니다.
설령 노이즈에 의해 잘못된 출력결과가 나간다 하더라도, 다음스캔에서 이를 바로잡아줍니다.

여러분이 C언어나 기타 다른 언어로 프로그램을 짜신다 하더라도, PLC처럼 전체적인 상황을 루프를 돌면서 계속 확실하게 유지시켜주는 방식으로 프로그램을 짠다면, 그것이 바로 노이즈에 강한 프로그램을 짜는 요령이 되겠습니다.

[출처] (추천글)노이즈에 강한 프로그래밍|작성자 큐블