1
6
7
13
14
15
16
17
18
19
20
21
22
23
24
25
26
33
34
35
36
37
38
39
40
53
54
66
67
80
81
91
92
93
94
95
96
97
98
99
100
101
106
107
108
113
114
115
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
/* ... */
/* ... */
#include <stdbool.h>
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "esp_attr.h"
#include "esp_cpu.h"
#include "esp_partition.h"
#include "driver/gptimer.h"
#include "esp_flash.h"10 includes
#define TIMER_RESOLUTION_HZ (1 * 1000 * 1000)
#define TIMER_ALARM_PERIOD_S 1
#define RECORD_TIME_PREPARE() uint32_t __t1, __t2
#define RECORD_TIME_START() do {__t1 = esp_cpu_get_cycle_count();} while(0)
#define RECORD_TIME_END(p_time) do{__t2 = esp_cpu_get_cycle_count(); p_time = (__t2 - __t1);} while(0)
#define GET_US_BY_CCOUNT(t) ((double)(t)/CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ)6 defines
const static char *TAG = "Example";
DRAM_ATTR static uint32_t s_t1;
DRAM_ATTR static uint32_t s_flash_func_t2;
DRAM_ATTR static uint32_t s_iram_func_t2;
static NOINLINE_ATTR void s_function_in_flash(void)
{
/* ... */
for (int i = 0; i < 100; i++) {
asm volatile("nop");
}{...}
s_flash_func_t2 = esp_cpu_get_cycle_count();
}{ ... }
static IRAM_ATTR NOINLINE_ATTR void s_function_in_iram(void)
{
/* ... */
for (int i = 0; i < 100; i++) {
asm volatile("nop");
}{...}
s_iram_func_t2 = esp_cpu_get_cycle_count();
}{ ... }
static bool IRAM_ATTR on_gptimer_alarm_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx)
{
bool is_flash = *(bool *)user_ctx;
s_t1 = esp_cpu_get_cycle_count();
if (is_flash) {
s_function_in_flash();
}{...} else {
s_function_in_iram();
}{...}
return false;
}{ ... }
static const esp_partition_t *s_get_partition(void)
{
const esp_partition_t *result = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "storage1");
if (!result) {
ESP_LOGE(TAG, "Can't find the partition, please define it correctly in `partitions.csv`");
abort();
}{...}
return result;
}{ ... }
void app_main(void)
{
const esp_partition_t *part = s_get_partition();
ESP_LOGI(TAG, "found partition '%s' at offset 0x%"PRIx32" with size 0x%"PRIx32, part->label, part->address, part->size);
ESP_ERROR_CHECK(esp_flash_erase_region(part->flash_chip, part->address, part->size));
gptimer_handle_t gptimer = NULL;
gptimer_config_t timer_config = {
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
.direction = GPTIMER_COUNT_UP,
.resolution_hz = TIMER_RESOLUTION_HZ,
}{...};
ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer));
gptimer_alarm_config_t alarm_config = {
.reload_count = 0,
.alarm_count = 1 * 1000 * 1000,
.flags.auto_reload_on_alarm = false,
}{...};
ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config));
gptimer_event_callbacks_t cbs = {
.on_alarm = on_gptimer_alarm_cb,
}{...};
bool is_flash = true;
ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, &is_flash));
ESP_ERROR_CHECK(gptimer_enable(gptimer));
ESP_ERROR_CHECK(gptimer_start(gptimer));
uint32_t erase_time = 0;
RECORD_TIME_PREPARE();
RECORD_TIME_START();
ESP_ERROR_CHECK(esp_flash_erase_region(part->flash_chip, part->address, part->size));
RECORD_TIME_END(erase_time);
ESP_ERROR_CHECK(gptimer_stop(gptimer));
ESP_LOGI(TAG, "Flash Driver Erase Operation finishes, duration:\n\t\t%0.2f us", GET_US_BY_CCOUNT(erase_time));
ESP_LOGI(TAG, "During Erase, ISR callback function(in flash) response time:\n\t\t%0.2f us", GET_US_BY_CCOUNT(s_flash_func_t2 - s_t1));
is_flash = false;
ESP_ERROR_CHECK(gptimer_set_raw_count(gptimer, 0));
ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config));
ESP_ERROR_CHECK(gptimer_start(gptimer));
RECORD_TIME_START();
ESP_ERROR_CHECK(esp_flash_erase_region(part->flash_chip, part->address, part->size));
RECORD_TIME_END(erase_time);
ESP_ERROR_CHECK(gptimer_stop(gptimer));
ESP_LOGI(TAG, "Flash Driver Erase Operation finishes, duration:\n\t\t%0.2f us", GET_US_BY_CCOUNT(erase_time));
ESP_LOGI(TAG, "During Erase, ISR callback function(in iram) response time:\n\t\t%0.2f us", GET_US_BY_CCOUNT(s_iram_func_t2 - s_t1));
ESP_LOGI(TAG, "Finish");
ESP_ERROR_CHECK(gptimer_disable(gptimer));
ESP_ERROR_CHECK(gptimer_del_timer(gptimer));
}{ ... }