![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
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 00017 #if !DEVICE_FLASH 00018 #error [NOT_SUPPORTED] Flash API not supported for this target 00019 #endif 00020 00021 #include "utest/utest.h" 00022 #include "unity/unity.h" 00023 #include "greentea-client/test_env.h" 00024 00025 #include "mbed.h" 00026 #include "flash_api.h" 00027 00028 using namespace utest::v1; 00029 00030 #define TEST_CYCLES 1000000 00031 #define ALLOWED_DRIFT_PPM 1000 //0.1% 00032 00033 /* 00034 return values to be checked are documented at: 00035 http://arm-software.github.io/CMSIS_5/Pack/html/algorithmFunc.html#Verify 00036 */ 00037 00038 #ifndef ALIGN_DOWN 00039 #define ALIGN_DOWN(x, a) ((x)& ~((a) - 1)) 00040 #endif 00041 00042 static int timer_diff_start; 00043 00044 static void erase_range(flash_t *flash, uint32_t addr, uint32_t size) 00045 { 00046 while (size > 0) { 00047 uint32_t sector_size = flash_get_sector_size(flash, addr); 00048 TEST_ASSERT_NOT_EQUAL(0, sector_size); 00049 int32_t ret = flash_erase_sector(flash, addr); 00050 TEST_ASSERT_EQUAL_INT32(0, ret); 00051 addr += sector_size; 00052 size = size > sector_size ? size - sector_size : 0; 00053 } 00054 } 00055 #ifdef __CC_ARM 00056 MBED_NOINLINE 00057 __asm static void delay_loop(uint32_t count) 00058 { 00059 1 00060 SUBS a1, a1, #1 00061 BCS %BT1 00062 BX lr 00063 } 00064 #elif defined (__ICCARM__) 00065 MBED_NOINLINE 00066 static void delay_loop(uint32_t count) 00067 { 00068 __asm volatile( 00069 "loop: \n" 00070 " SUBS %0, %0, #1 \n" 00071 " BCS.n loop\n" 00072 : "+r" (count) 00073 : 00074 : "cc" 00075 ); 00076 } 00077 #elif defined ( __GNUC__ ) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) 00078 MBED_NOINLINE 00079 static void delay_loop(uint32_t count) 00080 { 00081 __asm__ volatile ( 00082 "%=:\n\t" 00083 #if defined(__thumb__) && !defined(__thumb2__) && !defined(__ARMCC_VERSION) 00084 "SUB %0, #1\n\t" 00085 #else 00086 "SUBS %0, %0, #1\n\t" 00087 #endif 00088 "BCS %=b\n\t" 00089 : "+l" (count) 00090 : 00091 : "cc" 00092 ); 00093 } 00094 #endif 00095 00096 MBED_NOINLINE 00097 static int time_cpu_cycles(uint32_t cycles) 00098 { 00099 Timer timer; 00100 timer.start(); 00101 00102 int timer_start = timer.read_us(); 00103 00104 uint32_t delay = cycles; 00105 delay_loop(delay); 00106 int timer_end = timer.read_us(); 00107 00108 timer.stop(); 00109 return timer_end - timer_start; 00110 } 00111 00112 void flash_init_test() 00113 { 00114 timer_diff_start = time_cpu_cycles(TEST_CYCLES); 00115 00116 flash_t test_flash; 00117 int32_t ret = flash_init(&test_flash); 00118 TEST_ASSERT_EQUAL_INT32(0, ret); 00119 ret = flash_free(&test_flash); 00120 TEST_ASSERT_EQUAL_INT32(0, ret); 00121 } 00122 00123 void flash_mapping_alignment_test() 00124 { 00125 flash_t test_flash; 00126 int32_t ret = flash_init(&test_flash); 00127 TEST_ASSERT_EQUAL_INT32(0, ret); 00128 00129 const uint32_t page_size = flash_get_page_size(&test_flash); 00130 const uint32_t flash_start = flash_get_start_address(&test_flash); 00131 const uint32_t flash_size = flash_get_size(&test_flash); 00132 TEST_ASSERT_TRUE(page_size != 0UL); 00133 00134 uint32_t sector_size = flash_get_sector_size(&test_flash, flash_start); 00135 for (uint32_t offset = 0; offset < flash_size; offset += sector_size) { 00136 const uint32_t sector_start = flash_start + offset; 00137 sector_size = flash_get_sector_size(&test_flash, sector_start); 00138 const uint32_t sector_end = sector_start + sector_size - 1; 00139 const uint32_t end_sector_size = flash_get_sector_size(&test_flash, sector_end); 00140 00141 // Sector size must be a valid value 00142 TEST_ASSERT_NOT_EQUAL(MBED_FLASH_INVALID_SIZE, sector_size); 00143 // Sector size must be greater than zero 00144 TEST_ASSERT_NOT_EQUAL(0, sector_size); 00145 // All flash sectors must be a multiple of page size 00146 TEST_ASSERT_EQUAL(0, sector_size % page_size); 00147 // Sector address must be a multiple of sector size 00148 TEST_ASSERT_EQUAL(0, sector_start % sector_size); 00149 // All address in a sector must return the same sector size 00150 TEST_ASSERT_EQUAL(sector_size, end_sector_size); 00151 } 00152 00153 // Make sure unmapped flash is reported correctly 00154 TEST_ASSERT_EQUAL(MBED_FLASH_INVALID_SIZE, flash_get_sector_size(&test_flash, flash_start - 1)); 00155 TEST_ASSERT_EQUAL(MBED_FLASH_INVALID_SIZE, flash_get_sector_size(&test_flash, flash_start + flash_size)); 00156 00157 ret = flash_free(&test_flash); 00158 TEST_ASSERT_EQUAL_INT32(0, ret); 00159 } 00160 00161 void flash_erase_sector_test() 00162 { 00163 flash_t test_flash; 00164 int32_t ret = flash_init(&test_flash); 00165 TEST_ASSERT_EQUAL_INT32(0, ret); 00166 00167 uint32_t addr_after_last = flash_get_start_address(&test_flash) + flash_get_size(&test_flash); 00168 uint32_t last_sector_size = flash_get_sector_size(&test_flash, addr_after_last - 1); 00169 uint32_t last_sector = addr_after_last - last_sector_size; 00170 TEST_ASSERT_EQUAL_INT32(0, last_sector % last_sector_size); 00171 ret = flash_erase_sector(&test_flash, last_sector); 00172 TEST_ASSERT_EQUAL_INT32(0, ret); 00173 00174 ret = flash_free(&test_flash); 00175 TEST_ASSERT_EQUAL_INT32(0, ret); 00176 } 00177 00178 // Erase sector, write one page, erase sector and write new data 00179 void flash_program_page_test() 00180 { 00181 flash_t test_flash; 00182 int32_t ret = flash_init(&test_flash); 00183 TEST_ASSERT_EQUAL_INT32(0, ret); 00184 00185 uint32_t test_size = flash_get_page_size(&test_flash); 00186 uint8_t *data = new uint8_t[test_size]; 00187 uint8_t *data_flashed = new uint8_t[test_size]; 00188 for (uint32_t i = 0; i < test_size; i++) { 00189 data[i] = 0xCE; 00190 } 00191 00192 // the one before the last page in the system 00193 uint32_t address = flash_get_start_address(&test_flash) + flash_get_size(&test_flash) - (2*test_size); 00194 00195 // sector size might not be same as page size 00196 uint32_t erase_sector_boundary = ALIGN_DOWN(address, flash_get_sector_size(&test_flash, address)); 00197 ret = flash_erase_sector(&test_flash, erase_sector_boundary); 00198 TEST_ASSERT_EQUAL_INT32(0, ret); 00199 00200 ret = flash_program_page(&test_flash, address, data, test_size); 00201 TEST_ASSERT_EQUAL_INT32(0, ret); 00202 00203 ret = flash_read(&test_flash, address, data_flashed, test_size); 00204 TEST_ASSERT_EQUAL_INT32(0, ret); 00205 TEST_ASSERT_EQUAL_UINT8_ARRAY(data, data_flashed, test_size); 00206 00207 // sector size might not be same as page size 00208 erase_sector_boundary = ALIGN_DOWN(address, flash_get_sector_size(&test_flash, address)); 00209 ret = flash_erase_sector(&test_flash, erase_sector_boundary); 00210 TEST_ASSERT_EQUAL_INT32(0, ret); 00211 00212 // write another data to be certain we are re-flashing 00213 for (uint32_t i = 0; i < test_size; i++) { 00214 data[i] = 0xAC; 00215 } 00216 ret = flash_program_page(&test_flash, address, data, test_size); 00217 TEST_ASSERT_EQUAL_INT32(0, ret); 00218 00219 ret = flash_read(&test_flash, address, data_flashed, test_size); 00220 TEST_ASSERT_EQUAL_INT32(0, ret); 00221 TEST_ASSERT_EQUAL_UINT8_ARRAY(data, data_flashed, test_size); 00222 00223 ret = flash_free(&test_flash); 00224 TEST_ASSERT_EQUAL_INT32(0, ret); 00225 delete[] data; 00226 delete[] data_flashed; 00227 } 00228 00229 // make sure programming works with an unaligned data buffer 00230 void flash_buffer_alignment_test() 00231 { 00232 flash_t test_flash; 00233 int32_t ret = flash_init(&test_flash); 00234 TEST_ASSERT_EQUAL_INT32(0, ret); 00235 00236 const uint32_t page_size = flash_get_page_size(&test_flash); 00237 const uint32_t buf_size = page_size + 4; 00238 uint8_t *data = new uint8_t[buf_size]; 00239 uint8_t *data_flashed = new uint8_t[buf_size]; 00240 for (uint32_t i = 0; i < buf_size; i++) { 00241 data[i] = i & 0xFF; 00242 } 00243 00244 // use the last four pages for the alignment test 00245 const uint32_t flash_end = flash_get_start_address(&test_flash) + flash_get_size(&test_flash); 00246 const uint32_t test_addr = flash_end - page_size * 4; 00247 const uint32_t erase_sector_boundary = ALIGN_DOWN(test_addr, flash_get_sector_size(&test_flash, test_addr)); 00248 erase_range(&test_flash, erase_sector_boundary, flash_end - erase_sector_boundary); 00249 00250 // make sure page program works with an unaligned data buffer 00251 for (uint32_t i = 0; i < 4; i++) { 00252 const uint32_t addr = test_addr + i * page_size; 00253 ret = flash_program_page(&test_flash, addr, data + i, page_size); 00254 TEST_ASSERT_EQUAL_INT32(0, ret); 00255 00256 ret = flash_read(&test_flash, addr, data_flashed, page_size); 00257 TEST_ASSERT_EQUAL_INT32(0, ret); 00258 TEST_ASSERT_EQUAL_UINT8_ARRAY(data + i, data_flashed, page_size); 00259 } 00260 00261 ret = flash_free(&test_flash); 00262 TEST_ASSERT_EQUAL_INT32(0, ret); 00263 delete[] data; 00264 delete[] data_flashed; 00265 } 00266 00267 // check the execution speed at the start and end of the test to make sure 00268 // cache settings weren't changed 00269 void flash_clock_and_cache_test() 00270 { 00271 const int timer_diff_end = time_cpu_cycles(TEST_CYCLES); 00272 const int acceptable_range = timer_diff_start / (1000000 / ALLOWED_DRIFT_PPM); 00273 TEST_ASSERT_UINT32_WITHIN(acceptable_range, timer_diff_start, timer_diff_end); 00274 } 00275 00276 Case cases[] = { 00277 Case("Flash - init", flash_init_test), 00278 Case("Flash - mapping alignment", flash_mapping_alignment_test), 00279 Case("Flash - erase sector", flash_erase_sector_test), 00280 Case("Flash - program page", flash_program_page_test), 00281 Case("Flash - buffer alignment test", flash_buffer_alignment_test), 00282 Case("Flash - clock and cache test", flash_clock_and_cache_test), 00283 }; 00284 00285 utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { 00286 GREENTEA_SETUP(20, "default_auto"); 00287 return greentea_test_setup_handler(number_of_cases); 00288 } 00289 00290 Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); 00291 00292 int main() { 00293 Harness::run(specification); 00294 }
Generated on Sun Jul 17 2022 08:25:27 by
![doxygen](doxygen.png)