Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2009, Swedish Institute of Computer Science 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * This file is part of the Contiki operating system. 00030 * 00031 */ 00032 00033 /** 00034 * \file 00035 * Coffee architecture-dependent functionality for the STM32W108-based mb851 00036 * platform. 00037 * \author 00038 * Salvatore Pitrulli <salvopitru@users.sourceforge.net> 00039 */ 00040 00041 00042 #include "cfs-coffee-arch.h" 00043 00044 #define DEBUG 1 00045 #if DEBUG 00046 #include <stdio.h> 00047 #define PRINTF(...) printf(__VA_ARGS__) 00048 #else 00049 #define PRINTF(...) 00050 #endif 00051 00052 #define TESTCOFFEE 1 00053 #define DEBUG_CFS 1 00054 #if TESTCOFFEE 00055 #if DEBUG_CFS 00056 #include <stdio.h> 00057 #define PRINTF_CFS(...) printf(__VA_ARGS__) 00058 #else 00059 #define PRINTF_CFS(...) 00060 #endif 00061 00062 #include "cfs/cfs.h" 00063 #include "cfs/cfs-coffee.h" 00064 #include "lib/crc16.h" 00065 #include "lib/random.h" 00066 #include <stdio.h> 00067 00068 #define FAIL(x) PRINTF("FAILED\n");error = (x); goto end; 00069 00070 #define FILE_SIZE 512 00071 00072 int 00073 coffee_file_test(void) 00074 { 00075 int error; 00076 int wfd, rfd, afd; 00077 unsigned char buf[256], buf2[11]; 00078 int r, i, j, total_read; 00079 unsigned offset; 00080 00081 cfs_remove("T1"); 00082 cfs_remove("T2"); 00083 cfs_remove("T3"); 00084 cfs_remove("T4"); 00085 cfs_remove("T5"); 00086 00087 wfd = rfd = afd = -1; 00088 00089 for(r = 0; r < sizeof(buf); r++) { 00090 buf[r] = r; 00091 } 00092 00093 PRINTF("TEST 1\n"); 00094 00095 /* Test 1: Open for writing. */ 00096 wfd = cfs_open("T1", CFS_WRITE); 00097 if(wfd < 0) { 00098 FAIL(-1); 00099 } 00100 00101 PRINTF("PASSED\n"); 00102 PRINTF("TEST "); 00103 PRINTF("2\n"); 00104 00105 /* Test 2: Write buffer. */ 00106 r = cfs_write(wfd, buf, sizeof(buf)); 00107 if(r < 0) { 00108 FAIL(-2); 00109 } else if(r < sizeof(buf)) { 00110 FAIL(-3); 00111 } 00112 00113 PRINTF("PASSED\n"); 00114 PRINTF("TEST "); 00115 PRINTF("3\n"); 00116 00117 /* Test 3: Deny reading. */ 00118 r = cfs_read(wfd, buf, sizeof(buf)); 00119 if(r >= 0) { 00120 FAIL(-4); 00121 } 00122 00123 PRINTF("PASSED\n"); 00124 PRINTF("TEST "); 00125 PRINTF("4\n"); 00126 00127 /* Test 4: Open for reading. */ 00128 rfd = cfs_open("T1", CFS_READ); 00129 if(rfd < 0) { 00130 FAIL(-5); 00131 } 00132 00133 PRINTF("PASSED\n"); 00134 PRINTF("TEST "); 00135 PRINTF("5\n"); 00136 00137 /* Test 5: Write to read-only file. */ 00138 r = cfs_write(rfd, buf, sizeof(buf)); 00139 if(r >= 0) { 00140 FAIL(-6); 00141 } 00142 00143 PRINTF("PASSED\n"); 00144 PRINTF("TEST "); 00145 PRINTF("7\n"); 00146 00147 /* Test 7: Read the buffer written in Test 2. */ 00148 memset(buf, 0, sizeof(buf)); 00149 r = cfs_read(rfd, buf, sizeof(buf)); 00150 if(r < 0) { 00151 FAIL(-8); 00152 } else if(r < sizeof(buf)) { 00153 PRINTF_CFS("r=%d\n", r); 00154 FAIL(-9); 00155 } 00156 00157 PRINTF("PASSED\n"); 00158 PRINTF("TEST "); 00159 PRINTF("8\n"); 00160 00161 /* Test 8: Verify that the buffer is correct. */ 00162 for(r = 0; r < sizeof(buf); r++) { 00163 if(buf[r] != r) { 00164 PRINTF_CFS("r=%d. buf[r]=%d\n", r, buf[r]); 00165 FAIL(-10); 00166 } 00167 } 00168 00169 PRINTF("PASSED\n"); 00170 PRINTF("TEST "); 00171 PRINTF("9\n"); 00172 00173 /* Test 9: Seek to beginning. */ 00174 if(cfs_seek(wfd, 0, CFS_SEEK_SET) != 0) { 00175 FAIL(-11); 00176 } 00177 00178 PRINTF("PASSED\n"); 00179 PRINTF("TEST "); 00180 PRINTF("10\n"); 00181 00182 /* Test 10: Write to the log. */ 00183 r = cfs_write(wfd, buf, sizeof(buf)); 00184 if(r < 0) { 00185 FAIL(-12); 00186 } else if(r < sizeof(buf)) { 00187 FAIL(-13); 00188 } 00189 00190 PRINTF("PASSED\n"); 00191 PRINTF("TEST "); 00192 PRINTF("11\n"); 00193 00194 /* Test 11: Read the data from the log. */ 00195 cfs_seek(rfd, 0, CFS_SEEK_SET); 00196 memset(buf, 0, sizeof(buf)); 00197 r = cfs_read(rfd, buf, sizeof(buf)); 00198 if(r < 0) { 00199 FAIL(-14); 00200 } else if(r < sizeof(buf)) { 00201 FAIL(-15); 00202 } 00203 00204 PRINTF("PASSED\n"); 00205 PRINTF("TEST "); 00206 PRINTF("12\n"); 00207 00208 /* Test 12: Verify that the data is correct. */ 00209 for(r = 0; r < sizeof(buf); r++) { 00210 if(buf[r] != r) { 00211 FAIL(-16); 00212 } 00213 } 00214 00215 PRINTF("PASSED\n"); 00216 PRINTF("TEST "); 00217 PRINTF("13\n"); 00218 00219 /* Test 13: Write a reversed buffer to the file. */ 00220 for(r = 0; r < sizeof(buf); r++) { 00221 buf[r] = sizeof(buf) - r - 1; 00222 } 00223 if(cfs_seek(wfd, 0, CFS_SEEK_SET) != 0) { 00224 FAIL(-17); 00225 } 00226 r = cfs_write(wfd, buf, sizeof(buf)); 00227 if(r < 0) { 00228 FAIL(-18); 00229 } else if(r < sizeof(buf)) { 00230 FAIL(-19); 00231 } 00232 if(cfs_seek(rfd, 0, CFS_SEEK_SET) != 0) { 00233 FAIL(-20); 00234 } 00235 00236 PRINTF("PASSED\n"); 00237 PRINTF("TEST "); 00238 PRINTF("14\n"); 00239 00240 /* Test 14: Read the reversed buffer. */ 00241 cfs_seek(rfd, 0, CFS_SEEK_SET); 00242 memset(buf, 0, sizeof(buf)); 00243 r = cfs_read(rfd, buf, sizeof(buf)); 00244 if(r < 0) { 00245 FAIL(-21); 00246 } else if(r < sizeof(buf)) { 00247 PRINTF_CFS("r = %d\n", r); 00248 FAIL(-22); 00249 } 00250 00251 PRINTF("PASSED\n"); 00252 PRINTF("TEST "); 00253 PRINTF("15\n"); 00254 00255 /* Test 15: Verify that the data is correct. */ 00256 for(r = 0; r < sizeof(buf); r++) { 00257 if(buf[r] != sizeof(buf) - r - 1) { 00258 FAIL(-23); 00259 } 00260 } 00261 00262 cfs_close(rfd); 00263 cfs_close(wfd); 00264 00265 if(cfs_coffee_reserve("T2", FILE_SIZE) < 0) { 00266 FAIL(-24); 00267 } 00268 00269 PRINTF("PASSED\n"); 00270 PRINTF("TEST "); 00271 PRINTF("16\n"); 00272 00273 /* Test 16: Test multiple writes at random offset. */ 00274 for(r = 0; r < 100; r++) { 00275 wfd = cfs_open("T2", CFS_WRITE | CFS_READ); 00276 if(wfd < 0) { 00277 FAIL(-25); 00278 } 00279 00280 offset = random_rand() % FILE_SIZE; 00281 00282 for(r = 0; r < sizeof(buf); r++) { 00283 buf[r] = r; 00284 } 00285 00286 if(cfs_seek(wfd, offset, CFS_SEEK_SET) != offset) { 00287 FAIL(-26); 00288 } 00289 00290 if(cfs_write(wfd, buf, sizeof(buf)) != sizeof(buf)) { 00291 FAIL(-27); 00292 } 00293 00294 if(cfs_seek(wfd, offset, CFS_SEEK_SET) != offset) { 00295 FAIL(-28); 00296 } 00297 00298 memset(buf, 0, sizeof(buf)); 00299 if(cfs_read(wfd, buf, sizeof(buf)) != sizeof(buf)) { 00300 FAIL(-29); 00301 } 00302 00303 for(i = 0; i < sizeof(buf); i++) { 00304 if(buf[i] != i) { 00305 PRINTF_CFS("buf[%d] != %d\n", i, buf[i]); 00306 FAIL(-30); 00307 } 00308 } 00309 } 00310 PRINTF("PASSED\n"); 00311 PRINTF("TEST "); 00312 PRINTF("17\n"); 00313 /* Test 17: Append data to the same file many times. */ 00314 #define APPEND_BYTES 3000 00315 #define BULK_SIZE 10 00316 for (i = 0; i < APPEND_BYTES; i += BULK_SIZE) { 00317 afd = cfs_open("T3", CFS_WRITE | CFS_APPEND); 00318 if (afd < 0) { 00319 FAIL(-31); 00320 } 00321 for (j = 0; j < BULK_SIZE; j++) { 00322 buf[j] = 1 + ((i + j) & 0x7f); 00323 } 00324 if ((r = cfs_write(afd, buf, BULK_SIZE)) != BULK_SIZE) { 00325 PRINTF_CFS("Count:%d, r=%d\n", i, r); 00326 FAIL(-32); 00327 } 00328 cfs_close(afd); 00329 } 00330 00331 PRINTF("PASSED\n"); 00332 PRINTF("TEST "); 00333 PRINTF("18\n"); 00334 00335 /* Test 18: Read back the data written in Test 17 and verify that it 00336 is correct. */ 00337 afd = cfs_open("T3", CFS_READ); 00338 if(afd < 0) { 00339 FAIL(-33); 00340 } 00341 total_read = 0; 00342 while((r = cfs_read(afd, buf2, sizeof(buf2))) > 0) { 00343 for(j = 0; j < r; j++) { 00344 if(buf2[j] != 1 + ((total_read + j) & 0x7f)) { 00345 FAIL(-34); 00346 } 00347 } 00348 total_read += r; 00349 } 00350 if(r < 0) { 00351 PRINTF_CFS("FAIL:-35 r=%d\n",r); 00352 FAIL(-35); 00353 } 00354 if(total_read != APPEND_BYTES) { 00355 PRINTF_CFS("FAIL:-35 total_read=%d\n",total_read); 00356 FAIL(-35); 00357 } 00358 cfs_close(afd); 00359 00360 PRINTF("PASSED\n"); 00361 PRINTF("TEST "); 00362 PRINTF("19\n"); 00363 00364 /***************T4********************/ 00365 /* file T4 and T5 writing forces to use garbage collector in greedy mode 00366 * this test is designed for 10kb of file system 00367 * */ 00368 #define APPEND_BYTES_1 2000 00369 #define BULK_SIZE_1 10 00370 for (i = 0; i < APPEND_BYTES_1; i += BULK_SIZE_1) { 00371 afd = cfs_open("T4", CFS_WRITE | CFS_APPEND); 00372 if (afd < 0) { 00373 FAIL(-36); 00374 } 00375 for (j = 0; j < BULK_SIZE_1; j++) { 00376 buf[j] = 1 + ((i + j) & 0x7f); 00377 } 00378 00379 if ((r = cfs_write(afd, buf, BULK_SIZE_1)) != BULK_SIZE_1) { 00380 PRINTF_CFS("Count:%d, r=%d\n", i, r); 00381 FAIL(-37); 00382 } 00383 cfs_close(afd); 00384 } 00385 00386 afd = cfs_open("T4", CFS_READ); 00387 if(afd < 0) { 00388 FAIL(-38); 00389 } 00390 total_read = 0; 00391 while((r = cfs_read(afd, buf2, sizeof(buf2))) > 0) { 00392 for(j = 0; j < r; j++) { 00393 if(buf2[j] != 1 + ((total_read + j) & 0x7f)) { 00394 PRINTF_CFS("FAIL:-39, total_read=%d r=%d\n",total_read,r); 00395 FAIL(-39); 00396 } 00397 } 00398 total_read += r; 00399 } 00400 if(r < 0) { 00401 PRINTF_CFS("FAIL:-40 r=%d\n",r); 00402 FAIL(-40); 00403 } 00404 if(total_read != APPEND_BYTES_1) { 00405 PRINTF_CFS("FAIL:-41 total_read=%d\n",total_read); 00406 FAIL(-41); 00407 } 00408 cfs_close(afd); 00409 /***************T5********************/ 00410 PRINTF("PASSED\n"); 00411 PRINTF("TEST "); 00412 PRINTF("20\n"); 00413 #define APPEND_BYTES_2 1000 00414 #define BULK_SIZE_2 10 00415 for (i = 0; i < APPEND_BYTES_2; i += BULK_SIZE_2) { 00416 afd = cfs_open("T5", CFS_WRITE | CFS_APPEND); 00417 if (afd < 0) { 00418 FAIL(-42); 00419 } 00420 for (j = 0; j < BULK_SIZE_2; j++) { 00421 buf[j] = 1 + ((i + j) & 0x7f); 00422 } 00423 00424 if ((r = cfs_write(afd, buf, BULK_SIZE_2)) != BULK_SIZE_2) { 00425 PRINTF_CFS("Count:%d, r=%d\n", i, r); 00426 FAIL(-43); 00427 } 00428 00429 cfs_close(afd); 00430 } 00431 00432 afd = cfs_open("T5", CFS_READ); 00433 if(afd < 0) { 00434 FAIL(-44); 00435 } 00436 total_read = 0; 00437 while((r = cfs_read(afd, buf2, sizeof(buf2))) > 0) { 00438 for(j = 0; j < r; j++) { 00439 if(buf2[j] != 1 + ((total_read + j) & 0x7f)) { 00440 PRINTF_CFS("FAIL:-45, total_read=%d r=%d\n",total_read,r); 00441 FAIL(-45); 00442 } 00443 } 00444 total_read += r; 00445 } 00446 if(r < 0) { 00447 PRINTF_CFS("FAIL:-46 r=%d\n",r); 00448 FAIL(-46); 00449 } 00450 if(total_read != APPEND_BYTES_2) { 00451 PRINTF_CFS("FAIL:-47 total_read=%d\n",total_read); 00452 FAIL(-47); 00453 } 00454 cfs_close(afd); 00455 00456 PRINTF("PASSED\n"); 00457 00458 error = 0; 00459 end: 00460 cfs_close(wfd); cfs_close(rfd); cfs_close(afd); 00461 return error; 00462 } 00463 #endif /* TESTCOFFEE */ 00464 00465 void stm32w_flash_read(int32u address, void * data, int32u length) 00466 { 00467 int8u * pdata = (int8u *)address; 00468 ENERGEST_ON(ENERGEST_TYPE_FLASH_READ); 00469 memcpy(data, pdata, length); 00470 ENERGEST_OFF(ENERGEST_TYPE_FLASH_READ); 00471 } 00472 00473 void stm32w_flash_erase(int8u sector) 00474 { 00475 //halInternalFlashErase(MFB_PAGE_ERASE, COFFEE_START + (sector) * COFFEE_SECTOR_SIZE); 00476 00477 int16u data = 0; 00478 int32u addr = COFFEE_START + (sector) * COFFEE_SECTOR_SIZE; 00479 int32u end = addr + COFFEE_SECTOR_SIZE; 00480 00481 /* This prevents from accidental write to CIB. */ 00482 if (!(addr >= MFB_BOTTOM && end <= MFB_TOP + 1)) { 00483 return; 00484 } 00485 00486 for(; addr < end; addr += 2){ 00487 halInternalFlashWrite(addr, &data, 1); 00488 } 00489 } 00490 00491 // Allocates a buffer of FLASH_PAGE_SIZE bytes statically (rather than on the stack). 00492 #ifndef STATIC_FLASH_BUFFER 00493 #define STATIC_FLASH_BUFFER 1 00494 #endif 00495 00496 void stm32w_flash_write(int32u address, const void * data, int32u length) 00497 { 00498 const int32u end = address + length; 00499 int32u i; 00500 int32u next_page, curr_page; 00501 int16u offset; 00502 00503 #if STATIC_FLASH_BUFFER 00504 static int8u buf[FLASH_PAGE_SIZE]; 00505 #else 00506 int8u buf[FLASH_PAGE_SIZE]; 00507 #endif 00508 00509 for(i = address; i < end;) { 00510 next_page = (i | (FLASH_PAGE_SIZE-1)) + 1; 00511 curr_page = i & ~(FLASH_PAGE_SIZE-1); 00512 offset = i-curr_page; 00513 if(next_page > end) { 00514 next_page = end; 00515 } 00516 00517 // Read a page from flash and put it into a mirror buffer. 00518 stm32w_flash_read(curr_page, buf, FLASH_PAGE_SIZE); 00519 // Update flash mirror data with new data. 00520 memcpy(buf + offset, data, next_page - i); 00521 // Erase flash page. 00522 ENERGEST_ON(ENERGEST_TYPE_FLASH_WRITE); 00523 halInternalFlashErase(MFB_PAGE_ERASE, i); 00524 // Write modified data form mirror buffer into the flash. 00525 halInternalFlashWrite(curr_page, (int16u *)buf, FLASH_PAGE_SIZE/2); 00526 ENERGEST_OFF(ENERGEST_TYPE_FLASH_WRITE); 00527 00528 data = (uint8_t *)data + next_page - i; 00529 i = next_page; 00530 } 00531 00532 } 00533