임베디드 레시피

Egloos | Log-in





낸드플래시(NAND Flash)가 뭐죠?


뭘 알아야 이해를 하지!

낸드플래시 메모리는 주로 대용량의 데이타 저장용으로 많이 쓰이고 있답니다.
우선 낸드 플래시는 노어 플래시와 달리 임베디드 시스템을 동작 시키는 메인 바이너리가 들어 있어도 낸드 플래시에서 실행되지 않습니다. 낸드 플래시에 들어 있는 바이러리. 즉, 메인 바이너리를 에스디램(SDRAM)으로 반드시 복사를 하고  난 후 에스디램에서 동작하게 되어 있어요.  그럼 누가 에스디램으로 복사를 해 주는 걸까요? 그건 바로 부트로더가 해 준답니다.
 낸드 플래시에는 부트로더와 임베디스 시스템을 구동시키주는 메인 바이너리가 함께 내장되어 있어요. 시피유마다 낸드 플래시를 지원하는지 확인을 해 보면 주로 낸드 플래시가 지원하는 시피유는 인터널 램이 있으며, 역할은 낸드 플래시에 있는 부트로더를 동작시키는 일이랍니다. 임베디드 시스템에 전원이 들어가면 시피유는 어떤 플래시 메모리를 사용하는지 판단하고 만약 낸드 플래시라면 낸드 컨트롤러에 의해 낸드 플래시에 있는 부트로더를 인터널램으로 자동으로 복사하고 난 후 인터널 램에 있는 부트로더를 실행한답니다. 부트로더는 낸드 플래시에 있는 메인 바이너리, 즉 임베디드 시스템을 동작시키는 메인 바이너리를 에스디램으로 복사를 한 후 임베디드 시스템이 동작하게 되지요. 
 


 
그런데 왜 낸드 플래시는 노어 플래시와 달리 플래시 내에서는 실행이 안 되는 걸까요? 반드시 에스디램으로 복사를 해야만 하는 걸까요? 왜 그럴까요? 그건 바로 낸드 플래시에는 주소가 없기 때문이랍니다.
노어 플래시와 에스디램은 주소를 표현하기 위해서 시피유와 메모리 사이에 데이타와 어드레스 라인을 연결하지만 낸드 플래시는 데이타 라인과 어드레스 라인을 연결하지 않아요. 데이타 라인과 어드레스 라인을 연결하지 않는다는 것은 그 만큼 임베디드 제품의 크기를 줄일 수가 있다는 의미와 같아요.
 
그림과 같이 몇 개의 핀에만 연결하면 되지요. 임베디드 제품을 만들 때 노어 플래시보다 작아서 제품 공간도 적게 차지하고 하드웨어적으로 라인 연결도 몇 개 안되고 더불어 용량까지 훨씬 크니 정말 좋죠. 무엇보다도 최고인 것은 단가가 노어 플래시보다 싸다는 것죠. ㅎㅎ
낸드 플래시 컨트롤러에서 4개가 가장 중요한데 에엘이(ALE), 씨엘이(CLE), Data, Stat랍니다. ALE는 ADDRESS LATCH ENABLE의 약자로 낸드의 몇 번째 페이지이지를 알려 주기 위해서 필요하구요. CLE는 지우기, 쓰기, 읽기와 같은 명령어를 보내기 위해서 필요하답니다. Data는 낸드에 있는 내용은 바로 읽어 볼 수 가 없기 때문에 반드시 에스디램으로 복사해야 하는데, 이때 Data를 Buffer처럼 사용하기 위해서랍니다. Stat는 현재 지우기, 쓰기, 읽기 상태를 알려 주는 역할을 합니다. 웹에서 K9F5608D0D 검색을 해 보시면 낸드 데이타 시트를 찾을 수가 있을 겁니다. 데이터 시트를 열어서 확인을 해 보면 32M x 8 Bit NAND Flash Memory 되어 있어요.


