Select one of the symbols to view example projects that use it.
 
Outline
#include <stdio.h>
#include <string.h>
#include "esp_flash.h"
#include "esp_partition.h"
#include "esp_vfs.h"
#include "esp_vfs_fat.h"
#include "sdkconfig.h"
#include "flash_encrypt_fatfs.h"
TAG
example_read_write_fatfs()
example_fatfs_partition_test(const esp_partition_t *, const size_t)
Files
loading (4/5)...
SourceVuESP-IDF Framework and Examplesflash_encryption samplemain/flash_encrypt_fatfs.c
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/* * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 *//* ... */ /* Flash encryption Example This example code is in the Public Domain (or CC0 licensed, at your option.) Unless required by applicable law or agreed to in writing, this software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *//* ... */ #include <stdio.h> #include <string.h> #include "esp_flash.h" #include "esp_partition.h" #include "esp_vfs.h" #include "esp_vfs_fat.h" #include "sdkconfig.h" #include "flash_encrypt_fatfs.h"8 includes static size_t example_fatfs_partition_test(const esp_partition_t* partition, const size_t text_data_offset); static const char* TAG = "example_fatfs"; void example_read_write_fatfs(void) { const esp_partition_t* partition = NULL; // Not encrypted partition test partition = esp_partition_find_first( ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, CUSTOM_FAT_PART_NAME_NE); assert(partition); size_t open_test_string_offset = example_fatfs_partition_test(partition, SIZE_MAX); assert(open_test_string_offset != SIZE_MAX); // Encrypted partition test partition = esp_partition_find_first( ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, CUSTOM_FAT_PART_NAME_E); assert(partition); example_fatfs_partition_test(partition, open_test_string_offset); }{ ... } // Performs fatfs test on the partition. // Erases, formats, writes and reads text file containing "test string". // Then: // If parameter text_data_offset == SIZE_MAX, it tries to find test string on the partition using // esp_partition_read. Returns offset from the beginning of the partition if "test string" is found, otherwise returns SIZE_MAX // If parameter text_data_offset != SIZE_MAX, it compares the flash content at the text_data_offset with the "test string" // If data matches, returns text_data_offset, if it doesn't match, returns SIZE_MAX static size_t example_fatfs_partition_test(const esp_partition_t* partition, const size_t text_data_offset) { const char* TEST_FAT_STRING = "the quick brown fox jumped over the lazy dog"; // Mount path for the partition const char *base_path = "/spiflash"; // Handle of the wear levelling library instance wl_handle_t s_wl_handle = WL_INVALID_HANDLE; esp_err_t err = ESP_FAIL; ESP_LOGI(TAG, "FAT partition \"%s\" is %sencrypted. Size is (0x%" PRIx32 " bytes) ", partition->label, (partition->encrypted) ? "" : "not ", (long unsigned int)partition->size ); ESP_LOGI(TAG, "Formatting FAT filesystem"); err = esp_vfs_fat_spiflash_format_rw_wl(base_path, partition->label); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to format FATFS (%s)", esp_err_to_name(err)); return SIZE_MAX; }{...} ESP_LOGI(TAG, "Mounting FAT filesystem"); // To mount device we need name of device partition, define base_path // and allow format partition in case if it is new one and was not formatted before const esp_vfs_fat_mount_config_t mount_config = { .max_files = 4, .format_if_mount_failed = false, .allocation_unit_size = CONFIG_WL_SECTOR_SIZE }{...}; err = esp_vfs_fat_spiflash_mount_rw_wl(base_path, partition->label, &mount_config, &s_wl_handle); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err)); return SIZE_MAX; }{...} const size_t RD_BUFF_LEN = 64; char read_buffer[RD_BUFF_LEN]; char *device_filename; device_filename = "/spiflash/inner.txt"; // Open file for writing ESP_LOGI(TAG, "Opening file"); FILE *f; f = fopen(device_filename, "wb"); if (f == NULL) { ESP_LOGE(TAG, "Failed to open file for writing"); return SIZE_MAX; }{...} fprintf(f, TEST_FAT_STRING); fclose(f); ESP_LOGI(TAG, "Written to file: '%s'", TEST_FAT_STRING); // Open file for reading ESP_LOGI(TAG, "Reading file"); f = fopen(device_filename, "rb"); if (f == NULL) { ESP_LOGE(TAG, "Failed to open file for reading"); return SIZE_MAX; }{...} fgets(read_buffer, sizeof(read_buffer), f); fclose(f); // strip newline char *pos = strchr(read_buffer, '\n'); if (pos) { *pos = '\0'; }{...} ESP_LOGI(TAG, "Read from file: '%s'", read_buffer); // Unmount FATFS ESP_LOGI(TAG, "Unmounting FAT filesystem"); ESP_ERROR_CHECK(esp_vfs_fat_spiflash_unmount_rw_wl(base_path, s_wl_handle)); if (text_data_offset == SIZE_MAX) { // try to find the TEST_FAT_STRING on the partition using esp_flash_read read. ESP_LOGI(TAG, "Read partition using esp_flash_read until test string is found"); size_t read_offset = 0; size_t read_len = RD_BUFF_LEN; void* text_addr = NULL; assert(partition->size > RD_BUFF_LEN); assert(RD_BUFF_LEN > strlen(TEST_FAT_STRING)); // read from partition until it's end while (true) { ESP_ERROR_CHECK(esp_flash_read(NULL, read_buffer, partition->address + read_offset, read_len)); // try to find characters, break the loop if found // buffer is read_buffer, len is read_len text_addr = memmem(read_buffer, read_len, TEST_FAT_STRING, strlen(TEST_FAT_STRING)); if (text_addr != NULL) { ESP_LOG_BUFFER_HEXDUMP(TAG, text_addr, strlen(TEST_FAT_STRING), ESP_LOG_INFO); // calculate offset from the beginning of the partition size_t test_str_part_offset = (text_addr - (void*)read_buffer) + read_offset; ESP_LOGI(TAG, "Test string was found at offset (0x%" PRIx32 ")", (long unsigned int)test_str_part_offset); return test_str_part_offset; }{...} // advance read buffer by the RD_BUFF_LEN - strlen(TEST_FAT_STRING) read_offset += (RD_BUFF_LEN - strlen(TEST_FAT_STRING)); if ((read_offset + strlen(TEST_FAT_STRING)) > partition->size) { // remaining unread space is not long enough to hold the searched string break; }{...} else { // remaining unread space is either the size of buffer or just the rest up to the end of partition read_len = (partition->size >= (read_offset + RD_BUFF_LEN)) ? RD_BUFF_LEN : partition->size - read_offset; }{...} }{...} }{...} else { // offset, where the expected test string should be is in text_data_offset. Try to read it, compare and report ESP_LOGI(TAG, "Read partition using esp_flash_read at expected offset (0x%" PRIx32 ") ", (long unsigned int)text_data_offset); assert(text_data_offset <= partition->size); assert((text_data_offset + strlen(TEST_FAT_STRING)) <= partition->size); // read from flash ESP_ERROR_CHECK(esp_flash_read(NULL, read_buffer, partition->address + text_data_offset, strlen(TEST_FAT_STRING))); ESP_LOG_BUFFER_HEXDUMP(TAG, read_buffer, strlen(TEST_FAT_STRING), ESP_LOG_INFO); if (memcmp(read_buffer, TEST_FAT_STRING, strlen(TEST_FAT_STRING)) == 0) { ESP_LOGI(TAG, "Data matches test string"); return text_data_offset; }{...} ESP_LOGI(TAG, "Data does not match test string"); }{...} return SIZE_MAX; }{ ... }
Details