2019. 5. 30. 16:03ㆍ임베디드/ATmega128
avr-gcc에서 int 자료형은 2바이트 크기를 갖는다. 다만 ATmega128은 8비트 마이크로컨트롤러로 2바이트 자료형을 처리할 때는 2 클록에 처리할 수 있다. 따라서 한 클록 이후 인터럽트가 걸린다면 문제가 생길 수 있다.
예를 들어,
#include <avr/io.h>
#include <avr/interrupt.h>
volatile int value = 0;
ISR(외부 인터럽트) {
value = (value + 1) % 2;
}
int main(void) {
int local_value;
setinterrpt();
while(1) {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
local_value = value;
}
if(local_value == 1) {
do_something();
}
}
}
만일 ATOMIC_BLOCK이 걸려있지 않다면 value 한 클럭 읽어오고 나서 인터럽트 후 변경된 value의 나머지 부분을 읽어오게 되어서 잘못된 데이터 입력이 된다. 따라서 이렇게 인터럽트 내부에서 사용되는 data가 main 안에서도 영향을 끼친다면 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) 옵션을 사용해 읽어오는 동안에는 인터럽트가 일어나지 않도록 하는 것이 옳은 방법이다
* ATOMIC_BLOCK(ATOMIC_FORCHEN) 옵션은 블록 내의 코드가 실행되는 도중 SREG 레지스터 값이 바뀔 수도 있다는 점이 있다. 하지만 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) 옵션은 SREG 레지스터 값을 보장한다
'임베디드 > ATmega128' 카테고리의 다른 글
아두이노와 AVR의 차이 (0) | 2019.05.30 |
---|---|
포토레지스터, 포토다이오드, 포토트랜지스터 (0) | 2019.05.30 |
RTC 오실레이터는 왜 32.768KHz인가 (0) | 2019.05.28 |
ISP 다운로드 시 ISP clock 주파수 설정 (0) | 2019.05.27 |
#include "" 와 <>의 차이 (0) | 2019.05.26 |