01 libfat 업그레이드

원문 : http://kkamagui.springnote.com/pages/407195

 

들어가기 전에...

 

0. 시작하면서...

 홈 브루를 개발하다보면 자료를 저장하거나 데이터를 읽어올 필요가 있다. 이를 위히 FAT로 포맷된 카드에서 자료를 읽을 수 있도록 libfat라는 라이브러리를 지원한다. 하지만 최신의 장비와 같은 경우, Devkit pro에 포함된 기본 libfat.a 라이브러리에서 지원하지 않을 가능성이 크다.

 내가 가진 장비를 지원하기위해 libfat 라이브러리를 업그레이드 하는 과정을 살펴보자.

 

1. libfat 소스 다운로드 및 링크

 개발한 홈 브루가 데이터를 읽고 쓰려면 FAT 라이브러리가 있어야 한다. 그리고 당연히 하드웨어적인 섹터 IO를 수행하는 라이브러리가 있어야 한다. 기존의 Devkit Pro에 포함된 libfat.a가 IO를 지원하지 않는다는 가정하에 http://sourceforge.net/project/downloading.php?group_id=114505&use_mirror=nchc&filename=libfat-src-20070127.tar.bz2&12016483 에서 libfat 소스를 다운받아서 추가한 후 컴파일 하는 과정을 살펴보자.

 일단 현재( 2007/08/08 21:04:06 )까지 최신 버전인 libfat-src-20070127.tar.tar 파일을 다운 받아서 devkit pro를 설치한 폴더에 압축을 푼다. 그럼 아래와 같은 폴더 구조를 가질 것이다.

libfat1.PNG

 

  여기서 disk_io 폴더에 들어가서 disk.c 파일을 열고 아래와 같은 부분을 찾아본다.

  1. const IO_INTERFACE* ioInterfaces[] = {
     &_io_dldi,  // Reserved for new interfaces
    #ifdef NDS
     // Place Slot 1 (DS Card) interfaces here
     &_io_njsd, &_io_nmmc,
    #endif
     // Place Slot 2 (GBA Cart) interfaces here
     &_io_mpcf, &_io_m3cf, &_io_sccf, &_io_scsd, &_io_m3sd
    };

  위의 코드에서 보듯이 DLDI와 몇몇 장비만 추가적으로 지원한다는 것을 알 수 있다. 고로 내 장비의 이름이 위에 없다면 해당 장비를 판매하는 곳에 가서 libfat 용 파일을 Low IO를 수행하는 파일을 받아야 한다. 각 장비 개발사에 가면 아래와 같은 파일들을 구할 수 있을 것이다.

libfat2.PNG

 이제 이 파일을 disk_io 폴더에 복사해 넣고 io_r4tf.h 파일을 아래와 같이 수정한다.

  1. #ifndef IO_R4TF_H
    #define IO_R4TF_H
  2. // 'R4TF'
    #define DEVICE_TYPE_R4TF 0x46543452
  3. // 추가한 부분
    #ifdef NDS
    #define SUPPORT_R4TF
    #endif
  4. #include "disc_io.h"
  5. // 추가한 부분
    typedef IO_INTERFACE* LPIO_INTERFACE;
  6. // 수정한 부분
    extern IO_INTERFACE* R4TF_GetInterface(void);
  7. // 추가한 부분
    extern IO_INTERFACE io_r4tf;
  8. #endif

 

 그리고 disk.c 파일을 열어서 위에서 언급했던 부분을 아래와 같이 수정한다.

  1. const IO_INTERFACE* ioInterfaces[] = {
     &_io_dldi,  // Reserved for new interfaces
    #ifdef NDS
     // Place Slot 1 (DS Card) interfaces here
     &io_r4tf, //&_io_njsd, &_io_nmmc,
    #endif
     // Place Slot 2 (GBA Cart) interfaces here
     &_io_mpcf, &_io_m3cf, &_io_sccf, &_io_scsd, &_io_m3sd
    };

 

 자 이제 수정이 다 끝났으니 build를 수행할 차례이다. cmd.exe 를 실행시켜서 libfat가 있는 소스로 이동한다음 make를 입력하면 아래와 같이 컴파일 및 링크가 시작된다.

