• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "hc_file_iot_flash_test.h"
17 
18 #include <hctest.h>
19 #include <iot_errno.h>
20 #include <iot_flash.h>
21 #include <securec.h>
22 #include <stdbool.h>
23 #include <stdint.h>
24 #include <stdlib.h>
25 
26 #include "print_log.h"
27 #include "test_timer.h"
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 #if FLASH_START_ADDRESS_HICHAIN
34 
35 #define FLASH_SIZE_4_K 4096
36 
37 #define TOTAL_STORAGE_SIZE FLASH_SIZE_4_K // 4K Bytes
38 #define GROUP_OFFSET_ADDR 0x0100          // sizeof(struct FlashHeader)
39 #define TCIS_OFFSET_ADDR 0x0BC0
40 #define KEY_OFFSET_ADDR 0x0DC0
41 #define PART2_OFFSET_ADDR 0x0EC0
42 #define PART3_OFFSET_ADDR 0x0F00
43 #define SALT_OFFSET_ADDR 0x0F40
44 #define MK_OFFSET_ADDR 0x0F80
45 #define MAGIC_NUM 0x07DECADE
46 #define DEFAULT_VERSION 0x01
47 
48 typedef enum FileIdEnumT {
49     FILE_ID_GROUP = 0,
50     FILE_ID_TCIS_DATA,
51     FILE_ID_KEYCONTENT,
52     FILE_ID_PART2,
53     FILE_ID_PART3,
54     FILE_ID_SALT,
55     FILE_ID_MK,
56     FILE_ID_LAST,
57 } FileIdEnum;
58 
59 static uint32_t g_startAddr = FLASH_START_ADDRESS_HICHAIN;
60 
61 static const struct FlashHeader {
62     struct VersionHeader {
63         uint64_t magic;
64         uint16_t version;
65         uint8_t reserved[54]; // 54: Reserved bytes for expansion
66     } versionHeader;
67     struct FileHeader {
68         uint32_t start;
69         uint32_t size;
70         uint32_t end;
71     } fileHeaders[FILE_ID_LAST];
72     uint8_t reserved[108]; // 108: Reserved bytes for expansion
73 } g_flashHeader = {
74     .versionHeader = {
75         .magic = MAGIC_NUM,
76         .version = DEFAULT_VERSION,
77     },
78     .fileHeaders[FILE_ID_GROUP] = {
79         .start = GROUP_OFFSET_ADDR,
80         .size = TCIS_OFFSET_ADDR - GROUP_OFFSET_ADDR,
81         .end = TCIS_OFFSET_ADDR,
82     },
83     .fileHeaders[FILE_ID_TCIS_DATA] = {
84         .start = TCIS_OFFSET_ADDR,
85         .size = KEY_OFFSET_ADDR - TCIS_OFFSET_ADDR,
86         .end = KEY_OFFSET_ADDR,
87     },
88     .fileHeaders[FILE_ID_KEYCONTENT] = {
89         .start = KEY_OFFSET_ADDR,
90         .size = PART2_OFFSET_ADDR - KEY_OFFSET_ADDR,
91         .end = PART2_OFFSET_ADDR,
92     },
93     .fileHeaders[FILE_ID_PART2] = {
94         .start = PART2_OFFSET_ADDR,
95         .size = PART3_OFFSET_ADDR - PART2_OFFSET_ADDR,
96         .end = PART3_OFFSET_ADDR,
97     },
98     .fileHeaders[FILE_ID_PART3] = {
99         .start = PART3_OFFSET_ADDR,
100         .size = SALT_OFFSET_ADDR - PART3_OFFSET_ADDR,
101         .end = SALT_OFFSET_ADDR,
102     },
103     .fileHeaders[FILE_ID_SALT] = {
104         .start = SALT_OFFSET_ADDR,
105         .size = MK_OFFSET_ADDR - SALT_OFFSET_ADDR,
106         .end = MK_OFFSET_ADDR,
107     },
108     .fileHeaders[FILE_ID_MK] = {
109         .start = MK_OFFSET_ADDR,
110         .size = TOTAL_STORAGE_SIZE - MK_OFFSET_ADDR,
111         .end = TOTAL_STORAGE_SIZE,
112     },
113 };
114 
115 enum {
116     RANDOM_READ_TIMES = 20,
117 };
118 
ReadFlash(uint32_t offset,uint8_t * buffer,uint32_t size)119 static void ReadFlash(uint32_t offset, uint8_t *buffer, uint32_t size)
120 {
121     int res;
122     RUN_AND_PRINT_ELAPSED_TIME(res, IoTFlashInit());
123     TEST_ASSERT_EQUAL(IOT_SUCCESS, res);
124 
125     RUN_AND_PRINT_ELAPSED_TIME(res, IoTFlashRead(g_startAddr + offset, size, buffer));
126     TEST_ASSERT_EQUAL(IOT_SUCCESS, res);
127 
128     RUN_AND_PRINT_ELAPSED_TIME(res, IoTFlashDeinit());
129     TEST_ASSERT_EQUAL(IOT_SUCCESS, res);
130 }
131 
WriteFlash(uint32_t offset,const uint8_t * buffer,uint32_t size)132 static void WriteFlash(uint32_t offset, const uint8_t *buffer, uint32_t size)
133 {
134     int res;
135     RUN_AND_PRINT_ELAPSED_TIME(res, IoTFlashInit());
136     TEST_ASSERT_EQUAL(IOT_SUCCESS, res);
137 
138     LOGI("begin write, g_startAddr + offset = %lu, size = %lu, buffer = %p",
139         (unsigned long)(g_startAddr + offset), (unsigned long)(size), buffer);
140     RUN_AND_PRINT_ELAPSED_TIME(res, IoTFlashWrite(g_startAddr + offset, size, buffer, true));
141     TEST_ASSERT_EQUAL(IOT_SUCCESS, res);
142 
143     RUN_AND_PRINT_ELAPSED_TIME(res, IoTFlashDeinit());
144     TEST_ASSERT_EQUAL(IOT_SUCCESS, res);
145 }
146 
TestIotFlashWrite(const uint8_t * totalDataContent,uint32_t sz)147 static void TestIotFlashWrite(const uint8_t *totalDataContent, uint32_t sz)
148 {
149     LOGI("begin to test writing flash");
150     WriteFlash(0, totalDataContent, sz);
151     LOGI("test writing flash done");
152 }
153 
TestIotFlashReadWholeBlock(uint8_t * totalData,uint32_t sz,const uint8_t * totalDataContent,uint32_t contentSz)154 static void TestIotFlashReadWholeBlock(
155     uint8_t *totalData, uint32_t sz, const uint8_t *totalDataContent, uint32_t contentSz)
156 {
157     int res = memset_s(totalData, sz, 0, sz);
158     TEST_ASSERT_EQUAL(EOK, res);
159     LOGI("begin to test read whole flash");
160     ReadFlash(0, totalData, sz);
161     LOGI("test reading whole flash done");
162 
163     TEST_ASSERT_EQUAL(sz, contentSz);
164     TEST_ASSERT_EQUAL_HEX8_ARRAY(totalData, totalDataContent, sz);
165 }
166 
TestIotFlashReadFlashHeader(struct FlashHeader * flashHeader,const struct FlashHeader * flashHeaderCompare)167 static void TestIotFlashReadFlashHeader(
168     struct FlashHeader *flashHeader, const struct FlashHeader *flashHeaderCompare)
169 {
170     int res = memset_s(flashHeader, sizeof(*flashHeader), 0, sizeof(*flashHeader));
171     TEST_ASSERT_EQUAL(EOK, res);
172     LOGI("begin reading header");
173     ReadFlash(0, (uint8_t *)flashHeader, sizeof(struct FlashHeader));
174     LOGI("end reading header");
175 
176     TEST_ASSERT_EQUAL_HEX8_ARRAY((const uint8_t *)flashHeader, (const uint8_t *)flashHeaderCompare,
177         sizeof(struct FlashHeader));
178 }
179 
TestIotFlashReadSmallFiles(uint8_t * totalData,uint32_t sz,const uint8_t * totalDataContent,uint32_t contentSz)180 static void TestIotFlashReadSmallFiles(
181     uint8_t *totalData, uint32_t sz, const uint8_t *totalDataContent, uint32_t contentSz)
182 {
183     LOGI("begin reading small files");
184     TEST_ASSERT_EQUAL((uint32_t)(TOTAL_STORAGE_SIZE), contentSz);
185     int res;
186     for (int i = 0; i < FILE_ID_LAST; ++i) {
187         LOGI("test flash file %d/%d", i, FILE_ID_LAST);
188         res = memset_s(totalData, sz, 0, sz);
189         TEST_ASSERT_EQUAL(EOK, res);
190 
191         LOGI("test read from %lu, size %lu", (unsigned long)(g_flashHeader.fileHeaders[i].start),
192             (unsigned long)(g_flashHeader.fileHeaders[i].size));
193         ReadFlash(g_flashHeader.fileHeaders[i].start, totalData, g_flashHeader.fileHeaders[i].size);
194 
195         TEST_ASSERT_EQUAL_HEX8_ARRAY(totalData, totalDataContent + g_flashHeader.fileHeaders[i].start,
196             g_flashHeader.fileHeaders[i].size);
197     }
198     LOGI("end reading small files");
199 }
200 
TestIotFlashReadRandom(uint8_t * totalData,uint32_t sz,const uint8_t * totalDataContent,uint32_t contentSz)201 static void TestIotFlashReadRandom(uint8_t *totalData, uint32_t sz, const uint8_t *totalDataContent, uint32_t contentSz)
202 {
203     LOGI("begin reading random bytes");
204     TEST_ASSERT_EQUAL((uint32_t)(TOTAL_STORAGE_SIZE), contentSz);
205     int res;
206     for (int i = 0; i < RANDOM_READ_TIMES; ++i) {
207         uint32_t startAddr = rand() % TOTAL_STORAGE_SIZE;
208         uint32_t size = rand() % (TOTAL_STORAGE_SIZE - startAddr);
209         LOGI("test random read flash %d/%d, startAddr = %lu, size = %lu", i,
210             RANDOM_READ_TIMES, (unsigned long)(startAddr), (unsigned long)(size));
211         res = memset_s(totalData, sz, 0, sz);
212         TEST_ASSERT_EQUAL(EOK, res);
213         ReadFlash(startAddr, totalData, size);
214         TEST_ASSERT_EQUAL_HEX8_ARRAY(totalData, totalDataContent + startAddr, size);
215     }
216     LOGI("end reading random bytes");
217 
218     LOGI("begin reading small bytes");
219     for (int i = 0; i < RANDOM_READ_TIMES; ++i) {
220         uint32_t size = i + 1;
221         uint32_t startAddr = rand() % (TOTAL_STORAGE_SIZE - size);
222         LOGI("test random read flash %d/%d, startAddr = %lu, size = %lu", i,
223             RANDOM_READ_TIMES, (unsigned long)(startAddr), (unsigned long)(size));
224         res = memset_s(totalData, sz, 0, sz);
225         TEST_ASSERT_EQUAL(EOK, res);
226         ReadFlash(startAddr, totalData, size);
227         TEST_ASSERT_EQUAL_HEX8_ARRAY(totalData, totalDataContent + startAddr, size);
228     }
229     LOGI("end reading small bytes");
230 }
231 
TestHcFileIotFlash(void)232 void TestHcFileIotFlash(void)
233 {
234     uint8_t *totalData = (uint8_t *)malloc(TOTAL_STORAGE_SIZE);
235     TEST_ASSERT_NOT_NULL(totalData);
236     uint8_t *totalDataContent = (uint8_t *)malloc(TOTAL_STORAGE_SIZE);
237     TEST_ASSERT_NOT_NULL(totalDataContent);
238     LOGI("malloc memory succeed");
239 
240     int res, zeroCount = 0;
241     struct FlashHeader flashHeader;
242     res = memset_s(&flashHeader, sizeof(flashHeader), 0, sizeof(flashHeader));
243     TEST_ASSERT_EQUAL(EOK, res);
244     for (uint32_t i = 0; i < TOTAL_STORAGE_SIZE; ++i) {
245         totalDataContent[i] = rand() % UINT8_MAX;
246         if (totalDataContent[i] == 0) {
247             ++zeroCount;
248         }
249     }
250     TEST_ASSERT_NOT_EQUAL(TOTAL_STORAGE_SIZE, zeroCount);
251 
252     TestIotFlashWrite(totalDataContent, TOTAL_STORAGE_SIZE);
253 
254     TestIotFlashReadWholeBlock(totalData, TOTAL_STORAGE_SIZE, totalDataContent, TOTAL_STORAGE_SIZE);
255 
256     TestIotFlashReadFlashHeader(&flashHeader, (struct FlashHeader *)totalDataContent);
257 
258     TestIotFlashReadSmallFiles(totalData, TOTAL_STORAGE_SIZE, totalDataContent, TOTAL_STORAGE_SIZE);
259 
260     TestIotFlashReadRandom(totalData, TOTAL_STORAGE_SIZE, totalDataContent, TOTAL_STORAGE_SIZE);
261 
262     free(totalData);
263     free(totalDataContent);
264 }
265 
266 #else // FLASH_START_ADDRESS_HICHAIN
267 
268 void TestHcFileIotFlash(void)
269 {
270     LOGE("no FLASH_START_ADDRESS_HICHAIN, do not test iot flash");
271 }
272 
273 #endif // FLASH_START_ADDRESS_HICHAIN
274 
275 #ifdef __cplusplus
276 }
277 #endif
278