TwlIPL/build/tests/Shared2File/src/main.c
yosiokat 14f8a1b781 アプリ間共有ファイルテストを追加。
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@1537 b08762b0-b915-fc4b-9d8c-17b2551a87ff
2008-05-27 07:30:29 +00:00

491 lines
14 KiB
C

/*---------------------------------------------------------------------------*
Project: TwlSDK - nandApp - demos - backup
File: main.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <twl.h>
#include <DEMO.h>
static void PrintBootType();
static void InitDEMOSystem();
static void InitInteruptSystem();
static void InitAllocSystem();
static void InitFileSystem();
static char* LoadFile(const char* path);
static BOOL SaveFile(const char* path, void* pData, u32 size);
static u32 GetCounter(const char* root);
static void SetCounter(const char* root, u32 counter);
static void PrintBackup(const char* root);
static BOOL AddBackup(const char* root);
static void PrintAndAddBackup(const char* root);
// OS_Printfのフック関数
#ifndef SDK_FINALROM
void OS_Printf(const char *fmt, ...)
{
char dst[256];
int ret;
va_list va;
va_start(va, fmt);
ret = OS_VSPrintf(dst, fmt, va);
va_end(va);
OS_PutString(dst);
}
#endif
/*---------------------------------------------------------------------------*
Name: TwlMain
Description: メイン関数です。
Arguments: なし。
Returns: なし。
*---------------------------------------------------------------------------*/
void TwlMain(void)
{
OS_Init();
RTC_Init();
InitInteruptSystem();
InitFileSystem();
InitAllocSystem();
InitDEMOSystem();
OS_Printf("*** start nandApp demo\n");
OS_Printf("Build:%s %s\n", __DATE__, __TIME__);
PrintBootType();
// Shared2 ファイルは NAND 上に保存されます。
// そのため使用する API は FS API となり、
// ファイルシステムとしてアクセスすることができます。
{
// 「shared2」は アプリ間で共有できるファイルのアーカイブ名です。
OS_Printf("Shared2 file %04x:\n", *(u16 *)( HW_TWL_ROM_HEADER_BUF + 0x020c ) );
PrintAndAddBackup("shared2:");
OS_Printf("\n");
}
OS_Printf("*** End of demo\n");
// ランチャーに戻れるように、
// 終了しない
for (;;)
{
// フレーム更新。
{
DEMO_DrawFlip();
OS_WaitVBlankIntr();
}
}
OS_Terminate();
}
/*---------------------------------------------------------------------------*
Name: LoadFile
Description: 内部でメモリを確保しファイルを読み込みます。
Arguments: path: 読み込むファイルのパス。
Returns: ファイルが存在するならファイルの内容が読み込まれた
内部で確保したバッファへのポインタを返します。
このポインタは FS_Free で解放する必要があります。
*---------------------------------------------------------------------------*/
static char* LoadFile(const char* path)
{
FSFile f;
BOOL bSuccess;
char* pBuffer;
u32 fileSize;
s32 readSize;
FS_InitFile(&f);
bSuccess = FS_OpenFileEx(&f, path, FS_FILEMODE_R);
if( ! bSuccess )
{
return NULL;
}
fileSize = FS_GetFileLength(&f);
pBuffer = (char*)OS_Alloc(fileSize + 1);
SDK_POINTER_ASSERT(pBuffer);
readSize = FS_ReadFile(&f, pBuffer, (s32)fileSize);
SDK_ASSERT( readSize == fileSize );
bSuccess = FS_CloseFile(&f);
SDK_ASSERT( bSuccess );
pBuffer[fileSize] = '\0';
return pBuffer;
}
/*---------------------------------------------------------------------------*
Name: SaveFile
Description: ファイルを作成しデータを書き込みます。
途中のディレクトリは作成しません。
Arguments: path: 作成するファイルのパス。
pData: 書き込むデータ。
size: 書き込むデータのサイズ。
Returns: 成功すればTRUE
*---------------------------------------------------------------------------*/
static BOOL SaveFile(const char* path, void* pData, u32 size)
{
FSFile f;
BOOL bSuccess;
FSResult fsResult;
s32 writtenSize;
FS_InitFile(&f);
FS_CreateFile(path, (FS_PERMIT_R|FS_PERMIT_W));
bSuccess = FS_OpenFileEx(&f, path, FS_FILEMODE_W);
if (bSuccess == FALSE)
{
FSResult res = FS_GetArchiveResultCode(path);
OS_Printf("Failed create file:%d\n", res);
return FALSE;
}
SDK_ASSERT( bSuccess );
fsResult = FS_SetFileLength(&f, 0);
SDK_ASSERT( fsResult == FS_RESULT_SUCCESS );
writtenSize = FS_WriteFile(&f, pData, (s32)size);
SDK_ASSERT( writtenSize == size );
bSuccess = FS_CloseFile(&f);
SDK_ASSERT( bSuccess );
return TRUE;
}
/*---------------------------------------------------------------------------*
Name: GetCounter
Description: /counter.bin に保存されているカウンタ値を読み込みます。
Arguments: root: counter.bin が保存されているディレクトリのパス。
Returns: カウンタ値を返します。
/counter.bin が存在しない場合は 0 を返します。
*---------------------------------------------------------------------------*/
static u32 GetCounter(const char* root)
{
char path[FS_FILE_NAME_MAX];
char* pBuffer;
u32 counter = 0;
STD_TSNPrintf(path, sizeof(path), "%s/counter.bin", root);
pBuffer = LoadFile(path);
if( pBuffer != NULL )
{
counter = MI_LoadLE32(pBuffer);
OS_Free(pBuffer);
}
OS_Printf("%s counter is %d.\n", root, counter);
return counter;
}
/*---------------------------------------------------------------------------*
Name: SetCounter
Description: /counter.bin にカウンタ値を保存します。
ファイルが無い場合は作成します。
Arguments: root: counter.bin を保存するディレクトリのパス。
counter: 保存するカウンタ値。
Returns: なし。
*---------------------------------------------------------------------------*/
static void SetCounter(const char* root, u32 counter)
{
char path[FS_FILE_NAME_MAX];
STD_TSNPrintf(path, sizeof(path), "%s/counter.bin", root);
(void)SaveFile(path, &counter, sizeof(counter));
}
/*---------------------------------------------------------------------------*
Name: PrintBackup
Description: 指定されたディレクトリの内容を print します。
サブディレクトリの内容は print しません。
Arguments: root: 対象のディレクトリのパス。
Returns: なし。
*---------------------------------------------------------------------------*/
static void PrintBackup(const char* root)
{
FSFile dir;
FSDirectoryEntryInfo entry;
BOOL bSuccess;
int numEntry = 0;
FS_InitFile(&dir);
bSuccess = FS_OpenDirectory(&dir, root, FS_FILEMODE_R);
if( bSuccess )
{
while( FS_ReadDirectory(&dir, &entry) )
{
// 自分や親を指すエントリはスキップします
if( (STD_CompareString(entry.longname, ".") == 0)
|| (STD_CompareString(entry.longname, "..") == 0) )
{
continue;
}
if( (entry.attributes & FS_ATTRIBUTE_IS_DIRECTORY) != 0 )
{
// ディレクトリ
OS_Printf(" d %s\n", entry.longname);
}
else
{
// ファイル
char path[FS_FILE_NAME_MAX];
char* text;
char* found_cr;
char* found_lf;
// 最初の改行までの内容を表示します。
STD_TSNPrintf(path, sizeof(path), "%s/%s", root, entry.longname);
text = LoadFile(path);
SDK_POINTER_ASSERT(text);
found_cr = STD_SearchString(text, "\r");
if( found_cr != NULL )
{
*found_cr = '\0';
}
found_lf = STD_SearchString(text, "\n");
if( found_lf != NULL )
{
*found_lf = '\0';
}
OS_Printf(" f %-6s %s\n", entry.longname, text);
OS_Free(text);
}
numEntry++;
}
bSuccess = FS_CloseDirectory(&dir);
SDK_ASSERT( bSuccess );
}
if( numEntry == 0 )
{
OS_TPrintf(" (no entry)\n");
}
}
/*---------------------------------------------------------------------------*
Name: AddBackup
Description: 対象のディレクトリにテスト用のディレクトリとファイルを
作成します。
Arguments: root: 対象のディレクトリのパス。
Returns: 成功すればTRUE
*---------------------------------------------------------------------------*/
static BOOL AddBackup(const char* root)
{
char path[FS_FILE_NAME_MAX];
char text[256];
u32 counter;
BOOL bSuccess;
u8 GameCode[ 5 ];
// ROMヘッダからGameCode取得
{
int i;
u8 *p = (u8 *)(HW_TWL_ROM_HEADER_BUF + 0x0233 );
MI_CpuClear8( GameCode, sizeof(GameCode) );
for( i = 0; i < 4; i++ ) {
GameCode[ i ] = *p--;
}
}
// ファイルに書き込む内容を生成します。
STD_TSNPrintf(text, sizeof(text), ": generated by %s", GameCode );
// ファイル名の生成に使用するカウンタ値を取得/更新します。
counter = GetCounter(root);
counter++;
SetCounter(root, counter);
// ディレクトリを作成
STD_TSNPrintf(path, sizeof(path), "%s/dir_%d", root, counter);
bSuccess = FS_CreateDirectory(path, (FS_PERMIT_R|FS_PERMIT_W));
if (bSuccess == FALSE)
{
FSResult res = FS_GetArchiveResultCode(path);
OS_Printf("Failed create directory:%d\n", res);
return FALSE;
}
SDK_ASSERT( bSuccess );
// ファイルを作成
STD_TSNPrintf(path, sizeof(path), "%s/file_%d", root, counter);
(void)SaveFile(path, text, (u32)STD_GetStringLength(text));
return TRUE;
}
/*---------------------------------------------------------------------------*
Name: PrintAndAddBackup
Description: 対象のディレクトリの内容を表示した後、テスト用の
ディレクトリとファイルを作成します。
Arguments: root: 対象のディレクトリのパス。
Returns: なし。
*---------------------------------------------------------------------------*/
static void PrintAndAddBackup(const char* root)
{
PrintBackup(root);
(void)AddBackup(root);
}
/*---------------------------------------------------------------------------*
Name: PrintBootType
Description: BootType を print します。
Arguments: なし。
Returns: なし。
*---------------------------------------------------------------------------*/
static void PrintBootType()
{
const OSBootType btype = OS_GetBootType();
switch( btype )
{
case OS_BOOTTYPE_ROM: OS_TPrintf("OS_GetBootType = OS_BOOTTYPE_ROM\n"); break;
case OS_BOOTTYPE_NAND: OS_TPrintf("OS_GetBootType = OS_BOOTTYPE_NAND\n"); break;
default:
{
OS_Warning("unknown BootType(=%d)", btype);
}
break;
}
}
/*---------------------------------------------------------------------------*
Name: InitDEMOSystem
Description: コンソールの画面出力用の表示設定を行います。
Arguments: なし。
Returns: なし。
*---------------------------------------------------------------------------*/
static void InitDEMOSystem()
{
// 画面表示の初期化。
DEMOInitCommon();
DEMOInitVRAM();
DEMOInitDisplayBitmap();
DEMOHookConsole();
DEMOSetBitmapTextColor(GX_RGBA(31, 31, 0, 1));
DEMOSetBitmapGroundColor(DEMO_RGB_CLEAR);
DEMOStartDisplay();
}
/*---------------------------------------------------------------------------*
Name: InitInteruptSystem
Description: 割り込みを初期化します。
Arguments: なし。
Returns: なし。
*---------------------------------------------------------------------------*/
static void InitInteruptSystem()
{
// 個別割り込みフラグを全て不許可に
(void)OS_SetIrqMask(0);
// マスター割り込みフラグを許可に
(void)OS_EnableIrq();
// IRQ 割り込みを許可します
(void)OS_EnableInterrupts();
}
/*---------------------------------------------------------------------------*
Name: InitAllocSystem
Description: ヒープを作成して OS_Alloc が使えるようにします。
Arguments: なし。
Returns: なし。
*---------------------------------------------------------------------------*/
static void InitAllocSystem()
{
void* newArenaLo;
OSHeapHandle hHeap;
// メインアリーナのアロケートシステムを初期化
newArenaLo = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
OS_SetMainArenaLo(newArenaLo);
// メインアリーナ上にヒープを作成
hHeap = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi());
OS_SetCurrentHeap(OS_ARENA_MAIN, hHeap);
}
/*---------------------------------------------------------------------------*
Name: InitFileSystem
Description: FS を初期化します。
この関数を呼び出す前に InitInteruptSystem() が
呼ばれている必要があります。
Arguments: なし。
Returns: なし。
*---------------------------------------------------------------------------*/
static void InitFileSystem()
{
// ARM7との通信FIFO割り込み許可
(void)OS_EnableIrqMask(OS_IE_SPFIFO_RECV);
// ファイルシステム初期化
FS_Init( FS_DMA_NOT_USE );
}