이제 본격적으로 낸드 플래시를 제어하는 방법을 알아 보아요.
낸드 플래시는 주소를 표현할 때 블럭으로 표시한답니다.  블럭은 또 작은 페이지로 나누어져 있으며,  한 페이지는 크게 256byte, 2Kbyte, 4Kbyte로 나눌 수가 있어요. 읽기쓰기는 페이지단위, 지우기는 블럭단위로 동작되는게 특징이고, 낸드 플래시는 노어 플래시와 달리 베드블럭이라는 것이 처리해야 해요. 베드블럭(ECC)이라고 함은 특정 블럭이 읽기, 쓰기가 되지 않는 영역을 말하는데 일반적으로 낸드 플래시가 최초에 만들어 질 때 베드블럭이 발생하기도 하고 임베디드 제품을 사용하다가도 발생할 수가 있어요. 한번 베드블럭이 발생하면 다시는 그 블럭에 읽기, 쓰기를 할 수가 없기 때문에 그 블럭은 없다고 생각하도록 시피유에게 알려 줘야 해요. 그게 바로 베드블럭 처리랍니다.  베드블럭 처리 방식이 다양하게 있는데 일반적으로 많이 알려져 있는 방식이 XSR입니다.
 
그럼 낸드 플래시 메모리를 Erase부터 살펴보도록 하죠. 2번의 명령어가 들어가는 되네요.

 

노어 플래시처럼 주소가 필요한데 어디에다가 해야 할까요? 앞서 말씀 드린바와 같이 낸드 플래시는 주소가 없기 때문에 다른 곳에다 해야 되요. 바로 낸드 플래시 컨트롤러에다 말이죠.
 
그럼 본격적으로 지우기 동작부터 살펴봐요.
우선 낸드 플래시 데이타 시티를 살펴보니 지우기 동작은 2번의 명령을 보내면 되군요. 여기서 주의해야 될 사항이 있는데요. CLE는 2번이지만 ALE에도 몇 번째의 페이지를 선택할지에 대한 정보를 넣어 줘야 해요.
ALE에 페이지 정보는 어떻게 줘야 할까요? 낸드 플래시 데이타 시트를 보니 다음과 같은 그림이 있어서 살펴보니 낸드 플래시에 페이지 정보를 주기 위해서는 3번 명령.(1st Cycle ~ 3rd Cycle)이 필요하네요
 


 페이지정보는 2nd, 3th Cycle에서 정해 진다고 하니 최종 지우기 동작은 명령어 2번, 페이지 정보 2번 해서 4번 동작을 하면 됩니다.

하드웨어 디버거로 지우기 동작을 해 보면 다음과 같아요.
 
Local &NFCMD &NFADDR &NFDATA &NFSTAT
&NFCMD=0x4E000004
&NFADDR=0x4E000008
&NFDATA=0x4E00000C
&NFSTAT=0x4E000010
 
Data.Set &NFCMD %w 0x60                           // 1st Bus Cycle
Data.Set &NFADDR %w ((0x0>> 9) & 0xFF)      //  1st Bus Cycle
Data.Set &NFADDR %w ((0x0>> 17) & 0xFF)    //  2st Bus Cycle
Data.Set &NFCMD %w 0xD0                          //  2st Bus Cycle
 
씨 프로그램으로 구현을 하면 다음과 같아요.
 
#define NFCMD                   *(volatile unsigned char *)(0x4E000004)
#define NFADDR                  *(volatile unsigned char *)(0x4E000008)
#define NFDATA                  *(volatile unsigned char *)(0x4E00000C)
#define NFSTAT                  *(volatile unsigned char *)(0x4E000010)
#define NFEnable()              *(volatile unsigned long *)(0x4E000000) &= ~(1<<11)
#define NFDisable()             *(volatile unsigned long *)(0x4E000000) |=  (1<<11)
#define CMD_READ0               0x00
#define CMD_READ1               0x01
#define CMD_READ2               0x50
#define CMD_BLOCK_ERASE         0x60
#define CMD_READ_STATUS         0x70
 
void erase (void)
{
 
       row = theParam->start_addr;
       len = theParam->size >> 14;
 
        NFEnable();
 
        NFCMD  = CMD_BLOCK_ERASE;
        NFADDR = (row >> 9) & 0xFF;
        NFADDR = (row >> 17) & 0xFF;
        NFCMD  = 0xD0;
}
 
이제 쓰기 동작을 해 보아요. 지우기와 마찬가지로 명령어 2번에 페이지 정보 3번이 필요해요.

 

