Skip to content

Commit 714bff4

Browse files
0xc0170c1728p9
authored andcommitted
test: add flash functional tests for flash HAL
1 parent f6aece3 commit 714bff4

File tree

1 file changed

+190
-0
lines changed
  • TESTS/mbed_hal/flash/functional_tests

1 file changed

+190
-0
lines changed
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2016 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#if !DEVICE_FLASH
18+
#error [NOT_SUPPORTED] Flash API not supported for this target
19+
#endif
20+
21+
#include "utest/utest.h"
22+
#include "unity/unity.h"
23+
#include "greentea-client/test_env.h"
24+
25+
#include "mbed.h"
26+
#include "flash_api.h"
27+
#include "flash_data.h"
28+
29+
using namespace utest::v1;
30+
31+
/*
32+
return values to be checked are documented at:
33+
http://arm-software.github.io/CMSIS_5/Pack/html/algorithmFunc.html#Verify
34+
*/
35+
36+
#ifndef ALIGN_DOWN
37+
#define ALIGN_DOWN(x, a) ((x)& ~((a) - 1))
38+
#endif
39+
40+
void flash_init_test()
41+
{
42+
flash_t test_flash;
43+
int32_t ret = flash_init(&test_flash);
44+
TEST_ASSERT_EQUAL_INT32(ret, 0);
45+
ret = flash_free(&test_flash);
46+
TEST_ASSERT_EQUAL_INT32(ret, 0);
47+
}
48+
49+
// Erase sector, write one page, erase sector and write new data
50+
void flash_program_page_test()
51+
{
52+
flash_t test_flash;
53+
int32_t ret = flash_init(&test_flash);
54+
TEST_ASSERT_EQUAL_INT32(ret, 0);
55+
56+
uint32_t test_size = flash_get_page_size(&test_flash);
57+
uint8_t *data = new uint8_t[test_size];
58+
for (uint32_t i = 0; i < test_size; i++) {
59+
data[i] = 0xCE;
60+
}
61+
62+
// the one before the last page in the system
63+
uint32_t address = (test_flash.target_config->flash_start + test_flash.target_config->flash_size) - (2*test_size);
64+
65+
// sector size might not be same as page size
66+
uint32_t erase_sector_boundary = ALIGN_DOWN(address, flash_get_sector_size(&test_flash, address));
67+
ret = flash_erase_sector(&test_flash, erase_sector_boundary);
68+
TEST_ASSERT_EQUAL_INT32(ret, 0);
69+
70+
ret = flash_program_page(&test_flash, address, data, test_size);
71+
TEST_ASSERT_EQUAL_INT32(ret, 0);
72+
uint8_t *data_flashed = (uint8_t *)address;
73+
TEST_ASSERT_EQUAL_UINT8_ARRAY(data, data_flashed, test_size);
74+
75+
// sector size might not be same as page size
76+
erase_sector_boundary = ALIGN_DOWN(address, flash_get_sector_size(&test_flash, address));
77+
ret = flash_erase_sector(&test_flash, erase_sector_boundary);
78+
TEST_ASSERT_EQUAL_INT32(ret, 0);
79+
80+
// write another data to be certain we are re-flashing
81+
for (uint32_t i = 0; i < test_size; i++) {
82+
data[i] = 0xAC;
83+
}
84+
ret = flash_program_page(&test_flash, address, data, test_size);
85+
TEST_ASSERT_EQUAL_INT32(ret, 0);
86+
TEST_ASSERT_EQUAL_UINT8_ARRAY(data, data_flashed, test_size);
87+
88+
ret = flash_free(&test_flash);
89+
TEST_ASSERT_EQUAL_INT32(ret, 0);
90+
delete[] data;
91+
}
92+
93+
void flash_erase_sector_test()
94+
{
95+
flash_t test_flash;
96+
int32_t ret = flash_init(&test_flash);
97+
TEST_ASSERT_EQUAL_INT32(ret, 0);
98+
99+
uint32_t sector_size = 0x1000;
100+
uint32_t address = (test_flash.target_config->flash_start + test_flash.target_config->flash_size) - (4*sector_size);
101+
// sector size might not be same as page size
102+
uint32_t erase_sector_boundary = ALIGN_DOWN(address, flash_get_sector_size(&test_flash, address));
103+
ret = flash_erase_sector(&test_flash, erase_sector_boundary);
104+
TEST_ASSERT_EQUAL_INT32(ret, 0);
105+
106+
ret = flash_free(&test_flash);
107+
TEST_ASSERT_EQUAL_INT32(ret, 0);
108+
}
109+
110+
void flash_erase_sector_error_test()
111+
{
112+
flash_t test_flash;
113+
int32_t ret = flash_init(&test_flash);
114+
TEST_ASSERT_EQUAL_INT32(ret, 0);
115+
116+
// most common sector size to get an sector address
117+
uint32_t sector_size = 0x1000;
118+
uint32_t address = (test_flash.target_config->flash_start + test_flash.target_config->flash_size) - (4*sector_size);
119+
uint32_t erase_sector_boundary = ALIGN_DOWN(address, flash_get_sector_size(&test_flash, address));
120+
121+
// unaligned address
122+
erase_sector_boundary += 1;
123+
ret = flash_erase_sector(&test_flash, erase_sector_boundary);
124+
TEST_ASSERT_EQUAL_INT32(ret, -1);
125+
126+
ret = flash_free(&test_flash);
127+
TEST_ASSERT_EQUAL_INT32(ret, 0);
128+
}
129+
130+
void flash_program_page_error_test()
131+
{
132+
flash_t test_flash;
133+
int32_t ret = flash_init(&test_flash);
134+
TEST_ASSERT_EQUAL_INT32(ret, 0);
135+
136+
137+
uint32_t test_size = flash_get_page_size(&test_flash);
138+
// the one before the last page in the system
139+
uint32_t address = (test_flash.target_config->flash_start + test_flash.target_config->flash_size) - (2*test_size);
140+
141+
// sector size might not be same as page size
142+
uint32_t erase_sector_boundary = ALIGN_DOWN(address, flash_get_sector_size(&test_flash, address));
143+
ret = flash_erase_sector(&test_flash, erase_sector_boundary);
144+
TEST_ASSERT_EQUAL_INT32(ret, 0);
145+
146+
// we store the current data, and verify later they have not changed
147+
uint8_t *data = new uint8_t[test_size];
148+
uint8_t *previous_data = new uint8_t[test_size];
149+
uint8_t *current_data = (uint8_t *)address;
150+
for (uint32_t i = 0; i < test_size; i++) {
151+
previous_data[i] = *current_data;
152+
data[i] = 0xCE;
153+
current_data++;
154+
}
155+
156+
address += 1UL;
157+
ret = flash_program_page(&test_flash, address, data, test_size);
158+
TEST_ASSERT_EQUAL_INT32(ret, -1);
159+
TEST_ASSERT_EQUAL_UINT8_ARRAY(previous_data, current_data, test_size);
160+
161+
ret = flash_free(&test_flash);
162+
TEST_ASSERT_EQUAL_INT32(ret, 0);
163+
delete[] data;
164+
delete[] previous_data;
165+
}
166+
167+
utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) {
168+
greentea_case_failure_abort_handler(source, reason);
169+
return STATUS_CONTINUE;
170+
}
171+
172+
Case cases[] = {
173+
Case("Flash - init", flash_init_test, greentea_failure_handler),
174+
Case("Flash - erase sector", flash_erase_sector_test, greentea_failure_handler),
175+
Case("Flash - program page", flash_program_page_test, greentea_failure_handler),
176+
Case("Flash - erase sector errors", flash_erase_sector_error_test, greentea_failure_handler),
177+
Case("Flash - program page errors", flash_program_page_error_test, greentea_failure_handler),
178+
179+
};
180+
181+
utest::v1::status_t greentea_test_setup(const size_t number_of_cases) {
182+
GREENTEA_SETUP(20, "default_auto");
183+
return greentea_test_setup_handler(number_of_cases);
184+
}
185+
186+
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
187+
188+
int main() {
189+
Harness::run(specification);
190+
}

0 commit comments

Comments
 (0)