Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of 352 by
basic.cpp
00001 /* 00002 * mbed Microcontroller Library 00003 * Copyright (c) 2006-2016 ARM Limited 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 * 00017 */ 00018 00019 /* The following copyright notice is reproduced from the glibc project 00020 * REF_LICENCE_GLIBC 00021 * 00022 * Copyright (C) 1991, 1992 Free Software Foundation, Inc. 00023 * This file is part of the GNU C Library. 00024 * 00025 * The GNU C Library is free software; you can redistribute it and/or 00026 * modify it under the terms of the GNU Library General Public License as 00027 * published by the Free Software Foundation; either version 2 of the 00028 * License, or (at your option) any later version. 00029 * 00030 * The GNU C Library is distributed in the hope that it will be useful, 00031 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00032 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00033 * Library General Public License for more details. 00034 * 00035 * You should have received a copy of the GNU Library General Public 00036 * License along with the GNU C Library; see the file COPYING.LIB. If 00037 * not, write to the Free Software Foundation, Inc., 675 Mass Ave, 00038 * Cambridge, MA 02139, USA. 00039 */ 00040 00041 00042 /** @file basic.cpp POSIX File API (stdio) test cases 00043 * 00044 * Consult the documentation under the test-case functions for 00045 * a description of the individual test case. 00046 * 00047 * this file includes ports for the mbed 2 test cases from the following locations: 00048 * - https://github.com:/armmbed/mbed-os/features/unsupported/tests/mbed/dir_sd/main.cpp. 00049 * - https://github.com:/armmbed/mbed-os/features/unsupported/tests/mbed/file/main.cpp. 00050 * - https://github.com:/armmbed/mbed-os/features/unsupported/tests/mbed/sd/main.cpp 00051 * - https://github.com:/armmbed/mbed-os/features/unsupported/tests/mbed/sd_perf_handle/main.cpp 00052 * - https://github.com:/armmbed/mbed-os/features/unsupported/tests/mbed/sd_perf_stdio/main.cpp. 00053 */ 00054 00055 #include "mbed.h" 00056 #include "mbed_config.h" 00057 #include "FATFileSystem.h" 00058 #include "SDBlockDevice.h" 00059 #include "test_env.h" 00060 #include "fsfat_debug.h" 00061 #include "fsfat_test.h" 00062 #include "utest/utest.h" 00063 #include "unity/unity.h" 00064 #include "greentea-client/test_env.h" 00065 00066 #include <stdio.h> 00067 #include <stdlib.h> 00068 #include <string.h> 00069 #include <errno.h> 00070 #include <algorithm> 00071 /* retarget.h is included after errno.h so symbols are mapped to 00072 * consistent values for all toolchains */ 00073 #include "platform/mbed_retarget.h" 00074 00075 using namespace utest::v1; 00076 00077 /* DEVICE_SPI 00078 * This symbol is defined in targets.json if the target has a SPI interface, which is required for SDCard support. 00079 * 00080 * MBED_CONF_APP_FSFAT_SDCARD_INSTALLED 00081 * For testing purposes, an SDCard must be installed on the target for the test cases in this file to succeed. 00082 * If the target has an SD card installed then the MBED_CONF_APP_FSFAT_SDCARD_INSTALLED will be generated 00083 * from the mbed_app.json, which includes the line 00084 * { 00085 * "config": { 00086 * "UART_RX": "D0", 00087 * <<< lines removed >>> 00088 * "DEVICE_SPI": 1, 00089 * "MBED_CONF_APP_FSFAT_SDCARD_INSTALLED": 1 00090 * }, 00091 * <<< lines removed >>> 00092 */ 00093 #if defined(DEVICE_SPI) && defined(MBED_CONF_APP_FSFAT_SDCARD_INSTALLED) 00094 00095 #define FSFAT_BASIC_TEST_00 fsfat_basic_test_00 00096 #define FSFAT_BASIC_TEST_01 fsfat_basic_test_01 00097 #define FSFAT_BASIC_TEST_02 fsfat_basic_test_02 00098 #define FSFAT_BASIC_TEST_03 fsfat_basic_test_03 00099 #define FSFAT_BASIC_TEST_04 fsfat_basic_test_04 00100 #define FSFAT_BASIC_TEST_05 fsfat_basic_test_05 00101 #define FSFAT_BASIC_TEST_06 fsfat_basic_test_06 00102 #define FSFAT_BASIC_TEST_07 fsfat_basic_test_07 00103 #define FSFAT_BASIC_TEST_08 fsfat_basic_test_08 00104 #define FSFAT_BASIC_TEST_09 fsfat_basic_test_09 00105 #define FSFAT_BASIC_TEST_10 fsfat_basic_test_10 00106 00107 #define FSFAT_BASIC_MSG_BUF_SIZE 256 00108 #define FSFAT_BASIC_TEST_05_TEST_STRING "Hello World!" 00109 00110 static const char *sd_file_path = "/sd/out.txt"; 00111 static const char *sd_mount_pt = "sd"; 00112 static const int FSFAT_BASIC_DATA_SIZE = 256; 00113 static char fsfat_basic_msg_g[FSFAT_BASIC_MSG_BUF_SIZE]; 00114 static char fsfat_basic_buffer[1024]; 00115 static const int FSFAT_BASIC_KIB_RW = 128; 00116 static Timer fsfat_basic_timer; 00117 static const char *fsfat_basic_bin_filename = "/sd/testfile.bin"; 00118 static const char *fsfat_basic_bin_filename_test_08 = "testfile.bin"; 00119 static const char *fsfat_basic_bin_filename_test_10 = "0:testfile.bin"; 00120 00121 00122 00123 SDBlockDevice sd(MBED_CONF_SD_SPI_MOSI, MBED_CONF_SD_SPI_MISO, MBED_CONF_SD_SPI_CLK, MBED_CONF_SD_SPI_CS); 00124 FATFileSystem fs(sd_mount_pt, &sd); 00125 00126 #define FSFAT_BASIC_MSG(_buf, _max_len, _fmt, ...) \ 00127 do \ 00128 { \ 00129 snprintf((_buf), (_max_len), (_fmt), __VA_ARGS__); \ 00130 }while(0); 00131 00132 /** @brief fopen test case 00133 * 00134 * - open a file 00135 * - generate random data items, write the item to the file and store a coy in a buffer for later use. 00136 * - close the file. 00137 * - open the file. 00138 * - read the data items from the file and check they are the same as write. 00139 * - close the file. 00140 * 00141 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00142 */ 00143 static control_t fsfat_basic_test_00() 00144 { 00145 00146 uint8_t data_written[FSFAT_BASIC_DATA_SIZE] = { 0 }; 00147 bool read_result = false; 00148 bool write_result = false; 00149 00150 // Fill data_written buffer with random data 00151 // Write these data into the file 00152 FSFAT_FENTRYLOG("%s:entered\n", __func__); 00153 { 00154 FSFAT_DBGLOG("%s:SD: Writing ... ", __func__); 00155 FILE *f = fopen(sd_file_path, "w"); 00156 if (f) { 00157 for (int i = 0; i < FSFAT_BASIC_DATA_SIZE; i++) { 00158 data_written[i] = rand() % 0XFF; 00159 fprintf(f, "%c", data_written[i]); 00160 } 00161 write_result = true; 00162 fclose(f); 00163 } 00164 FSFAT_DBGLOG("[%s]\n", write_result ? "OK" : "FAIL"); 00165 } 00166 TEST_ASSERT_MESSAGE(write_result == true, "Error: write_result is set to false."); 00167 00168 // Read back the data from the file and store them in data_read 00169 { 00170 FSFAT_DBGLOG("%s:SD: Reading data ... ", __func__); 00171 FILE *f = fopen(sd_file_path, "r"); 00172 if (f) { 00173 read_result = true; 00174 for (int i = 0; i < FSFAT_BASIC_DATA_SIZE; i++) { 00175 uint8_t data = fgetc(f); 00176 if (data != data_written[i]) { 00177 read_result = false; 00178 break; 00179 } 00180 } 00181 fclose(f); 00182 } 00183 FSFAT_DBGLOG("[%s]\n", read_result ? "OK" : "FAIL"); 00184 } 00185 TEST_ASSERT_MESSAGE(read_result == true, "Error: read_result is set to false."); 00186 return CaseNext; 00187 } 00188 00189 00190 /** @brief test-fseek.c test ported from glibc project. See the licence at REF_LICENCE_GLIBC. 00191 * 00192 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00193 */ 00194 static control_t fsfat_basic_test_01() 00195 { 00196 FILE *fp, *fp1; 00197 int i, j; 00198 int ret = 0; 00199 00200 FSFAT_FENTRYLOG("%s:entered\n", __func__); 00201 fp = fopen (sd_file_path, "w+"); 00202 if (fp == NULL) { 00203 FSFAT_DBGLOG("errno=%d\n", errno); 00204 TEST_ASSERT_MESSAGE(false, "error"); 00205 return CaseNext; 00206 } 00207 00208 for (i = 0; i < 256; i++) { 00209 putc (i, fp); 00210 } 00211 /* FIXME: freopen() should open the specified file closing the first stream. As can be seen from the 00212 * code below, the old file descriptor fp can still be used, and this should not happen. 00213 */ 00214 fp1 = freopen (sd_file_path, "r", fp); 00215 TEST_ASSERT_MESSAGE(fp1 == fp, "Error: cannot open file for reading"); 00216 00217 for (i = 1; i <= 255; i++) { 00218 ret = fseek (fp, (long) -i, SEEK_END); 00219 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s:Error: fseek() failed (ret=%d).\n", __func__, (int) ret); 00220 TEST_ASSERT_MESSAGE(ret == 0, fsfat_basic_msg_g); 00221 00222 if ((j = getc (fp)) != 256 - i) { 00223 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: SEEK_END failed (j=%d)\n", __func__, j); 00224 TEST_ASSERT_MESSAGE(false, fsfat_basic_msg_g); 00225 } 00226 ret = fseek (fp, (long) i, SEEK_SET); 00227 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: Cannot SEEK_SET (ret=%d).\n", __func__, (int) ret); 00228 TEST_ASSERT_MESSAGE(ret == 0, fsfat_basic_msg_g); 00229 00230 if ((j = getc (fp)) != i) { 00231 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: Cannot SEEK_SET (j=%d).\n", __func__, j); 00232 TEST_ASSERT_MESSAGE(ret == 0, fsfat_basic_msg_g); 00233 } 00234 if ((ret = fseek (fp, (long) i, SEEK_SET))) { 00235 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: Cannot SEEK_SET (ret=%d).\n", __func__, (int) ret); 00236 TEST_ASSERT_MESSAGE(ret == 0, fsfat_basic_msg_g); 00237 } 00238 if ((ret = fseek (fp, (long) (i >= 128 ? -128 : 128), SEEK_CUR))) { 00239 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: Cannot SEEK_CUR (ret=%d).\n", __func__, (int) ret); 00240 TEST_ASSERT_MESSAGE(ret == 0, fsfat_basic_msg_g); 00241 } 00242 if ((j = getc (fp)) != (i >= 128 ? i - 128 : i + 128)) { 00243 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: Cannot SEEK_CUR (j=%d).\n", __func__, j); 00244 TEST_ASSERT_MESSAGE(ret == 0, fsfat_basic_msg_g); 00245 } 00246 } 00247 fclose (fp); 00248 remove(sd_file_path); 00249 return CaseNext; 00250 } 00251 00252 00253 /** @brief test_rdwr.c test ported from glibc project. See the licence at REF_LICENCE_GLIBC. 00254 * 00255 * WARNING: this test does not currently work. See WARNING comments below. 00256 * 00257 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00258 */ 00259 static control_t fsfat_basic_test_02() 00260 { 00261 static const char hello[] = "Hello, world.\n"; 00262 static const char replace[] = "Hewwo, world.\n"; 00263 static const size_t replace_from = 2, replace_to = 4; 00264 const char *filename = sd_file_path; 00265 char buf[BUFSIZ]; 00266 FILE *f; 00267 int lose = 0; 00268 int32_t ret = 0; 00269 char *rets = NULL; 00270 00271 FSFAT_FENTRYLOG("%s:entered\n", __func__); 00272 f = fopen(filename, "w+"); 00273 if (f == NULL) { 00274 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: Cannot open file for writing (filename=%s).\n", __func__, filename); 00275 TEST_ASSERT_MESSAGE(false, fsfat_basic_msg_g); 00276 } 00277 00278 ret = fputs(hello, f); 00279 if (ret == EOF) { 00280 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: fputs() failed to write string to file (filename=%s, string=%s).\n", __func__, filename, hello); 00281 TEST_ASSERT_MESSAGE(false, fsfat_basic_msg_g); 00282 } 00283 00284 rewind(f); 00285 rets = fgets(buf, sizeof(buf), f); 00286 if (rets == NULL) { 00287 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: fgets() failed to get string from file (filename=%s).\n", __func__, filename); 00288 TEST_ASSERT_MESSAGE(false, fsfat_basic_msg_g); 00289 } 00290 rets = NULL; 00291 00292 rewind(f); 00293 ret = fputs(buf, f); 00294 if (ret == EOF) { 00295 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: fputs() failed to write string to file (filename=%s, string=%s).\n", __func__, filename, buf); 00296 TEST_ASSERT_MESSAGE(false, fsfat_basic_msg_g); 00297 } 00298 00299 rewind(f); 00300 { 00301 register size_t i; 00302 for (i = 0; i < replace_from; ++i) 00303 { 00304 int c = getc(f); 00305 if (c == EOF) 00306 { 00307 FSFAT_DBGLOG("EOF at %u.\n", i); 00308 lose = 1; 00309 break; 00310 } 00311 else if (c != hello[i]) 00312 { 00313 FSFAT_DBGLOG("Got '%c' instead of '%c' at %u.\n", 00314 (unsigned char) c, hello[i], i); 00315 lose = 1; 00316 break; 00317 } 00318 } 00319 } 00320 /* WARNING: printf("%s: here1. (lose = %d)\n", __func__, lose); */ 00321 { 00322 long int where = ftell(f); 00323 if (where == replace_from) 00324 { 00325 register size_t i; 00326 for (i = replace_from; i < replace_to; ++i) { 00327 if (putc(replace[i], f) == EOF) { 00328 FSFAT_DBGLOG("putc('%c') got %s at %u.\n", 00329 replace[i], strerror(errno), i); 00330 lose = 1; 00331 break; 00332 } 00333 /* WARNING: The problem seems to be that putc() is not writing the 'w' chars into the file 00334 * FSFAT_DBGLOG("%s: here1.5. (char = %c, char as int=%d, ret=%d) \n", __func__, replace[i], (int) replace[i], ret); 00335 */ 00336 } 00337 } 00338 else if (where == -1L) 00339 { 00340 FSFAT_DBGLOG("ftell got %s (should be at %u).\n", 00341 strerror(errno), replace_from); 00342 lose = 1; 00343 } 00344 else 00345 { 00346 FSFAT_DBGLOG("ftell returns %ld; should be %u.\n", where, replace_from); 00347 lose = 1; 00348 } 00349 } 00350 00351 if (!lose) 00352 { 00353 rewind(f); 00354 memset(buf, 0, BUFSIZ); 00355 if (fgets(buf, sizeof(buf), f) == NULL) 00356 { 00357 FSFAT_DBGLOG("fgets got %s.\n", strerror(errno)); 00358 lose = 1; 00359 } 00360 else if (strcmp(buf, replace)) 00361 { 00362 FSFAT_DBGLOG("Read \"%s\" instead of \"%s\".\n", buf, replace); 00363 lose = 1; 00364 } 00365 } 00366 00367 if (lose) { 00368 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: Test Failed. Losing file (filename=%s).\n", __func__, filename); 00369 TEST_ASSERT_MESSAGE(false, fsfat_basic_msg_g); 00370 } 00371 remove(filename); 00372 return CaseNext; 00373 } 00374 00375 /** @brief temptest.c test ported from glibc project. See the licence at REF_LICENCE_GLIBC. 00376 * 00377 * tmpnam() is currently not implemented 00378 * 00379 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00380 */ 00381 static control_t fsfat_basic_test_03() 00382 { 00383 char *fn = NULL; 00384 00385 FSFAT_FENTRYLOG("%s:entered\n", __func__); 00386 fn = tmpnam((char *) NULL); 00387 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: appeared to generate a filename when function is not implemented.\n", __func__); 00388 TEST_ASSERT_MESSAGE(fn == NULL, fsfat_basic_msg_g); 00389 return CaseNext; 00390 } 00391 00392 00393 static bool fsfat_basic_fileno_check(const char *name, FILE *stream, int fd) 00394 { 00395 /* ARMCC stdio.h currently does not define fileno() */ 00396 #ifndef __ARMCC_VERSION 00397 int sfd = fileno (stream); 00398 FSFAT_DBGLOG("(fileno (%s) = %d) %c= %d\n", name, sfd, sfd == fd ? '=' : '!', fd); 00399 00400 if (sfd == fd) { 00401 return true; 00402 } else { 00403 return false; 00404 } 00405 #else 00406 /* For ARMCC behave as though test had passed. */ 00407 return true; 00408 #endif /* __ARMCC_VERSION */ 00409 } 00410 00411 /* defines for next test case */ 00412 #ifndef STDIN_FILENO 00413 #define STDIN_FILENO 0 00414 #endif 00415 00416 #ifndef STDOUT_FILENO 00417 #define STDOUT_FILENO 1 00418 #endif 00419 00420 #ifndef STDERR_FILENO 00421 #define STDERR_FILENO 2 00422 #endif 00423 00424 00425 /** @brief tst-fileno.c test ported from glibc project. See the licence at REF_LICENCE_GLIBC. 00426 * 00427 * WARNING: this test does not currently work. See WARNING comments below. 00428 * 00429 * 00430 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00431 */ 00432 static control_t fsfat_basic_test_04() 00433 { 00434 /* ARMCC stdio.h currently does not define fileno() */ 00435 #ifndef __ARMCC_VERSION 00436 int ret = -1; 00437 ret = fsfat_basic_fileno_check("stdin", stdin, STDIN_FILENO); 00438 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: stdin does not have expected file number (expected=%d, fileno=%d.\n", __func__, (int) stdin, fileno(stdin)); 00439 TEST_ASSERT_MESSAGE(ret == true, fsfat_basic_msg_g); 00440 00441 ret = fsfat_basic_fileno_check("stdout", stdout, STDOUT_FILENO); 00442 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: stdout does not have expected file number (expected=%d, fileno=%d.\n", __func__, (int) stdout, fileno(stdout)); 00443 TEST_ASSERT_MESSAGE(ret == true, fsfat_basic_msg_g); 00444 00445 ret = fsfat_basic_fileno_check("stderr", stderr, STDERR_FILENO); 00446 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: stderr does not have expected file number (expected=%d, fileno=%d.\n", __func__, (int) stderr, fileno(stderr)); 00447 TEST_ASSERT_MESSAGE(ret == true, fsfat_basic_msg_g); 00448 #endif /* __ARMCC_VERSION */ 00449 return CaseNext; 00450 } 00451 00452 00453 /** @brief basic test to opendir() on a directory. 00454 * 00455 * This test has been ported from armmbed/mbed-os/features/unsupported/tests/mbed/dir_sd/main.cpp. 00456 * 00457 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00458 */ 00459 static control_t fsfat_basic_test_05() 00460 { 00461 FILE *f; 00462 const char *str = FSFAT_BASIC_TEST_05_TEST_STRING; 00463 int ret = 0; 00464 00465 FSFAT_DBGLOG("%s:Write files\n", __func__); 00466 char filename[32]; 00467 for (int i = 0; i < 10; i++) { 00468 sprintf(filename, "/sd/test_%d.txt", i); 00469 FSFAT_DBGLOG("Creating file: %s\n", filename); 00470 f = fopen(filename, "w"); 00471 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: fopen() failed.\n", __func__); 00472 TEST_ASSERT_MESSAGE(f != NULL, fsfat_basic_msg_g); 00473 00474 ret = fprintf(f, str); 00475 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: writing file.\n", __func__); 00476 TEST_ASSERT_MESSAGE(ret == (int) strlen(str), fsfat_basic_msg_g); 00477 00478 ret = fclose(f); 00479 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: fclose() failed.\n", __func__); 00480 TEST_ASSERT_MESSAGE(ret == 0, fsfat_basic_msg_g); 00481 } 00482 00483 FSFAT_DBGLOG("%s:List files:\n", __func__); 00484 DIR *d = opendir("/sd"); 00485 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: opendir() failed.\n", __func__); 00486 TEST_ASSERT_MESSAGE(d != NULL, fsfat_basic_msg_g); 00487 00488 struct dirent *p; 00489 while ((p = readdir(d)) != NULL) 00490 FSFAT_DBGLOG("%s\n", p->d_name); 00491 closedir(d); 00492 00493 return CaseNext; 00494 } 00495 00496 00497 /** @brief basic test to write a file to sd card, and read it back again 00498 * 00499 * This test has been ported from armmbed/mbed-os/features/unsupported/tests/mbed/file/main.cpp. 00500 * 00501 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00502 */ 00503 static control_t fsfat_basic_test_06() 00504 { 00505 int ret = -1; 00506 char mac[16]; 00507 mbed_mac_address(mac); 00508 FSFAT_DBGLOG("mac address: %02x,%02x,%02x,%02x,%02x,%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 00509 00510 FILE *f; 00511 const char *str = FSFAT_BASIC_TEST_05_TEST_STRING; 00512 int str_len = strlen(FSFAT_BASIC_TEST_05_TEST_STRING); 00513 00514 f = fopen(sd_file_path, "w"); 00515 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: fopen() failed.\n", __func__); 00516 TEST_ASSERT_MESSAGE(f != NULL, fsfat_basic_msg_g); 00517 00518 ret = fprintf(f, str); 00519 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: writing file.\n", __func__); 00520 TEST_ASSERT_MESSAGE(ret == (int) strlen(str), fsfat_basic_msg_g); 00521 00522 ret = fclose(f); 00523 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: fclose() failed.\n", __func__); 00524 TEST_ASSERT_MESSAGE(ret == 0, fsfat_basic_msg_g); 00525 00526 // Read 00527 f = fopen(sd_file_path, "r"); 00528 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: fopen() failed.\n", __func__); 00529 TEST_ASSERT_MESSAGE(f != NULL, fsfat_basic_msg_g); 00530 00531 int n = fread(fsfat_basic_buffer, sizeof(unsigned char), str_len, f); 00532 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: fread() failed.\n", __func__); 00533 TEST_ASSERT_MESSAGE(n == str_len, fsfat_basic_msg_g); 00534 00535 ret = fclose(f); 00536 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: fclose() failed.\n", __func__); 00537 TEST_ASSERT_MESSAGE(ret == 0, fsfat_basic_msg_g); 00538 00539 return CaseNext; 00540 } 00541 00542 00543 /** @brief basic test to write a file to sd card. 00544 * 00545 * This test has been ported from armmbed/mbed-os/features/unsupported/tests/mbed/sd/main.cpp. 00546 * 00547 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00548 */ 00549 static control_t fsfat_basic_test_07() 00550 { 00551 uint8_t data_written[FSFAT_BASIC_DATA_SIZE] = { 0 }; 00552 00553 // Fill data_written buffer with random data 00554 // Write these data into the file 00555 bool write_result = false; 00556 { 00557 FSFAT_DBGLOG("%s:SD: Writing ... ", __func__); 00558 FILE *f = fopen(sd_file_path, "w"); 00559 if (f) { 00560 for (int i = 0; i < FSFAT_BASIC_DATA_SIZE; i++) { 00561 data_written[i] = rand() % 0XFF; 00562 fprintf(f, "%c", data_written[i]); 00563 } 00564 write_result = true; 00565 fclose(f); 00566 } 00567 FSFAT_DBGLOG("[%s]\n", write_result ? "OK" : "FAIL"); 00568 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: unexpected write failure.\n", __func__); 00569 TEST_ASSERT_MESSAGE(write_result == true, fsfat_basic_msg_g); 00570 } 00571 00572 // Read back the data from the file and store them in data_read 00573 bool read_result = false; 00574 { 00575 FSFAT_DBGLOG("%s:SD: Reading data ... ", __func__); 00576 FILE *f = fopen(sd_file_path, "r"); 00577 if (f) { 00578 read_result = true; 00579 for (int i = 0; i < FSFAT_BASIC_DATA_SIZE; i++) { 00580 uint8_t data = fgetc(f); 00581 if (data != data_written[i]) { 00582 read_result = false; 00583 break; 00584 } 00585 } 00586 fclose(f); 00587 } 00588 FSFAT_DBGLOG("[%s]\n", read_result ? "OK" : "FAIL"); 00589 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: unexpected read failure.\n", __func__); 00590 TEST_ASSERT_MESSAGE(read_result == true, fsfat_basic_msg_g); 00591 } 00592 return CaseNext; 00593 } 00594 00595 00596 static bool fsfat_basic_test_file_write_fhandle(const char *filename, const int kib_rw) 00597 { 00598 int ret = -1; 00599 File file; 00600 00601 ret = file.open(&fs, filename, O_WRONLY | O_CREAT | O_TRUNC); 00602 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: failed to open file.\n", __func__); 00603 TEST_ASSERT_MESSAGE(ret == 0, fsfat_basic_msg_g); 00604 00605 int byte_write = 0; 00606 fsfat_basic_timer.start(); 00607 for (int i = 0; i < kib_rw; i++) { 00608 ret = file.write(fsfat_basic_buffer, sizeof(fsfat_basic_buffer)); 00609 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: failed to write to file.\n", __func__); 00610 TEST_ASSERT_MESSAGE(ret == sizeof(fsfat_basic_buffer), fsfat_basic_msg_g); 00611 byte_write++; 00612 } 00613 fsfat_basic_timer.stop(); 00614 file.close(); 00615 #ifdef FSFAT_DEBUG 00616 double test_time_sec = fsfat_basic_timer.read_us() / 1000000.0; 00617 double speed = kib_rw / test_time_sec; 00618 FSFAT_DBGLOG("%d KiB write in %.3f sec with speed of %.4f KiB/s\n", byte_write, test_time_sec, speed); 00619 #endif 00620 fsfat_basic_timer.reset(); 00621 return true; 00622 } 00623 00624 00625 static bool fsfat_basic_test_file_read_fhandle(const char *filename, const int kib_rw) 00626 { 00627 int ret = -1; 00628 File file; 00629 ret = file.open(&fs, filename, O_RDONLY); 00630 00631 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: failed to open file.\n", __func__); 00632 TEST_ASSERT_MESSAGE(ret == 0, fsfat_basic_msg_g); 00633 00634 fsfat_basic_timer.start(); 00635 int byte_read = 0; 00636 while (file.read(fsfat_basic_buffer, sizeof(fsfat_basic_buffer)) == sizeof(fsfat_basic_buffer)) { 00637 byte_read++; 00638 } 00639 fsfat_basic_timer.stop(); 00640 file.close(); 00641 #ifdef FSFAT_DEBUG 00642 double test_time_sec = fsfat_basic_timer.read_us() / 1000000.0; 00643 double speed = kib_rw / test_time_sec; 00644 FSFAT_DBGLOG("%d KiB read in %.3f sec with speed of %.4f KiB/s\n", byte_read, test_time_sec, speed); 00645 #endif 00646 fsfat_basic_timer.reset(); 00647 return true; 00648 } 00649 00650 00651 static char fsfat_basic_test_random_char() 00652 { 00653 return rand() % 100; 00654 } 00655 00656 00657 /** @brief basic sd card performance test 00658 * 00659 * This test has been ported from armmbed/mbed-os/features/unsupported/tests/mbed/sd_perf_handle/main.cpp. 00660 * 00661 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00662 */ 00663 static control_t fsfat_basic_test_08() 00664 { 00665 // Test header 00666 FSFAT_DBGLOG("\n%s:SD Card FileHandle Performance Test\n", __func__); 00667 FSFAT_DBGLOG("File name: %s\n", fsfat_basic_bin_filename); 00668 FSFAT_DBGLOG("Buffer size: %d KiB\n", (FSFAT_BASIC_KIB_RW * sizeof(fsfat_basic_buffer)) / 1024); 00669 00670 // Initialize buffer 00671 srand(0); 00672 char *buffer_end = fsfat_basic_buffer + sizeof(fsfat_basic_buffer); 00673 std::generate (fsfat_basic_buffer, buffer_end, fsfat_basic_test_random_char); 00674 00675 bool result = true; 00676 for (;;) { 00677 FSFAT_DBGLOG("%s:Write test...\n", __func__); 00678 if (fsfat_basic_test_file_write_fhandle(fsfat_basic_bin_filename_test_08, FSFAT_BASIC_KIB_RW) == false) { 00679 result = false; 00680 break; 00681 } 00682 00683 FSFAT_DBGLOG("%s:Read test...\n", __func__); 00684 if (fsfat_basic_test_file_read_fhandle(fsfat_basic_bin_filename_test_08, FSFAT_BASIC_KIB_RW) == false) { 00685 result = false; 00686 break; 00687 } 00688 break; 00689 } 00690 TEST_ASSERT_MESSAGE(result == true, "something went wrong"); 00691 return CaseNext; 00692 } 00693 00694 00695 bool fsfat_basic_test_sf_file_write_stdio(const char *filename, const int kib_rw) 00696 { 00697 int ret = -1; 00698 FILE* file = fopen(filename, "w"); 00699 00700 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: failed to open file.\n", __func__); 00701 TEST_ASSERT_MESSAGE(file != NULL, fsfat_basic_msg_g); 00702 00703 int byte_write = 0; 00704 fsfat_basic_timer.start(); 00705 for (int i = 0; i < kib_rw; i++) { 00706 ret = fwrite(fsfat_basic_buffer, sizeof(char), sizeof(fsfat_basic_buffer), file); 00707 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: failed to write to file.\n", __func__); 00708 TEST_ASSERT_MESSAGE(ret == sizeof(fsfat_basic_buffer), fsfat_basic_msg_g); 00709 byte_write++; 00710 } 00711 fsfat_basic_timer.stop(); 00712 fclose(file); 00713 #ifdef FSFAT_DEBUG 00714 double test_time_sec = fsfat_basic_timer.read_us() / 1000000.0; 00715 double speed = kib_rw / test_time_sec; 00716 FSFAT_DBGLOG("%d KiB write in %.3f sec with speed of %.4f KiB/s\n", byte_write, test_time_sec, speed); 00717 #endif 00718 fsfat_basic_timer.reset(); 00719 return true; 00720 } 00721 00722 00723 bool fsfat_basic_test_sf_file_read_stdio(const char *filename, const int kib_rw) 00724 { 00725 FILE* file = fopen(filename, "r"); 00726 00727 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: failed to open file.\n", __func__); 00728 TEST_ASSERT_MESSAGE(file != NULL, fsfat_basic_msg_g); 00729 fsfat_basic_timer.start(); 00730 int byte_read = 0; 00731 while (fread(fsfat_basic_buffer, sizeof(char), sizeof(fsfat_basic_buffer), file) == sizeof(fsfat_basic_buffer)) { 00732 byte_read++; 00733 } 00734 fsfat_basic_timer.stop(); 00735 fclose(file); 00736 #ifdef FSFAT_DEBUG 00737 double test_time_sec = fsfat_basic_timer.read_us() / 1000000.0; 00738 double speed = kib_rw / test_time_sec; 00739 FSFAT_DBGLOG("%d KiB read in %.3f sec with speed of %.4f KiB/s\n", byte_read, test_time_sec, speed); 00740 #endif 00741 fsfat_basic_timer.reset(); 00742 return true; 00743 } 00744 00745 00746 /** @brief basic test to write a file to sd card. 00747 * 00748 * This test has been ported from armmbed/mbed-os/features/unsupported/tests/mbed/sd_perf_stdio/main.cpp. 00749 * 00750 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00751 */ 00752 static control_t fsfat_basic_test_09() 00753 { 00754 // Test header 00755 FSFAT_DBGLOG("\n%s:SD Card Stdio Performance Test\n", __func__); 00756 FSFAT_DBGLOG("File name: %s\n", fsfat_basic_bin_filename); 00757 FSFAT_DBGLOG("Buffer size: %d KiB\n", (FSFAT_BASIC_KIB_RW * sizeof(fsfat_basic_buffer)) / 1024); 00758 00759 // Initialize buffer 00760 srand(0); 00761 char *buffer_end = fsfat_basic_buffer + sizeof(fsfat_basic_buffer); 00762 std::generate (fsfat_basic_buffer, buffer_end, fsfat_basic_test_random_char); 00763 00764 bool result = true; 00765 for (;;) { 00766 FSFAT_DBGLOG("%s:Write test...\n", __func__); 00767 if (fsfat_basic_test_sf_file_write_stdio(fsfat_basic_bin_filename, FSFAT_BASIC_KIB_RW) == false) { 00768 result = false; 00769 break; 00770 } 00771 00772 FSFAT_DBGLOG("%s:Read test...\n", __func__); 00773 if (fsfat_basic_test_sf_file_read_stdio(fsfat_basic_bin_filename, FSFAT_BASIC_KIB_RW) == false) { 00774 result = false; 00775 break; 00776 } 00777 break; 00778 } 00779 TEST_ASSERT_MESSAGE(result == true, "Expected true result not found"); 00780 return CaseNext; 00781 } 00782 00783 00784 bool fsfat_basic_test_file_write_fatfs(const char *filename, const int kib_rw) 00785 { 00786 FIL file; 00787 FRESULT res = f_open(&file, filename, FA_WRITE | FA_CREATE_ALWAYS); 00788 00789 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: failed to open file.\n", __func__); 00790 TEST_ASSERT_MESSAGE(res == FR_OK, fsfat_basic_msg_g); 00791 00792 int byte_write = 0; 00793 unsigned int bytes = 0; 00794 fsfat_basic_timer.start(); 00795 for (int i = 0; i < kib_rw; i++) { 00796 res = f_write(&file, fsfat_basic_buffer, sizeof(fsfat_basic_buffer), &bytes); 00797 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: failed to write to file.\n", __func__); 00798 TEST_ASSERT_MESSAGE(res == FR_OK, fsfat_basic_msg_g); 00799 byte_write++; 00800 } 00801 fsfat_basic_timer.stop(); 00802 f_close(&file); 00803 #ifdef FSFAT_DEBUG 00804 double test_time_sec = fsfat_basic_timer.read_us() / 1000000.0; 00805 double speed = kib_rw / test_time_sec; 00806 FSFAT_DBGLOG("%d KiB write in %.3f sec with speed of %.4f KiB/s\n", byte_write, test_time_sec, speed); 00807 #endif 00808 fsfat_basic_timer.reset(); 00809 return true; 00810 } 00811 00812 bool fsfat_basic_test_file_read_fatfs(const char *filename, const int kib_rw) 00813 { 00814 FIL file; 00815 FRESULT res = f_open(&file, filename, FA_READ | FA_OPEN_EXISTING); 00816 00817 FSFAT_BASIC_MSG(fsfat_basic_msg_g, FSFAT_BASIC_MSG_BUF_SIZE, "%s: Error: failed to open file.\n", __func__); 00818 TEST_ASSERT_MESSAGE(res == FR_OK, fsfat_basic_msg_g); 00819 00820 fsfat_basic_timer.start(); 00821 int byte_read = 0; 00822 unsigned int bytes = 0; 00823 do { 00824 res = f_read(&file, fsfat_basic_buffer, sizeof(fsfat_basic_buffer), &bytes); 00825 byte_read++; 00826 } while (res == FR_OK && bytes == sizeof(fsfat_basic_buffer)); 00827 fsfat_basic_timer.stop(); 00828 f_close(&file); 00829 #ifdef FSFAT_DEBUG 00830 double test_time_sec = fsfat_basic_timer.read_us() / 1000000.0; 00831 double speed = kib_rw / test_time_sec; 00832 FSFAT_DBGLOG("%d KiB read in %.3f sec with speed of %.4f KiB/s\n", byte_read, test_time_sec, speed); 00833 #endif 00834 fsfat_basic_timer.reset(); 00835 return true; 00836 } 00837 00838 /** @brief basic test to write a file to sd card. 00839 * 00840 * This test has been ported from armmbed/mbed-os/features/unsupported/tests/mbed/sd_perf_stdio/main.cpp. 00841 * 00842 * @return on success returns CaseNext to continue to next test case, otherwise will assert on errors. 00843 */ 00844 static control_t fsfat_basic_test_10() 00845 { 00846 // Test header 00847 FSFAT_DBGLOG("\n%sSD Card FatFS Performance Test\n", __func__); 00848 FSFAT_DBGLOG("File name: %s\n", fsfat_basic_bin_filename_test_10); 00849 FSFAT_DBGLOG("Buffer size: %d KiB\n", (FSFAT_BASIC_KIB_RW * sizeof(fsfat_basic_buffer)) / 1024); 00850 00851 // Initialize buffer 00852 srand(1); 00853 char *buffer_end = fsfat_basic_buffer + sizeof(fsfat_basic_buffer); 00854 std::generate (fsfat_basic_buffer, buffer_end, fsfat_basic_test_random_char); 00855 00856 bool result = true; 00857 for (;;) { 00858 FSFAT_DBGLOG("%s:Write test...\n", __func__); 00859 if (fsfat_basic_test_file_write_fatfs(fsfat_basic_bin_filename_test_10, FSFAT_BASIC_KIB_RW) == false) { 00860 result = false; 00861 break; 00862 } 00863 00864 FSFAT_DBGLOG("%s:Read test...\n", __func__); 00865 if (fsfat_basic_test_file_read_fatfs(fsfat_basic_bin_filename_test_10, FSFAT_BASIC_KIB_RW) == false) { 00866 result = false; 00867 break; 00868 } 00869 break; 00870 } 00871 TEST_ASSERT_MESSAGE(result == true, "Expected true result not found"); 00872 return CaseNext; 00873 } 00874 00875 #else 00876 00877 #define FSFAT_BASIC_TEST_00 fsfat_basic_test_dummy 00878 #define FSFAT_BASIC_TEST_01 fsfat_basic_test_dummy 00879 #define FSFAT_BASIC_TEST_02 fsfat_basic_test_dummy 00880 #define FSFAT_BASIC_TEST_03 fsfat_basic_test_dummy 00881 #define FSFAT_BASIC_TEST_04 fsfat_basic_test_dummy 00882 #define FSFAT_BASIC_TEST_05 fsfat_basic_test_dummy 00883 #define FSFAT_BASIC_TEST_06 fsfat_basic_test_dummy 00884 #define FSFAT_BASIC_TEST_07 fsfat_basic_test_dummy 00885 #define FSFAT_BASIC_TEST_08 fsfat_basic_test_dummy 00886 #define FSFAT_BASIC_TEST_09 fsfat_basic_test_dummy 00887 #define FSFAT_BASIC_TEST_10 fsfat_basic_test_dummy 00888 00889 00890 /** @brief fsfat_basic_test_dummy Dummy test case for testing when platform doesnt have an SDCard installed. 00891 * 00892 * @return success always 00893 */ 00894 static control_t fsfat_basic_test_dummy() 00895 { 00896 printf("Null test\n"); 00897 return CaseNext; 00898 } 00899 00900 #endif /* defined(DEVICE_SPI) && defined(MBED_CONF_APP_FSFAT_SDCARD_INSTALLED) */ 00901 00902 utest::v1::status_t greentea_setup(const size_t number_of_cases) 00903 { 00904 GREENTEA_SETUP(300, "default_auto"); 00905 return greentea_test_setup_handler(number_of_cases); 00906 } 00907 00908 00909 Case cases[] = { 00910 /* 1 2 3 4 5 6 7 */ 00911 /* 1234567890123456789012345678901234567890123456789012345678901234567890 */ 00912 Case("FSFAT_BASIC_TEST_00: fopen()/fgetc()/fprintf()/fclose() test.", FSFAT_BASIC_TEST_00), 00913 Case("FSFAT_BASIC_TEST_01: fopen()/fseek()/fclose() test.", FSFAT_BASIC_TEST_01), 00914 /* WARNING: Test case not working but currently not required for PAL support 00915 * Case("FSFAT_BASIC_TEST_02: fopen()/fgets()/fputs()/ftell()/rewind()/remove() test.", FSFAT_BASIC_TEST_02) */ 00916 Case("FSFAT_BASIC_TEST_03: tmpnam() test.", FSFAT_BASIC_TEST_03), 00917 Case("FSFAT_BASIC_TEST_04: fileno() test.", FSFAT_BASIC_TEST_04), 00918 Case("FSFAT_BASIC_TEST_05: opendir() basic test.", FSFAT_BASIC_TEST_05), 00919 Case("FSFAT_BASIC_TEST_06: fread()/fwrite() file to sdcard.", FSFAT_BASIC_TEST_06), 00920 Case("FSFAT_BASIC_TEST_07: sdcard fwrite() file test.", FSFAT_BASIC_TEST_07), 00921 Case("FSFAT_BASIC_TEST_08: FATFileSystem::read()/write() test.", FSFAT_BASIC_TEST_08), 00922 Case("FSFAT_BASIC_TEST_09: POSIX FILE API fread()/fwrite() test.", FSFAT_BASIC_TEST_09), 00923 Case("FSFAT_BASIC_TEST_10: ChanFS read()/write()) test.", FSFAT_BASIC_TEST_10), 00924 }; 00925 00926 00927 /* Declare your test specification with a custom setup handler */ 00928 Specification specification(greentea_setup, cases); 00929 00930 int main() 00931 { 00932 return !Harness::run(specification); 00933 }
Generated on Tue Jul 12 2022 21:51:18 by
