1
6
11
12
13
14
20
24
25
29
30
31
32
33
34
35
36
37
39
40
43
44
45
48
49
50
51
52
56
57
61
62
66
67
71
72
76
77
78
79
80
81
82
83
84
85
86
94
95
96
97
98
99
101
109
110
111
112
113
114
115
116
117
120
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
150
151
152
153
154
155
156
157
161
162
163
164
168
169
170
171
179
180
181
185
186
/* ... */
#include "WL_Ext_Perf.h"
#include "Partition.h"
#include <stdlib.h>
#include <inttypes.h>
#include "esp_log.h"5 includes
static const char *TAG = "wl_ext_perf";
#define WL_EXT_RESULT_CHECK(result) \
if (result != ESP_OK) { \
ESP_LOGE(TAG,"%s(%d): result = 0x%08" PRIx32, __FUNCTION__, __LINE__, (uint32_t) result); \
return (result); \
}{...}
...
WL_Ext_Perf::WL_Ext_Perf(): WL_Flash()
{
this->sector_buffer = NULL;
}{ ... }
WL_Ext_Perf::~WL_Ext_Perf()
{
free(this->sector_buffer);
}{ ... }
esp_err_t WL_Ext_Perf::config(WL_Config_s *cfg, Partition *partition)
{
wl_ext_cfg_t *ext_cfg = (wl_ext_cfg_t *)cfg;
this->flash_sector_size = ext_cfg->flash_sector_size;
this->fat_sector_size = ext_cfg->fat_sector_size;
/* ... */
this->flash_fat_sector_size_factor = this->flash_sector_size / this->fat_sector_size;
if (this->flash_fat_sector_size_factor < 1) {
return ESP_ERR_INVALID_ARG;
}{...}
this->sector_buffer = (uint32_t *)malloc(ext_cfg->flash_sector_size);
if (this->sector_buffer == NULL) {
return ESP_ERR_NO_MEM;
}{...}
return WL_Flash::config(cfg, partition);
}{ ... }
esp_err_t WL_Ext_Perf::init()
{
return WL_Flash::init();
}{ ... }
size_t WL_Ext_Perf::get_flash_size()
{
return WL_Flash::get_flash_size();
}{ ... }
size_t WL_Ext_Perf::get_sector_size()
{
return this->fat_sector_size;
}{ ... }
esp_err_t WL_Ext_Perf::erase_sector(size_t sector)
{
return WL_Flash::erase_sector(sector);
}{ ... }
/* ... */
esp_err_t WL_Ext_Perf::erase_sector_fit(uint32_t first_erase_sector, uint32_t count)
{
esp_err_t result = ESP_OK;
ESP_LOGV(TAG, "%s begin, first_erase_sector = 0x%08" PRIx32 ", count = %" PRIu32, __func__, first_erase_sector, count);
uint32_t flash_sector_base_addr = first_erase_sector / this->flash_fat_sector_size_factor;
uint32_t pre_check_start = first_erase_sector % this->flash_fat_sector_size_factor;
for (int i = 0; i < this->flash_fat_sector_size_factor; i++) {
if ((i < pre_check_start) || (i >= count + pre_check_start)) {
result = this->read(flash_sector_base_addr * this->flash_sector_size + i * this->fat_sector_size,
&this->sector_buffer[i * this->fat_sector_size / sizeof(uint32_t)],
this->fat_sector_size);
WL_EXT_RESULT_CHECK(result);
}{...}
}{...}
result = WL_Flash::erase_sector(flash_sector_base_addr);
WL_EXT_RESULT_CHECK(result);
/* ... */
for (int i = 0; i < this->flash_fat_sector_size_factor; i++) {
if ((i < pre_check_start) || (i >= count + pre_check_start)) {
result = this->write(flash_sector_base_addr * this->flash_sector_size + i * this->fat_sector_size,
&this->sector_buffer[i * this->fat_sector_size / sizeof(uint32_t)],
this->fat_sector_size);
WL_EXT_RESULT_CHECK(result);
}{...}
}{...}
return ESP_OK;
}{ ... }
esp_err_t WL_Ext_Perf::erase_range(size_t start_address, size_t size)
{
esp_err_t result = ESP_OK;
if ((start_address % this->fat_sector_size) != 0) {
result = ESP_ERR_INVALID_ARG;
}{...}
if (((size % this->fat_sector_size) != 0) || (size == 0)) {
result = ESP_ERR_INVALID_SIZE;
}{...}
WL_EXT_RESULT_CHECK(result);
ESP_LOGV(TAG, "%s begin, addr = 0x%08" PRIx32 ", size = %" PRIu32, __func__, (uint32_t) start_address, (uint32_t) size);
uint32_t sectors_count = size / this->fat_sector_size;
uint32_t pre_check_start = (start_address / this->fat_sector_size) % this->flash_fat_sector_size_factor;
uint32_t pre_check_count = (this->flash_fat_sector_size_factor - pre_check_start);
if (pre_check_count > sectors_count) {
pre_check_count = sectors_count;
}{...}
uint32_t post_check_count = (sectors_count - pre_check_count) % this->flash_fat_sector_size_factor;
uint32_t post_check_start = ((start_address + size - post_check_count * this->fat_sector_size) / this->fat_sector_size);
uint32_t rest_check_count = sectors_count - pre_check_count - post_check_count;
if ((pre_check_count == this->flash_fat_sector_size_factor) && (0 == pre_check_start)) {
rest_check_count+=this->flash_fat_sector_size_factor;
pre_check_count = 0;
}{...}
uint32_t rest_check_start = start_address + pre_check_count * this->fat_sector_size;
if (pre_check_count != 0) {
result = this->erase_sector_fit(start_address / this->fat_sector_size, pre_check_count);
WL_EXT_RESULT_CHECK(result);
}{...}
ESP_LOGV(TAG, "%s rest_check_start = %" PRIu32 ", pre_check_count=%" PRIu32 ", rest_check_count=%" PRIu32 ", post_check_count=%" PRIu32, __func__, rest_check_start, pre_check_count, rest_check_count, post_check_count);
if (rest_check_count > 0) {
rest_check_count = rest_check_count / this->flash_fat_sector_size_factor;
size_t start_sector = rest_check_start / this->flash_sector_size;
for (size_t i = 0; i < rest_check_count; i++) {
result = WL_Flash::erase_sector(start_sector + i);
WL_EXT_RESULT_CHECK(result);
}{...}
}{...}
if (post_check_count != 0) {
result = this->erase_sector_fit(post_check_start, post_check_count);
WL_EXT_RESULT_CHECK(result);
}{...}
return ESP_OK;
}{ ... }