libfat3.PNG

<build 진행중>

 libfat4.PNG

<build 완료>

 

 위처럼 빌드 완료 화면이 나오지 않고 에러가 표시되면 잘못 수정한 것이므로 에러 메시지를 보고 마저 수정한 후 처리하도록 한다. 빌드가 완료되고 나면 libfat 폴더 밑의 nds 폴더 밑의 lib 폴더에 libfat.a 파일이 생긴걸 알 수 있다.

libfat5.PNG

<libfat.a 파일 정상 생성>

 

 위에서 생성된 파일을 아래와 같이 libnds 폴더 아래에 lib 폴더에 복사하면 설치가 끝난다.

libfat6.PNG

 

 

2. 테스트

 libfat 라이브러리를 빌드했으니 테스트를 한번 해보자. 아래는 directory를 탐색하고 파일을 생성해서 데이터를 쓰는 소스이다.

  1. #include <nds.h>
    #include <fat.h>
    #include <stdio.h>
    #include <sys/dir.h>
  2. bool TestFile( void );
  3. int main(void)
    {
        // LCD Core를 켠다.
        powerON( POWER_ALL_2D );
  4.     // 파일을 테스트 한다.
        TestFile();
  5.     while(1)
        {
            // 아무 interrupt나 대기한다.
            swiWaitForIRQ();
        }
       
        return 0;
    }
  6. /**
        파일을 테스트 한다.
    */
    bool TestFile( void )
    {
        char vcBuffer[ 256 ];
        FILE* fp;
        struct stat st;
        char filename[256];
        int i;
  7.     if( ( fatInitDefault() == false ) )
        {
            return false;
        }
  8.     // Directory Test
        DIR_ITER* dir;
        dir = diropen("/");
        if( dir == NULL )
        { 
            //iprintf("Unable to open the directory.\n");
        }
        else
        { 
            i = 0;
            while( dirnext( dir, filename, &st ) == 0 )
            {  
                // st.st_mode & S_IFDIR indicates a directory  
                //sprintf( vcBuffer, "%s: %s",
                //    (st.st_mode & S_IFDIR ? " DIR" : "FILE"), filename);
            }
        }
  9.     dirclose( dir );
  10.         
        // File Test
        //fp = fopen("fat1:/a.txt", "wb+");
        fp = fopen("/a.txt", "wb+");
        if( fp == NULL )
        {
            return false;
        }
  11.     // 읽기 테스트
        if( fread( vcBuffer, 1, sizeof( vcBuffer), fp ) != 0 )
        {
            // TODO Something...
        }
           
        if( fwrite( "testfile", 1, 8, fp ) <= 0 )
        {
            fclose( fp );
            return false;
        }
       
        fclose( fp );
        return true;
    }

 위에서 보는 것과 같이 파일 관련 함수인 fopen/fread/fwrite/fclose 함수와 디렉토리 관련 함수인 diropen/dirnext/dirclose를 그대로 사용할 수 있음을 알 수 있다.

 실행 결과 나온 프로그램을 NDS에서 실행하면 그냥 하얀 화면만 뜰 것이다. 그대로 종료한 후 다시 디스크를 열어보면 a.txt 파일이 생기고 그 안에 "testfile"이라는 내용이 들어있음을 확인 할 수 있다. 자세한 소스는 첨부 파일로 추가했다.

 만약 실행했는데, 정상적으로 파일이 생성되지 않았다면 라이브러리가 정상적으로 생성되지 않았기 때문이므로 위의 순서대로 다시 빌드해서 사용하도록 하자.

 

3. 첨부

 

 

 

이 글은 스프링노트에서 작성되었습니다.

+ Recent posts