]> git.sur5r.net Git - freertos/blob - FreeRTOS-Labs/Demo/Common/FreeRTOS_Plus_FAT_Demos/CreateAndVerifyExampleFiles.c
Add the Labs projects provided in the V10.2.1_191129 zip file.
[freertos] / FreeRTOS-Labs / Demo / Common / FreeRTOS_Plus_FAT_Demos / CreateAndVerifyExampleFiles.c
1 /*\r
2     FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.\r
3     All rights reserved\r
4 \r
5     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     This file is part of the FreeRTOS distribution.\r
8 \r
9     FreeRTOS is free software; you can redistribute it and/or modify it under\r
10     the terms of the GNU General Public License (version 2) as published by the\r
11     Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
12 \r
13     ***************************************************************************\r
14     >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
15     >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
16     >>!   obliged to provide the source code for proprietary components     !<<\r
17     >>!   outside of the FreeRTOS kernel.                                   !<<\r
18     ***************************************************************************\r
19 \r
20     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
21     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
22     FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
23     link: http://www.freertos.org/a00114.html\r
24 \r
25     ***************************************************************************\r
26      *                                                                       *\r
27      *    FreeRTOS provides completely free yet professionally developed,    *\r
28      *    robust, strictly quality controlled, supported, and cross          *\r
29      *    platform software that is more than just the market leader, it     *\r
30      *    is the industry's de facto standard.                               *\r
31      *                                                                       *\r
32      *    Help yourself get started quickly while simultaneously helping     *\r
33      *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
34      *    tutorial book, reference manual, or both:                          *\r
35      *    http://www.FreeRTOS.org/Documentation                              *\r
36      *                                                                       *\r
37     ***************************************************************************\r
38 \r
39     http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading\r
40     the FAQ page "My application does not run, what could be wrong?".  Have you\r
41     defined configASSERT()?\r
42 \r
43     http://www.FreeRTOS.org/support - In return for receiving this top quality\r
44     embedded software for free we request you assist our global community by\r
45     participating in the support forum.\r
46 \r
47     http://www.FreeRTOS.org/training - Investing in training allows your team to\r
48     be as productive as possible as early as possible.  Now you can receive\r
49     FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
50     Ltd, and the world's leading authority on the world's leading RTOS.\r
51 \r
52     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
53     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
54     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
55 \r
56     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
57     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
58 \r
59     http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
60     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
61     licenses offer ticketed support, indemnification and commercial middleware.\r
62 \r
63     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
64     engineered and independently SIL3 certified version for use in safety and\r
65     mission critical applications that require provable dependability.\r
66 \r
67     1 tab == 4 spaces!\r
68 */\r
69 \r
70 \r
71 /*\r
72  * Create and verify a few example files using both line based and character\r
73  * based reads and writes.\r
74  */\r
75 \r
76 /* FreeRTOS+FAT headers. */\r
77 #include "ff_headers.h"\r
78 #include "ff_stdio.h"\r
79 \r
80 /* FTP headers. */\r
81 #include "FreeRTOSIPConfig.h"\r
82 \r
83 /* Demo headers. */\r
84 #include "DefaultWebPages.h"\r
85 \r
86 /* The number of bytes read/written to the example files at a time. */\r
87 #define fsRAM_BUFFER_SIZE                               200\r
88 \r
89 /* The number of bytes written to the file that uses f_putc() and f_getc(). */\r
90 #define fsPUTC_FILE_SIZE                                100\r
91 \r
92 /*\r
93  * Create a set of example files in the root directory of the volume using\r
94  * ff_fwrite().\r
95  */\r
96 static void prvCreateDemoFilesUsing_ff_fwrite( const char *pcMountPath );\r
97 \r
98 /*\r
99  * Use ff_fread() to read back and verify the files that were created by\r
100  * prvCreateDemoFilesUsing_ff_fwrite().\r
101  */\r
102 static void prvVerifyDemoFileUsing_ff_fread( void );\r
103 \r
104 /*\r
105  * Create an example file in a sub-directory using f_putc().\r
106  */\r
107 static void prvCreateDemoFileUsing_ff_fputc( const char *pcMountPath );\r
108 \r
109 /*\r
110  * Use f_getc() to read back and verify the file that was created by\r
111  * prvCreateDemoFileUsing_f_putc().\r
112  */\r
113 static void prvVerifyDemoFileUsing_ff_fgetc( const char *pcMountPath );\r
114 \r
115 /*\r
116  * Create the configHTTP_ROOT directory, and add a basic default web page.\r
117  */\r
118 #if( ipconfigUSE_HTTP == 1 )\r
119 \r
120         #ifndef configHTTP_ROOT\r
121                 #error configHTTP_ROOT must be defined to a string that holds the directory to be used as the root for the HTTP server\r
122         #endif\r
123 \r
124         static void prvCreateDefaultWebPage( void );\r
125 \r
126 #endif /* ipconfigUSE_HTTP */\r
127 \r
128 /* Names of directories that are created. */\r
129 static const char *pcDirectory1 = "SUB1", *pcDirectory2 = "SUB2", *pcFullPath = "/SUB1/SUB2";\r
130 \r
131 /*-----------------------------------------------------------*/\r
132 \r
133 void vCreateAndVerifyExampleFiles( const char *pcMountPath )\r
134 {\r
135         /* Create and verify a few example files using both line based and character\r
136         based reads and writes. */\r
137         prvCreateDemoFilesUsing_ff_fwrite( pcMountPath );\r
138         prvVerifyDemoFileUsing_ff_fread();\r
139         prvCreateDemoFileUsing_ff_fputc( pcMountPath );\r
140         prvVerifyDemoFileUsing_ff_fgetc( pcMountPath );\r
141 \r
142         #if( ipconfigUSE_HTTP == 1 )\r
143         {\r
144                 prvCreateDefaultWebPage();\r
145         }\r
146         #endif /* ipconfigUSE_HTTP */\r
147 }\r
148 /*-----------------------------------------------------------*/\r
149 \r
150 static void prvCreateDemoFilesUsing_ff_fwrite( const char *pcMountPath )\r
151 {\r
152 BaseType_t xFileNumber, xWriteNumber;\r
153 const BaseType_t xMaxFiles = 5;\r
154 int32_t lItemsWritten;\r
155 int32_t lResult;\r
156 FF_FILE *pxFile;\r
157 char *pcRAMBuffer, *pcFileName;\r
158 \r
159         /* Allocate buffers used to hold date written to/from the disk, and the\r
160         file names. */\r
161         pcRAMBuffer = ( char * ) pvPortMalloc( fsRAM_BUFFER_SIZE );\r
162         pcFileName = ( char * ) pvPortMalloc( ffconfigMAX_FILENAME );\r
163         configASSERT( pcRAMBuffer );\r
164         configASSERT( pcFileName );\r
165 \r
166         /* Ensure in the root of the mount being used. */\r
167         lResult = ff_chdir( pcMountPath );\r
168         configASSERT( lResult >= 0 );\r
169 \r
170         /* Create xMaxFiles files.  Each created file will be\r
171         ( xFileNumber * fsRAM_BUFFER_SIZE ) bytes in length, and filled\r
172         with a different repeating character. */\r
173         for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ )\r
174         {\r
175                 /* Generate a file name. */\r
176                 snprintf( pcFileName, ffconfigMAX_FILENAME, "root%03d.txt", ( int ) xFileNumber );\r
177 \r
178                 /* Obtain the current working directory and print out the file name and\r
179                 the     directory into which the file is being written. */\r
180                 ff_getcwd( pcRAMBuffer, fsRAM_BUFFER_SIZE );\r
181                 FF_PRINTF( "Creating file %s in %s\n", pcFileName, pcRAMBuffer );\r
182 \r
183                 /* Open the file, creating the file if it does not already exist. */\r
184                 pxFile = ff_fopen( pcFileName, "w" );\r
185                 configASSERT( pxFile );\r
186 \r
187                 /* Fill the RAM buffer with data that will be written to the file.  This\r
188                 is just a repeating ascii character that indicates the file number. */\r
189                 memset( pcRAMBuffer, ( int ) ( '0' + xFileNumber ), fsRAM_BUFFER_SIZE );\r
190 \r
191                 /* Write the RAM buffer to the opened file a number of times.  The\r
192                 number of times the RAM buffer is written to the file depends on the\r
193                 file number, so the length of each created file will be different. */\r
194                 for( xWriteNumber = 0; xWriteNumber < xFileNumber; xWriteNumber++ )\r
195                 {\r
196                         lItemsWritten = ff_fwrite( pcRAMBuffer, fsRAM_BUFFER_SIZE, 1, pxFile );\r
197                         configASSERT( lItemsWritten == 1 );\r
198                 }\r
199 \r
200                 /* Close the file so another file can be created. */\r
201                 ff_fclose( pxFile );\r
202         }\r
203 \r
204         vPortFree( pcRAMBuffer );\r
205         vPortFree( pcFileName );\r
206 }\r
207 /*-----------------------------------------------------------*/\r
208 \r
209 static void prvVerifyDemoFileUsing_ff_fread( void )\r
210 {\r
211 BaseType_t xFileNumber, xReadNumber;\r
212 const BaseType_t xMaxFiles = 5;\r
213 size_t xItemsRead, xChar;\r
214 FF_FILE *pxFile;\r
215 char *pcRAMBuffer, *pcFileName;\r
216 \r
217         /* Allocate buffers used to hold date written to/from the disk, and the\r
218         file names. */\r
219         pcRAMBuffer = ( char * ) pvPortMalloc( fsRAM_BUFFER_SIZE );\r
220         pcFileName = ( char * ) pvPortMalloc( ffconfigMAX_FILENAME );\r
221         configASSERT( pcRAMBuffer );\r
222         configASSERT( pcFileName );\r
223 \r
224         /* Read back the files that were created by\r
225         prvCreateDemoFilesUsing_ff_fwrite(). */\r
226         for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ )\r
227         {\r
228                 /* Generate the file name. */\r
229                 snprintf( pcFileName, ffconfigMAX_FILENAME, "root%03d.txt", ( int ) xFileNumber );\r
230 \r
231                 /* Obtain the current working directory and print out the file name and\r
232                 the     directory from which the file is being read. */\r
233                 ff_getcwd( pcRAMBuffer, fsRAM_BUFFER_SIZE );\r
234                 FF_PRINTF( "Reading file %s from %s\n", pcFileName, pcRAMBuffer );\r
235 \r
236                 /* Open the file for reading. */\r
237                 pxFile = ff_fopen( pcFileName, "r" );\r
238                 configASSERT( pxFile );\r
239 \r
240                 /* Read the file into the RAM buffer, checking the file contents are as\r
241                 expected.  The size of the file depends on the file number. */\r
242                 for( xReadNumber = 0; xReadNumber < xFileNumber; xReadNumber++ )\r
243                 {\r
244                         /* Start with the RAM buffer clear. */\r
245                         memset( pcRAMBuffer, 0x00, fsRAM_BUFFER_SIZE );\r
246 \r
247                         xItemsRead = ff_fread( pcRAMBuffer, fsRAM_BUFFER_SIZE, 1, pxFile );\r
248                         configASSERT( xItemsRead == 1 );\r
249 \r
250                         /* Check the RAM buffer is filled with the expected data.  Each\r
251                         file contains a different repeating ascii character that indicates\r
252                         the number of the file. */\r
253                         for( xChar = 0; xChar < fsRAM_BUFFER_SIZE; xChar++ )\r
254                         {\r
255                                 configASSERT( pcRAMBuffer[ xChar ] == ( '0' + ( char ) xFileNumber ) );\r
256                         }\r
257                 }\r
258 \r
259                 /* Close the file. */\r
260                 ff_fclose( pxFile );\r
261         }\r
262 \r
263         vPortFree( pcRAMBuffer );\r
264         vPortFree( pcFileName );\r
265 \r
266         /*_RB_ also test what happens when attempting to read using too large item\r
267         sizes, etc. */\r
268 }\r
269 /*-----------------------------------------------------------*/\r
270 \r
271 static void prvCreateDemoFileUsing_ff_fputc( const char *pcMountPath )\r
272 {\r
273 int32_t iReturn, iByte, iReturned;\r
274 FF_FILE *pxFile;\r
275 char *pcRAMBuffer, *pcFileName;\r
276 \r
277         /* Allocate buffers used to hold date written to/from the disk, and the\r
278         file names. */\r
279         pcRAMBuffer = ( char * ) pvPortMalloc( fsRAM_BUFFER_SIZE );\r
280         pcFileName = ( char * ) pvPortMalloc( ffconfigMAX_FILENAME );\r
281         configASSERT( pcRAMBuffer );\r
282         configASSERT( pcFileName );\r
283 \r
284         /* Obtain and print out the working directory. */\r
285         ff_getcwd( pcRAMBuffer, fsRAM_BUFFER_SIZE );\r
286         FF_PRINTF( "In directory %s\n", pcRAMBuffer );\r
287 \r
288         /* Create a sub directory. */\r
289         iReturn = ff_mkdir( pcDirectory1 );\r
290         configASSERT( iReturn == pdFREERTOS_ERRNO_NONE );\r
291 \r
292         /* Move into the created sub-directory. */\r
293         iReturn = ff_chdir( pcDirectory1 );\r
294         configASSERT( iReturn == pdFREERTOS_ERRNO_NONE );\r
295 \r
296         /* Obtain and print out the working directory. */\r
297         ff_getcwd( pcRAMBuffer, fsRAM_BUFFER_SIZE );\r
298         FF_PRINTF( "In directory %s\n", pcRAMBuffer );\r
299 \r
300         /* Create a subdirectory in the new directory. */\r
301         iReturn = ff_mkdir( pcDirectory2 );\r
302         configASSERT( iReturn == pdFREERTOS_ERRNO_NONE );\r
303 \r
304         /* Move into the directory just created - now two directories down from\r
305         the root. */\r
306         iReturn = ff_chdir( pcDirectory2 );\r
307         configASSERT( iReturn == pdFREERTOS_ERRNO_NONE );\r
308 \r
309         /* Obtain and print out the working directory. */\r
310         ff_getcwd( pcRAMBuffer, fsRAM_BUFFER_SIZE );\r
311         FF_PRINTF( "In directory %s\n", pcRAMBuffer );\r
312         snprintf( pcFileName, ffconfigMAX_FILENAME, "%s%s", pcMountPath, pcFullPath );\r
313         configASSERT( strcmp( pcRAMBuffer, pcFileName ) == 0 );\r
314 \r
315         /* Generate the file name. */\r
316         snprintf( pcFileName, ffconfigMAX_FILENAME, "%s.txt", pcDirectory2 );\r
317 \r
318         /* Print out the file name and the directory into which the file is being\r
319         written. */\r
320         FF_PRINTF( "Writing file %s in %s\n", pcFileName, pcRAMBuffer );\r
321 \r
322         pxFile = ff_fopen( pcFileName, "w" );\r
323         configASSERT( pxFile );\r
324 \r
325         /* Create a file 1 byte at a time.  The file is filled with incrementing\r
326         ascii characters starting from '0'. */\r
327         for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ )\r
328         {\r
329                 iReturned = ff_fputc( ( ( int ) '0' + iByte ), pxFile );\r
330                 configASSERT( iReturned ==  ( ( int ) '0' + iByte ) );\r
331         }\r
332 \r
333         /* Finished so close the file. */\r
334         ff_fclose( pxFile );\r
335 \r
336         /* Move back to the root directory. */\r
337         iReturned = ff_chdir( "../.." );\r
338         configASSERT( iReturn == pdFREERTOS_ERRNO_NONE );\r
339 \r
340         /* Obtain and print out the working directory. */\r
341         ff_getcwd( pcRAMBuffer, fsRAM_BUFFER_SIZE );\r
342         FF_PRINTF( "Back in root directory %s\n", pcRAMBuffer );\r
343         configASSERT( strcmp( pcRAMBuffer, pcMountPath ) == 0 );\r
344 \r
345         vPortFree( pcRAMBuffer );\r
346         vPortFree( pcFileName );\r
347 }\r
348 /*-----------------------------------------------------------*/\r
349 \r
350 static void prvVerifyDemoFileUsing_ff_fgetc( const char *pcMountPath )\r
351 {\r
352 int iByte, iReturned;\r
353 FF_FILE *pxFile;\r
354 char *pcRAMBuffer, *pcFileName;\r
355 \r
356         /* Allocate buffers used to hold date written to/from the disk, and the\r
357         file names. */\r
358         pcRAMBuffer = ( char * ) pvPortMalloc( fsRAM_BUFFER_SIZE );\r
359         pcFileName = ( char * ) pvPortMalloc( ffconfigMAX_FILENAME );\r
360         configASSERT( pcRAMBuffer );\r
361         configASSERT( pcFileName );\r
362 \r
363         /* Move into the directory in which the file was created. */\r
364         snprintf( pcFileName, ffconfigMAX_FILENAME, "%s%s", pcMountPath, pcFullPath );\r
365         iReturned = ff_chdir( pcFileName );\r
366         configASSERT( iReturned == pdFREERTOS_ERRNO_NONE );\r
367 \r
368         /* Obtain and print out the working directory. */\r
369         ff_getcwd( pcRAMBuffer, fsRAM_BUFFER_SIZE );\r
370         FF_PRINTF( "Back in directory %s\n", pcRAMBuffer );\r
371         configASSERT( strcmp( pcRAMBuffer, pcFileName ) == 0 );\r
372 \r
373         /* pcFileName is about to be overwritten - take a copy. */\r
374         strcpy( pcRAMBuffer, pcFileName );\r
375 \r
376         /* Generate the file name. */\r
377         sprintf( pcFileName, "%s.txt", pcDirectory2 );\r
378 \r
379         /* Print out the file name and the directory from which the file is being\r
380         read. */\r
381         FF_PRINTF( "Reading file %s in %s\n", pcFileName, pcRAMBuffer );\r
382 \r
383         /* This time the file is opened for reading. */\r
384         pxFile = ff_fopen( pcFileName, "r" );\r
385 \r
386         /* Read the file 1 byte at a time. */\r
387         for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ )\r
388         {\r
389                 iReturned = ff_fgetc( pxFile );\r
390                 configASSERT( iReturned ==  ( ( int ) '0' + iByte ) );\r
391         }\r
392 \r
393         /* Should not be able to read another bytes. */\r
394         iReturned = ff_fgetc( pxFile );\r
395         configASSERT( iReturned ==  FF_EOF );\r
396 \r
397         /* Finished so close the file. */\r
398         ff_fclose( pxFile );\r
399 \r
400         /* Move back to the root directory. */\r
401         iReturned = ff_chdir( "../.." );\r
402 \r
403         /* Obtain and print out the working directory. */\r
404         ff_getcwd( pcRAMBuffer, fsRAM_BUFFER_SIZE );\r
405         FF_PRINTF( "Back in root directory %s\n", pcRAMBuffer );\r
406 \r
407         vPortFree( pcRAMBuffer );\r
408         vPortFree( pcFileName );\r
409 }\r
410 /*-----------------------------------------------------------*/\r
411 \r
412 #if( ipconfigUSE_HTTP == 1 )\r
413 \r
414         static void prvCreateDefaultWebPage( void )\r
415         {\r
416         int iReturned;\r
417         size_t x;\r
418         FF_FILE *pxFile;\r
419 \r
420                 /* Create the directory used as the root of the HTTP server. */\r
421                 iReturned = ff_mkdir( configHTTP_ROOT );\r
422 \r
423                 if( iReturned == pdFREERTOS_ERRNO_NONE )\r
424                 {\r
425                         /* Move into the configHTTP_ROOT directory. */\r
426                         ff_chdir( configHTTP_ROOT );\r
427 \r
428                         /* Create each file defined by the xHTTPFilesToCopy array, which is\r
429                         defined in DefaultWebPages.h. */\r
430                         for( x = 0; x < sizeof( xHTTPFilesToCopy ) / sizeof( xFileToCopy_t ); x++ )\r
431                         {\r
432                                 /* Create the file. */\r
433                                 pxFile = ff_fopen( xHTTPFilesToCopy[ x ].pcFileName, "w+" );\r
434 \r
435                                 if( pxFile != NULL )\r
436                                 {\r
437                                         /* Write out all the data to the file. */\r
438                                         ff_fwrite( xHTTPFilesToCopy[ x ].pucFileData,\r
439                                                            xHTTPFilesToCopy[ x ].xFileSize,\r
440                                                            1,\r
441                                                            pxFile );\r
442 \r
443                                         ff_fclose( pxFile );\r
444                                 }\r
445                         }\r
446                 }\r
447         }\r
448 \r
449 #endif /* ipconfigUSE_HTTP */\r
450 /*-----------------------------------------------------------*/\r
451 \r