본문 바로가기
노어플래시(NOR Flash)가 뭐죠?

뭘 알아야 이해를 하지!
노어 플래시 메모리는 주로 프로그램을 구동시키는 실행 바이너리를 내장하고 있습니다. 호스트피시(Host PC)에서 하드디스크가 있다면 임베디드 시스템에도 그와 같은 기능을 위한 메모리가 필요한데 그 중에 하나가 노어 플래시 메모리입니다. 임베디드 시스템에서는 노어 플래시나 낸드 플래시, 원낸드 플래시가 많이 사용되고 있는데, 대용량을 요구하는 임베디드 시스템이 아니라면 대부분 노어 플래시 메모리를 사용합니다. 그럼 임베디드 시스템에서는 노어 플래시, 낸드 플래시, 원낸드 플래시 아무거나 사용해도 될까요? 물론 아니겠죠?
시피유에서 어떤 타입의 메모리를 지원하는지 반드시 확인 한 후에 플래시를 사용해야 해요. 노어 플래시, 낸드 플래시, 원낸드 플래시가 지원되는지 확인을 하셔야 하구요 간혹 낸드 플래시를 지원 안 하는 경우도 있으니깐요..
노어 플래시의 특징은 노어 플래시 내에 바이너리가 들어 있다면 시피유가 노어플래시 메모리의 바이너리를 읽어서 프로그램을 바로 실행을 할 수가 있어요. 하지만 낸드 플래시나 원낸드 플래시의 경우에는 낸드 플래시에 있는 바이너리를 에스디램으로 복사를 한 후 시피유가 에스디램에서 동작 시킨답니다.

노어 플래시는 시피유와 연결할 때 어드레스와 데이타 선 있어요. 즉, 개발자가 노어 플래시 메모리에 프로그램을 다운로드 할 때 직접 주소를 지정할 수가 있어서 쉽게 할 수가 있어요.

노어 플래시는 개발자가 언제든지 지웠다 쓸 수가 있습니다. 대략 1000번 이상 지우기, 쓰기가 가능합니다. 노어 플래시 메모리에서 프로그램이 실행되는 것과 에스디램에서 프로그램이 실행되는 속도를 비교해 보면 당연히 에스디램에서 동작하는 것이 빠릅니다. 즉, 낸드나 원낸드는 바이너리가 에스디램으로 복사 된 후 에스디램에서 실행되니 노어 플래시에서 실행되는 것 보다 좀 더 빠른 성능을 내는 제품으로 만들 수가 있답니다. 노아 플래시메모리는 읽기, 쓰기, 지우기로 나눌 수가 있습니다. 각각의 동작방법에 대해 알아보도록 하겠습니다.

첫 번째, 지우기 동작입니다. 노아 플래시에 있는 바이너리를 지우기 위해서는 시피유가 정해진 규칙대로만 실행을 하면 지우기 동작을 해요. 그 규칙은 다음과 같아요.

위의 그림은 1st~6th까지 시피유가 노어 메모리쪽으로 6번 명령어를 보낸다는 의미 입니다.
하드웨어 디버거로 지우기 동작을 해 볼까요?

노어 플래시 시작어드레스가 0x0번지이고 16bit의 Data Bus일 경우일 때 아래와 같은 메모리 영역이 보입니다.
___address____|________0________4________8________C
SD:00000000|>54202F2F 315F3233 30303030 57203130
SD:00000010| 4A206465 32206E75 30302034 3A33303A
SD:00000020| 32203733 0D393030 200A0D0A 0D3A3A42
SD:00000030| 0A0D200A 4F4F5420 5241424C 0D4E4F20

주소와 상관없이 노어플래시는 데이타 시트에 나와 있는 데로 해당 어드레스에 데이터만 넣으면 되요. 그런데 Address가 0x555가 아니라 0xAAA 로 해야 합니다. 왜 일까요? 회로도 에서 CPU와 Flash Address 핀을 보세요. CPU의 A1핀이 Flash 의 A0 핀에 연결되어 있어요. 그것이 이유입니다. Flash 입장에서 0x555입니다. 결론은 Address를 왼쪽으로 1bit shift 시켰습니다.

