2011년5월31일_ATmega128 내부EEPROM 하드웨어적 오류와 회피법, HexaView 프로젝트

 

● 순위데이터 기록 오류 수정
● 두더지게임 발표
● HexaView 프로젝트 진행

★문서 작성시 그림을 작게 할 것.

 

ATmega128 내부 EEPROM 전원 투입시 오류


● 발견

두더지 게임 프로젝트를 진행하며 DK-128보드의 ATmega128 (AVR) MCU의 결함을 발견하였다.
내부EEPROM에 게임진행 후 얻은 총점을 0번지 부터 9번지까지 기록하여 전원을 재투입하더라도 데이터가 보존되도록 하였으나..
가끔 그 데이터가 0으로 초기화되는 것이었다. 어떤 때는 1번지와 2번지도 0으로 초기화도 되었다.
그래서 내가 작성한 소스코드를 살펴보았으나 내부EEPROM의 0번지 데이터를 0으로 초기화하는 그 어떤 코드도 없었다.
따로 초기화함수가 존재하나 그 함수가 호출되는 조건이 전원을 켜고 난 후가 아니다.
그리고 그 함수가 호출된다면 그것은 더 큰 문제이다.

우선 인터넷 검색을 하여 비슷한 증상을 경험한 사례가 있는지 알아 보았다.


Why AVR's EEPROM will be erased randomly?

Wed, 02/27/2008 - 01:29 — allankliu

Some AVR developers reported that the AVR's EEPROM will be erased randomly. And these poor people are driven crazy because they have no clue about the real cause for it. Is AVR micro's embedded EEPROM not stable at all? Well, there are not perfect products in the world. But I would rather to say the real cause might be yourself.

Do you have any idea what AVR is doing during reset? Have you even done some testing for its reset behavior? AVR is a very fast microcontroller, cause it is an RISC micro. (Here I dislike the word of RISC, since RISC is a real microprocessor concept which has many related infrastructure in compilers, which is not suitable for microcontroller. I like to say AVR is a RISC like microcontroller, simple and fast.) Speed is its advantage, but sometimes it will cause a lot of issues if designer is not ready for it. Please read the AVR specification, you will find out that AVR is in a unstable RUNNING mode before valid reset is generated. Yes, it is RUNNING! During the process of downloading (actually uploading) program to AVR, between WRITE and VERIFY modes, the reset will be released, then pulled down in VERIFY mode. During this very short duration of reset pin released, the program is RUNNING randomly. I have a LCD project using AVR. During downloading, the LCD will show some content before VERIFY mode. Because this period, most of the ram data is random , so incorrect content is displayed anyway. When system drops into verify, the LCD is frozen.

So if your hardware has not enough precaution for reset circuit, during the power on reset, before valid reset is generated, AVR is randomly running. For example, writing EEPROM, while running is out of control, the data written into AVR is also random as well as the EEPROM address, since most of the AVR registers are zero during this period. So the so-called ZERO address is not stable is spread. If your program runs other routines before drops into EEPROM routines, who knows it wrote what in where? So it is unstable if you have no idea about it. So after your power on the system, the data is changed by your own program. Is that clear?

Solution is:

  1. You can avoid using zero address of EEPROM for data storage, not a complete solution (Even IAR complier will use second EEPROM as default);
  2. Using CRC for EEPROM data integrity checking;
  3. Enable BOD of AVR, set 4.2V for 5V system, set 2.7V for 3.3V system, but some old AVR has not BOD inside;
  4. Using external Reset chip such as DS1233, KIA7045 or IMP809/810. 

네이버에서 검색해 보니 내부EEPROM에 문제가 있다는 글을 쉽게 찾을 수 있었다.
위에 해결책 4가지를 보면,
1. 내부EEPROM의 0번지를 피해서 쓰라.
2. CRC를 사용해 데이터 무결성을 체크하라.
3. 브라운 아웃 디텍터(BOD)를 활성화하여 전원전압 상승시간에는 확실히 리셋상태를 유지하라.
4. 외부 리셋IC를 사용하라.

상단의 본문을 보지 않더라도 해결책 자체에 ATmega128 하드웨어가 완벽한 것이 아니라 약간의 오류가 있다는 것을 알 수 있다.
뭐 AVR MCU도 인간이 만든 것이니 오류가 없을 순 없겠지…
그래서 EEPROM관련 레지스터를 다시 살펴 보았다.

image

우선 제일 처음 나오는 주소 레지스터인 EEAR을 보니,
초기값이 X로 전원 투입시 어떤 값이 될지 알 수 없다. 초기값이 0인줄 알았는데 다시 보니 아니었다.
0이 아니면 0번지를 가리키지 않으므로 0번지가 초기화되는 일은 없을 텐데…
0번지 외에도 초기화된다는 사례가 있고 나도 경험하였었다.



