1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - FS - demos - async
3 File: main.c
4
5 Copyright 2003-2008 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Date:: 2008-10-02 #$
14 $Rev: 8827 $
15 $Author: yosizaki $
16 *---------------------------------------------------------------------------*/
17
18 #include <nitro.h>
19
20
21 // Behavioral test of asynchronous FS operations
22
23 enum
24 {
25 data_00,
26 data_ff,
27 data_inc,
28 data_dec,
29 datamode_max
30 };
31
32 #define TASK_THREAD_MAX 4
33 #define TASK_REPEAT_TIMES 1
34
35 typedef struct
36 {
37 OSThread thread;
38 u8 stack[4096] ATTRIBUTE_ALIGN(32);
39 u8 buf[CARD_ROM_PAGE_SIZE] ATTRIBUTE_ALIGN(32);
40 int mode;
41 u32 priority;
42 u8 padding[24];
43 }
44 TaskThread;
45
46
47 static TaskThread task_thread[TASK_THREAD_MAX] ATTRIBUTE_ALIGN(32);
48 static u32 total_read_size = 0;
49
50 // A task that opens a file and continues to read
AsyncAccessTask(void * p)51 static void AsyncAccessTask(void *p)
52 {
53 TaskThread *const pt = (TaskThread *) p;
54 int i;
55 int repeat;
56 int count;
57 int total_size;
58 BOOL ret;
59 FSFile file;
60 count = 0;
61 repeat = 0;
62 total_size = 0;
63 for (;;)
64 {
65 switch (pt->mode)
66 {
67 case data_00:
68 ret = FS_OpenFileEx(&file, "rom:/00.bin", FS_FILEMODE_R);
69 break;
70 case data_ff:
71 ret = FS_OpenFileEx(&file, "rom:/ff.bin", FS_FILEMODE_R);
72 break;
73 case data_inc:
74 ret = FS_OpenFileEx(&file, "rom:/inc.bin", FS_FILEMODE_R);
75 break;
76 case data_dec:
77 ret = FS_OpenFileEx(&file, "rom:/dec.bin", FS_FILEMODE_R);
78 break;
79 default:
80 ret = FALSE;
81 break;
82 }
83 SDK_ASSERT(ret);
84 for (;;)
85 {
86 int n = FS_ReadFile(&file, pt->buf, sizeof(pt->buf));
87 SDK_ASSERT(n >= 0);
88 if (n == 0)
89 break;
90 switch (pt->mode)
91 {
92 case data_00:
93 for (i = 0; i < n; ++i)
94 {
95 SDK_ASSERT(pt->buf[i] == 0x00);
96 }
97 break;
98 case data_ff:
99 for (i = 0; i < n; ++i)
100 {
101 SDK_ASSERT(pt->buf[i] == 0xFF);
102 }
103 break;
104 case data_inc:
105 for (i = 0; i < n; ++i)
106 {
107 SDK_ASSERT(pt->buf[i] == (u8)i);
108 }
109 break;
110 case data_dec:
111 for (i = 0; i < n; ++i)
112 {
113 SDK_ASSERT(pt->buf[i] == (u8)~i);
114 }
115 break;
116 }
117 total_size += n;
118 }
119 ret = FS_CloseFile(&file);
120 SDK_ASSERT(ret);
121 ++count;
122 if (++repeat >= TASK_REPEAT_TIMES)
123 {
124 u32 current_total;
125 OSIntrMode bak_psr = OS_DisableInterrupts();
126 total_read_size += total_size;
127 current_total = total_read_size;
128 total_size = 0;
129 OS_TPrintf("thread[%d](priority=%2d) : %8d times done. (mode=%d) ... total %8d byte\n",
130 pt - task_thread, pt->priority, count, pt->mode, current_total);
131 (void)OS_RestoreInterrupts(bak_psr);
132 repeat = 0;
133 if (++pt->mode >= datamode_max)
134 {
135 pt->mode = data_00;
136 }
137 }
138 }
139 }
140
NitroMain(void)141 void NitroMain(void)
142 {
143 // Initialize the OS and memory allocator
144 OS_Init();
145 {
146 OSHeapHandle hh;
147 void *tmp;
148 tmp = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
149 OS_SetArenaLo(OS_ARENA_MAIN, tmp);
150 hh = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi());
151 if (hh < 0)
152 {
153 OS_TPanic("ARM9: Fail to create heap...\n");
154 }
155 (void)OS_SetCurrentHeap(OS_ARENA_MAIN, hh);
156 }
157 (void)OS_EnableIrq();
158 // Initialize the FS
159 FS_Init(3);
160 {
161 u32 need_size = FS_GetTableSize();
162 void *p_table = OS_Alloc(need_size);
163 SDK_ASSERT(p_table != NULL);
164 (void)FS_LoadTable(p_table, need_size);
165 }
166
167 OS_TPrintf("\n"
168 "++++++++++++++++++++++++++++++++++++++++\n"
169 "test : create %d threads to check asynchronous access ... \n\n", TASK_THREAD_MAX);
170 {
171 int i;
172 // Create multiple threads that continue to read a file
173 for (i = 0; i < TASK_THREAD_MAX; ++i)
174 {
175 TaskThread * pt = &task_thread[i];
176 pt->mode = data_00 + i;
177 pt->priority = (u32)(OS_THREAD_LAUNCHER_PRIORITY - (pt - task_thread));
178 OS_CreateThread(&pt->thread,
179 AsyncAccessTask, pt,
180 pt->stack + sizeof(pt->stack), sizeof(pt->stack), pt->priority);
181 OS_WakeupThreadDirect(&pt->thread);
182 }
183 }
184
185 // As for the rest, a log will continue to be output for each thread
186 for (;;)
187 {
188 OS_Halt();
189 }
190
191 }
192