Data.Set 0xAAA %w 0xAA // 1st Bus Cycle
Data.Set 0x554 %w 0x55 // 2st Bus Cycle
Data.Set 0xAAA %w 0x80 // 3st Bus Cycle
Data.Set 0xAAA %w 0xAA // 4st Bus Cycle
Data.Set 0x554 %w 0x55 // 5st Bus Cycle
Data.Set 0xAAA %w 0x10 // 6st Bus Cycle

위의 과정이 끝나고 나면 노어 플래시 메모리에는 다음과 같이 된답니다.

___address____|________0________4________8________C
SD:00000000|>FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
SD:00000010| FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
SD:00000020| FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
SD:00000030| FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

정상적인 Erase Command가 수행되면 Dump 창의 Flash 내용이 여러 값들로 규칙적으로 변해요. 그러다가 Erase Time이 다 지나게 되면, 0xFFFF 값으로 Flash의 내용이 채워지면 정상적인 Erase 랍니다. Flash는 지워지면 0x0000이 아닌 0xFFFF로 된답니다.

씨 프로그램으로 만든다면 다음과 같아요.

int main(void)
{

addr16a = (unsigned short *) (*parameter + 0xaaa);/* first and third address for command sequence */
addr16b = (unsigned short *) (*parameter + 0x554);/* second address for command sequence */

/* start command sequence for chip erase */
*addr16a = 0xaa;
*addr16b = 0x55;
*addr16a = 0x80;
*addr16a = 0xaa;
*addr16b = 0x55;
*addr16a = 0x10;

}

두 번째, 쓰기 동작입니다.

쓰기 동작하기 전에 반드시 NOR 플래시는 지워진 상태 즉, 'FFFF' 일 때만 쓰기가 되니 반드시 ERASE가 끝난 상태에서 해야 합니다. 현재 지워진 상태에서,
___address____|________0________4________8________C
SD:00000000|>FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
SD:00000010| FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
SD:00000020| FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
SD:00000030| FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

1sth~3st까지는 명령어를 보내고 마지막 4st에는 쓰고자 하는 주소에다 데이터 값을 쓰면 된답니다.

Data.Set 0xAAA %w 0xAA //1st Bus Cycle
Data.Set 0x554 %w 0x55 //2st Bus Cycle
Data.Set 0xAAA %w 0xA0 //3st Bus Cycle
Data.Set 0x0 %w 0x1234 //4st Bus Cycle

___address____|________0________4________8________C
SD:00000000|>00001234 FFFFFFFF FFFFFFFF FFFFFFFF
SD:00000010| FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
SD:00000020| FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
SD:00000030| FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

씨 프로그램으로 만든다면 다음과 같아요.

int main(void)
{
addr16a = (unsigned short *) (*parameter + 0xaaa);/* first and third address for command sequence */
addr16b = (unsigned short *) (*parameter + 0x554);/* second address for command sequence */

/* start command sequence for programming one byte */
*addr16a = 0xaa;
*addr16b = 0x55;
*addr16a = 0xa0;
*addr16 = *data16;
}

마지막으로 읽기 동작입니다. 읽기 동작은 특별한 커맨드 없이 읽을 수가 있어요.
하드웨어 디버거에서는 Dump를 하면 됩니다.

___address____|________0________4________8________C
SD:00000000|>64410A0D 65747061 20444972 44303530
SD:00000010| 0A0D6846 64410A0D 65747061 6D614E72
SD:00000020| 54222065 45434152 2D203233 41434D20
SD:00000030| 46202D20 72656269 74704F20 49206369
SD:00000040| 7265746E 65636166 200A0D22 754E0A0D
SD:00000050| 7479626D 34207365 0A0D0A0D 65786946

하지만 모든 노어 플래시가 이러한 방식으로 지우기와 쓰기를 하지 않아요. 조금 다른 타입의 노어 플래시가 있답니다.

지금 보는 노어 플래시는 2번 만에 지우기를 한답니다.

