임베디드 시스템과 펌웨어
위의 프로그램을 최적화를 켜고 컴파일하면 타이머 인터럽트가 발생해도 led_on()이 호출되지 않는 경우가 있습니다. 원인과 대책의 조합으로 올바른 것은 무엇입니까?
int flag = 0;
void timer_isr(void) { flag = 1; }
int main(void) {
while (flag == 0) { }
led_on();
}
- A컴파일러가 flag를 한 번만 읽고 루프 안에서 다시 읽지 않기 때문이다. flag에 volatile을 붙인다
- B인터럽트가 발생하면 flag가 0으로 돌아가기 때문이다. flag를 long으로 한다
- Cwhile의 내용이 비어 있으면 CPU가 멈추기 때문이다. 루프 안에 덧셈을 넣는다
정답과 해설 보기
정답: A. 컴파일러가 flag를 한 번만 읽고 루프 안에서 다시 읽지 않기 때문이다. flag에 volatile을 붙인다
컴파일러는 main 안만 보고 '루프 안에서 flag를 바꾸는 것은 없다'고 판단하여, flag를 한 번만 레지스터에 읽고 그 값으로 계속 도는 코드를 만들기도 합니다. 인터럽트 핸들러가 메모리 상의 flag를 바꿔도 루프는 그것을 보지 않습니다. volatile을 붙이면 접근할 때마다 메모리에서 읽고 쓰게 됩니다. 여러 바이트 변수에서는 읽기/쓰기 도중에 인터럽트되지 않도록 하는 추가적인 대책도 필요합니다.