Toyomasa Watarai
/
Mbed-example-WS-W27
Mbed Cloud example program for workshop in W27 2018.
Embed:
(wiki syntax)
Show/hide line numbers
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) || (MBED_CONF_SD_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 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 16:22:04 by 1.7.2