하드웨어 디버거로 지우기 동작을 해 볼까요?
Data.Set 0x0 %w 0x30 //1st Bus Cycle
Data.Set 0x0 %w 0xD0 //2st Bus Cycle

혹시나 이렇게 했는데도 불구하고 지워지지 않을 때가 있답니다. 그때는 언락(Unlock)이라는 명령어를 넣어 보세요. Unlock이라는 것은 사용자가 잘못해서 지우는 동작을 했다면 바로 지워지는 것을 막기 위해서 보통 때는 지우는 명령어가 들어와도 지워지지 않도록 락(lock)로 되어 있다가 반드시 언락이라는 명령어와 함께 지우는 명령어가 들어오면 지워지도록 하는 것이랍니다. 마치 윈도우에서 휴지통 넣기와 휴지통 비우기와 비슷한 개념이죠.
1st, 2st는 Unlock 명령어 입니다.

Data.Set 0x0 %w 0x60 //1st Bus Cycle
Data.Set 0x0 %w 0xD0 //2st Bus Cycle
Data.Set 0x0 %w 0x30 //3st Bus Cycle
Data.Set 0x0 %w 0xD0 //4st Bus Cycle

이제 쓰기 동작도 살펴봐야죠.
이번에도 2번만에 쓰기 동작을 하네요.

하드웨어 디버거로 쓰기 동작을 해 볼까요?
Data.Set 0x0 %w 0x40 //1st Bus Cycle
Data.Set 0x0 %w 0x1234 //2st Bus Cycle

___address____|________0________4________8________C
SD:00000000|>00001234 FFFFFFFF FFFFFFFF FFFFFFFF
SD:00000010| FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
SD:00000020| FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
SD:00000030| FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF

지금까지 노어플래시에 대해 알아 봤어요.

Linked at 친절한 임베디드 시스템 개발자.. at 2010/03/22 23:27

... bsp; 202 캐시메모리(Cache Memory)가 뭐죠? 203 노어 플래시 (NOR FLASH)가 뭐죠? 204 낸드플래시(NAND Flash)가 뭐죠? 205 에스 ... more

Commented by 히언 at 2010/03/23 07:56
띠용
Commented by soto at 2010/03/23 08:01
잘 지내시죠?ㅋㅋ
Commented by 히언 at 2010/03/23 21:44
띠용 그림 수정되었습니다~ 으흐흐
Commented by soto at 2010/03/27 05:39
감사 ^^
Commented by ruring at 2010/03/25 17:21
항상 잘보고가요 ^-^~
Commented by soto at 2010/03/25 18:53
감사합니다. ^^
Commented by at 2010/03/25 22:30
와우~~~
서당개 3년이면 풍월 읖을 수 있을까나? ㅜ,.ㅜ
아자
힘내서 열심히 볼게요.
Commented by soto at 2010/03/27 05:39
시도하는 것과 실행하는 것은 작은 차이지만 결과는 큰 차이랍니다. 조금씩 힘을 내서 실행해 보신다면 좋은 결과가 있으리라 생각됩니다. ^^;
Commented by at 2010/03/31 01:26
그림 정리가 항상 멋지시네요.
Commented by soto at 2010/03/31 06:51
오호~~! 감사해요.
Commented by blueban at 2010/03/31 01:43
깔끔해서 이해가 잘 됩니다.
수고하세요.
Commented by soto at 2010/03/31 06:52
늦은 밤까지 열공을 하시다니.. 열정이 대단하십니다. ㅋㅋ
Commented by 어디까지나 at 2010/03/31 02:05
열심히 보고있습니다 많은 정보 주셔서 감사합니다.
Commented by soto at 2010/03/31 06:54
네..감사해요.
Commented by cgv at 2010/04/01 23:10
역시 공부할꺼리는 넘쳐 나는 군요.
정보 고맙습니다.
Commented by soto at 2010/04/03 05:59
그러네요. ^^;
※ 이 포스트는 더 이상 덧글을 남길 수 없습니다.
친절한 임베디드 시스템 개발자 되기 강좌 글 전체 리스트 (링크) -



댓글





친절한 임베디드 개발자 되기 강좌 글 전체 리스트 (링크) -