1
6
7
8
9
10
11
12
13
19
20
21
22
23
24
25
26
27
28
37
44
45
48
49
52
53
54
55
56
57
58
59
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
108
114
115
116
117
118
119
120
121
125
126
127
128
129
130
131
132
133
134
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
167
175
176
177
178
179
180
181
/* ... */
#include "WL_Ext_Safe.h"
#include <stdlib.h>
#include <inttypes.h>
#include "esp_log.h"
static const char *TAG = "wl_ext_safe";
#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); \
}{...}
...
#ifndef FLASH_ERASE_VALUE
#define FLASH_ERASE_VALUE 0xffffffff
#endif
#ifndef WL_EXT_SAFE_OK
#define WL_EXT_SAFE_OK 0x12345678
#endif
/* ... */
struct WL_Ext_Safe_State {
public:
uint32_t sector_restore_sign;
uint32_t sector_base_addr;
uint32_t sector_base_addr_offset;
uint32_t count;...
}{ ... };
WL_Ext_Safe::WL_Ext_Safe(): WL_Ext_Perf()
{
}{ ... }
WL_Ext_Safe::~WL_Ext_Safe()
{
}{ ... }
esp_err_t WL_Ext_Safe::config(WL_Config_s *cfg, Partition *partition)
{
esp_err_t result = ESP_OK;
result = WL_Ext_Perf::config(cfg, partition);
WL_EXT_RESULT_CHECK(result);
/* ... */
this->buff_trans_state_addr = WL_Ext_Perf::get_flash_size() - 2 * this->flash_sector_size;
this->dump_addr = WL_Ext_Perf::get_flash_size() - 1 * this->flash_sector_size;
return ESP_OK;
}{ ... }
esp_err_t WL_Ext_Safe::init()
{
esp_err_t result = ESP_OK;
ESP_LOGV(TAG, "%s", __func__);
result = WL_Ext_Perf::init();
WL_EXT_RESULT_CHECK(result);
result = this->recover();
return result;
}{ ... }
size_t WL_Ext_Safe::get_flash_size()
{
ESP_LOGV(TAG, "%s size = %" PRIu32, __func__, (uint32_t) (WL_Ext_Perf::get_flash_size() - 2 * this->flash_sector_size));
return WL_Ext_Perf::get_flash_size() - 2 * this->flash_sector_size;
}{ ... }
esp_err_t WL_Ext_Safe::recover()
{
esp_err_t result = ESP_OK;
WL_Ext_Safe_State state;
result = this->read(this->buff_trans_state_addr, &state, sizeof(WL_Ext_Safe_State));
WL_EXT_RESULT_CHECK(result);
ESP_LOGV(TAG, "%s recover, start_addr = 0x%08" PRIx32 ", sector_base_addr = 0x%08" PRIx32 ", sector_base_addr_offset= %" PRIu32 ", count=%" PRIu32, __func__, state.sector_restore_sign, state.sector_base_addr, state.sector_base_addr_offset, state.count);
if (state.sector_restore_sign == WL_EXT_SAFE_OK) {
result = this->read(this->dump_addr, this->sector_buffer, this->flash_sector_size);
WL_EXT_RESULT_CHECK(result);
result = this->erase_sector(state.sector_base_addr);
WL_EXT_RESULT_CHECK(result);
/* ... */
for (int i = 0; i < this->flash_fat_sector_size_factor; i++) {
if ((i < state.sector_base_addr_offset) || (i >= state.count + state.sector_base_addr_offset)) {
result = this->write(state.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 = this->erase_range(this->buff_trans_state_addr, this->flash_sector_size);
}{...}
return result;
}{ ... }
/* ... */
esp_err_t WL_Ext_Safe::erase_sector_fit(uint32_t first_erase_sector, uint32_t count)
{
esp_err_t result = ESP_OK;
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;
ESP_LOGV(TAG, "%s first_erase_sector=0x%08" PRIx32 ", count = %" PRIu32, __func__, first_erase_sector, count);
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 = this->erase_sector(this->dump_addr / this->flash_sector_size);
WL_EXT_RESULT_CHECK(result);
result = this->write(this->dump_addr, this->sector_buffer, this->flash_sector_size);
WL_EXT_RESULT_CHECK(result);
WL_Ext_Safe_State state;
state.sector_restore_sign = WL_EXT_SAFE_OK;
state.sector_base_addr = flash_sector_base_addr;
state.sector_base_addr_offset = pre_check_start;
state.count = count;
result = this->erase_sector(this->buff_trans_state_addr / this->flash_sector_size);
WL_EXT_RESULT_CHECK(result);
result = this->write(this->buff_trans_state_addr + 0, &state, sizeof(WL_Ext_Safe_State));
WL_EXT_RESULT_CHECK(result);
result = this->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);
}{...}
}{...}
result = this->erase_sector(this->buff_trans_state_addr / this->flash_sector_size);
WL_EXT_RESULT_CHECK(result);
return ESP_OK;
}{ ... }