init

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2017 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #include "mbed.h"
00017 #include "greentea-client/test_env.h"
00018 #include "unity.h"
00019 #include "utest.h"
00020 
00021 #include "HeapBlockDevice.h"
00022 #include "FATFileSystem.h"
00023 #include "MBRBlockDevice.h"
00024 #include <stdlib.h>
00025 #include "mbed_retarget.h"
00026 
00027 using namespace utest::v1;
00028 
00029 #ifndef MBED_EXTENDED_TESTS
00030     #error [NOT_SUPPORTED] Filesystem tests not supported by default
00031 #endif
00032 
00033 // Test block device
00034 #define BLOCK_SIZE 512
00035 #define BLOCK_COUNT 512
00036 HeapBlockDevice bd(BLOCK_COUNT*BLOCK_SIZE, BLOCK_SIZE);
00037 
00038 
00039 // Test formatting and partitioning
00040 void test_format() {
00041     // Create two partitions splitting device in ~half
00042     int err = MBRBlockDevice::partition(&bd, 1, 0x83, 0, (BLOCK_COUNT/2)*BLOCK_SIZE);
00043     TEST_ASSERT_EQUAL(0, err);
00044 
00045     err = MBRBlockDevice::partition(&bd, 2, 0x83, -(BLOCK_COUNT/2)*BLOCK_SIZE);
00046     TEST_ASSERT_EQUAL(0, err);
00047 
00048     // Load both partitions
00049     MBRBlockDevice part1(&bd, 1);
00050     err = part1.init();
00051     TEST_ASSERT_EQUAL(0, err);
00052 
00053     MBRBlockDevice part2(&bd, 2);
00054     err = part2.init();
00055     TEST_ASSERT_EQUAL(0, err);
00056 
00057     // Format both partitions
00058     err = FATFileSystem::format(&part1);
00059     TEST_ASSERT_EQUAL(0, err);
00060 
00061     err = FATFileSystem::format(&part2);
00062     TEST_ASSERT_EQUAL(0, err);
00063 
00064     // Unload the partitions
00065     err = part1.deinit();
00066     TEST_ASSERT_EQUAL(0, err);
00067 
00068     err = part2.deinit();
00069     TEST_ASSERT_EQUAL(0, err);
00070 }
00071 
00072 
00073 // Simple multipartition test for reading/writing files
00074 template <ssize_t TEST_SIZE>
00075 void test_read_write() {
00076     // Load both partitions
00077     MBRBlockDevice part1(&bd, 1);
00078     int err = part1.init();
00079     TEST_ASSERT_EQUAL(0, err);
00080 
00081     MBRBlockDevice part2(&bd, 2);
00082     err = part2.init();
00083     TEST_ASSERT_EQUAL(0, err);
00084 
00085     // Create fat filesystems on both partitions
00086     FATFileSystem fs1("fat1");
00087     FATFileSystem fs2("fat2");
00088 
00089     err = fs1.mount(&part1);
00090     TEST_ASSERT_EQUAL(0, err);
00091 
00092     err = fs2.mount(&part2);
00093     TEST_ASSERT_EQUAL(0, err);
00094 
00095     uint8_t *buffer1 = (uint8_t *)malloc(TEST_SIZE);
00096     TEST_ASSERT(buffer1);
00097 
00098     uint8_t *buffer2 = (uint8_t *)malloc(TEST_SIZE);
00099     TEST_ASSERT(buffer2);
00100     
00101     // Fill with random sequence
00102     srand(1);
00103 
00104     for (int i = 0; i < TEST_SIZE; i++) {
00105         buffer1[i] = 0xff & rand();
00106     }
00107 
00108     for (int i = 0; i < TEST_SIZE; i++) {
00109         buffer2[i] = 0xff & rand();
00110     }
00111 
00112     // write and read files on both partitions
00113     File file;
00114     err = file.open(&fs1, "test_read_write.dat", O_WRONLY | O_CREAT);
00115     TEST_ASSERT_EQUAL(0, err);
00116     ssize_t size = file.write(buffer1, TEST_SIZE);
00117     TEST_ASSERT_EQUAL(TEST_SIZE, size);
00118     err = file.close();
00119     TEST_ASSERT_EQUAL(0, err);
00120 
00121     err = file.open(&fs2, "test_read_write.dat", O_WRONLY | O_CREAT);
00122     TEST_ASSERT_EQUAL(0, err);
00123     size = file.write(buffer2, TEST_SIZE);
00124     TEST_ASSERT_EQUAL(TEST_SIZE, size);
00125     err = file.close();
00126     TEST_ASSERT_EQUAL(0, err);
00127 
00128     err = file.open(&fs1, "test_read_write.dat", O_RDONLY);
00129     TEST_ASSERT_EQUAL(0, err);
00130     size = file.read(buffer1, TEST_SIZE);
00131     TEST_ASSERT_EQUAL(TEST_SIZE, size);
00132     err = file.close();
00133     TEST_ASSERT_EQUAL(0, err);
00134 
00135     err = file.open(&fs2, "test_read_write.dat", O_RDONLY);
00136     TEST_ASSERT_EQUAL(0, err);
00137     size = file.read(buffer2, TEST_SIZE);
00138     TEST_ASSERT_EQUAL(TEST_SIZE, size);
00139     err = file.close();
00140     TEST_ASSERT_EQUAL(0, err);
00141 
00142     // Check that the data was unmodified
00143     srand(1);
00144 
00145     for (int i = 0; i < TEST_SIZE; i++) {
00146         TEST_ASSERT_EQUAL(0xff & rand(), buffer1[i]);
00147     }
00148 
00149     for (int i = 0; i < TEST_SIZE; i++) {
00150         TEST_ASSERT_EQUAL(0xff & rand(), buffer2[i]);
00151     }
00152 
00153     err = fs1.unmount();
00154     TEST_ASSERT_EQUAL(0, err);
00155 
00156     err = fs2.unmount();
00157     TEST_ASSERT_EQUAL(0, err);
00158 
00159     err = part1.deinit();
00160     TEST_ASSERT_EQUAL(0, err);
00161 
00162     err = part2.deinit();
00163     TEST_ASSERT_EQUAL(0, err);
00164 }
00165 
00166 void test_single_mbr() {
00167     int err = bd.init();
00168     TEST_ASSERT_EQUAL(0, err);
00169 
00170     const bd_addr_t MBR_OFFSET = 0;
00171     const bd_addr_t FAT1_OFFSET = 1;
00172     const bd_addr_t FAT2_OFFSET = BLOCK_COUNT/2;
00173 
00174     uint8_t *buffer = (uint8_t *)malloc(BLOCK_SIZE);
00175     TEST_ASSERT(buffer);
00176 
00177     // Check that all three header blocks have the 0x55aa signature
00178     err = bd.read(buffer, MBR_OFFSET*BLOCK_SIZE, BLOCK_SIZE);
00179     TEST_ASSERT_EQUAL(0, err);
00180     TEST_ASSERT(memcmp(&buffer[BLOCK_SIZE-2], "\x55\xaa", 2) == 0);
00181 
00182     err = bd.read(buffer, FAT1_OFFSET*BLOCK_SIZE, BLOCK_SIZE);
00183     TEST_ASSERT_EQUAL(0, err);
00184     TEST_ASSERT(memcmp(&buffer[BLOCK_SIZE-2], "\x55\xaa", 2) == 0);
00185 
00186     err = bd.read(buffer, FAT2_OFFSET*BLOCK_SIZE, BLOCK_SIZE);
00187     TEST_ASSERT_EQUAL(0, err);
00188     TEST_ASSERT(memcmp(&buffer[BLOCK_SIZE-2], "\x55\xaa", 2) == 0);
00189 
00190     // Check that the headers for both filesystems contain a jump code
00191     // indicating they are actual FAT superblocks and not an extra MBR
00192     err = bd.read(buffer, FAT1_OFFSET*BLOCK_SIZE, BLOCK_SIZE);
00193     TEST_ASSERT_EQUAL(0, err);
00194     TEST_ASSERT(buffer[0] == 0xe9 || buffer[0] == 0xeb || buffer[0] == 0xe8);
00195 
00196     err = bd.read(buffer, FAT2_OFFSET*BLOCK_SIZE, BLOCK_SIZE);
00197     TEST_ASSERT_EQUAL(0, err);
00198     TEST_ASSERT(buffer[0] == 0xe9 || buffer[0] == 0xeb || buffer[0] == 0xe8);
00199 
00200     free(buffer);
00201 
00202     bd.deinit();
00203     TEST_ASSERT_EQUAL(0, err);
00204 }
00205 
00206 
00207 // Test setup
00208 utest::v1::status_t test_setup(const size_t number_of_cases) {
00209     GREENTEA_SETUP(10, "default_auto");
00210     return verbose_test_setup_handler(number_of_cases);
00211 }
00212 
00213 Case cases[] = {
00214     Case("Testing formating", test_format),
00215     Case("Testing read write < block", test_read_write<BLOCK_SIZE/2>),
00216     Case("Testing read write > block", test_read_write<2*BLOCK_SIZE>),
00217     Case("Testing for no extra MBRs", test_single_mbr),
00218 };
00219 
00220 Specification specification(test_setup, cases);
00221 
00222 int main() {
00223     return !Harness::run(specification);
00224 }