앞에서의 플래시 문서를 포함한 전체적인 플래시의 내용을 정리한 문서이다.

알아야 할 것들

  1. flash datasheet
  2. flash 관련 API

데이터 시트가 왜 필요한지 의문을 가질지도 모르겠다. 하지만, 정말 중요하다. 데이터 시트에는 플래시의 동작과 커맨드, Manufactuer Code 등 많은 정보를 가지고 있다.
또한 이 것을 보고, 현재 쓰고 있는 플래시의 방식이 top 또는 bottom 인지 알아야 한다. 아래 표의 정보를 데이터 시트를 통해 알 수 있다.

모델명 M29W160ET(T는 top 방식을 뜻함)
배속 X16(16bit access)
Manufacturer Code 0020h
Device Code 22C4h

위의 모델명을 참고하여, top 방식의 블럭을 설정하면 된다. 또한 우리는 16bit access 를 한다. 기본적으로 8bit 도 지원하지만, CPU 칩 회로도 상 불가능하다. Manufacturer, Device Code 는 플래시 테스트 프로그램을 통해서 확인할 수 있다. 데이터 시트에 나온 커맨드(명령을) 특정 번지에 넣어주면, 읽을 수 있다. 이를 통해 초기 플래시 디버깅도 가능하다.
이제 플래시를 read/write 하는 프로그램을 통해 확인해보자!!

플래시 프로그램 분석

일단 가장 기본이 되는 main.c 부터 살펴보자!!

U8 temp[20];           // 플래시에 넣을 Data 를 배열로 정의
temp[0] = 't';         // test 를 data 에 입력
temp[1] = 'e';
temp[2] = 's';
temp[3] = 't';
 
FLASH_Initx();        // 플래시 디바이스 초기화
FLASH_Open();         //  디바이스 열기
 
WriteBlock(1, temp, 4);     // 1번 블럭에 'test' 를 4 만큼 쓴다. 

위의 설명을 봐도 그렇지만, 어떤 디바이스를 사용하려면, 우선 초기화(init) 하고 열기(open)를 해주어야 한다. 이 동작이 끝나면, 이제 사용할 준비가 끝난 것이다. 그리고 나서, 플래시를 읽고 쓸수 있다. 위에서 선언해준 배열은 플래시에 쓸 데이터이다. 여기서는 'test' 라는 문자를 넣었다.

이제 위에서 호출한 함수들을 하나하나 살펴보자!!

ST_ErrorCode_t FLASH_Initx()
{
    ST_ErrorCode_t          ErrCode;
    STFLASH_InitParams_t    InitParams;
 
 
  // partition_init_heap(  &TheSystemPartition,   (U8 *)SystemMemory,   sizeof(SystemMemory));
   printf("Start flash init!\n");
 
    InitParams.DeviceType = DEVICE_TYPE;    // STFLASH_M29W160BT
 //   if ( BankNum == BANK0 )
//    {
    InitParams.BaseAddress = (U32*)0x7f800000;//STFLASH_BANK_0_BASE;  시작 주소
    InitParams.VppAddress  = (U32*)NULL;
 //   }
 
    InitParams.MinAccessWidth  = MIN_ACCESS_WIDTH;     // 16bit
    InitParams.MaxAccessWidth  = MAX_ACCESS_WIDTH;     // 16bit
    InitParams.NumberOfBlocks  = NUM_BLOCKS;
    InitParams.Blocks          = BlockData_s;          // 35
    InitParams.DriverPartition = SystemPartition;
 
    ErrCode = STFLASH_Init(FLASHDeviceName[0], &InitParams );    // ST 에서 제공하는 함수 호출
 
	if(ErrCode!=ST_NO_ERROR)
	{
		printf("Init Error!\n");
		return (ErrCode);
	}
	else
		printf("Flash init sucess!\n");
 
    STTBX_Print(("STFLASH_Init(%s)=%s\n", FLASHDeviceName[0], GetErrorText(ErrCode) ));
 
    return ( ErrCode );
 
} /* end FLASH_Init */
ST_ErrorCode_t FLASH_Open()
{
    ST_ErrorCode_t          ErrCode;
    STFLASH_OpenParams_t    OpenParams;
 
    ErrCode = STFLASH_Open(FLASHDeviceName[0], &OpenParams, &FLASHHnd);   // ST 에서 제공하는 함수 호출
 
    STTBX_Print(("STFLASH_Open(%s)=%s\n", FLASHDeviceName[0], GetErrorText(ErrCode) ));
 
	if(ErrCode!=ST_NO_ERROR)
	{
		GeneralError(ErrCode);
		printf("Open Error!\n");
		return (ErrCode);
	}
 
    return ( ErrCode );
 
} /* end FLASH_Open */
BOOL WriteBlock(U8 blockId, U8* data, U32 len)   // 몇 번째 블럭인지, 배열단위의 데이터, 길이
{
	ST_ErrorCode_t      errCode;
	U32 uWriteLen,re;
 
       errCode = STFLASH_Erase( FLASHHnd,            // ST 에서 제공한 지우는 함수
                                         0+(0x00010000*blockId),   // 위의 블럭 단위로 되어 있다.
                                         0x00010000);
	if(errCode!=ST_NO_ERROR)
	{
		GeneralError(errCode);
		printf("\nRease Error!\n");
		return false;
	}
	else
		printf("Rease Sucess Block %d\n",blockId);
 
	errCode = STFLASH_Write( FLASHHnd,          // ST 에서 제공하는 쓰는 함수
                                     0+(0x00010000*blockId),        // 블럭 단위
                                     data,
                                     len,
                                     &uWriteLen );
	if(errCode!=ST_NO_ERROR)
	{
		GeneralError(errCode);
		printf("Write Error!\n");
		return false;
	}
	else
		printf("Write Sucess Block %d  adress %x offset %x  size %d\n",blockId,0x7fe00000+(0x00010000*blockId),0x00010000*blockId,uWriteLen);
 
	for(re=0;re<len;re++)
		printf("%x ",data[re]);
	printf("\n\n");	
 
	return true;
 
}

위의 프로그램에서 볼 수 있듯이, 플래시는 블럭(block)단위로 access 한다. 그리고 반드시 write 하기 전에는 해당 블럭을 erase 한다. 내가 예전에 쓰던 프로그램은 직접 주소를 넣어서 write 하는 프로그램이다. 그 직접 주소를 넣을 때는 블럭의 맨 처음 주소를 넣어야 한다.

STFLASH_Block_t      BlockData_s[NUM_BLOCKS] =
{ { 0x00010000, STFLASH_MAIN_BLOCK },/* 0 */
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
 
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
 
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
  { 0x00010000, STFLASH_MAIN_BLOCK },
 
  { 0x00010000, STFLASH_MAIN_BLOCK },/*64k*/
  { 0x00008000, STFLASH_MAIN_BLOCK },/* 32k*/
  { 0x00002000,  STFLASH_PARAMETER_BLOCK },
  { 0x00002000,  STFLASH_PARAMETER_BLOCK },/*8k*/
  { 0x00004000,  STFLASH_BOOT_BLOCK } }; /* 16k */  /*34*/
  • computer/digitalarena/플래시_정리.txt
  • Last modified: 3 years ago
  • by likewind