하드웨어 디버거로 쓰기 동작을 해 보면 다음과 같아요.
 
Local &NFCMD &NFADDR &NFDATA &NFSTAT &addr &col &row
&NFCMD=0x4E000004
&NFADDR=0x4E000008
&NFDATA=0x4E00000C
&NFSTAT=0x4E000010
&addr=0x0
&col=(&addr)&0xFF
&row=(&addr>>9)
 
Data.Set &NFCMD %w 0x80                           // 1st Bus Cycle
Data.Set &NFADDR %w &col                           //  1st Bus Cycle
Data.Set &NFADDR %w ((&row)&0xFF)             //  2st Bus Cycle
Data.Set &NFADDR %w ((&row)>>8)&0xFF)     //  3st Bus Cycle
 
data.copy 0x0++512 &NFDATA
Data.Set &NFCMD %w 0xD0                          //  2st Bus Cycle
 씨 프로그램으로 구현을 한다면,
 
int page_program (int dst, int src, int len)
{
    int col = (dst) & 0xFF;
    int row = (dst >> 9);
 
    if (len > 512)
        len = 512;
 
    NFEnable();
    NFCMD  = 0x80;
    NFADDR = (col);              // column
    NFADDR = (row)      & 0xFF;  // row
    NFADDR = (row >> 8) & 0xFF;  // row
    for (col = 0; col < len; col++)
    {
        NFDATA = ((char *)src)[col];
    }
    NFCMD  = 0x10;
 
낸드 플래시에 있는 내용을 보려면 반드시 에스디램으로 복사한 후 최종적으로 에스디램을 덤프해서 봐야 해요.

 
void test (int src, int dst, int len)
{
    int col = src & 0x1FF;
    int row = (src >> 9);
    NFEnable();
    NFCMD   = col & 0xFF;
    NFADDR  = col >> 8;             // column
    NFADDR  = (row)      & 0xFF;    // row
    NFADDR  = (row >> 8) & 0xFF;    // row
 
            *(unsigned char *)(dst + (row << 9) + col) = NFDATA;
 }
 


 ㅎㅎ Season2의 Flash Memory Control하기 를 참고해 보시는 것도 좋을 것 같다는 의견 내 BoA요~

by 히언 | 2010/03/28 22:15 | SOTO Story | 트랙백 | 핑백(2) | 덧글(12)

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

... 203 노어 플래시 (NOR FLASH)가 뭐죠? 204 낸드플래시(NAND Flash)가 뭐죠? 205 에스디램(SDRAM)이 뭐죠? &n ... more

Linked at 더러운 북극토끼님의 이글루입니.. at 2015/10/07 15:31

... ... more

Commented by 히언 at 2010/03/28 23:28
얏호 멋진데요.
Commented by soto at 2010/03/29 08:51
감사합니다. ~~!!
Commented by ruring at 2010/03/29 14:19
ㅎ_ㅎ! 공부하다 가욤 ㅎㅎ
Commented by soto at 2010/03/30 07:02
네. 감사합니다.~~!!
Commented by Wn at 2010/03/31 01:25
글 보면서 열공하고 있습니다.
다음이 기대됩니다.
고맙습니다.
Commented by soto at 2010/03/31 06:49
도움이 되셨으면 좋겠습니다. ㅎㅎ
Commented by HAN at 2010/03/31 01:33
짝짝짝!!!
정말 친절한 임베디드 시스템 이네요^^
Commented by soto at 2010/03/31 06:50
친절한 강좌가 되도록 항상 노력할게요. *^^*
Commented by bule at 2010/04/01 23:08
전공책이 이처럼 만 되어 있어도 공부할 맛이 날텐데...
잘 보고 있습니다.
Commented by soto at 2010/04/02 15:32
저도 비슷한 생각을 많이 했었어요. ^^
Commented by 수진 at 2010/04/07 23:34
잘 보고 그냥 휙 가기가 오늘은 뭐하네요.
언제나 잘 보고 또 연습합니다.
수고요~~
Commented by soto at 2010/04/12 17:11
감사합니다. ^^; 궁금한 내용이 있으시면 글 남겨 주세요.
※ 이 포스트는 더 이상 덧글을 남길 수 없습니다.

◀ 이전 페이지          다음 페이지 ▶