image

다음으로 나오는 데이터 레지스터인 EEDR을 보니,
초기값이 0으로 되어있다.

 

image

마지막으로 살펴볼 레지스터는 EEPROM에 읽고 쓰기를 담당하는 제어 레지스터인 EECR이다.
2번째 EEMWE비트는 EEPROM Master Write Enable로 쓰기 전에 먼저 1로 세트되어야 EEPROM에 기록할 수 있다.

image

먼저 EEMWE를 세트하고 다음에 EEWE를 세트한다.
EEWE가 세트되어 있다면 현재 기록 중이니 기록할 수 없는 상태가 되고,
기록을 마치면 자동으로 EEMWE가 클리어되고 EEWE가 클리어된다.

EEMWE의 초기값은 0이니 절대 EEPROM에 데이터가 기록되지 않는다고 생각되나,
EEWE의 초기값이 X로 불안정하다.
그럼 어떤 원인에 의해서 EEMWE가 1로 세트된다면 EEAR의 랜덤값과 EEDR의 0…즉, 무작위로 데이터가 0으로 초기화 될 수 있다.

어떠한 원인에 의해 EEMWE비트가 1로 세트될까?

다시 돌아가서 문제가 발생한 시점에 대해 알아 보면,
AVR MCU가 동작 중에는 데이터의 변조가 일어나지 않으나 전원투입 시에만 일어나고 다른 사례를 살펴보아도 같았다.
DK-128보드의 회로를 보면 EXT보드의 전원입력단에 전원평활용과 바이패스 커패시터(콘덴서)가 달려 있다.


imageimage  

전원을 투입하면 상기의 그림과 같이 전원 전압이 갑자기 5V가 되는 것이 아니라 커패시터에 전하를 충전하는 시간 동안…
전원전압이 서서히 상승한다. (서서히라고 표현하였지만 실제 상승시간이 인간이 보기엔 짧다. (이상한 표현))

Datasheet p.1의 동작전압범위를 보면,

image

ATmega128L이 아닌 ATmega128의 경우 최소전압이 4.5V이다.
즉, 4.5V이하에선 정상적인 동작을 보증하지 않는다는 이야기이다.
전원전압이 4.5V이하인 시점…즉, tbod이전의 시간대엔 AVR MCU가 정상적인 동작을 하지 않는다.

정상적인 동작을 하지 않는 시간대엔 어떤 일이 벌어지는가?
알 수 없다.
알 수 없으나 추론을 하자면,

① AVR MCU내부에 레지스터를 초기화하는 하드웨어(회로)가 있다.
② 그 하드웨어는 전원전압이 안정적일 때는 아무 문제 없이 정상동작한다.
③ 그 하드웨어는 전원전압이 불안정할 때는 정상적으로 동작하지 않는다.
④ 그 하드웨어가 불안정할 때는 데이터시트에 명시된 것과 다르게 동작한여 초기값이 바뀐다.
⑤ EECR레지스터의 2번째 비트인 EEMWE가 0이 아닌 1로 세트된다.
⑥ EEAR레지스터의 랜덤값과 EEDR의 0이 작용하여 EEPROM에 기록이 된다.

전원투입 → 전원전압 상승시간동안 레지스터 초기화 회로의 불안정동작 → 엉뚱한 값이 레지스터에 들어감 → EEPROM 오류

위와 같이 4단계에 걸쳐 무작위로 EEPROM에 원치 않는 엉뚱한 값이 기록이 될 수 있다.
정답은 ATMEL社만 알고 있겠지...

 

 

 

HexaView 프로젝트 약간 진행 후

 

 

(화면 출력 구상)

 

 

 

HexaView.c

image

 

main.c

image

 

출력화면

image

 

printf( ) 색깔 (리눅스)

 

COLOR

bgcolor Code

Text Code

Black

40

30

Red

41

31

Green

42

32

Yellow

43

33

Blue

44

34

Pupple

45

35

Cyan

46

36

White

47

37

printf( ) 함수의 인자로 const char * ( 큰 따옴표)에 다음과 같이,

\x1b[47m  - 다음에 오는 문자들은 하얀 바탕위에 써진다.
\x1b[30m  - 다음에 오는 문자들은 검은 글씨로 써진다.
\x1b[0m   - 이 다음에 오는 문자들은 기본색상으로 써진다.


<Example>

 
printf(“여기는 기본 색…\x1b[47m\x1b[30m여기서 부터는 하얀 바탕에 검은 글씨…\x1b[0m여기는 기본 색…\n\n”);


<실행결과>

image