mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 09:09:10 -04:00
Compare commits
216 Commits
e493a4c30e
...
ba15ac8634
Author | SHA1 | Date | |
---|---|---|---|
|
ba15ac8634 | ||
|
e1b9532848 | ||
|
a05d4e9e86 | ||
|
64fe41a7dc | ||
|
c990c8f752 | ||
|
d3ec2dc904 | ||
|
e7cc27417f | ||
|
3bcc85d96d | ||
|
0e0e298322 | ||
|
cbfa3eb350 | ||
|
e8394e801f | ||
|
166790d354 | ||
|
c0695e4216 | ||
|
222f48367f | ||
|
ee409e042a | ||
|
caafeff63f | ||
|
ec6745a137 | ||
|
86b7acc932 | ||
|
98733692c9 | ||
|
7689a801d4 | ||
|
9944c8acbe | ||
|
3a925002a7 | ||
|
1e8c0b7956 | ||
|
28b768807e | ||
|
b10888a591 | ||
|
8aa9103307 | ||
|
4f71b49aa6 | ||
|
aac59ed5ec | ||
|
4f4254537c | ||
|
4ef6e37fcb | ||
|
2ccc45dd11 | ||
|
e47549e9e7 | ||
|
70c29f9575 | ||
|
6a125fbafa | ||
|
2a635b6c63 | ||
|
2cc8fc907c | ||
|
d2fa3fd234 | ||
|
d5fb9c8cc1 | ||
|
bb0eecee0e | ||
|
0e956b5977 | ||
|
0021be424f | ||
|
5ab3dd40ba | ||
|
b36bc02ef1 | ||
|
6d09d5e2f7 | ||
|
3f25d48520 | ||
|
9abe6da406 | ||
|
b49a979a51 | ||
|
0e18b8b4cb | ||
|
1c1572ed51 | ||
|
1f5473dd1a | ||
|
2e8f0a47ff | ||
|
5da482e871 | ||
|
bbc33583ad | ||
|
ec177e963f | ||
|
e08f69aaff | ||
|
7851240037 | ||
|
73c5a68c6f | ||
|
f4ccb8e766 | ||
|
c50b102787 | ||
|
e4063e4aa2 | ||
|
7249a022e5 | ||
|
a30195d87b | ||
|
05bdb58297 | ||
|
b8ab11b1c7 | ||
|
5eae543571 | ||
|
609f5ef9a0 | ||
|
c62682cd07 | ||
|
3926b436b5 | ||
|
effc809cfb | ||
|
9e00034ec7 | ||
|
70db0406fc | ||
|
9e24590d9b | ||
|
c6b756b2d7 | ||
|
4ad49c4ae7 | ||
|
956f6c6e3b | ||
|
c33ac6d1a9 | ||
|
4b89915e41 | ||
|
4a21a9e341 | ||
|
57042ab56c | ||
|
75a7abe946 | ||
|
72f87748e8 | ||
|
d6ed894113 | ||
|
804a99790a | ||
|
89a6a7fc30 | ||
|
bea97c8e91 | ||
|
f5b297a654 | ||
|
8bb7427775 | ||
|
93259b9508 | ||
|
81956c63c8 | ||
|
371e1bb4c9 | ||
|
be1539f926 | ||
|
3f17cc2ab8 | ||
|
acdf49a5ac | ||
|
42039cde0a | ||
|
d43bb775a5 | ||
|
26563474d6 | ||
|
872c42ecf7 | ||
|
5fd169059d | ||
|
eaebc58e61 | ||
|
3bd69d296d | ||
|
316674a096 | ||
|
3908360e46 | ||
|
4fd6d3deae | ||
|
f83699a67f | ||
|
2006d66aee | ||
|
94c9e5299a | ||
|
c215bb04f6 | ||
|
bf89a900a3 | ||
|
b501ebe138 | ||
|
96b204bc9e | ||
|
0d16e61d96 | ||
|
ba31aab2f4 | ||
|
6c14a4b9f1 | ||
|
6b0cbe54e6 | ||
|
6c363a4075 | ||
|
80cfaeb7cc | ||
|
3e94cd5888 | ||
|
cfeca10c06 | ||
|
0d0bec6c31 | ||
|
8bb5d87f0c | ||
|
de48a67083 | ||
|
d5e5f44d36 | ||
|
2777ff73f4 | ||
|
e0c2bf1d0a | ||
|
1ab4819b74 | ||
|
173e001680 | ||
|
b22f9d2d42 | ||
|
eebf301acc | ||
|
a6371d2a97 | ||
|
fdf4070cdc | ||
|
539f7edbb3 | ||
|
eeab4e4469 | ||
|
d13b69558a | ||
|
1546c28a5f | ||
|
55dfd61796 | ||
|
121910b939 | ||
|
1f0d8585ca | ||
|
dfa2a980d7 | ||
|
9805fc85ee | ||
|
746f2e2d49 | ||
|
94667365d3 | ||
|
51f1bc3ced | ||
|
4c400e9311 | ||
|
943c9cc560 | ||
|
f47085ac70 | ||
|
eea13b76a1 | ||
|
9ac4c49553 | ||
|
1d866dc4a0 | ||
|
2429a578ad | ||
|
801c3a4c60 | ||
|
7fa47e87dd | ||
|
d121672808 | ||
|
9177682a7e | ||
|
fcbcdf32d8 | ||
|
b76369ddb6 | ||
|
b829fcff3e | ||
|
5e7d08d083 | ||
|
3a9a208edc | ||
|
d6b1a9909f | ||
|
a6b632661c | ||
|
9032828325 | ||
|
d1ce75b018 | ||
|
e741161b2e | ||
|
f5731c832f | ||
|
ab111b7f79 | ||
|
0f7dd04a83 | ||
|
26315f1c84 | ||
|
c2f015ace1 | ||
|
49fcfafed3 | ||
|
7808bccfb9 | ||
|
cc9d354ba8 | ||
|
659cfcb1f6 | ||
|
2845b70f83 | ||
|
6ad84919ad | ||
|
34ab97f081 | ||
|
706a17bdf1 | ||
|
7716134457 | ||
|
508b033cc0 | ||
|
c110c31957 | ||
|
68f8b999bb | ||
|
f728202ee9 | ||
|
3938792732 | ||
|
4446e2f632 | ||
|
d5d126b73e | ||
|
95f454b510 | ||
|
75e099129e | ||
|
7f8d47203e | ||
|
dd1de21216 | ||
|
e7500c711d | ||
|
c805a5cff8 | ||
|
64eb3a28b6 | ||
|
25a6744ff7 | ||
|
0f15c28a84 | ||
|
5639b6888d | ||
|
82f094669a | ||
|
b7237ff0e6 | ||
|
84cb47d7e0 | ||
|
2231d6b158 | ||
|
0cd1bc6753 | ||
|
7de5c312a3 | ||
|
f23acef8eb | ||
|
03109eb013 | ||
|
c8e5b0611a | ||
|
035c1ac901 | ||
|
f550724055 | ||
|
78392f0e84 | ||
|
ee54dbfaab | ||
|
b5b49eba82 | ||
|
b07276265a | ||
|
cebab7fa7f | ||
|
002e6b8cec | ||
|
00c304535f | ||
|
0b8ed8d76e | ||
|
b667770cc6 | ||
|
0d0f4adbf8 | ||
|
835d1b0bac |
@ -63,7 +63,7 @@ variables:
|
||||
CI_AUTO_TEST_SCRIPT_REPO_BRANCH: "ci/v3.1"
|
||||
|
||||
# Versioned esp-idf-doc env image to use for all document building jobs
|
||||
ESP_IDF_DOC_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-idf-doc-env:v8"
|
||||
ESP_IDF_DOC_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-idf-doc-env:v10"
|
||||
|
||||
.setup_tools_unless_target_test: &setup_tools_unless_target_test |
|
||||
if [[ -n "$IDF_DONT_USE_MIRRORS" ]]; then
|
||||
|
@ -74,6 +74,10 @@ if(CONFIG_COMPILER_DISABLE_GCC8_WARNINGS)
|
||||
"-Wno-int-in-bool-context")
|
||||
endif()
|
||||
|
||||
if(CONFIG_COMPILER_WARN_WRITE_STRINGS)
|
||||
list(APPEND compile_options "-Wwrite-strings")
|
||||
endif()
|
||||
|
||||
if(CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE)
|
||||
list(APPEND compile_definitions "-DNDEBUG")
|
||||
endif()
|
||||
@ -90,6 +94,13 @@ if(CONFIG_COMPILER_DUMP_RTL_FILES)
|
||||
list(APPEND compile_options "-fdump-rtl-expand")
|
||||
endif()
|
||||
|
||||
if(NOT ${CMAKE_C_COMPILER_VERSION} VERSION_LESS 8.0.0)
|
||||
if(CONFIG_COMPILER_HIDE_PATHS_MACROS)
|
||||
list(APPEND compile_options "-fmacro-prefix-map=${CMAKE_SOURCE_DIR}=.")
|
||||
list(APPEND compile_options "-fmacro-prefix-map=${IDF_PATH}=IDF")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# GCC-specific options
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
list(APPEND compile_options "-fstrict-volatile-bitfields"
|
||||
|
@ -30,7 +30,7 @@ endif()
|
||||
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
INCLUDE_DIRS "${include_dirs}"
|
||||
PRIV_REQUIRES soc
|
||||
PRIV_REQUIRES soc esp_ipc
|
||||
LDFRAGMENTS linker.lf)
|
||||
|
||||
|
||||
|
@ -22,7 +22,9 @@
|
||||
#include "soc/cpu.h"
|
||||
#include "soc/timer_periph.h"
|
||||
#include "esp_app_trace.h"
|
||||
#include "esp_freertos_hooks.h"
|
||||
#include "esp_private/dbg_stubs.h"
|
||||
#include "esp_ipc.h"
|
||||
#include "hal/wdt_hal.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/libc_stubs.h"
|
||||
@ -37,128 +39,113 @@
|
||||
#define LOG_LOCAL_LEVEL CONFIG_LOG_DEFAULT_LEVEL
|
||||
#include "esp_log.h"
|
||||
const static char *TAG = "esp_gcov_rtio";
|
||||
static volatile bool s_create_gcov_task = false;
|
||||
static volatile bool s_gcov_task_running = false;
|
||||
|
||||
extern void __gcov_dump(void);
|
||||
extern void __gcov_reset(void);
|
||||
|
||||
static struct syscall_stub_table s_gcov_stub_table;
|
||||
|
||||
|
||||
static int gcov_stub_lock_try_acquire_recursive(_lock_t *lock)
|
||||
void gcov_dump_task(void *pvParameter)
|
||||
{
|
||||
if (*lock && uxSemaphoreGetCount((xSemaphoreHandle)(*lock)) == 0) {
|
||||
// we can do nothing here, gcov dump is initiated with some resource locked
|
||||
// which is also used by gcov functions
|
||||
ESP_EARLY_LOGE(TAG, "Lock 0x%x is busy during GCOV dump! System state can be inconsistent after dump!", lock);
|
||||
}
|
||||
return pdTRUE;
|
||||
}
|
||||
int dump_result = 0;
|
||||
bool *running = (bool *)pvParameter;
|
||||
|
||||
static void gcov_stub_lock_acquire_recursive(_lock_t *lock)
|
||||
{
|
||||
gcov_stub_lock_try_acquire_recursive(lock);
|
||||
}
|
||||
ESP_EARLY_LOGV(TAG, "%s stack use in %d", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL));
|
||||
|
||||
static void gcov_stub_lock_release_recursive(_lock_t *lock)
|
||||
{
|
||||
}
|
||||
|
||||
static int esp_dbg_stub_gcov_dump_do(void)
|
||||
{
|
||||
int ret = ESP_OK;
|
||||
FILE* old_stderr = stderr;
|
||||
FILE* old_stdout = stdout;
|
||||
static struct syscall_stub_table *old_tables[portNUM_PROCESSORS];
|
||||
|
||||
old_tables[0] = syscall_table_ptr_pro;
|
||||
#if portNUM_PROCESSORS > 1
|
||||
old_tables[1] = syscall_table_ptr_app;
|
||||
#endif
|
||||
ESP_EARLY_LOGV(TAG, "Alloc apptrace down buf %d bytes", ESP_GCOV_DOWN_BUF_SIZE);
|
||||
void *down_buf = malloc(ESP_GCOV_DOWN_BUF_SIZE);
|
||||
if (down_buf == NULL) {
|
||||
ESP_EARLY_LOGE(TAG, "Could not allocate memory for the buffer");
|
||||
return ESP_ERR_NO_MEM;
|
||||
dump_result = ESP_ERR_NO_MEM;
|
||||
goto gcov_exit;
|
||||
}
|
||||
ESP_EARLY_LOGV(TAG, "Config apptrace down buf");
|
||||
esp_apptrace_down_buffer_config(down_buf, ESP_GCOV_DOWN_BUF_SIZE);
|
||||
ESP_EARLY_LOGV(TAG, "Dump data...");
|
||||
// incase of dual-core chip APP and PRO CPUs share the same table, so it is safe to save only PRO's table
|
||||
memcpy(&s_gcov_stub_table, syscall_table_ptr_pro, sizeof(s_gcov_stub_table));
|
||||
s_gcov_stub_table._lock_acquire_recursive = &gcov_stub_lock_acquire_recursive;
|
||||
s_gcov_stub_table._lock_release_recursive = &gcov_stub_lock_release_recursive;
|
||||
s_gcov_stub_table._lock_try_acquire_recursive = &gcov_stub_lock_try_acquire_recursive,
|
||||
syscall_table_ptr_pro = &s_gcov_stub_table;
|
||||
#if portNUM_PROCESSORS > 1
|
||||
syscall_table_ptr_app = &s_gcov_stub_table;
|
||||
#endif
|
||||
/* we are directing the std outputs to the fake ones in order to reduce stack usage */
|
||||
FILE *old_stderr = stderr;
|
||||
FILE *old_stdout = stdout;
|
||||
stderr = (FILE *) &__sf_fake_stderr;
|
||||
stdout = (FILE *) &__sf_fake_stdout;
|
||||
ESP_EARLY_LOGV(TAG, "Dump data...");
|
||||
__gcov_dump();
|
||||
// reset dump status to allow incremental data accumulation
|
||||
__gcov_reset();
|
||||
stdout = old_stdout;
|
||||
stderr = old_stderr;
|
||||
syscall_table_ptr_pro = old_tables[0];
|
||||
#if portNUM_PROCESSORS > 1
|
||||
syscall_table_ptr_app = old_tables[1];
|
||||
#endif
|
||||
ESP_EARLY_LOGV(TAG, "Free apptrace down buf");
|
||||
free(down_buf);
|
||||
stderr = old_stderr;
|
||||
stdout = old_stdout;
|
||||
ESP_EARLY_LOGV(TAG, "Finish file transfer session");
|
||||
ret = esp_apptrace_fstop(ESP_APPTRACE_DEST_TRAX);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!", ret);
|
||||
dump_result = esp_apptrace_fstop(ESP_APPTRACE_DEST_TRAX);
|
||||
if (dump_result != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!", dump_result);
|
||||
}
|
||||
|
||||
gcov_exit:
|
||||
ESP_EARLY_LOGV(TAG, "dump_result %d", dump_result);
|
||||
if (running) {
|
||||
*running = false;
|
||||
}
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "%s stack use out %d", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL));
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void gcov_create_task(void *arg)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
xTaskCreatePinnedToCore(&gcov_dump_task, "gcov_dump_task", 2048, (void *)&s_gcov_task_running, configMAX_PRIORITIES - 1, NULL, 0);
|
||||
}
|
||||
|
||||
void gcov_create_task_tick_hook(void)
|
||||
{
|
||||
extern esp_err_t esp_ipc_start_gcov_from_isr(uint32_t cpu_id, esp_ipc_func_t func, void* arg);
|
||||
if (s_create_gcov_task) {
|
||||
if (esp_ipc_start_gcov_from_isr(xPortGetCoreID(), &gcov_create_task, NULL) == ESP_OK) {
|
||||
s_create_gcov_task = false;
|
||||
}
|
||||
}
|
||||
ESP_EARLY_LOGV(TAG, "exit %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Triggers gcov info dump.
|
||||
* @brief Triggers gcov info dump task
|
||||
* This function is to be called by OpenOCD, not by normal user code.
|
||||
* TODO: what about interrupted flash access (when cache disabled)???
|
||||
* TODO: what about interrupted flash access (when cache disabled)
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
static int esp_dbg_stub_gcov_entry(void)
|
||||
{
|
||||
return esp_dbg_stub_gcov_dump_do();
|
||||
/* we are in isr context here */
|
||||
s_create_gcov_task = true;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int gcov_rtio_atexit(void (*function)(void) __attribute__ ((unused)))
|
||||
{
|
||||
uint32_t capabilities = 0;
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
esp_dbg_stub_entry_set(ESP_DBG_STUB_ENTRY_GCOV, (uint32_t)&esp_dbg_stub_gcov_entry);
|
||||
return 0;
|
||||
if (esp_dbg_stub_entry_get(ESP_DBG_STUB_ENTRY_CAPABILITIES, &capabilities) == ESP_OK) {
|
||||
esp_dbg_stub_entry_set(ESP_DBG_STUB_ENTRY_CAPABILITIES, capabilities | ESP_DBG_STUB_CAP_GCOV_TASK);
|
||||
}
|
||||
esp_register_freertos_tick_hook(gcov_create_task_tick_hook);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void esp_gcov_dump(void)
|
||||
{
|
||||
// disable IRQs on this CPU, other CPU is halted by OpenOCD
|
||||
unsigned irq_state = portENTER_CRITICAL_NESTED();
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
int other_core = xPortGetCoreID() ? 0 : 1;
|
||||
esp_cpu_stall(other_core);
|
||||
#endif
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
|
||||
while (!esp_apptrace_host_is_connected(ESP_APPTRACE_DEST_TRAX)) {
|
||||
wdt_hal_context_t twdt = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
|
||||
wdt_hal_context_t iwdt = {.inst = WDT_MWDT1, .mwdt_dev = &TIMERG1};
|
||||
//Feed the Task Watchdog (TG0) to prevent it from timing out
|
||||
wdt_hal_write_protect_disable(&twdt);
|
||||
wdt_hal_feed(&twdt);
|
||||
wdt_hal_write_protect_enable(&twdt);
|
||||
//Likewise, feed the Interrupt Watchdog (TG1) to prevent a reboot
|
||||
wdt_hal_write_protect_disable(&iwdt);
|
||||
wdt_hal_feed(&iwdt);
|
||||
wdt_hal_write_protect_enable(&iwdt);
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
|
||||
esp_dbg_stub_gcov_dump_do();
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
esp_cpu_unstall(other_core);
|
||||
#endif
|
||||
portEXIT_CRITICAL_NESTED(irq_state);
|
||||
/* We are not in isr context here. Waiting for the completion is safe */
|
||||
s_gcov_task_running = true;
|
||||
s_create_gcov_task = true;
|
||||
while (s_gcov_task_running) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
}
|
||||
|
||||
void *gcov_rtio_fopen(const char *path, const char *mode)
|
||||
|
@ -887,8 +887,8 @@ esp_err_t esp_ota_erase_last_boot_app_partition(void)
|
||||
}
|
||||
|
||||
#if SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS > 1 && CONFIG_SECURE_BOOT_V2_ENABLED
|
||||
esp_err_t esp_ota_revoke_secure_boot_public_key(esp_ota_secure_boot_public_key_index_t index) {
|
||||
|
||||
esp_err_t esp_ota_revoke_secure_boot_public_key(esp_ota_secure_boot_public_key_index_t index)
|
||||
{
|
||||
if (!esp_secure_boot_enabled()) {
|
||||
ESP_LOGE(TAG, "Secure boot v2 has not been enabled.");
|
||||
return ESP_FAIL;
|
||||
@ -901,8 +901,70 @@ esp_err_t esp_ota_revoke_secure_boot_public_key(esp_ota_secure_boot_public_key_i
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ets_secure_boot_revoke_public_key_digest(index);
|
||||
esp_image_sig_public_key_digests_t app_digests = { 0 };
|
||||
esp_err_t err = esp_secure_boot_get_signature_blocks_for_running_app(true, &app_digests);
|
||||
if (err != ESP_OK || app_digests.num_digests == 0) {
|
||||
ESP_LOGE(TAG, "This app is not signed, but check signature on update is enabled in config. It won't be possible to verify any update.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ets_secure_boot_key_digests_t trusted_keys;
|
||||
int ets_status = ets_secure_boot_read_key_digests(&trusted_keys);
|
||||
if (ets_status != ETS_OK) {
|
||||
ESP_LOGE(TAG, "Could not read the secure boot key digests from efuse. Aborting..");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (trusted_keys.key_digests[index] == NULL) {
|
||||
ESP_LOGI(TAG, "Trusted Key block(%d) already revoked.", index);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_image_sig_public_key_digests_t trusted_digests = { 0 };
|
||||
for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
|
||||
if (i == index) {
|
||||
continue; // omitting - to find if there is a valid key after revoking this digest
|
||||
}
|
||||
|
||||
if (trusted_keys.key_digests[i] != NULL) {
|
||||
bool all_zeroes = true;
|
||||
for (unsigned j = 0; j < ESP_SECURE_BOOT_DIGEST_LEN; j++) {
|
||||
all_zeroes = all_zeroes && (*(uint8_t *)(trusted_keys.key_digests[i] + j) == 0);
|
||||
}
|
||||
if (!all_zeroes) {
|
||||
memcpy(trusted_digests.key_digests[trusted_digests.num_digests++], (uint8_t *)trusted_keys.key_digests[i], ESP_SECURE_BOOT_DIGEST_LEN);
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Empty trusted key block (%d).", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool match = false;
|
||||
for (unsigned i = 0; i < trusted_digests.num_digests; i++) {
|
||||
if (match == true) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (unsigned j = 0; j < app_digests.num_digests; j++) {
|
||||
if (memcmp(trusted_digests.key_digests[i], app_digests.key_digests[j], ESP_SECURE_BOOT_DIGEST_LEN) == 0) {
|
||||
ESP_LOGI(TAG, "App key block(%d) matches Trusted key block(%d)[%d -> Next active trusted key block].", j, i, i);
|
||||
esp_err_t err = esp_efuse_set_digest_revoke(index);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to revoke digest (0x%x).", err);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_LOGI(TAG, "Revoked signature block %d.", index);
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (match == false) {
|
||||
ESP_LOGE(TAG, "Running app doesn't have another valid secure boot key. Cannot revoke current key(%d).", index);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
@ -472,6 +472,7 @@ menu "Security features"
|
||||
bool "Enable hardware Secure Boot in bootloader (READ DOCS FIRST)"
|
||||
default n
|
||||
depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || ESP32C3_REV_MIN_3
|
||||
select ESPTOOLPY_NO_STUB if !IDF_TARGET_ESP32 && !IDF_TARGET_ESP32S2
|
||||
help
|
||||
Build a bootloader which enables Secure Boot on first boot.
|
||||
|
||||
@ -732,9 +733,17 @@ menu "Security features"
|
||||
efuse when Secure Boot is enabled. This prevents any more efuses from being read protected.
|
||||
|
||||
If this option is set, it will remain possible to write the EFUSE_RD_DIS efuse field after Secure
|
||||
Boot is enabled. This may allow an attacker to read-protect the BLK2 efuse holding the public
|
||||
key digest, causing an immediate denial of service and possibly allowing an additional fault
|
||||
injection attack to bypass the signature protection.
|
||||
Boot is enabled. This may allow an attacker to read-protect the BLK2 efuse (for ESP32) and
|
||||
BLOCK4-BLOCK10 (i.e. BLOCK_KEY0-BLOCK_KEY5)(for other chips) holding the public key digest, causing an
|
||||
immediate denial of service and possibly allowing an additional fault injection attack to
|
||||
bypass the signature protection.
|
||||
|
||||
NOTE: Once a BLOCK is read-protected, the application will read all zeros from that block
|
||||
|
||||
NOTE: If "UART ROM download mode (Permanently disabled (recommended))" or
|
||||
"UART ROM download mode (Permanently switch to Secure mode (recommended))" is set,
|
||||
then it is __NOT__ possible to read/write efuses using espefuse.py utility.
|
||||
However, efuse can be read/written from the application
|
||||
|
||||
config SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC
|
||||
bool "Leave UART bootloader encryption enabled"
|
||||
|
@ -48,6 +48,7 @@ SECTIONS
|
||||
*libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*)
|
||||
|
@ -36,6 +36,7 @@ SECTIONS
|
||||
*libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*)
|
||||
|
@ -35,6 +35,7 @@ SECTIONS
|
||||
*libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*)
|
||||
|
@ -36,6 +36,7 @@ SECTIONS
|
||||
*libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*)
|
||||
|
@ -27,6 +27,7 @@ if(BOOTLOADER_BUILD)
|
||||
"src/bootloader_panic.c"
|
||||
"src/${IDF_TARGET}/bootloader_sha.c"
|
||||
"src/${IDF_TARGET}/flash_encrypt.c"
|
||||
"src/${IDF_TARGET}/bootloader_soc.c"
|
||||
"src/${IDF_TARGET}/bootloader_${IDF_TARGET}.c"
|
||||
)
|
||||
list(APPEND priv_requires hal)
|
||||
|
@ -105,6 +105,15 @@ bool bootloader_common_label_search(const char *list, char *label);
|
||||
*/
|
||||
void bootloader_configure_spi_pins(int drv);
|
||||
|
||||
/**
|
||||
* @brief Get flash CS IO
|
||||
*
|
||||
* Can be determined by eFuse values, or the default value
|
||||
*
|
||||
* @return Flash CS IO
|
||||
*/
|
||||
uint8_t bootloader_flash_get_cs_io(void);
|
||||
|
||||
/**
|
||||
* @brief Calculates a sha-256 for a given partition or returns a appended digest.
|
||||
*
|
||||
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @brief Configure analog super WDT reset
|
||||
*
|
||||
* @param enable Boolean to enable or disable super WDT reset
|
||||
*/
|
||||
void bootloader_ana_super_wdt_reset_config(bool enable);
|
||||
|
||||
/**
|
||||
* @brief Configure analog brownout reset
|
||||
*
|
||||
* @param enable Boolean to enable or disable brownout reset
|
||||
*/
|
||||
void bootloader_ana_bod_reset_config(bool enable);
|
||||
|
||||
/**
|
||||
* @brief Configure analog clock glitch reset
|
||||
*
|
||||
* @param enable Boolean to enable or disable clock glitch reset
|
||||
*/
|
||||
void bootloader_ana_clock_glitch_reset_config(bool enable);
|
@ -29,6 +29,7 @@
|
||||
#include "esp_rom_crc.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_rom_efuse.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_common.h"
|
||||
@ -192,8 +193,19 @@ void bootloader_common_vddsdio_configure(void)
|
||||
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
|
||||
}
|
||||
|
||||
|
||||
RESET_REASON bootloader_common_get_reset_reason(int cpu_no)
|
||||
{
|
||||
return rtc_get_reset_reason(cpu_no);
|
||||
}
|
||||
|
||||
uint8_t bootloader_flash_get_cs_io(void)
|
||||
{
|
||||
uint8_t cs_io;
|
||||
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
|
||||
if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_SPI) {
|
||||
cs_io = SPI_CS0_GPIO_NUM;
|
||||
} else {
|
||||
cs_io = (spiconfig >> 18) & 0x3f;
|
||||
}
|
||||
return cs_io;
|
||||
}
|
||||
|
@ -27,5 +27,5 @@ uint8_t bootloader_common_get_chip_revision(void)
|
||||
uint32_t bootloader_common_get_chip_ver_pkg(void)
|
||||
{
|
||||
// should return the same value as esp_efuse_get_pkg_ver()
|
||||
return REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_PKG_VERSION);
|
||||
return REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_4_REG, EFUSE_PKG_VERSION);
|
||||
}
|
||||
|
@ -77,6 +77,7 @@
|
||||
#include "bootloader_utility.h"
|
||||
#include "bootloader_sha.h"
|
||||
#include "bootloader_console.h"
|
||||
#include "bootloader_soc.h"
|
||||
#include "esp_efuse.h"
|
||||
|
||||
static const char *TAG = "boot";
|
||||
@ -637,6 +638,12 @@ static void load_image(const esp_image_metadata_t *image_data)
|
||||
ESP_LOGI(TAG, "Disabling RNG early entropy source...");
|
||||
bootloader_random_disable();
|
||||
|
||||
/* Disable glitch reset after all the security checks are completed.
|
||||
* Glitch detection can be falsely triggered by EMI interference (high RF TX power, etc)
|
||||
* and to avoid such false alarms, disable it.
|
||||
*/
|
||||
bootloader_ana_clock_glitch_reset_config(false);
|
||||
|
||||
// copy loaded segments to RAM, set up caches for mapped segments, and start application
|
||||
unpack_load_app(image_data);
|
||||
}
|
||||
|
21
components/bootloader_support/src/esp32/bootloader_soc.c
Normal file
21
components/bootloader_support/src/esp32/bootloader_soc.c
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
|
||||
void bootloader_ana_super_wdt_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
void bootloader_ana_bod_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
void bootloader_ana_clock_glitch_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
@ -45,6 +45,7 @@
|
||||
#include "regi2c_ctrl.h"
|
||||
#include "bootloader_console.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_soc.h"
|
||||
|
||||
static const char *TAG = "boot.esp32c3";
|
||||
|
||||
@ -272,7 +273,7 @@ static inline void bootloader_hardware_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void bootloader_glitch_reset_disable(void)
|
||||
static inline void bootloader_ana_reset_config(void)
|
||||
{
|
||||
/*
|
||||
For origin chip & ECO1: only support swt reset;
|
||||
@ -280,10 +281,27 @@ static inline void bootloader_glitch_reset_disable(void)
|
||||
For ECO3: fix clock glitch reset bug, support all reset, include: swt & brownout & clock glitch reset.
|
||||
*/
|
||||
uint8_t chip_version = bootloader_common_get_chip_revision();
|
||||
if (chip_version < 2) {
|
||||
REG_SET_FIELD(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SEL, RTC_CNTL_FIB_SUPER_WDT_RST);
|
||||
} else if (chip_version == 2) {
|
||||
REG_SET_FIELD(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SEL, RTC_CNTL_FIB_SUPER_WDT_RST | RTC_CNTL_FIB_BOR_RST);
|
||||
switch (chip_version) {
|
||||
case 0:
|
||||
case 1:
|
||||
//Enable WDT reset. Disable BOR and GLITCH reset
|
||||
bootloader_ana_super_wdt_reset_config(true);
|
||||
bootloader_ana_bod_reset_config(false);
|
||||
bootloader_ana_clock_glitch_reset_config(false);
|
||||
break;
|
||||
case 2:
|
||||
//Enable WDT and BOR reset. Disable GLITCH reset
|
||||
bootloader_ana_super_wdt_reset_config(true);
|
||||
bootloader_ana_bod_reset_config(true);
|
||||
bootloader_ana_clock_glitch_reset_config(false);
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
//Enable WDT, BOR, and GLITCH reset
|
||||
bootloader_ana_super_wdt_reset_config(true);
|
||||
bootloader_ana_bod_reset_config(true);
|
||||
bootloader_ana_clock_glitch_reset_config(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -292,7 +310,7 @@ esp_err_t bootloader_init(void)
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
bootloader_hardware_init();
|
||||
bootloader_glitch_reset_disable();
|
||||
bootloader_ana_reset_config();
|
||||
bootloader_super_wdt_auto_feed();
|
||||
// protect memory region
|
||||
bootloader_init_mem();
|
||||
|
41
components/bootloader_support/src/esp32c3/bootloader_soc.c
Normal file
41
components/bootloader_support/src/esp32c3/bootloader_soc.c
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
void bootloader_ana_super_wdt_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SUPER_WDT_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
|
||||
} else {
|
||||
REG_CLR_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_BYPASS_RST);
|
||||
}
|
||||
}
|
||||
|
||||
void bootloader_ana_bod_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_BOR_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ANA_RST_EN);
|
||||
} else {
|
||||
REG_CLR_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ANA_RST_EN);
|
||||
}
|
||||
}
|
||||
|
||||
void bootloader_ana_clock_glitch_reset_config(bool enable)
|
||||
{
|
||||
REG_CLR_BIT(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_GLITCH_RST);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_GLITCH_RST_EN);
|
||||
} else {
|
||||
REG_CLR_BIT(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_GLITCH_RST_EN);
|
||||
}
|
||||
}
|
@ -152,6 +152,12 @@ static esp_err_t initialise_flash_encryption(void)
|
||||
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT);
|
||||
|
||||
#if defined(CONFIG_SECURE_BOOT_V2_ENABLED) && !defined(CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS)
|
||||
// This bit is set when enabling Secure Boot V2, but we can't enable it until this later point in the first boot
|
||||
// otherwise the Flash Encryption key cannot be read protected
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS);
|
||||
#endif
|
||||
|
||||
esp_err_t err = esp_efuse_batch_write_commit();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err);
|
||||
|
@ -269,7 +269,7 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag
|
||||
ESP_LOGI(TAG, "Disable hardware & software JTAG...");
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_PAD_JTAG);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_USB_JTAG);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_SOFT_DIS_JTAG);
|
||||
esp_efuse_write_field_cnt(ESP_EFUSE_SOFT_DIS_JTAG, ESP_EFUSE_SOFT_DIS_JTAG[0]->bit_count);
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED");
|
||||
#endif
|
||||
@ -280,6 +280,21 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag
|
||||
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_EN);
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS
|
||||
bool rd_dis_now = true;
|
||||
#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
|
||||
/* If flash encryption is not enabled yet then don't read-disable efuses yet, do it later in the boot
|
||||
when Flash Encryption is being enabled */
|
||||
rd_dis_now = esp_flash_encryption_enabled();
|
||||
#endif
|
||||
if (rd_dis_now) {
|
||||
ESP_LOGI(TAG, "Prevent read disabling of additional efuses...");
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS);
|
||||
}
|
||||
#else
|
||||
ESP_LOGW(TAG, "Allowing read disabling of additional efuses - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
esp_err_t err = esp_efuse_batch_write_commit();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err);
|
||||
|
21
components/bootloader_support/src/esp32s2/bootloader_soc.c
Normal file
21
components/bootloader_support/src/esp32s2/bootloader_soc.c
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
|
||||
void bootloader_ana_super_wdt_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
void bootloader_ana_bod_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
void bootloader_ana_clock_glitch_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
@ -176,6 +176,12 @@ static esp_err_t initialise_flash_encryption(void)
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_BOOT_REMAP);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT);
|
||||
|
||||
#if defined(CONFIG_SECURE_BOOT_V2_ENABLED) && !defined(CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS)
|
||||
// This bit is set when enabling Secure Boot V2, but we can't enable it until this later point in the first boot
|
||||
// otherwise the Flash Encryption key cannot be read protected
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS);
|
||||
#endif
|
||||
|
||||
esp_err_t err = esp_efuse_batch_write_commit();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err);
|
||||
|
@ -282,6 +282,21 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag
|
||||
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_EN);
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS
|
||||
bool rd_dis_now = true;
|
||||
#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
|
||||
/* If flash encryption is not enabled yet then don't read-disable efuses yet, do it later in the boot
|
||||
when Flash Encryption is being enabled */
|
||||
rd_dis_now = esp_flash_encryption_enabled();
|
||||
#endif
|
||||
if (rd_dis_now) {
|
||||
ESP_LOGI(TAG, "Prevent read disabling of additional efuses...");
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS);
|
||||
}
|
||||
#else
|
||||
ESP_LOGW(TAG, "Allowing read disabling of additional efuses - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
esp_err_t err = esp_efuse_batch_write_commit();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err);
|
||||
|
21
components/bootloader_support/src/esp32s3/bootloader_soc.c
Normal file
21
components/bootloader_support/src/esp32s3/bootloader_soc.c
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
|
||||
void bootloader_ana_super_wdt_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
void bootloader_ana_bod_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
void bootloader_ana_clock_glitch_reset_config(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
@ -270,7 +270,7 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag
|
||||
#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
|
||||
ESP_LOGI(TAG, "Disable hardware & software JTAG...");
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_HARD_DIS_JTAG);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_SOFT_DIS_JTAG);
|
||||
esp_efuse_write_field_cnt(ESP_EFUSE_SOFT_DIS_JTAG, ESP_EFUSE_SOFT_DIS_JTAG[0]->bit_count);
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
@ -354,14 +354,15 @@ static bool verify_load_addresses(int segment_index, intptr_t load_addr, intptr_
|
||||
const char *reason = NULL;
|
||||
extern int _dram_start, _dram_end, _loader_text_start, _loader_text_end;
|
||||
void *load_addr_p = (void *)load_addr;
|
||||
void *load_end_p = (void *)load_end;
|
||||
void *load_inclusive_end_p = (void *)load_end - 0x1;
|
||||
void *load_exclusive_end_p = (void *)load_end;
|
||||
|
||||
if (load_end == load_addr) {
|
||||
return true; // zero-length segments are fine
|
||||
}
|
||||
assert(load_end > load_addr); // data_len<16MB is checked in verify_segment_header() which is called before this, so this should always be true
|
||||
|
||||
if (esp_ptr_in_dram(load_addr_p) && esp_ptr_in_dram(load_end_p)) { /* Writing to DRAM */
|
||||
if (esp_ptr_in_dram(load_addr_p) && esp_ptr_in_dram(load_inclusive_end_p)) { /* Writing to DRAM */
|
||||
/* Check if we're clobbering the stack */
|
||||
intptr_t sp = (intptr_t)get_sp();
|
||||
if (bootloader_util_regions_overlap(sp - STACK_LOAD_HEADROOM, SOC_ROM_STACK_START,
|
||||
@ -396,8 +397,8 @@ static bool verify_load_addresses(int segment_index, intptr_t load_addr, intptr_
|
||||
iram_load_addr = (intptr_t)esp_ptr_diram_dram_to_iram((void *)SOC_DIRAM_DRAM_LOW);
|
||||
}
|
||||
|
||||
if (esp_ptr_in_diram_dram(load_end_p)) {
|
||||
iram_load_end = (intptr_t)esp_ptr_diram_dram_to_iram(load_end_p);
|
||||
if (esp_ptr_in_diram_dram(load_inclusive_end_p)) {
|
||||
iram_load_end = (intptr_t)esp_ptr_diram_dram_to_iram(load_exclusive_end_p);
|
||||
} else {
|
||||
iram_load_end = (intptr_t)esp_ptr_diram_dram_to_iram((void *)SOC_DIRAM_DRAM_HIGH);
|
||||
}
|
||||
@ -409,7 +410,7 @@ static bool verify_load_addresses(int segment_index, intptr_t load_addr, intptr_
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (esp_ptr_in_iram(load_addr_p) && esp_ptr_in_iram(load_end_p)) { /* Writing to IRAM */
|
||||
else if (esp_ptr_in_iram(load_addr_p) && esp_ptr_in_iram(load_inclusive_end_p)) { /* Writing to IRAM */
|
||||
/* Check for overlap of 'loader' section of IRAM */
|
||||
if (bootloader_util_regions_overlap((intptr_t)&_loader_text_start, (intptr_t)&_loader_text_end,
|
||||
load_addr, load_end)) {
|
||||
@ -433,8 +434,8 @@ static bool verify_load_addresses(int segment_index, intptr_t load_addr, intptr_
|
||||
dram_load_addr = (intptr_t)esp_ptr_diram_iram_to_dram((void *)SOC_DIRAM_IRAM_LOW);
|
||||
}
|
||||
|
||||
if (esp_ptr_in_diram_iram(load_end_p)) {
|
||||
dram_load_end = (intptr_t)esp_ptr_diram_iram_to_dram(load_end_p);
|
||||
if (esp_ptr_in_diram_iram(load_inclusive_end_p)) {
|
||||
dram_load_end = (intptr_t)esp_ptr_diram_iram_to_dram(load_exclusive_end_p);
|
||||
} else {
|
||||
dram_load_end = (intptr_t)esp_ptr_diram_iram_to_dram((void *)SOC_DIRAM_IRAM_HIGH);
|
||||
}
|
||||
@ -446,11 +447,11 @@ static bool verify_load_addresses(int segment_index, intptr_t load_addr, intptr_
|
||||
}
|
||||
}
|
||||
/* Sections entirely in RTC memory won't overlap with a vanilla bootloader but are valid load addresses, thus skipping them from the check */
|
||||
} else if (esp_ptr_in_rtc_iram_fast(load_addr_p) && esp_ptr_in_rtc_iram_fast(load_end_p)){
|
||||
} else if (esp_ptr_in_rtc_iram_fast(load_addr_p) && esp_ptr_in_rtc_iram_fast(load_inclusive_end_p)){
|
||||
return true;
|
||||
} else if (esp_ptr_in_rtc_dram_fast(load_addr_p) && esp_ptr_in_rtc_dram_fast(load_end_p)){
|
||||
} else if (esp_ptr_in_rtc_dram_fast(load_addr_p) && esp_ptr_in_rtc_dram_fast(load_inclusive_end_p)){
|
||||
return true;
|
||||
} else if (esp_ptr_in_rtc_slow(load_addr_p) && esp_ptr_in_rtc_slow(load_end_p)) {
|
||||
} else if (esp_ptr_in_rtc_slow(load_addr_p) && esp_ptr_in_rtc_slow(load_inclusive_end_p)) {
|
||||
return true;
|
||||
} else { /* Not a DRAM or an IRAM or RTC Fast IRAM, RTC Fast DRAM or RTC Slow address */
|
||||
reason = "bad load address range";
|
||||
|
@ -92,7 +92,7 @@ do{\
|
||||
} while(0)
|
||||
|
||||
#define OSI_FUNCS_TIME_BLOCKING 0xffffffff
|
||||
#define OSI_VERSION 0x00010002
|
||||
#define OSI_VERSION 0x00010003
|
||||
#define OSI_MAGIC_VALUE 0xFADEBEAD
|
||||
|
||||
/* SPIRAM Configuration */
|
||||
@ -184,6 +184,10 @@ struct osi_funcs_t {
|
||||
void *(* _coex_schm_curr_phase_get)(void);
|
||||
int (* _coex_wifi_channel_get)(uint8_t *primary, uint8_t *secondary);
|
||||
int (* _coex_register_wifi_channel_change_callback)(void *cb);
|
||||
xt_handler (*_set_isr_l3)(int n, xt_handler f, void *arg);
|
||||
void (*_interrupt_l3_disable)(void);
|
||||
void (*_interrupt_l3_restore)(void);
|
||||
void *(* _customer_queue_create)(uint32_t queue_len, uint32_t item_size);
|
||||
uint32_t _magic;
|
||||
};
|
||||
|
||||
@ -270,6 +274,7 @@ static bool btdm_queue_generic_deregister(btdm_queue_item_t *queue);
|
||||
#endif /* CONFIG_SPIRAM_USE_MALLOC */
|
||||
static void IRAM_ATTR interrupt_disable(void);
|
||||
static void IRAM_ATTR interrupt_restore(void);
|
||||
static void IRAM_ATTR task_yield(void);
|
||||
static void IRAM_ATTR task_yield_from_isr(void);
|
||||
static void *semphr_create_wrapper(uint32_t max, uint32_t init);
|
||||
static void semphr_delete_wrapper(void *semphr);
|
||||
@ -327,7 +332,7 @@ static const struct osi_funcs_t osi_funcs_ro = {
|
||||
._ints_on = xt_ints_on,
|
||||
._interrupt_disable = interrupt_disable,
|
||||
._interrupt_restore = interrupt_restore,
|
||||
._task_yield = vPortYield,
|
||||
._task_yield = task_yield,
|
||||
._task_yield_from_isr = task_yield_from_isr,
|
||||
._semphr_create = semphr_create_wrapper,
|
||||
._semphr_delete = semphr_delete_wrapper,
|
||||
@ -378,6 +383,10 @@ static const struct osi_funcs_t osi_funcs_ro = {
|
||||
._coex_schm_curr_phase_get = coex_schm_curr_phase_get_wrapper,
|
||||
._coex_wifi_channel_get = coex_wifi_channel_get_wrapper,
|
||||
._coex_register_wifi_channel_change_callback = coex_register_wifi_channel_change_callback_wrapper,
|
||||
._set_isr_l3 = xt_set_interrupt_handler,
|
||||
._interrupt_l3_disable = interrupt_disable,
|
||||
._interrupt_l3_restore = interrupt_restore,
|
||||
._customer_queue_create = NULL,
|
||||
._magic = OSI_MAGIC_VALUE,
|
||||
};
|
||||
|
||||
@ -512,6 +521,11 @@ static void IRAM_ATTR interrupt_restore(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void IRAM_ATTR task_yield(void)
|
||||
{
|
||||
vPortYield();
|
||||
}
|
||||
|
||||
static void IRAM_ATTR task_yield_from_isr(void)
|
||||
{
|
||||
portYIELD_FROM_ISR();
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit fb49791b7c1a8a35f06e68124c90022667b4cff1
|
||||
Subproject commit cfbb0571fb424ca4a68a0c172cbff1fdc79fd91b
|
@ -1 +1 @@
|
||||
Subproject commit 12f00c45ce9c8cf9a9b2e607b4954f12d4191ffb
|
||||
Subproject commit a8099f0c7f1976c3a6ccd44a106728c87a78b1aa
|
@ -380,7 +380,7 @@ esp_err_t esp_ble_gattc_search_service(esp_gatt_if_t gattc_if, uint16_t conn_id,
|
||||
/**
|
||||
* @brief Find all the service with the given service uuid in the gattc cache, if the svc_uuid is NULL, find all the service.
|
||||
* Note: It just get service from local cache, won't get from remote devices. If want to get it from remote device, need
|
||||
* to used the esp_ble_gattc_search_service.
|
||||
* to used the esp_ble_gattc_cache_refresh, then call esp_ble_gattc_get_service again.
|
||||
*
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
* @param[in] conn_id: connection ID which identify the server.
|
||||
|
@ -126,7 +126,7 @@ static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result);
|
||||
#endif
|
||||
#endif
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr);
|
||||
static BOOLEAN bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr);
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir);
|
||||
@ -3069,7 +3069,9 @@ static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev
|
||||
bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
|
||||
}
|
||||
|
||||
bta_dm_remove_sec_dev_entry(bd_addr);
|
||||
if (bta_dm_remove_sec_dev_entry(bd_addr)) {
|
||||
return BTM_SEC_DEV_REC_REMOVED;
|
||||
}
|
||||
}
|
||||
|
||||
return BTM_SUCCESS;
|
||||
@ -3740,12 +3742,13 @@ static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle)
|
||||
** remtoe device does not exist, else schedule for dev entry removal upon
|
||||
ACL close
|
||||
**
|
||||
** Returns void
|
||||
** Returns TRUE if device entry is removed from Security device DB, FALSE otherwise
|
||||
**
|
||||
*******************************************************************************/
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
|
||||
static BOOLEAN bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
|
||||
{
|
||||
BOOLEAN is_device_deleted = FALSE;
|
||||
UINT16 index = 0;
|
||||
if ( BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_LE) ||
|
||||
BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_BR_EDR)) {
|
||||
@ -3763,7 +3766,7 @@ static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
|
||||
APPL_TRACE_ERROR(" %s Device does not exist in DB", __FUNCTION__);
|
||||
}
|
||||
} else {
|
||||
BTM_SecDeleteDevice (remote_bd_addr, bta_dm_cb.device_list.peer_device[index].transport);
|
||||
is_device_deleted = BTM_SecDeleteDevice (remote_bd_addr, bta_dm_cb.device_list.peer_device[index].transport);
|
||||
#if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
|
||||
/* need to remove all pending background connection */
|
||||
BTA_GATTC_CancelOpen(0, remote_bd_addr, FALSE);
|
||||
@ -3771,6 +3774,7 @@ static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
|
||||
BTA_GATTC_Refresh(remote_bd_addr, false);
|
||||
#endif
|
||||
}
|
||||
return is_device_deleted;
|
||||
}
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
|
||||
@ -4978,9 +4982,6 @@ void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data)
|
||||
p_data->ble_update_conn_params.latency,
|
||||
p_data->ble_update_conn_params.timeout)) {
|
||||
APPL_TRACE_ERROR("Update connection parameters failed!");
|
||||
} else {
|
||||
BTM_BleConfigConnParams(p_data->ble_update_conn_params.min_int, p_data->ble_update_conn_params.max_int,
|
||||
p_data->ble_update_conn_params.latency, p_data->ble_update_conn_params.timeout);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
|
@ -397,7 +397,7 @@ static UINT64 time_now_us(void)
|
||||
{
|
||||
#if _POSIX_TIMERS
|
||||
struct timespec ts_now;
|
||||
clock_gettime(CLOCK_BOOTTIME, &ts_now);
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts_now);
|
||||
return ((UINT64)ts_now.tv_sec * 1000000L) + ((UINT64)ts_now.tv_nsec / 1000);
|
||||
#else
|
||||
struct timeval ts_now;
|
||||
|
@ -2981,6 +2981,7 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT
|
||||
int i;
|
||||
DEV_CLASS dev_class;
|
||||
UINT8 old_sec_state;
|
||||
UINT8 res;
|
||||
|
||||
BTM_TRACE_EVENT ("btm_sec_rmt_name_request_complete\n");
|
||||
if (((p_bd_addr == NULL) && !BTM_ACL_IS_CONNECTED(btm_cb.connecting_bda))
|
||||
@ -3161,9 +3162,12 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT
|
||||
/* This is required when different entities receive link notification and auth complete */
|
||||
if (!(p_dev_rec->security_required & BTM_SEC_OUT_AUTHENTICATE)) {
|
||||
if (btm_cb.api.p_auth_complete_callback) {
|
||||
(*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
|
||||
res = (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
|
||||
p_dev_rec->dev_class,
|
||||
p_dev_rec->sec_bd_name, HCI_SUCCESS);
|
||||
if (res == BTM_SEC_DEV_REC_REMOVED) {
|
||||
p_dev_rec = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -3853,6 +3857,7 @@ static void btm_sec_auth_collision (UINT16 handle)
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
void btm_sec_auth_complete (UINT16 handle, UINT8 status)
|
||||
{
|
||||
UINT8 res;
|
||||
UINT8 old_sm4;
|
||||
tBTM_PAIRING_STATE old_state = btm_cb.pairing_state;
|
||||
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle);
|
||||
@ -3942,9 +3947,12 @@ void btm_sec_auth_complete (UINT16 handle, UINT8 status)
|
||||
if (btm_cb.api.p_auth_complete_callback) {
|
||||
/* report the authentication status */
|
||||
if (old_state != BTM_PAIR_STATE_IDLE) {
|
||||
(*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
|
||||
res = (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
|
||||
p_dev_rec->dev_class,
|
||||
p_dev_rec->sec_bd_name, status);
|
||||
if (res == BTM_SEC_DEV_REC_REMOVED) {
|
||||
p_dev_rec = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4241,6 +4249,7 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
|
||||
{
|
||||
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bda);
|
||||
UINT8 res;
|
||||
UINT8 sec_dev_rec_status;
|
||||
BOOLEAN is_pairing_device = FALSE;
|
||||
tACL_CONN *p_acl_cb;
|
||||
UINT8 bit_shift = 0;
|
||||
@ -4379,9 +4388,12 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
|
||||
|
||||
/* We need to notify host that the key is not known any more */
|
||||
if (btm_cb.api.p_auth_complete_callback) {
|
||||
(*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
|
||||
sec_dev_rec_status = (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
|
||||
p_dev_rec->dev_class,
|
||||
p_dev_rec->sec_bd_name, status);
|
||||
if (sec_dev_rec_status == BTM_SEC_DEV_REC_REMOVED) {
|
||||
p_dev_rec = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
@ -4412,9 +4424,12 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
|
||||
|
||||
/* We need to notify host that the key is not known any more */
|
||||
if (btm_cb.api.p_auth_complete_callback) {
|
||||
(*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
|
||||
sec_dev_rec_status = (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
|
||||
p_dev_rec->dev_class,
|
||||
p_dev_rec->sec_bd_name, status);
|
||||
if (sec_dev_rec_status == BTM_SEC_DEV_REC_REMOVED) {
|
||||
p_dev_rec = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4447,9 +4462,12 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
|
||||
}
|
||||
|
||||
if (btm_cb.api.p_auth_complete_callback) {
|
||||
(*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
|
||||
sec_dev_rec_status = (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
|
||||
p_dev_rec->dev_class,
|
||||
p_dev_rec->sec_bd_name, HCI_SUCCESS);
|
||||
if (sec_dev_rec_status == BTM_SEC_DEV_REC_REMOVED) {
|
||||
p_dev_rec = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
|
||||
@ -4668,6 +4686,7 @@ void btm_sec_link_key_notification (UINT8 *p_bda, UINT8 *p_link_key, UINT8 key_t
|
||||
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_bda);
|
||||
BOOLEAN we_are_bonding = FALSE;
|
||||
BOOLEAN ltk_derived_lk = FALSE;
|
||||
UINT8 res;
|
||||
|
||||
BTM_TRACE_EVENT ("btm_sec_link_key_notification() BDA:%04x%08x, TYPE: %d\n",
|
||||
(p_bda[0] << 8) + p_bda[1], (p_bda[2] << 24) + (p_bda[3] << 16) + (p_bda[4] << 8) + p_bda[5],
|
||||
@ -4772,8 +4791,11 @@ void btm_sec_link_key_notification (UINT8 *p_bda, UINT8 *p_link_key, UINT8 key_t
|
||||
/* for derived key, always send authentication callback for BR channel */
|
||||
|| ltk_derived_lk) {
|
||||
if (btm_cb.api.p_auth_complete_callback) {
|
||||
(*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
|
||||
res = (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
|
||||
p_dev_rec->sec_bd_name, HCI_SUCCESS);
|
||||
if (res == BTM_SEC_DEV_REC_REMOVED) {
|
||||
p_dev_rec = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5760,9 +5782,10 @@ static char *btm_pair_state_descr (tBTM_PAIRING_STATE state)
|
||||
*******************************************************************************/
|
||||
void btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res, BOOLEAN is_le_transport)
|
||||
{
|
||||
tBTM_SEC_CALLBACK *p_callback = p_dev_rec->p_callback;
|
||||
tBTM_SEC_CALLBACK *p_callback;
|
||||
|
||||
if (p_dev_rec->p_callback) {
|
||||
if (p_dev_rec && p_dev_rec->p_callback) {
|
||||
p_callback = p_dev_rec->p_callback;
|
||||
p_dev_rec->p_callback = NULL;
|
||||
|
||||
#if BLE_INCLUDED == TRUE
|
||||
|
@ -74,6 +74,7 @@ enum {
|
||||
BTM_SET_PRIVACY_FAIL, /* 24 enable/disable local privacy failed*/
|
||||
BTM_SET_STATIC_RAND_ADDR_FAIL, /* 25 Command failed */
|
||||
BTM_INVALID_STATIC_RAND_ADDR, /* 26 invalid static rand addr */
|
||||
BTM_SEC_DEV_REC_REMOVED, /* 27 Device record relate to the bd_addr is removed */
|
||||
};
|
||||
|
||||
typedef uint8_t tBTM_STATUS;
|
||||
|
@ -1011,7 +1011,7 @@ void l2c_link_processs_ble_num_bufs (UINT16 num_lm_ble_bufs)
|
||||
*******************************************************************************/
|
||||
void l2c_ble_link_adjust_allocation (void)
|
||||
{
|
||||
UINT16 qq, yy = 0, qq_remainder;
|
||||
UINT16 qq, qq_remainder;
|
||||
tL2C_LCB *p_lcb;
|
||||
UINT16 hi_quota, low_quota;
|
||||
UINT16 num_lowpri_links = 0;
|
||||
@ -1096,8 +1096,8 @@ void l2c_ble_link_adjust_allocation (void)
|
||||
}
|
||||
}
|
||||
|
||||
L2CAP_TRACE_EVENT("l2c_ble_link_adjust_allocation LCB %d Priority: %d XmitQuota: %d",
|
||||
yy, p_lcb->acl_priority, p_lcb->link_xmit_quota);
|
||||
L2CAP_TRACE_EVENT("l2c_ble_link_adjust_allocation Priority: %d XmitQuota: %d",
|
||||
p_lcb->acl_priority, p_lcb->link_xmit_quota);
|
||||
|
||||
L2CAP_TRACE_EVENT(" SentNotAcked: %d RRUnacked: %d",
|
||||
p_lcb->sent_not_acked, l2cb.round_robin_unacked);
|
||||
|
@ -718,7 +718,7 @@ void l2c_info_timeout (tL2C_LCB *p_lcb)
|
||||
*******************************************************************************/
|
||||
void l2c_link_adjust_allocation (void)
|
||||
{
|
||||
UINT16 qq, yy = 0, qq_remainder;
|
||||
UINT16 qq, qq_remainder;
|
||||
tL2C_LCB *p_lcb;
|
||||
UINT16 hi_quota, low_quota;
|
||||
UINT16 num_lowpri_links = 0;
|
||||
@ -803,8 +803,8 @@ void l2c_link_adjust_allocation (void)
|
||||
}
|
||||
}
|
||||
|
||||
L2CAP_TRACE_EVENT ("l2c_link_adjust_allocation LCB %d Priority: %d XmitQuota: %d\n",
|
||||
yy, p_lcb->acl_priority, p_lcb->link_xmit_quota);
|
||||
L2CAP_TRACE_EVENT ("l2c_link_adjust_allocation Priority: %d XmitQuota: %d\n",
|
||||
p_lcb->acl_priority, p_lcb->link_xmit_quota);
|
||||
|
||||
L2CAP_TRACE_EVENT (" SentNotAcked: %d RRUnacked: %d\n",
|
||||
p_lcb->sent_not_acked, l2cb.round_robin_unacked);
|
||||
|
@ -44,8 +44,6 @@ choice BT_NIMBLE_LOG_LEVEL
|
||||
|
||||
config BT_NIMBLE_LOG_LEVEL_NONE
|
||||
bool "No logs"
|
||||
config BT_NIMBLE_LOG_LEVEL_CRIT
|
||||
bool "Critical logs"
|
||||
config BT_NIMBLE_LOG_LEVEL_ERROR
|
||||
bool "Error logs"
|
||||
config BT_NIMBLE_LOG_LEVEL_WARNING
|
||||
@ -62,8 +60,7 @@ config BT_NIMBLE_LOG_LEVEL
|
||||
default 1 if BT_NIMBLE_LOG_LEVEL_INFO
|
||||
default 2 if BT_NIMBLE_LOG_LEVEL_WARNING
|
||||
default 3 if BT_NIMBLE_LOG_LEVEL_ERROR
|
||||
default 4 if BT_NIMBLE_LOG_LEVEL_CRIT
|
||||
default 5 if BT_NIMBLE_LOG_LEVEL_NONE
|
||||
default 4 if BT_NIMBLE_LOG_LEVEL_NONE
|
||||
|
||||
config BT_NIMBLE_MAX_CONNECTIONS
|
||||
int "Maximum number of concurrent connections"
|
||||
|
@ -117,6 +117,8 @@ the adv packet will be discarded until the memory is restored. */
|
||||
#define BTDM_CTRL_AUTO_LATENCY_EFF false
|
||||
#endif
|
||||
|
||||
#define BTDM_CTRL_HLI false
|
||||
|
||||
#ifdef CONFIG_BTDM_CTRL_LEGACY_AUTH_VENDOR_EVT_EFF
|
||||
#define BTDM_CTRL_LEGACY_AUTH_VENDOR_EVT_EFF CONFIG_BTDM_CTRL_LEGACY_AUTH_VENDOR_EVT_EFF
|
||||
#else
|
||||
@ -151,6 +153,7 @@ the adv packet will be discarded until the memory is restored. */
|
||||
.ble_sca = CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF, \
|
||||
.pcm_role = CONFIG_BTDM_CTRL_PCM_ROLE_EFF, \
|
||||
.pcm_polar = CONFIG_BTDM_CTRL_PCM_POLAR_EFF, \
|
||||
.hli = BTDM_CTRL_HLI, \
|
||||
.magic = ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL, \
|
||||
};
|
||||
|
||||
@ -192,6 +195,7 @@ typedef struct {
|
||||
uint8_t ble_sca; /*!< BLE low power crystal accuracy index */
|
||||
uint8_t pcm_role; /*!< PCM role (master & slave)*/
|
||||
uint8_t pcm_polar; /*!< PCM polar trig (falling clk edge & rising clk edge) */
|
||||
bool hli; /*!< Using high level interrupt or not */
|
||||
uint32_t magic; /*!< Magic number */
|
||||
} esp_bt_controller_config_t;
|
||||
|
||||
|
@ -11,6 +11,11 @@
|
||||
#ifndef COAP_DTLS_H_
|
||||
#define COAP_DTLS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "libcoap.h"
|
||||
#include "coap_time.h"
|
||||
#include "str.h"
|
||||
|
||||
@ -627,5 +632,8 @@ void coap_dtls_set_log_level(int level);
|
||||
*/
|
||||
int coap_dtls_get_log_level(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* COAP_DTLS_H */
|
||||
|
@ -30,6 +30,7 @@
|
||||
static const char *TAG = "console.repl";
|
||||
|
||||
#define CONSOLE_PROMPT_MAX_LEN (32)
|
||||
#define CONSOLE_PATH_MAX_LEN (ESP_VFS_PATH_MAX)
|
||||
|
||||
typedef enum {
|
||||
CONSOLE_REPL_STATE_DEINIT,
|
||||
@ -48,11 +49,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
esp_console_repl_com_t repl_com; // base class
|
||||
int uart_channel; // uart channel number
|
||||
} esp_console_repl_uart_t;
|
||||
|
||||
typedef struct {
|
||||
esp_console_repl_com_t repl_com; // base class
|
||||
} esp_console_repl_usb_cdc_t;
|
||||
} esp_console_repl_universal_t;
|
||||
|
||||
static void esp_console_repl_task(void *args);
|
||||
static esp_err_t esp_console_repl_uart_delete(esp_console_repl_t *repl);
|
||||
@ -64,21 +61,18 @@ static esp_err_t esp_console_setup_history(const char *history_path, uint32_t ma
|
||||
esp_err_t esp_console_new_repl_usb_cdc(const esp_console_dev_usb_cdc_config_t *dev_config, const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
esp_console_repl_usb_cdc_t *cdc_repl = NULL;
|
||||
esp_console_repl_universal_t *cdc_repl = NULL;
|
||||
if (!repl_config | !dev_config | !ret_repl) {
|
||||
ret = ESP_ERR_INVALID_ARG;
|
||||
goto _exit;
|
||||
}
|
||||
// allocate memory for console REPL context
|
||||
cdc_repl = calloc(1, sizeof(esp_console_repl_usb_cdc_t));
|
||||
cdc_repl = calloc(1, sizeof(esp_console_repl_universal_t));
|
||||
if (!cdc_repl) {
|
||||
ret = ESP_ERR_NO_MEM;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
/* Disable buffering on stdin */
|
||||
setvbuf(stdin, NULL, _IONBF, 0);
|
||||
|
||||
/* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
|
||||
esp_vfs_dev_cdcacm_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
|
||||
/* Move the caret to the beginning of the next line on '\n' */
|
||||
@ -103,15 +97,18 @@ esp_err_t esp_console_new_repl_usb_cdc(const esp_console_dev_usb_cdc_config_t *d
|
||||
// setup prompt
|
||||
esp_console_setup_prompt(repl_config->prompt, &cdc_repl->repl_com);
|
||||
|
||||
/* Fill the structure here as it will be used directly by the created task. */
|
||||
cdc_repl->uart_channel = CONFIG_ESP_CONSOLE_UART_NUM;
|
||||
cdc_repl->repl_com.state = CONSOLE_REPL_STATE_INIT;
|
||||
cdc_repl->repl_com.repl_core.del = esp_console_repl_usb_cdc_delete;
|
||||
|
||||
/* spawn a single thread to run REPL */
|
||||
if (xTaskCreate(esp_console_repl_task, "console_repl", repl_config->task_stack_size,
|
||||
&cdc_repl->repl_com, repl_config->task_priority, &cdc_repl->repl_com.task_hdl) != pdTRUE) {
|
||||
cdc_repl, repl_config->task_priority, &cdc_repl->repl_com.task_hdl) != pdTRUE) {
|
||||
ret = ESP_FAIL;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
cdc_repl->repl_com.state = CONSOLE_REPL_STATE_INIT;
|
||||
cdc_repl->repl_com.repl_core.del = esp_console_repl_usb_cdc_delete;
|
||||
*ret_repl = &cdc_repl->repl_com.repl_core;
|
||||
return ESP_OK;
|
||||
_exit:
|
||||
@ -128,13 +125,13 @@ _exit:
|
||||
esp_err_t esp_console_new_repl_uart(const esp_console_dev_uart_config_t *dev_config, const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
esp_console_repl_uart_t *uart_repl = NULL;
|
||||
esp_console_repl_universal_t *uart_repl = NULL;
|
||||
if (!repl_config | !dev_config | !ret_repl) {
|
||||
ret = ESP_ERR_INVALID_ARG;
|
||||
goto _exit;
|
||||
}
|
||||
// allocate memory for console REPL context
|
||||
uart_repl = calloc(1, sizeof(esp_console_repl_uart_t));
|
||||
uart_repl = calloc(1, sizeof(esp_console_repl_universal_t));
|
||||
if (!uart_repl) {
|
||||
ret = ESP_ERR_NO_MEM;
|
||||
goto _exit;
|
||||
@ -144,9 +141,6 @@ esp_err_t esp_console_new_repl_uart(const esp_console_dev_uart_config_t *dev_con
|
||||
fflush(stdout);
|
||||
fsync(fileno(stdout));
|
||||
|
||||
/* Disable buffering on stdin */
|
||||
setvbuf(stdin, NULL, _IONBF, 0);
|
||||
|
||||
/* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
|
||||
esp_vfs_dev_uart_port_set_rx_line_endings(dev_config->channel, ESP_LINE_ENDINGS_CR);
|
||||
/* Move the caret to the beginning of the next line on '\n' */
|
||||
@ -194,16 +188,19 @@ esp_err_t esp_console_new_repl_uart(const esp_console_dev_uart_config_t *dev_con
|
||||
// setup prompt
|
||||
esp_console_setup_prompt(repl_config->prompt, &uart_repl->repl_com);
|
||||
|
||||
/* spawn a single thread to run REPL */
|
||||
/* Fill the structure here as it will be used directly by the created task. */
|
||||
uart_repl->uart_channel = dev_config->channel;
|
||||
uart_repl->repl_com.state = CONSOLE_REPL_STATE_INIT;
|
||||
uart_repl->repl_com.repl_core.del = esp_console_repl_uart_delete;
|
||||
|
||||
/* Spawn a single thread to run REPL, we need to pass `uart_repl` to it as
|
||||
* it also requires the uart channel. */
|
||||
if (xTaskCreate(esp_console_repl_task, "console_repl", repl_config->task_stack_size,
|
||||
&uart_repl->repl_com, repl_config->task_priority, &uart_repl->repl_com.task_hdl) != pdTRUE) {
|
||||
uart_repl, repl_config->task_priority, &uart_repl->repl_com.task_hdl) != pdTRUE) {
|
||||
ret = ESP_FAIL;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
uart_repl->uart_channel = dev_config->channel;
|
||||
uart_repl->repl_com.state = CONSOLE_REPL_STATE_INIT;
|
||||
uart_repl->repl_com.repl_core.del = esp_console_repl_uart_delete;
|
||||
*ret_repl = &uart_repl->repl_com.repl_core;
|
||||
return ESP_OK;
|
||||
_exit:
|
||||
@ -244,19 +241,10 @@ static esp_err_t esp_console_setup_prompt(const char *prompt, esp_console_repl_c
|
||||
}
|
||||
snprintf(repl_com->prompt, CONSOLE_PROMPT_MAX_LEN - 1, LOG_COLOR_I "%s " LOG_RESET_COLOR, prompt_temp);
|
||||
|
||||
printf("\r\n"
|
||||
"Type 'help' to get the list of commands.\r\n"
|
||||
"Use UP/DOWN arrows to navigate through command history.\r\n"
|
||||
"Press TAB when typing command name to auto-complete.\r\n");
|
||||
|
||||
/* Figure out if the terminal supports escape sequences */
|
||||
int probe_status = linenoiseProbe();
|
||||
if (probe_status) {
|
||||
/* zero indicates success */
|
||||
printf("\r\n"
|
||||
"Your terminal application does not support escape sequences.\n\n"
|
||||
"Line editing and history features are disabled.\n\n"
|
||||
"On Windows, try using Putty instead.\r\n");
|
||||
linenoiseSetDumbMode(1);
|
||||
#if CONFIG_LOG_COLORS
|
||||
/* Since the terminal doesn't support escape sequences,
|
||||
@ -325,7 +313,7 @@ static esp_err_t esp_console_repl_uart_delete(esp_console_repl_t *repl)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
esp_console_repl_com_t *repl_com = __containerof(repl, esp_console_repl_com_t, repl_core);
|
||||
esp_console_repl_uart_t *uart_repl = __containerof(repl_com, esp_console_repl_uart_t, repl_com);
|
||||
esp_console_repl_universal_t *uart_repl = __containerof(repl_com, esp_console_repl_universal_t, repl_com);
|
||||
// check if already de-initialized
|
||||
if (repl_com->state == CONSOLE_REPL_STATE_DEINIT) {
|
||||
ESP_LOGE(TAG, "already de-initialized");
|
||||
@ -345,7 +333,7 @@ static esp_err_t esp_console_repl_usb_cdc_delete(esp_console_repl_t *repl)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
esp_console_repl_com_t *repl_com = __containerof(repl, esp_console_repl_com_t, repl_core);
|
||||
esp_console_repl_usb_cdc_t *cdc_repl = __containerof(repl_com, esp_console_repl_usb_cdc_t, repl_com);
|
||||
esp_console_repl_universal_t *cdc_repl = __containerof(repl_com, esp_console_repl_universal_t, repl_com);
|
||||
// check if already de-initialized
|
||||
if (repl_com->state == CONSOLE_REPL_STATE_DEINIT) {
|
||||
ESP_LOGE(TAG, "already de-initialized");
|
||||
@ -361,9 +349,45 @@ _exit:
|
||||
|
||||
static void esp_console_repl_task(void *args)
|
||||
{
|
||||
esp_console_repl_com_t *repl_com = (esp_console_repl_com_t *)args;
|
||||
// waiting for task notify
|
||||
esp_console_repl_universal_t *repl_conf = (esp_console_repl_universal_t *) args;
|
||||
esp_console_repl_com_t *repl_com = &repl_conf->repl_com;
|
||||
const int uart_channel = repl_conf->uart_channel;
|
||||
|
||||
/* Waiting for task notify. This happens when `esp_console_start_repl()`
|
||||
* function is called. */
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
/* Change standard input and output of the task if the requested UART is
|
||||
* NOT the default one. This block will replace stdin, stdout and stderr.
|
||||
*/
|
||||
if (uart_channel != CONFIG_ESP_CONSOLE_UART_NUM) {
|
||||
char path[CONSOLE_PATH_MAX_LEN] = { 0 };
|
||||
snprintf(path, CONSOLE_PATH_MAX_LEN, "/dev/uart/%d", uart_channel);
|
||||
|
||||
stdin = fopen(path, "r");
|
||||
stdout = fopen(path, "w");
|
||||
stderr = stdout;
|
||||
}
|
||||
|
||||
/* Disable buffering on stdin of the current task.
|
||||
* If the console is ran on a different UART than the default one,
|
||||
* buffering shall only be disabled for the current one. */
|
||||
setvbuf(stdin, NULL, _IONBF, 0);
|
||||
|
||||
/* This message shall be printed here and not earlier as the stdout
|
||||
* has just been set above. */
|
||||
printf("\r\n"
|
||||
"Type 'help' to get the list of commands.\r\n"
|
||||
"Use UP/DOWN arrows to navigate through command history.\r\n"
|
||||
"Press TAB when typing command name to auto-complete.\r\n");
|
||||
|
||||
if (linenoiseIsDumbMode()) {
|
||||
printf("\r\n"
|
||||
"Your terminal application does not support escape sequences.\n\n"
|
||||
"Line editing and history features are disabled.\n\n"
|
||||
"On Windows, try using Putty instead.\r\n");
|
||||
}
|
||||
|
||||
while (repl_com->state == CONSOLE_REPL_STATE_START) {
|
||||
char *line = linenoise(repl_com->prompt);
|
||||
if (line == NULL) {
|
||||
|
@ -115,10 +115,12 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include "linenoise.h"
|
||||
|
||||
#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
|
||||
#define LINENOISE_MAX_LINE 4096
|
||||
#define LINENOISE_COMMAND_MAX_LEN 32
|
||||
|
||||
static linenoiseCompletionCallback *completionCallback = NULL;
|
||||
static linenoiseHintsCallback *hintsCallback = NULL;
|
||||
@ -203,6 +205,11 @@ void linenoiseSetDumbMode(int set) {
|
||||
dumbmode = set;
|
||||
}
|
||||
|
||||
/* Returns whether the current mode is dumbmode or not. */
|
||||
bool linenoiseIsDumbMode(void) {
|
||||
return dumbmode;
|
||||
}
|
||||
|
||||
static void flushWrite(void) {
|
||||
if (__fbufsize(stdout) > 0) {
|
||||
fflush(stdout);
|
||||
@ -214,47 +221,106 @@ static void flushWrite(void) {
|
||||
* and return it. On error -1 is returned, on success the position of the
|
||||
* cursor. */
|
||||
static int getCursorPosition(void) {
|
||||
char buf[32];
|
||||
int cols, rows;
|
||||
unsigned int i = 0;
|
||||
char buf[LINENOISE_COMMAND_MAX_LEN] = { 0 };
|
||||
int cols = 0;
|
||||
int rows = 0;
|
||||
int i = 0;
|
||||
const int out_fd = fileno(stdout);
|
||||
const int in_fd = fileno(stdin);
|
||||
/* The following ANSI escape sequence is used to get from the TTY the
|
||||
* cursor position. */
|
||||
const char get_cursor_cmd[] = "\x1b[6n";
|
||||
|
||||
/* Report cursor location */
|
||||
fprintf(stdout, "\x1b[6n");
|
||||
/* Send the command to the TTY on the other end of the UART.
|
||||
* Let's use unistd's write function. Thus, data sent through it are raw
|
||||
* reducing the overhead compared to using fputs, fprintf, etc... */
|
||||
write(out_fd, get_cursor_cmd, sizeof(get_cursor_cmd));
|
||||
|
||||
/* For USB CDC, it is required to flush the output. */
|
||||
flushWrite();
|
||||
/* Read the response: ESC [ rows ; cols R */
|
||||
|
||||
/* The other end will send its response which format is ESC [ rows ; cols R
|
||||
* We don't know exactly how many bytes we have to read, thus, perform a
|
||||
* read for each byte.
|
||||
* Stop right before the last character of the buffer, to be able to NULL
|
||||
* terminate it. */
|
||||
while (i < sizeof(buf)-1) {
|
||||
if (fread(buf+i, 1, 1, stdin) != 1) break;
|
||||
if (buf[i] == 'R') break;
|
||||
/* Keep using unistd's functions. Here, using `read` instead of `fgets`
|
||||
* or `fgets` guarantees us that we we can read a byte regardless on
|
||||
* whether the sender sent end of line character(s) (CR, CRLF, LF). */
|
||||
if (read(in_fd, buf + i, 1) != 1 || buf[i] == 'R') {
|
||||
/* If we couldn't read a byte from STDIN or if 'R' was received,
|
||||
* the transmission is finished. */
|
||||
break;
|
||||
}
|
||||
|
||||
/* For some reasons, it is possible that we receive new line character
|
||||
* after querying the cursor position on some UART. Let's ignore them,
|
||||
* this will not affect the rest of the program. */
|
||||
if (buf[i] != '\n') {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/* NULL-terminate the buffer, this is required by `sscanf`. */
|
||||
buf[i] = '\0';
|
||||
/* Parse it. */
|
||||
if (buf[0] != ESC || buf[1] != '[') return -1;
|
||||
if (sscanf(buf+2,"%d;%d",&rows,&cols) != 2) return -1;
|
||||
|
||||
/* Parse the received data to get the position of the cursor. */
|
||||
if (buf[0] != ESC || buf[1] != '[' || sscanf(buf+2,"%d;%d",&rows,&cols) != 2) {
|
||||
return -1;
|
||||
}
|
||||
return cols;
|
||||
}
|
||||
|
||||
/* Try to get the number of columns in the current terminal, or assume 80
|
||||
* if it fails. */
|
||||
static int getColumns(void) {
|
||||
int start, cols;
|
||||
int fd = fileno(stdout);
|
||||
int start = 0;
|
||||
int cols = 0;
|
||||
int written = 0;
|
||||
char seq[LINENOISE_COMMAND_MAX_LEN] = { 0 };
|
||||
const int fd = fileno(stdout);
|
||||
|
||||
/* The following ANSI escape sequence is used to tell the TTY to move
|
||||
* the cursor to the most-right position. */
|
||||
const char move_cursor_right[] = "\x1b[999C";
|
||||
const size_t cmd_len = sizeof(move_cursor_right);
|
||||
|
||||
/* This one is used to set the cursor position. */
|
||||
const char set_cursor_pos[] = "\x1b[%dD";
|
||||
|
||||
/* Get the initial position so we can restore it later. */
|
||||
start = getCursorPosition();
|
||||
if (start == -1) goto failed;
|
||||
if (start == -1) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Go to right margin and get position. */
|
||||
if (fwrite("\x1b[999C", 1, 6, stdout) != 6) goto failed;
|
||||
/* Send the command to go to right margin. Use `write` function instead of
|
||||
* `fwrite` for the same reasons explained in `getCursorPosition()` */
|
||||
if (write(fd, move_cursor_right, cmd_len) != cmd_len) {
|
||||
goto failed;
|
||||
}
|
||||
flushWrite();
|
||||
cols = getCursorPosition();
|
||||
if (cols == -1) goto failed;
|
||||
|
||||
/* Restore position. */
|
||||
/* After sending this command, we can get the new position of the cursor,
|
||||
* we'd get the size, in columns, of the opened TTY. */
|
||||
cols = getCursorPosition();
|
||||
if (cols == -1) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Restore the position of the cursor back. */
|
||||
if (cols > start) {
|
||||
char seq[32];
|
||||
snprintf(seq,32,"\x1b[%dD",cols-start);
|
||||
if (write(fd, seq, strlen(seq)) == -1) {
|
||||
/* Generate the move cursor command. */
|
||||
written = snprintf(seq, LINENOISE_COMMAND_MAX_LEN, set_cursor_pos, cols-start);
|
||||
|
||||
/* If `written` is equal or bigger than LINENOISE_COMMAND_MAX_LEN, it
|
||||
* means that the output has been truncated because the size provided
|
||||
* is too small. */
|
||||
assert (written < LINENOISE_COMMAND_MAX_LEN);
|
||||
|
||||
/* Send the command with `write`, which is not buffered. */
|
||||
if (write(fd, seq, written) == -1) {
|
||||
/* Can't recover... */
|
||||
}
|
||||
flushWrite();
|
||||
|
@ -69,6 +69,7 @@ void linenoiseHistoryFree(void);
|
||||
void linenoiseClearScreen(void);
|
||||
void linenoiseSetMultiLine(int ml);
|
||||
void linenoiseSetDumbMode(int set);
|
||||
bool linenoiseIsDumbMode(void);
|
||||
void linenoisePrintKeyCodes(void);
|
||||
void linenoiseAllowEmpty(bool);
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
#define PULSE_IO 21
|
||||
#define PCNT_INPUT_IO 4
|
||||
#define PCNT_CTRL_VCC_IO 5
|
||||
#define PCNT_CTRL_GND_IO 19
|
||||
#define PCNT_CTRL_GND_IO 2
|
||||
#define HIGHEST_LIMIT 10
|
||||
#define LOWEST_LIMIT 0
|
||||
#define MAX_THRESHOLD 5
|
||||
|
@ -1050,7 +1050,6 @@ TEST_CASE("SPI master hd dma TX without RX test", "[spi]")
|
||||
#endif //#if !DISABLED_FOR_TARGETS(ESP32C3)
|
||||
|
||||
|
||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3)
|
||||
/********************************************************************************
|
||||
* Test SPI transaction interval
|
||||
********************************************************************************/
|
||||
@ -1058,8 +1057,8 @@ TEST_CASE("SPI master hd dma TX without RX test", "[spi]")
|
||||
#ifndef CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE
|
||||
|
||||
#define RECORD_TIME_PREPARE() uint32_t __t1, __t2
|
||||
#define RECORD_TIME_START() do {__t1 = xthal_get_ccount();}while(0)
|
||||
#define RECORD_TIME_END(p_time) do{__t2 = xthal_get_ccount(); *p_time = (__t2-__t1);}while(0)
|
||||
#define RECORD_TIME_START() do {__t1 = esp_cpu_get_ccount();}while(0)
|
||||
#define RECORD_TIME_END(p_time) do{__t2 = esp_cpu_get_ccount(); *p_time = (__t2-__t1);}while(0)
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define GET_US_BY_CCOUNT(t) ((double)t/CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ)
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
@ -1203,5 +1202,3 @@ TEST_CASE("spi_speed","[spi]")
|
||||
master_free_device_bus(spi);
|
||||
}
|
||||
#endif // CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE
|
||||
|
||||
#endif // #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3)
|
||||
|
@ -24,7 +24,8 @@
|
||||
|
||||
#include "hal/spi_ll.h"
|
||||
|
||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3, ESP32C3)
|
||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3)
|
||||
#if !DISABLED_FOR_TARGETS(ESP32C3) //There is only one GPSPI controller, so single-board test is disabled.
|
||||
|
||||
/********************************************************************************
|
||||
* Test SIO
|
||||
@ -101,6 +102,8 @@ TEST_CASE("local test sio", "[spi]")
|
||||
spi_slave_free(TEST_SLAVE_HOST);
|
||||
master_free_device_bus(spi);
|
||||
}
|
||||
#endif //!DISABLED_FOR_TARGETS(ESP32C3) //There is only one GPSPI controller, so single-board test is disabled.
|
||||
|
||||
|
||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32C3)
|
||||
//These tests are ESP32 only due to lack of runners
|
||||
|
@ -44,8 +44,10 @@
|
||||
|
||||
#ifdef CONFIG_UART_ISR_IN_IRAM
|
||||
#define UART_ISR_ATTR IRAM_ATTR
|
||||
#define UART_MALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
|
||||
#else
|
||||
#define UART_ISR_ATTR
|
||||
#define UART_MALLOC_CAPS MALLOC_CAP_DEFAULT
|
||||
#endif
|
||||
|
||||
#define XOFF (0x13)
|
||||
@ -109,18 +111,13 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
uart_port_t uart_num; /*!< UART port number*/
|
||||
int queue_size; /*!< UART event queue size*/
|
||||
QueueHandle_t xQueueUart; /*!< UART queue handler*/
|
||||
int event_queue_size; /*!< UART event queue size*/
|
||||
intr_handle_t intr_handle; /*!< UART interrupt handle*/
|
||||
uart_mode_t uart_mode; /*!< UART controller actual mode set by uart_set_mode() */
|
||||
bool coll_det_flg; /*!< UART collision detection flag */
|
||||
bool rx_always_timeout_flg; /*!< UART always detect rx timeout flag */
|
||||
|
||||
//rx parameters
|
||||
int rx_buffered_len; /*!< UART cached data length */
|
||||
SemaphoreHandle_t rx_mux; /*!< UART RX data mutex*/
|
||||
int rx_buf_size; /*!< RX ring buffer size */
|
||||
RingbufHandle_t rx_ring_buf; /*!< RX ring buffer handler*/
|
||||
bool rx_buffer_full_flg; /*!< RX ring buffer full flag. */
|
||||
uint32_t rx_cur_remain; /*!< Data number that waiting to be read out in ring buffer item*/
|
||||
uint8_t *rx_ptr; /*!< pointer to the current data in ring buffer*/
|
||||
@ -128,14 +125,7 @@ typedef struct {
|
||||
uint8_t rx_data_buf[SOC_UART_FIFO_LEN]; /*!< Data buffer to stash FIFO data*/
|
||||
uint8_t rx_stash_len; /*!< stashed data length.(When using flow control, after reading out FIFO data, if we fail to push to buffer, we can just stash them.) */
|
||||
uart_pat_rb_t rx_pattern_pos;
|
||||
|
||||
//tx parameters
|
||||
SemaphoreHandle_t tx_fifo_sem; /*!< UART TX FIFO semaphore*/
|
||||
SemaphoreHandle_t tx_mux; /*!< UART TX mutex*/
|
||||
SemaphoreHandle_t tx_done_sem; /*!< UART TX done semaphore*/
|
||||
SemaphoreHandle_t tx_brk_sem; /*!< UART TX send break done semaphore*/
|
||||
int tx_buf_size; /*!< TX ring buffer size */
|
||||
RingbufHandle_t tx_ring_buf; /*!< TX ring buffer handler*/
|
||||
bool tx_waiting_fifo; /*!< this flag indicates that some task is waiting for FIFO empty interrupt, used to send all data without any data buffer*/
|
||||
uint8_t *tx_ptr; /*!< TX data pointer to push to FIFO in TX buffer mode*/
|
||||
uart_tx_data_t *tx_head; /*!< TX data pointer to head of the current buffer in TX ring buffer*/
|
||||
@ -145,6 +135,27 @@ typedef struct {
|
||||
uint8_t tx_brk_len; /*!< TX break signal cycle length/number */
|
||||
uint8_t tx_waiting_brk; /*!< Flag to indicate that TX FIFO is ready to send break signal after FIFO is empty, do not push data into TX FIFO right now.*/
|
||||
uart_select_notif_callback_t uart_select_notif_callback; /*!< Notification about select() events */
|
||||
QueueHandle_t event_queue; /*!< UART event queue handler*/
|
||||
RingbufHandle_t rx_ring_buf; /*!< RX ring buffer handler*/
|
||||
RingbufHandle_t tx_ring_buf; /*!< TX ring buffer handler*/
|
||||
SemaphoreHandle_t rx_mux; /*!< UART RX data mutex*/
|
||||
SemaphoreHandle_t tx_mux; /*!< UART TX mutex*/
|
||||
SemaphoreHandle_t tx_fifo_sem; /*!< UART TX FIFO semaphore*/
|
||||
SemaphoreHandle_t tx_done_sem; /*!< UART TX done semaphore*/
|
||||
SemaphoreHandle_t tx_brk_sem; /*!< UART TX send break done semaphore*/
|
||||
#if CONFIG_UART_ISR_IN_IRAM
|
||||
void *event_queue_storage;
|
||||
void *event_queue_struct;
|
||||
void *rx_ring_buf_storage;
|
||||
void *rx_ring_buf_struct;
|
||||
void *tx_ring_buf_storage;
|
||||
void *tx_ring_buf_struct;
|
||||
void *rx_mux_struct;
|
||||
void *tx_mux_struct;
|
||||
void *tx_fifo_sem_struct;
|
||||
void *tx_done_sem_struct;
|
||||
void *tx_brk_sem_struct;
|
||||
#endif
|
||||
} uart_obj_t;
|
||||
|
||||
typedef struct {
|
||||
@ -257,7 +268,9 @@ esp_err_t uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bit)
|
||||
esp_err_t uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t *stop_bit)
|
||||
{
|
||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
|
||||
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
||||
uart_hal_get_stop_bits(&(uart_context[uart_num].hal), stop_bit);
|
||||
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -273,7 +286,9 @@ esp_err_t uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode)
|
||||
esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t *parity_mode)
|
||||
{
|
||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
|
||||
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
||||
uart_hal_get_parity(&(uart_context[uart_num].hal), parity_mode);
|
||||
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -308,7 +323,7 @@ esp_err_t uart_set_sw_flow_ctrl(uart_port_t uart_num, bool enable, uint8_t rx_t
|
||||
{
|
||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
|
||||
UART_CHECK((rx_thresh_xon < SOC_UART_FIFO_LEN), "rx flow xon thresh error", ESP_FAIL);
|
||||
UART_CHECK((rx_thresh_xoff < SOC_UART_FIFO_LEN), "rx flow xon thresh error", ESP_FAIL);
|
||||
UART_CHECK((rx_thresh_xoff < SOC_UART_FIFO_LEN), "rx flow xoff thresh error", ESP_FAIL);
|
||||
uart_sw_flowctrl_t sw_flow_ctl = {
|
||||
.xon_char = XON,
|
||||
.xoff_char = XOFF,
|
||||
@ -391,7 +406,9 @@ static esp_err_t UART_ISR_ATTR uart_pattern_enqueue(uart_port_t uart_num, int po
|
||||
next = 0;
|
||||
}
|
||||
if (next == p_pos->rd) {
|
||||
#ifndef CONFIG_UART_ISR_IN_IRAM //Only log if ISR is not in IRAM
|
||||
ESP_EARLY_LOGW(UART_TAG, "Fail to enqueue pattern position, pattern queue is full.");
|
||||
#endif
|
||||
ret = ESP_FAIL;
|
||||
} else {
|
||||
p_pos->data[p_pos->wr] = pos;
|
||||
@ -849,8 +866,7 @@ static void UART_ISR_ATTR uart_rx_intr_handler_default(void *param)
|
||||
UART_EXIT_CRITICAL_ISR(&(uart_context[uart_num].spinlock));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((uart_intr_status & UART_INTR_RXFIFO_TOUT)
|
||||
} else if ((uart_intr_status & UART_INTR_RXFIFO_TOUT)
|
||||
|| (uart_intr_status & UART_INTR_RXFIFO_FULL)
|
||||
|| (uart_intr_status & UART_INTR_CMD_CHAR_DET)
|
||||
) {
|
||||
@ -909,8 +925,10 @@ static void UART_ISR_ATTR uart_rx_intr_handler_default(void *param)
|
||||
p_uart->rx_buffered_len + pat_idx);
|
||||
}
|
||||
UART_EXIT_CRITICAL_ISR(&(uart_context[uart_num].spinlock));
|
||||
if ((p_uart->xQueueUart != NULL) && (pdFALSE == xQueueSendFromISR(p_uart->xQueueUart, (void * )&uart_event, &HPTaskAwoken))) {
|
||||
if ((p_uart->event_queue != NULL) && (pdFALSE == xQueueSendFromISR(p_uart->event_queue, (void * )&uart_event, &HPTaskAwoken))) {
|
||||
#ifndef CONFIG_UART_ISR_IN_IRAM //Only log if ISR is not in IRAM
|
||||
ESP_EARLY_LOGV(UART_TAG, "UART event queue full");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
uart_event.type = UART_BUFFER_FULL;
|
||||
@ -1029,9 +1047,11 @@ static void UART_ISR_ATTR uart_rx_intr_handler_default(void *param)
|
||||
uart_event.type = UART_EVENT_MAX;
|
||||
}
|
||||
|
||||
if(uart_event.type != UART_EVENT_MAX && p_uart->xQueueUart) {
|
||||
if (pdFALSE == xQueueSendFromISR(p_uart->xQueueUart, (void * )&uart_event, &HPTaskAwoken)) {
|
||||
if (uart_event.type != UART_EVENT_MAX && p_uart->event_queue) {
|
||||
if (pdFALSE == xQueueSendFromISR(p_uart->event_queue, (void * )&uart_event, &HPTaskAwoken)) {
|
||||
#ifndef CONFIG_UART_ISR_IN_IRAM //Only log if ISR is not in IRAM
|
||||
ESP_EARLY_LOGV(UART_TAG, "UART event queue full");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1262,7 +1282,9 @@ esp_err_t uart_get_buffered_data_len(uart_port_t uart_num, size_t* size)
|
||||
{
|
||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
|
||||
UART_CHECK((p_uart_obj[uart_num]), "uart driver error", ESP_FAIL);
|
||||
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
||||
*size = p_uart_obj[uart_num]->rx_buffered_len;
|
||||
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -1303,14 +1325,19 @@ esp_err_t uart_flush_input(uart_port_t uart_num)
|
||||
}
|
||||
data = (uint8_t*) xRingbufferReceive(p_uart->rx_ring_buf, &size, (portTickType) 0);
|
||||
if (data == NULL) {
|
||||
bool error = false;
|
||||
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
||||
if ( p_uart_obj[uart_num]->rx_buffered_len != 0 ) {
|
||||
ESP_LOGE(UART_TAG, "rx_buffered_len error");
|
||||
p_uart_obj[uart_num]->rx_buffered_len = 0;
|
||||
error = true;
|
||||
}
|
||||
//We also need to clear the `rx_buffer_full_flg` here.
|
||||
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
||||
p_uart_obj[uart_num]->rx_buffer_full_flg = false;
|
||||
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
|
||||
if (error) {
|
||||
// this must be called outside the critical section
|
||||
ESP_LOGE(UART_TAG, "rx_buffered_len error");
|
||||
}
|
||||
break;
|
||||
}
|
||||
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
||||
@ -1337,7 +1364,138 @@ esp_err_t uart_flush_input(uart_port_t uart_num)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, QueueHandle_t *uart_queue, int intr_alloc_flags)
|
||||
static void uart_free_driver_obj(uart_obj_t *uart_obj)
|
||||
{
|
||||
if (uart_obj->tx_fifo_sem) {
|
||||
vSemaphoreDelete(uart_obj->tx_fifo_sem);
|
||||
}
|
||||
if (uart_obj->tx_done_sem) {
|
||||
vSemaphoreDelete(uart_obj->tx_done_sem);
|
||||
}
|
||||
if (uart_obj->tx_brk_sem) {
|
||||
vSemaphoreDelete(uart_obj->tx_brk_sem);
|
||||
}
|
||||
if (uart_obj->tx_mux) {
|
||||
vSemaphoreDelete(uart_obj->tx_mux);
|
||||
}
|
||||
if (uart_obj->rx_mux) {
|
||||
vSemaphoreDelete(uart_obj->rx_mux);
|
||||
}
|
||||
if (uart_obj->event_queue) {
|
||||
vQueueDelete(uart_obj->event_queue);
|
||||
}
|
||||
if (uart_obj->rx_ring_buf) {
|
||||
vRingbufferDelete(uart_obj->rx_ring_buf);
|
||||
}
|
||||
if (uart_obj->tx_ring_buf) {
|
||||
vRingbufferDelete(uart_obj->tx_ring_buf);
|
||||
}
|
||||
#if CONFIG_UART_ISR_IN_IRAM
|
||||
free(uart_obj->event_queue_storage);
|
||||
free(uart_obj->event_queue_struct);
|
||||
free(uart_obj->tx_ring_buf_storage);
|
||||
free(uart_obj->tx_ring_buf_struct);
|
||||
free(uart_obj->rx_ring_buf_storage);
|
||||
free(uart_obj->rx_ring_buf_struct);
|
||||
free(uart_obj->rx_mux_struct);
|
||||
free(uart_obj->tx_mux_struct);
|
||||
free(uart_obj->tx_brk_sem_struct);
|
||||
free(uart_obj->tx_done_sem_struct);
|
||||
free(uart_obj->tx_fifo_sem_struct);
|
||||
#endif
|
||||
free(uart_obj);
|
||||
}
|
||||
|
||||
static uart_obj_t *uart_alloc_driver_obj(int event_queue_size, int tx_buffer_size, int rx_buffer_size)
|
||||
{
|
||||
uart_obj_t *uart_obj = heap_caps_calloc(1, sizeof(uart_obj_t), UART_MALLOC_CAPS);
|
||||
if (!uart_obj) {
|
||||
return NULL;
|
||||
}
|
||||
#if CONFIG_UART_ISR_IN_IRAM
|
||||
if (event_queue_size > 0) {
|
||||
uart_obj->event_queue_storage = heap_caps_calloc(event_queue_size, sizeof(uart_event_t), UART_MALLOC_CAPS);
|
||||
uart_obj->event_queue_struct = heap_caps_calloc(1, sizeof(StaticQueue_t), UART_MALLOC_CAPS);
|
||||
if (!uart_obj->event_queue_storage || !uart_obj->event_queue_struct) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (tx_buffer_size > 0) {
|
||||
uart_obj->tx_ring_buf_storage = heap_caps_calloc(1, tx_buffer_size, UART_MALLOC_CAPS);
|
||||
uart_obj->tx_ring_buf_struct = heap_caps_calloc(1, sizeof(StaticRingbuffer_t), UART_MALLOC_CAPS);
|
||||
if (!uart_obj->tx_ring_buf_storage || !uart_obj->tx_ring_buf_struct) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
uart_obj->rx_ring_buf_storage = heap_caps_calloc(1, rx_buffer_size, UART_MALLOC_CAPS);
|
||||
uart_obj->rx_ring_buf_struct = heap_caps_calloc(1, sizeof(StaticRingbuffer_t), UART_MALLOC_CAPS);
|
||||
uart_obj->rx_mux_struct = heap_caps_calloc(1, sizeof(StaticSemaphore_t), UART_MALLOC_CAPS);
|
||||
uart_obj->tx_mux_struct = heap_caps_calloc(1, sizeof(StaticSemaphore_t), UART_MALLOC_CAPS);
|
||||
uart_obj->tx_brk_sem_struct = heap_caps_calloc(1, sizeof(StaticSemaphore_t), UART_MALLOC_CAPS);
|
||||
uart_obj->tx_done_sem_struct = heap_caps_calloc(1, sizeof(StaticSemaphore_t), UART_MALLOC_CAPS);
|
||||
uart_obj->tx_fifo_sem_struct = heap_caps_calloc(1, sizeof(StaticSemaphore_t), UART_MALLOC_CAPS);
|
||||
if (!uart_obj->rx_ring_buf_storage || !uart_obj->rx_ring_buf_struct || !uart_obj->rx_mux_struct ||
|
||||
!uart_obj->tx_mux_struct || !uart_obj->tx_brk_sem_struct || !uart_obj->tx_done_sem_struct ||
|
||||
!uart_obj->tx_fifo_sem_struct) {
|
||||
goto err;
|
||||
}
|
||||
if (event_queue_size > 0) {
|
||||
uart_obj->event_queue = xQueueCreateStatic(event_queue_size, sizeof(uart_event_t),
|
||||
uart_obj->event_queue_storage, uart_obj->event_queue_struct);
|
||||
if (!uart_obj->event_queue) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (tx_buffer_size > 0) {
|
||||
uart_obj->tx_ring_buf = xRingbufferCreateStatic(tx_buffer_size, RINGBUF_TYPE_NOSPLIT,
|
||||
uart_obj->tx_ring_buf_storage, uart_obj->tx_ring_buf_struct);
|
||||
if (!uart_obj->tx_ring_buf) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
uart_obj->rx_ring_buf = xRingbufferCreateStatic(rx_buffer_size, RINGBUF_TYPE_BYTEBUF,
|
||||
uart_obj->rx_ring_buf_storage, uart_obj->rx_ring_buf_struct);
|
||||
uart_obj->rx_mux = xSemaphoreCreateMutexStatic(uart_obj->rx_mux_struct);
|
||||
uart_obj->tx_mux = xSemaphoreCreateMutexStatic(uart_obj->tx_mux_struct);
|
||||
uart_obj->tx_brk_sem = xSemaphoreCreateBinaryStatic(uart_obj->tx_brk_sem_struct);
|
||||
uart_obj->tx_done_sem = xSemaphoreCreateBinaryStatic(uart_obj->tx_done_sem_struct);
|
||||
uart_obj->tx_fifo_sem = xSemaphoreCreateBinaryStatic(uart_obj->tx_fifo_sem_struct);
|
||||
if (!uart_obj->rx_ring_buf || !uart_obj->rx_mux || !uart_obj->tx_mux || !uart_obj->tx_brk_sem ||
|
||||
!uart_obj->tx_done_sem || !uart_obj->tx_fifo_sem) {
|
||||
goto err;
|
||||
}
|
||||
#else
|
||||
if (event_queue_size > 0) {
|
||||
uart_obj->event_queue = xQueueCreate(event_queue_size, sizeof(uart_event_t));
|
||||
if (!uart_obj->event_queue) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (tx_buffer_size > 0) {
|
||||
uart_obj->tx_ring_buf = xRingbufferCreate(tx_buffer_size, RINGBUF_TYPE_NOSPLIT);
|
||||
if (!uart_obj->tx_ring_buf) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
uart_obj->rx_ring_buf = xRingbufferCreate(rx_buffer_size, RINGBUF_TYPE_BYTEBUF);
|
||||
uart_obj->tx_mux = xSemaphoreCreateMutex();
|
||||
uart_obj->rx_mux = xSemaphoreCreateMutex();
|
||||
uart_obj->tx_brk_sem = xSemaphoreCreateBinary();
|
||||
uart_obj->tx_done_sem = xSemaphoreCreateBinary();
|
||||
uart_obj->tx_fifo_sem = xSemaphoreCreateBinary();
|
||||
if (!uart_obj->rx_ring_buf || !uart_obj->rx_mux || !uart_obj->tx_mux || !uart_obj->tx_brk_sem ||
|
||||
!uart_obj->tx_done_sem || !uart_obj->tx_fifo_sem) {
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
return uart_obj;
|
||||
|
||||
err:
|
||||
uart_free_driver_obj(uart_obj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int event_queue_size, QueueHandle_t *uart_queue, int intr_alloc_flags)
|
||||
{
|
||||
esp_err_t r;
|
||||
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
|
||||
@ -1356,7 +1514,7 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
|
||||
#endif
|
||||
|
||||
if (p_uart_obj[uart_num] == NULL) {
|
||||
p_uart_obj[uart_num] = (uart_obj_t*) heap_caps_calloc(1, sizeof(uart_obj_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
p_uart_obj[uart_num] = uart_alloc_driver_obj(event_queue_size, tx_buffer_size, rx_buffer_size);
|
||||
if (p_uart_obj[uart_num] == NULL) {
|
||||
ESP_LOGE(UART_TAG, "UART driver malloc error");
|
||||
return ESP_FAIL;
|
||||
@ -1365,13 +1523,7 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
|
||||
p_uart_obj[uart_num]->uart_mode = UART_MODE_UART;
|
||||
p_uart_obj[uart_num]->coll_det_flg = false;
|
||||
p_uart_obj[uart_num]->rx_always_timeout_flg = false;
|
||||
p_uart_obj[uart_num]->tx_fifo_sem = xSemaphoreCreateBinary();
|
||||
xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem);
|
||||
p_uart_obj[uart_num]->tx_done_sem = xSemaphoreCreateBinary();
|
||||
p_uart_obj[uart_num]->tx_brk_sem = xSemaphoreCreateBinary();
|
||||
p_uart_obj[uart_num]->tx_mux = xSemaphoreCreateMutex();
|
||||
p_uart_obj[uart_num]->rx_mux = xSemaphoreCreateMutex();
|
||||
p_uart_obj[uart_num]->queue_size = queue_size;
|
||||
p_uart_obj[uart_num]->event_queue_size = event_queue_size;
|
||||
p_uart_obj[uart_num]->tx_ptr = NULL;
|
||||
p_uart_obj[uart_num]->tx_head = NULL;
|
||||
p_uart_obj[uart_num]->tx_len_tot = 0;
|
||||
@ -1379,29 +1531,19 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
|
||||
p_uart_obj[uart_num]->tx_brk_len = 0;
|
||||
p_uart_obj[uart_num]->tx_waiting_brk = 0;
|
||||
p_uart_obj[uart_num]->rx_buffered_len = 0;
|
||||
uart_pattern_queue_reset(uart_num, UART_PATTERN_DET_QLEN_DEFAULT);
|
||||
|
||||
if(uart_queue) {
|
||||
p_uart_obj[uart_num]->xQueueUart = xQueueCreate(queue_size, sizeof(uart_event_t));
|
||||
*uart_queue = p_uart_obj[uart_num]->xQueueUart;
|
||||
ESP_LOGI(UART_TAG, "queue free spaces: %d", uxQueueSpacesAvailable(p_uart_obj[uart_num]->xQueueUart));
|
||||
} else {
|
||||
p_uart_obj[uart_num]->xQueueUart = NULL;
|
||||
}
|
||||
p_uart_obj[uart_num]->rx_buffer_full_flg = false;
|
||||
p_uart_obj[uart_num]->tx_waiting_fifo = false;
|
||||
p_uart_obj[uart_num]->rx_ptr = NULL;
|
||||
p_uart_obj[uart_num]->rx_cur_remain = 0;
|
||||
p_uart_obj[uart_num]->rx_head_ptr = NULL;
|
||||
p_uart_obj[uart_num]->rx_ring_buf = xRingbufferCreate(rx_buffer_size, RINGBUF_TYPE_BYTEBUF);
|
||||
if(tx_buffer_size > 0) {
|
||||
p_uart_obj[uart_num]->tx_ring_buf = xRingbufferCreate(tx_buffer_size, RINGBUF_TYPE_NOSPLIT);
|
||||
p_uart_obj[uart_num]->tx_buf_size = tx_buffer_size;
|
||||
} else {
|
||||
p_uart_obj[uart_num]->tx_ring_buf = NULL;
|
||||
p_uart_obj[uart_num]->tx_buf_size = 0;
|
||||
}
|
||||
p_uart_obj[uart_num]->uart_select_notif_callback = NULL;
|
||||
xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem);
|
||||
uart_pattern_queue_reset(uart_num, UART_PATTERN_DET_QLEN_DEFAULT);
|
||||
if (uart_queue) {
|
||||
*uart_queue = p_uart_obj[uart_num]->event_queue;
|
||||
ESP_LOGI(UART_TAG, "queue free spaces: %d", uxQueueSpacesAvailable(p_uart_obj[uart_num]->event_queue));
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(UART_TAG, "UART driver already installed");
|
||||
return ESP_FAIL;
|
||||
@ -1417,9 +1559,13 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
|
||||
uart_hal_disable_intr_mask(&(uart_context[uart_num].hal), UART_LL_INTR_MASK);
|
||||
uart_hal_clr_intsts_mask(&(uart_context[uart_num].hal), UART_LL_INTR_MASK);
|
||||
r = uart_isr_register(uart_num, uart_rx_intr_handler_default, p_uart_obj[uart_num], intr_alloc_flags, &p_uart_obj[uart_num]->intr_handle);
|
||||
if (r!=ESP_OK) goto err;
|
||||
if (r != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
r = uart_intr_config(uart_num, &uart_intr);
|
||||
if (r!=ESP_OK) goto err;
|
||||
if (r != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
return r;
|
||||
|
||||
err:
|
||||
@ -1439,45 +1585,10 @@ esp_err_t uart_driver_delete(uart_port_t uart_num)
|
||||
uart_disable_rx_intr(uart_num);
|
||||
uart_disable_tx_intr(uart_num);
|
||||
uart_pattern_link_free(uart_num);
|
||||
|
||||
if(p_uart_obj[uart_num]->tx_fifo_sem) {
|
||||
vSemaphoreDelete(p_uart_obj[uart_num]->tx_fifo_sem);
|
||||
p_uart_obj[uart_num]->tx_fifo_sem = NULL;
|
||||
}
|
||||
if(p_uart_obj[uart_num]->tx_done_sem) {
|
||||
vSemaphoreDelete(p_uart_obj[uart_num]->tx_done_sem);
|
||||
p_uart_obj[uart_num]->tx_done_sem = NULL;
|
||||
}
|
||||
if(p_uart_obj[uart_num]->tx_brk_sem) {
|
||||
vSemaphoreDelete(p_uart_obj[uart_num]->tx_brk_sem);
|
||||
p_uart_obj[uart_num]->tx_brk_sem = NULL;
|
||||
}
|
||||
if(p_uart_obj[uart_num]->tx_mux) {
|
||||
vSemaphoreDelete(p_uart_obj[uart_num]->tx_mux);
|
||||
p_uart_obj[uart_num]->tx_mux = NULL;
|
||||
}
|
||||
if(p_uart_obj[uart_num]->rx_mux) {
|
||||
vSemaphoreDelete(p_uart_obj[uart_num]->rx_mux);
|
||||
p_uart_obj[uart_num]->rx_mux = NULL;
|
||||
}
|
||||
if(p_uart_obj[uart_num]->xQueueUart) {
|
||||
vQueueDelete(p_uart_obj[uart_num]->xQueueUart);
|
||||
p_uart_obj[uart_num]->xQueueUart = NULL;
|
||||
}
|
||||
if(p_uart_obj[uart_num]->rx_ring_buf) {
|
||||
vRingbufferDelete(p_uart_obj[uart_num]->rx_ring_buf);
|
||||
p_uart_obj[uart_num]->rx_ring_buf = NULL;
|
||||
}
|
||||
if(p_uart_obj[uart_num]->tx_ring_buf) {
|
||||
vRingbufferDelete(p_uart_obj[uart_num]->tx_ring_buf);
|
||||
p_uart_obj[uart_num]->tx_ring_buf = NULL;
|
||||
}
|
||||
|
||||
heap_caps_free(p_uart_obj[uart_num]);
|
||||
uart_free_driver_obj(p_uart_obj[uart_num]);
|
||||
p_uart_obj[uart_num] = NULL;
|
||||
|
||||
#if SOC_UART_SUPPORT_RTC_CLK
|
||||
|
||||
uart_sclk_t sclk = 0;
|
||||
uart_hal_get_sclk(&(uart_context[uart_num].hal), &sclk);
|
||||
if (sclk == UART_SCLK_RTC) {
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <assert.h>
|
||||
#include "esp_efuse_table.h"
|
||||
|
||||
// md5_digest_table 61baa79d296df996c838bc2adc1837e5
|
||||
// md5_digest_table 7e5a29e190c8e3a63e1a85a40b50c355
|
||||
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
|
||||
// If you want to change some fields, you need to change esp_efuse_table.csv file
|
||||
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
|
||||
@ -192,7 +192,7 @@ static const esp_efuse_desc_t JTAG_SEL_ENABLE[] = {
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t SOFT_DIS_JTAG[] = {
|
||||
{EFUSE_BLK0, 48, 2}, // Set these bits to disable JTAG in the soft way (odd number 1 means disable). JTAG can be enabled in HMAC module.,
|
||||
{EFUSE_BLK0, 48, 3}, // Set these bits to disable JTAG in the soft way (odd number 1 means disable). JTAG can be enabled in HMAC module.,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t DIS_PAD_JTAG[] = {
|
||||
|
@ -59,7 +59,7 @@
|
||||
DIS_USB, EFUSE_BLK0, 45, 1, Disable USB function
|
||||
DIS_CAN, EFUSE_BLK0, 46, 1, Disable CAN function
|
||||
JTAG_SEL_ENABLE, EFUSE_BLK0, 47, 1, Set this bit to enable selection between usb_to_jtag and pad_to_jtag through strapping gpio10 when both reg_dis_usb_jtag and reg_dis_pad_jtag are equal to 0.
|
||||
SOFT_DIS_JTAG, EFUSE_BLK0, 48, 2, Set these bits to disable JTAG in the soft way (odd number 1 means disable). JTAG can be enabled in HMAC module.
|
||||
SOFT_DIS_JTAG, EFUSE_BLK0, 48, 3, Set these bits to disable JTAG in the soft way (odd number 1 means disable). JTAG can be enabled in HMAC module.
|
||||
DIS_PAD_JTAG, EFUSE_BLK0, 51, 1, Disable JTAG in the hard way. JTAG is disabled permanently.
|
||||
DIS_DOWNLOAD_MANUAL_ENCRYPT, EFUSE_BLK0, 52, 1, Disable flash encryption when in download boot modes.
|
||||
USB_DREFH, EFUSE_BLK0, 53, 2, Controls single-end input threshold vrefh 1.76 V to 2 V with step of 80 mV stored in eFuse.
|
||||
|
Can't render this file because it contains an unexpected character in line 7 and column 87.
|
@ -17,7 +17,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// md5_digest_table 61baa79d296df996c838bc2adc1837e5
|
||||
// md5_digest_table 7e5a29e190c8e3a63e1a85a40b50c355
|
||||
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
|
||||
// If you want to change some fields, you need to change esp_efuse_table.csv file
|
||||
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
|
||||
// Copyright 2017-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -17,7 +17,7 @@
|
||||
#include <assert.h>
|
||||
#include "esp_efuse_table.h"
|
||||
|
||||
// md5_digest_table d9cd89987a033ef74503daeb4dd8dd07
|
||||
// md5_digest_table c345ec20bb033bf5d071108ae644b54c
|
||||
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
|
||||
// If you want to change some fields, you need to change esp_efuse_table.csv file
|
||||
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
|
||||
@ -388,16 +388,20 @@ static const esp_efuse_desc_t WAFER_VERSION[] = {
|
||||
{EFUSE_BLK1, 114, 3}, // WAFER version 0:A,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t PKG_VERSION[] = {
|
||||
{EFUSE_BLK1, 117, 4}, // Package version 0:ESP32-S2 1:ESP32-S2FH16 2:ESP32-S2FH32,
|
||||
static const esp_efuse_desc_t FLASH_VERSION[] = {
|
||||
{EFUSE_BLK1, 117, 4}, // Flash_version,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t BLOCK1_VERSION[] = {
|
||||
{EFUSE_BLK1, 121, 3}, // BLOCK1 efuse version 0:No calibration 1:With calibration,
|
||||
{EFUSE_BLK1, 121, 3}, // BLOCK1 efuse version,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t SYS_DATA_PART0[] = {
|
||||
{EFUSE_BLK1, 126, 66}, // System configuration,
|
||||
static const esp_efuse_desc_t PSRAM_VERSION[] = {
|
||||
{EFUSE_BLK1, 124, 4}, // PSRAM version,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t PKG_VERSION[] = {
|
||||
{EFUSE_BLK1, 128, 4}, // Package version,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t OPTIONAL_UNIQUE_ID[] = {
|
||||
@ -405,7 +409,7 @@ static const esp_efuse_desc_t OPTIONAL_UNIQUE_ID[] = {
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t BLOCK2_VERSION[] = {
|
||||
{EFUSE_BLK2, 132, 3}, // Version of BLOCK2,
|
||||
{EFUSE_BLK2, 132, 3}, // Version of BLOCK2: 0-No ADC calib; 1-ADC calib V1; 2-ADC calib V2,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t USER_DATA[] = {
|
||||
@ -899,18 +903,23 @@ const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_PKG_VERSION[] = {
|
||||
&PKG_VERSION[0], // Package version 0:ESP32-S2 1:ESP32-S2FH16 2:ESP32-S2FH32
|
||||
const esp_efuse_desc_t* ESP_EFUSE_FLASH_VERSION[] = {
|
||||
&FLASH_VERSION[0], // Flash_version
|
||||
NULL
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_BLOCK1_VERSION[] = {
|
||||
&BLOCK1_VERSION[0], // BLOCK1 efuse version 0:No calibration 1:With calibration
|
||||
&BLOCK1_VERSION[0], // BLOCK1 efuse version
|
||||
NULL
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_SYS_DATA_PART0[] = {
|
||||
&SYS_DATA_PART0[0], // System configuration
|
||||
const esp_efuse_desc_t* ESP_EFUSE_PSRAM_VERSION[] = {
|
||||
&PSRAM_VERSION[0], // PSRAM version
|
||||
NULL
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_PKG_VERSION[] = {
|
||||
&PKG_VERSION[0], // Package version
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -920,7 +929,7 @@ const esp_efuse_desc_t* ESP_EFUSE_OPTIONAL_UNIQUE_ID[] = {
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_BLOCK2_VERSION[] = {
|
||||
&BLOCK2_VERSION[0], // Version of BLOCK2
|
||||
&BLOCK2_VERSION[0], // Version of BLOCK2: 0-No ADC calib; 1-ADC calib V1; 2-ADC calib V2
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -124,14 +124,16 @@
|
||||
SPI_PAD_CONFIG_D6, EFUSE_BLK1, 102, 6, SPI_PAD_configure D6
|
||||
SPI_PAD_CONFIG_D7, EFUSE_BLK1, 108, 6, SPI_PAD_configure D7
|
||||
WAFER_VERSION, EFUSE_BLK1, 114, 3, WAFER version 0:A
|
||||
PKG_VERSION, EFUSE_BLK1, 117, 4, Package version 0:ESP32-S2 1:ESP32-S2FH16 2:ESP32-S2FH32
|
||||
BLOCK1_VERSION, EFUSE_BLK1, 121, 3, BLOCK1 efuse version 0:No calibration 1:With calibration
|
||||
SYS_DATA_PART0, EFUSE_BLK1, 126, 66, System configuration
|
||||
FLASH_VERSION, EFUSE_BLK1, 117, 4, Flash_version
|
||||
BLOCK1_VERSION, EFUSE_BLK1, 121, 3, BLOCK1 efuse version
|
||||
PSRAM_VERSION, EFUSE_BLK1, 124, 4, PSRAM version
|
||||
PKG_VERSION, EFUSE_BLK1, 128, 4, Package version
|
||||
# SYS_DATA_PART0, EFUSE_BLK1, 132, 60, System configuration (Reserve)
|
||||
|
||||
# SYS_DATA_PART1 BLOCK# - System configuration
|
||||
#######################
|
||||
OPTIONAL_UNIQUE_ID, EFUSE_BLK2, 0, 128, Optional unique 128-bit ID
|
||||
BLOCK2_VERSION, EFUSE_BLK2, 132, 3, Version of BLOCK2
|
||||
BLOCK2_VERSION, EFUSE_BLK2, 132, 3, Version of BLOCK2: 0-No ADC calib; 1-ADC calib V1; 2-ADC calib V2
|
||||
|
||||
################
|
||||
USER_DATA, EFUSE_BLK3, 0, 256, User data
|
||||
|
Can't render this file because it contains an unexpected character in line 7 and column 87.
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
|
||||
// Copyright 2017-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -17,7 +17,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// md5_digest_table d9cd89987a033ef74503daeb4dd8dd07
|
||||
// md5_digest_table c345ec20bb033bf5d071108ae644b54c
|
||||
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
|
||||
// If you want to change some fields, you need to change esp_efuse_table.csv file
|
||||
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
|
||||
@ -114,9 +114,10 @@ extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D5[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D6[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D7[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_PKG_VERSION[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_VERSION[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_BLOCK1_VERSION[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_SYS_DATA_PART0[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_PSRAM_VERSION[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_PKG_VERSION[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_OPTIONAL_UNIQUE_ID[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_BLOCK2_VERSION[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA[];
|
||||
|
@ -470,6 +470,10 @@ int esp_tls_conn_http_new_async(const char *url, const esp_tls_cfg_t *cfg, esp_t
|
||||
* of bytes actually written to the TLS/SSL connection.
|
||||
* - <0 if write operation was not successful, because either an
|
||||
* error occured or an action must be taken by the calling process.
|
||||
* - ESP_TLS_ERR_SSL_WANT_READ/
|
||||
* ESP_TLS_ERR_SSL_WANT_WRITE.
|
||||
* if the handshake is incomplete and waiting for data to be available for reading.
|
||||
* In this case this functions needs to be called again when the underlying transport is ready for operation.
|
||||
*/
|
||||
static inline ssize_t esp_tls_conn_write(esp_tls_t *tls, const void *data, size_t datalen)
|
||||
{
|
||||
|
@ -190,9 +190,9 @@ ssize_t esp_mbedtls_write(esp_tls_t *tls, const char *data, size_t datalen)
|
||||
ESP_LOGE(TAG, "write error :%d:", ret);
|
||||
return ret;
|
||||
} else {
|
||||
// Exitting the tls-write process as less than desired datalen are writable
|
||||
// Exiting the tls-write process as less than desired datalen are writable
|
||||
ESP_LOGD(TAG, "mbedtls_ssl_write() returned %d, already written %d, exitting...", ret, written);
|
||||
return written;
|
||||
return (written > 0) ? written : ret;
|
||||
}
|
||||
}
|
||||
written += ret;
|
||||
|
@ -370,7 +370,7 @@ ssize_t esp_wolfssl_read(esp_tls_t *tls, char *data, size_t datalen)
|
||||
ssize_t esp_wolfssl_write(esp_tls_t *tls, const char *data, size_t datalen)
|
||||
{
|
||||
ssize_t ret = wolfSSL_write( (WOLFSSL *)tls->priv_ssl, (unsigned char *) data, datalen);
|
||||
if (ret < 0) {
|
||||
if (ret <= 0) {
|
||||
ret = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
|
||||
if (ret != ESP_TLS_ERR_SSL_WANT_READ && ret != ESP_TLS_ERR_SSL_WANT_WRITE) {
|
||||
ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, -ret);
|
||||
|
@ -423,7 +423,7 @@ menu "ESP32-specific"
|
||||
int
|
||||
prompt "RTC slow memory reserved for coprocessor" if ESP32_ULP_COPROC_ENABLED
|
||||
default 512 if ESP32_ULP_COPROC_ENABLED
|
||||
range 32 8192 if ESP32_ULP_COPROC_ENABLED
|
||||
range 32 8176 if ESP32_ULP_COPROC_ENABLED
|
||||
default 0 if !ESP32_ULP_COPROC_ENABLED
|
||||
range 0 0 if !ESP32_ULP_COPROC_ENABLED
|
||||
help
|
||||
|
@ -89,6 +89,15 @@ size_t esp_spiram_get_size(void);
|
||||
*/
|
||||
void esp_spiram_writeback_cache(void);
|
||||
|
||||
/**
|
||||
* @brief get psram CS IO
|
||||
*
|
||||
* This interface should be called after PSRAM is enabled, otherwise it will
|
||||
* return an invalid value -1/0xff.
|
||||
*
|
||||
* @return psram CS IO or -1/0xff if psram not enabled
|
||||
*/
|
||||
uint8_t esp_spiram_get_cs_io(void);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -97,7 +97,7 @@ MEMORY
|
||||
rtc_slow_seg(RW) : org = 0x50000000 + CONFIG_ESP32_ULP_COPROC_RESERVE_MEM,
|
||||
len = 0x2000 - CONFIG_ESP32_ULP_COPROC_RESERVE_MEM
|
||||
|
||||
/* external memory ,including data and text */
|
||||
/* external memory */
|
||||
extern_ram_seg(RWX) : org = 0x3F800000,
|
||||
len = 0x400000
|
||||
}
|
||||
|
@ -296,4 +296,8 @@ bool esp_spiram_is_initialized(void)
|
||||
return spiram_inited;
|
||||
}
|
||||
|
||||
uint8_t esp_spiram_get_cs_io(void)
|
||||
{
|
||||
return psram_get_cs_io();
|
||||
}
|
||||
#endif
|
||||
|
@ -203,6 +203,13 @@ typedef struct {
|
||||
|
||||
static void IRAM_ATTR psram_cache_init(psram_cache_mode_t psram_cache_mode, psram_vaddr_mode_t vaddrmode);
|
||||
|
||||
static uint8_t s_psram_cs_io = (uint8_t)-1;
|
||||
|
||||
uint8_t psram_get_cs_io(void)
|
||||
{
|
||||
return s_psram_cs_io;
|
||||
}
|
||||
|
||||
static void psram_clear_spi_fifo(psram_spi_num_t spi_num)
|
||||
{
|
||||
int i;
|
||||
@ -844,6 +851,7 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
|
||||
ESP_EARLY_LOGE(TAG, "Not a valid or known package id: %d", pkg_ver);
|
||||
abort();
|
||||
}
|
||||
s_psram_cs_io = psram_io.psram_cs_io;
|
||||
|
||||
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
|
||||
if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_SPI) {
|
||||
|
@ -67,4 +67,11 @@ psram_size_t psram_get_size(void);
|
||||
*/
|
||||
esp_err_t psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vaddrmode);
|
||||
|
||||
/**
|
||||
* @brief get psram CS IO
|
||||
*
|
||||
* @return psram CS IO
|
||||
*/
|
||||
uint8_t psram_get_cs_io(void);
|
||||
|
||||
#endif
|
||||
|
@ -16,14 +16,20 @@
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "esp32c3/rom/hmac.h"
|
||||
#include "esp32c3/rom/ets_sys.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_table.h"
|
||||
#include "esp_hmac.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_crypto_lock.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
|
||||
#include "hal/hmac_hal.h"
|
||||
|
||||
#define SHA256_BLOCK_SZ 64
|
||||
#define SHA256_PAD_SZ 8
|
||||
|
||||
static const char *TAG = "esp_hmac";
|
||||
|
||||
/**
|
||||
* @brief Apply the HMAC padding without the embedded length.
|
||||
*
|
||||
@ -130,3 +136,53 @@ esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static ets_efuse_block_t convert_key_type(hmac_key_id_t key_id) {
|
||||
return ETS_EFUSE_BLOCK_KEY0 + (ets_efuse_block_t) key_id;
|
||||
}
|
||||
|
||||
esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token)
|
||||
{
|
||||
int ets_status;
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
if ((!token) || (key_id >= HMAC_KEY_MAX))
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
|
||||
/* Check if JTAG is permanently disabled by HW Disable eFuse */
|
||||
if (esp_efuse_read_field_bit(ESP_EFUSE_DIS_PAD_JTAG)) {
|
||||
ESP_LOGE(TAG, "JTAG disabled permanently.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_crypto_hmac_lock_acquire();
|
||||
|
||||
ets_status = ets_jtag_enable_temporarily(token, convert_key_type(key_id));
|
||||
|
||||
if (ets_status != ETS_OK) {
|
||||
// ets_jtag_enable_temporarily returns either ETS_OK or ETS_FAIL
|
||||
err = ESP_FAIL;
|
||||
ESP_LOGE(TAG, "JTAG re-enabling failed (%d)", err);
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "HMAC computation in downstream mode is completed.");
|
||||
|
||||
ets_hmac_disable();
|
||||
|
||||
esp_crypto_hmac_lock_release();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_hmac_jtag_disable()
|
||||
{
|
||||
esp_crypto_hmac_lock_acquire();
|
||||
|
||||
REG_SET_BIT(HMAC_SET_INVALIDATE_JTAG_REG, HMAC_INVALIDATE_JTAG);
|
||||
|
||||
esp_crypto_hmac_lock_release();
|
||||
|
||||
ESP_LOGD(TAG, "Invalidate JTAG result register. JTAG disabled.");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -60,6 +60,35 @@ esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
|
||||
size_t message_len,
|
||||
uint8_t *hmac);
|
||||
|
||||
/**
|
||||
* @brief Use HMAC peripheral in Downstream mode to re-enable the JTAG, if it is not permanently disabled by HW.
|
||||
* In downstream mode, HMAC calculations performed by peripheral are used internally and not provided back to user.
|
||||
*
|
||||
* @param key_id Determines which of the 6 key blocks in the efuses should be used for the HMAC calculation.
|
||||
* The corresponding purpose field of the key block in the efuse must be set to HMAC downstream purpose.
|
||||
*
|
||||
* @param token Pre calculated HMAC value of the 32-byte 0x00 using SHA-256 and the known private HMAC key. The key is already
|
||||
* programmed to a eFuse key block. The key block number is provided as the first parameter to this function.
|
||||
*
|
||||
* @return
|
||||
* * ESP_OK, if the calculation was successful,
|
||||
* if the calculated HMAC value matches with provided token,
|
||||
* JTAG will be re-enable otherwise JTAG will remain disabled.
|
||||
* Return value does not indicate the JTAG status.
|
||||
* * ESP_FAIL, if the hmac calculation failed or JTAG is permanently disabled by EFUSE_HARD_DIS_JTAG eFuse parameter.
|
||||
* * ESP_ERR_INVALID_ARG, invalid input arguments
|
||||
*/
|
||||
esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token);
|
||||
|
||||
/**
|
||||
* @brief Disable the JTAG which might be enabled using the HMAC downstream mode. This function just clears the result generated
|
||||
* by calling esp_hmac_jtag_enable() API.
|
||||
*
|
||||
* @return
|
||||
* * ESP_OK return ESP_OK after writing the HMAC_SET_INVALIDATE_JTAG_REG with value 1.
|
||||
*/
|
||||
esp_err_t esp_hmac_jtag_disable(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -46,7 +46,7 @@ MEMORY
|
||||
|
||||
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
/* Flash mapped instruction data */
|
||||
iram0_2_seg (RX) : org = 0x42000020, len = 0x8000000-0x20
|
||||
iram0_2_seg (RX) : org = 0x42000020, len = 0x800000-0x20
|
||||
|
||||
/**
|
||||
* (0x20 offset above is a convenience for the app binary image generation.
|
||||
@ -65,7 +65,8 @@ MEMORY
|
||||
|
||||
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
/* Flash mapped constant data */
|
||||
drom0_0_seg (R) : org = 0x3C000020, len = 0x8000000-0x20
|
||||
drom0_0_seg (R) : org = 0x3C000020, len = 0x800000-0x20
|
||||
|
||||
|
||||
/* (See iram0_2_seg for meaning of 0x20 offset in the above.) */
|
||||
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
|
@ -14,7 +14,6 @@ PROVIDE ( UHCI1 = 0x6000c000 );
|
||||
PROVIDE ( HOST = 0x60015000 );
|
||||
PROVIDE ( RMT = 0x60016000 );
|
||||
PROVIDE ( RMTMEM = 0x60016400 );
|
||||
PROVIDE ( PCNT = 0x60017000 );
|
||||
PROVIDE ( SLC = 0x60018000 );
|
||||
PROVIDE ( LEDC = 0x60019000 );
|
||||
PROVIDE ( TIMERG0 = 0x6001F000 );
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "esp32c3/memprot.h"
|
||||
#include "riscv/interrupt.h"
|
||||
#include "esp32c3/rom/ets_sys.h"
|
||||
#include "esp_fault.h"
|
||||
#include "soc/cpu.h"
|
||||
|
||||
|
||||
extern int _iram_text_end;
|
||||
@ -469,6 +471,10 @@ void esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uint32_t
|
||||
|
||||
void esp_memprot_set_prot_int(bool invoke_panic_handler, bool lock_feature, void *split_addr, uint32_t *mem_type_mask)
|
||||
{
|
||||
//if being debugged check we are not glitched and dont enable Memprot
|
||||
if (esp_cpu_in_ocd_debug_mode()) {
|
||||
ESP_FAULT_ASSERT(esp_cpu_in_ocd_debug_mode());
|
||||
} else {
|
||||
uint32_t required_mem_prot = mem_type_mask == NULL ? (uint32_t) MEMPROT_ALL : *mem_type_mask;
|
||||
bool use_iram0 = required_mem_prot & MEMPROT_IRAM0_SRAM;
|
||||
bool use_dram0 = required_mem_prot & MEMPROT_DRAM0_SRAM;
|
||||
@ -500,8 +506,10 @@ void esp_memprot_set_prot_int(bool invoke_panic_handler, bool lock_feature, void
|
||||
esp_memprot_set_split_line(MEMPROT_IRAM0_LINE_1_SPLITLINE, line_addr);
|
||||
esp_memprot_set_split_line(MEMPROT_IRAM0_LINE_0_SPLITLINE, line_addr);
|
||||
esp_memprot_set_split_line(MEMPROT_IRAM0_DRAM0_SPLITLINE, line_addr);
|
||||
esp_memprot_set_split_line(MEMPROT_DRAM0_DMA_LINE_0_SPLITLINE, (void *)(MAP_IRAM_TO_DRAM((uint32_t)line_addr)));
|
||||
esp_memprot_set_split_line(MEMPROT_DRAM0_DMA_LINE_1_SPLITLINE, (void *)(MAP_IRAM_TO_DRAM((uint32_t)line_addr)));
|
||||
esp_memprot_set_split_line(MEMPROT_DRAM0_DMA_LINE_0_SPLITLINE,
|
||||
(void *) (MAP_IRAM_TO_DRAM((uint32_t) line_addr)));
|
||||
esp_memprot_set_split_line(MEMPROT_DRAM0_DMA_LINE_1_SPLITLINE,
|
||||
(void *) (MAP_IRAM_TO_DRAM((uint32_t) line_addr)));
|
||||
|
||||
//set permissions
|
||||
if (required_mem_prot & MEMPROT_IRAM0_SRAM) {
|
||||
@ -540,6 +548,7 @@ void esp_memprot_set_prot_int(bool invoke_panic_handler, bool lock_feature, void
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t esp_memprot_get_dram_status_reg_1()
|
||||
{
|
||||
|
@ -264,7 +264,7 @@ menu "ESP32S2-specific"
|
||||
int
|
||||
prompt "RTC slow memory reserved for coprocessor" if ESP32S2_ULP_COPROC_ENABLED
|
||||
default 2048 if ESP32S2_ULP_COPROC_ENABLED
|
||||
range 32 8192 if ESP32S2_ULP_COPROC_ENABLED
|
||||
range 32 8176 if ESP32S2_ULP_COPROC_ENABLED
|
||||
default 0 if !ESP32S2_ULP_COPROC_ENABLED
|
||||
range 0 0 if !ESP32S2_ULP_COPROC_ENABLED
|
||||
help
|
||||
|
@ -55,7 +55,8 @@ esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
|
||||
|
||||
esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token)
|
||||
{
|
||||
esp_err_t err;
|
||||
int ets_status;
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
if ((!token) || (key_id >= HMAC_KEY_MAX))
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@ -77,10 +78,10 @@ esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token)
|
||||
REG_WRITE(DPORT_JTAG_CTRL_0_REG + i, __builtin_bswap32(key_word));
|
||||
}
|
||||
|
||||
err = ets_hmac_calculate_downstream(convert_key_type(key_id), ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG);
|
||||
if (err != ETS_OK) {
|
||||
ESP_LOGE(TAG, "HMAC downstream JTAG enable mode setting failed.");
|
||||
return ESP_FAIL;
|
||||
ets_status = ets_hmac_calculate_downstream(convert_key_type(key_id), ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG);
|
||||
if (ets_status != ETS_OK) {
|
||||
err = ESP_FAIL;
|
||||
ESP_LOGE(TAG, "HMAC downstream JTAG enable mode setting failed. (%d)", err);
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "HMAC computation in downstream mode is completed.");
|
||||
@ -89,7 +90,7 @@ esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token)
|
||||
|
||||
esp_crypto_dma_lock_release();
|
||||
|
||||
return ESP_OK;
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_hmac_jtag_disable()
|
||||
|
@ -78,6 +78,15 @@ size_t esp_spiram_get_size(void);
|
||||
*/
|
||||
void esp_spiram_writeback_cache(void);
|
||||
|
||||
/**
|
||||
* @brief get psram CS IO
|
||||
*
|
||||
* This interface should be called after PSRAM is enabled, otherwise it will
|
||||
* return an invalid value -1/0xff.
|
||||
*
|
||||
* @return psram CS IO or -1/0xff if psram not enabled
|
||||
*/
|
||||
uint8_t esp_spiram_get_cs_io(void);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -102,6 +102,10 @@ MEMORY
|
||||
|
||||
/* RTC fast memory (same block as above), viewed from data bus */
|
||||
rtc_data_seg(RW) : org = 0x3ff9e000, len = 0x2000 - ESP_BOOTLOADER_RESERVE_RTC
|
||||
|
||||
/* external memory, covers the dport, dram0, dram1 cacheable address space */
|
||||
extern_ram_seg(RWX) : org = 0x3F500000,
|
||||
len = 0xA80000
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ESP32S2_USE_FIXED_STATIC_RAM_SIZE)
|
||||
|
@ -240,6 +240,17 @@ SECTIONS
|
||||
_noinit_end = ABSOLUTE(.);
|
||||
} > dram0_0_seg
|
||||
|
||||
/* external memory bss, from any global variable with EXT_RAM_ATTR attribute*/
|
||||
.ext_ram.bss (NOLOAD) :
|
||||
{
|
||||
_ext_ram_bss_start = ABSOLUTE(.);
|
||||
|
||||
mapping[extern_ram]
|
||||
|
||||
. = ALIGN(4);
|
||||
_ext_ram_bss_end = ABSOLUTE(.);
|
||||
} > extern_ram_seg
|
||||
|
||||
/* Shared RAM */
|
||||
.dram0.bss (NOLOAD) :
|
||||
{
|
||||
|
@ -30,7 +30,6 @@ static const char *TAG = "memprot";
|
||||
#include "hal/memprot_ll.h"
|
||||
#include "hal/memprot_peri_ll.h"
|
||||
#include "esp_fault.h"
|
||||
|
||||
#include "soc/cpu.h"
|
||||
|
||||
extern int _iram_text_end;
|
||||
@ -650,6 +649,11 @@ void esp_memprot_set_prot_peri2(mem_type_prot_t mem_type, uint32_t *split_addr,
|
||||
|
||||
void esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uint32_t *mem_type_mask)
|
||||
{
|
||||
//if being debugged check we are not glitched and dont enable Memprot
|
||||
if (esp_cpu_in_ocd_debug_mode()) {
|
||||
ESP_FAULT_ASSERT(esp_cpu_in_ocd_debug_mode());
|
||||
} else {
|
||||
|
||||
//any IRAM0/DRAM0 enable/disable call applies to all memory modules connected
|
||||
uint32_t required_mem_prot = mem_type_mask == NULL ? (uint32_t)MEMPROT_ALL : *mem_type_mask;
|
||||
bool use_iram0 = required_mem_prot & MEMPROT_IRAM0_SRAM || required_mem_prot & MEMPROT_IRAM0_RTCFAST;
|
||||
@ -671,12 +675,6 @@ void esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uint32_t
|
||||
esp_memprot_intr_ena(MEMPROT_PERI2_RTCSLOW_0, false);
|
||||
}
|
||||
|
||||
//connect to intr. matrix if not being debugged
|
||||
if (!esp_cpu_in_ocd_debug_mode()) {
|
||||
|
||||
ESP_FAULT_ASSERT(!esp_cpu_in_ocd_debug_mode());
|
||||
|
||||
//initialize for specific buses (any memory type does the job)
|
||||
if (invoke_panic_handler) {
|
||||
if (use_iram0) {
|
||||
esp_memprot_intr_init(MEMPROT_IRAM0_SRAM);
|
||||
|
@ -52,99 +52,36 @@ static const char* TAG = "spiram";
|
||||
|
||||
static bool spiram_inited=false;
|
||||
|
||||
/*
|
||||
Simple RAM test. Writes a word every 32 bytes. Takes about a second to complete for 4MiB. Returns
|
||||
true when RAM seems OK, false when test fails. WARNING: Do not run this before the 2nd cpu has been
|
||||
initialized (in a two-core system) or after the heap allocator has taken ownership of the memory.
|
||||
*/
|
||||
bool esp_spiram_test(void)
|
||||
{
|
||||
size_t spiram_size = esp_spiram_get_size();
|
||||
volatile int *spiram=(volatile int*)(SOC_EXTRAM_DATA_HIGH - spiram_size);
|
||||
size_t p;
|
||||
size_t s = spiram_size;
|
||||
int errct=0;
|
||||
int initial_err=-1;
|
||||
|
||||
if (SOC_EXTRAM_DATA_SIZE < spiram_size) {
|
||||
ESP_EARLY_LOGW(TAG, "Only test spiram from %08x to %08x\n", SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH);
|
||||
spiram=(volatile int*)SOC_EXTRAM_DATA_LOW;
|
||||
s = SOC_EXTRAM_DATA_SIZE;
|
||||
}
|
||||
for (p=0; p<(s/sizeof(int)); p+=8) {
|
||||
spiram[p]=p^0xAAAAAAAA;
|
||||
}
|
||||
for (p=0; p<(s/sizeof(int)); p+=8) {
|
||||
if (spiram[p]!=(p^0xAAAAAAAA)) {
|
||||
errct++;
|
||||
if (errct==1) initial_err=p*4;
|
||||
if (errct < 4) {
|
||||
ESP_EARLY_LOGE(TAG, "SPI SRAM error@%08x:%08x/%08x \n", &spiram[p], spiram[p], p^0xAAAAAAAA);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (errct) {
|
||||
ESP_EARLY_LOGE(TAG, "SPI SRAM memory test fail. %d/%d writes failed, first @ %X\n", errct, s/32, initial_err+SOC_EXTRAM_DATA_LOW);
|
||||
return false;
|
||||
} else {
|
||||
ESP_EARLY_LOGI(TAG, "SPI SRAM memory test OK");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#define DRAM0_ONLY_CACHE_SIZE BUS_IRAM0_CACHE_SIZE
|
||||
#define DRAM0_DRAM1_CACHE_SIZE (BUS_IRAM0_CACHE_SIZE + BUS_IRAM1_CACHE_SIZE)
|
||||
#define DRAM0_DRAM1_DPORT_CACHE_SIZE (BUS_IRAM0_CACHE_SIZE + BUS_IRAM1_CACHE_SIZE + BUS_DPORT_CACHE_SIZE)
|
||||
#define DBUS3_ONLY_CACHE_SIZE BUS_AHB_DBUS3_CACHE_SIZE
|
||||
#define DRAM0_DRAM1_DPORT_DBUS3_CACHE_SIZE (DRAM0_DRAM1_DPORT_CACHE_SIZE + DBUS3_ONLY_CACHE_SIZE)
|
||||
|
||||
#define SPIRAM_SIZE_EXC_DRAM0_DRAM1_DPORT (spiram_size - DRAM0_DRAM1_DPORT_CACHE_SIZE)
|
||||
#define SPIRAM_SIZE_EXC_DATA_CACHE (spiram_size - DRAM0_DRAM1_DPORT_DBUS3_CACHE_SIZE)
|
||||
|
||||
#define SPIRAM_SMALL_SIZE_MAP_VADDR (DRAM0_CACHE_ADDRESS_HIGH - spiram_size)
|
||||
#define SPIRAM_SMALL_SIZE_MAP_PADDR 0
|
||||
#define SPIRAM_SMALL_SIZE_MAP_SIZE spiram_size
|
||||
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
extern uint8_t _ext_ram_bss_start, _ext_ram_bss_end;
|
||||
#define ALIGN_UP_BY(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
|
||||
#define EXT_BSS_SIZE ((uint32_t)(&_ext_ram_bss_end - &_ext_ram_bss_start))
|
||||
#define EXT_BSS_PAGE_ALIGN_SIZE (ALIGN_UP_BY(EXT_BSS_SIZE, 0x10000))
|
||||
#endif
|
||||
|
||||
#define SPIRAM_MID_SIZE_MAP_VADDR (AHB_DBUS3_ADDRESS_HIGH - SPIRAM_SIZE_EXC_DRAM0_DRAM1_DPORT)
|
||||
#define SPIRAM_MID_SIZE_MAP_PADDR 0
|
||||
#define SPIRAM_MID_SIZE_MAP_SIZE (SPIRAM_SIZE_EXC_DRAM0_DRAM1_DPORT)
|
||||
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
#define SPIRAM_MAP_PADDR_START EXT_BSS_PAGE_ALIGN_SIZE
|
||||
#define FREE_DRAM0_DRAM1_DPORT_CACHE_START (DPORT_CACHE_ADDRESS_LOW + EXT_BSS_PAGE_ALIGN_SIZE)
|
||||
#define FREE_DRAM0_DRAM1_DPORT_CACHE_SIZE (DRAM0_DRAM1_DPORT_CACHE_SIZE - EXT_BSS_PAGE_ALIGN_SIZE)
|
||||
#else
|
||||
#define SPIRAM_MAP_PADDR_START 0
|
||||
#define FREE_DRAM0_DRAM1_DPORT_CACHE_START (DPORT_CACHE_ADDRESS_LOW)
|
||||
#define FREE_DRAM0_DRAM1_DPORT_CACHE_SIZE (DRAM0_DRAM1_DPORT_CACHE_SIZE)
|
||||
#endif // if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
|
||||
#define SPIRAM_BIG_SIZE_MAP_VADDR AHB_DBUS3_ADDRESS_LOW
|
||||
#define SPIRAM_BIG_SIZE_MAP_PADDR (AHB_DBUS3_ADDRESS_HIGH - DRAM0_DRAM1_DPORT_DBUS3_CACHE_SIZE)
|
||||
#define SPIRAM_BIG_SIZE_MAP_SIZE DBUS3_ONLY_CACHE_SIZE
|
||||
#define SPIRAM_MAP_VADDR_START (DRAM0_CACHE_ADDRESS_HIGH - spiram_map_size)
|
||||
#define SPIRAM_MAP_SIZE spiram_map_size
|
||||
|
||||
#define SPIRAM_MID_BIG_SIZE_MAP_VADDR DPORT_CACHE_ADDRESS_LOW
|
||||
#define SPIRAM_MID_BIG_SIZE_MAP_PADDR SPIRAM_SIZE_EXC_DRAM0_DRAM1_DPORT
|
||||
#define SPIRAM_MID_BIG_SIZE_MAP_SIZE DRAM0_DRAM1_DPORT_DBUS3_CACHE_SIZE
|
||||
|
||||
void IRAM_ATTR esp_spiram_init_cache(void)
|
||||
{
|
||||
size_t spiram_size = esp_spiram_get_size();
|
||||
Cache_Suspend_DCache();
|
||||
/* map the address from SPIRAM end to the start, map the address in order: DRAM1, DRAM1, DPORT, DBUS3 */
|
||||
if (spiram_size <= DRAM0_ONLY_CACHE_SIZE) {
|
||||
/* cache size <= 3MB + 512 KB, only map DRAM0 bus */
|
||||
Cache_Dbus_MMU_Set(MMU_ACCESS_SPIRAM, SPIRAM_SMALL_SIZE_MAP_VADDR, SPIRAM_SMALL_SIZE_MAP_PADDR, 64, SPIRAM_SMALL_SIZE_MAP_SIZE >> 16, 0);
|
||||
REG_CLR_BIT(EXTMEM_PRO_DCACHE_CTRL1_REG, EXTMEM_PRO_DCACHE_MASK_DRAM0);
|
||||
} else if (spiram_size <= DRAM0_DRAM1_CACHE_SIZE) {
|
||||
/* cache size <= 7MB + 512KB, only map DRAM0 and DRAM1 bus */
|
||||
Cache_Dbus_MMU_Set(MMU_ACCESS_SPIRAM, SPIRAM_SMALL_SIZE_MAP_VADDR, SPIRAM_SMALL_SIZE_MAP_PADDR, 64, SPIRAM_SMALL_SIZE_MAP_SIZE >> 16, 0);
|
||||
REG_CLR_BIT(EXTMEM_PRO_DCACHE_CTRL1_REG, EXTMEM_PRO_DCACHE_MASK_DRAM1 | EXTMEM_PRO_DCACHE_MASK_DRAM0);
|
||||
} else if (spiram_size <= DRAM0_DRAM1_DPORT_CACHE_SIZE) {
|
||||
/* cache size <= 10MB + 512KB, map DRAM0, DRAM1, DPORT bus */
|
||||
Cache_Dbus_MMU_Set(MMU_ACCESS_SPIRAM, SPIRAM_SMALL_SIZE_MAP_VADDR, SPIRAM_SMALL_SIZE_MAP_PADDR, 64, SPIRAM_SMALL_SIZE_MAP_SIZE >> 16, 0);
|
||||
REG_CLR_BIT(EXTMEM_PRO_DCACHE_CTRL1_REG, EXTMEM_PRO_DCACHE_MASK_DRAM1 | EXTMEM_PRO_DCACHE_MASK_DRAM0 | EXTMEM_PRO_DCACHE_MASK_DPORT);
|
||||
} else {
|
||||
/* cache size > 10MB + 512KB, map DRAM0, DRAM1, DPORT bus , only remap 0x3f500000 ~ 0x3ff90000*/
|
||||
Cache_Dbus_MMU_Set(MMU_ACCESS_SPIRAM, DPORT_CACHE_ADDRESS_LOW, SPIRAM_SMALL_SIZE_MAP_PADDR, 64, DRAM0_DRAM1_DPORT_CACHE_SIZE >> 16, 0);
|
||||
REG_CLR_BIT(EXTMEM_PRO_DCACHE_CTRL1_REG, EXTMEM_PRO_DCACHE_MASK_DRAM1 | EXTMEM_PRO_DCACHE_MASK_DRAM0 | EXTMEM_PRO_DCACHE_MASK_DPORT);
|
||||
}
|
||||
Cache_Resume_DCache(0);
|
||||
}
|
||||
|
||||
static uint32_t pages_for_flash = 0;
|
||||
static uint32_t instrcution_in_spiram = 0;
|
||||
static uint32_t next_map_page_num = 0;
|
||||
static uint32_t instruction_in_spiram = 0;
|
||||
static uint32_t rodata_in_spiram = 0;
|
||||
static size_t spiram_size = 0;
|
||||
static size_t spiram_map_size = 0;
|
||||
|
||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
|
||||
static int instr_flash2spiram_offs = 0;
|
||||
@ -163,9 +100,44 @@ static uint32_t page0_mapped = 0;
|
||||
static uint32_t page0_page = INVALID_PHY_PAGE;
|
||||
#endif
|
||||
|
||||
void IRAM_ATTR esp_spiram_init_cache(void)
|
||||
{
|
||||
spiram_map_size = spiram_size;
|
||||
Cache_Suspend_DCache();
|
||||
|
||||
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
/*if instruction or rodata in flash will be load to spiram, some subsequent operations require the start
|
||||
address to be aligned by page, so allocate N pages address space for spiram's bss*/
|
||||
Cache_Dbus_MMU_Set(MMU_ACCESS_SPIRAM, DPORT_CACHE_ADDRESS_LOW, 0, 64, EXT_BSS_PAGE_ALIGN_SIZE >> 16, 0);
|
||||
REG_CLR_BIT(EXTMEM_PRO_DCACHE_CTRL1_REG, EXTMEM_PRO_DCACHE_MASK_DPORT);
|
||||
next_map_page_num += (EXT_BSS_PAGE_ALIGN_SIZE >> 16);
|
||||
spiram_map_size -= EXT_BSS_PAGE_ALIGN_SIZE;
|
||||
#endif
|
||||
|
||||
/* map the address from SPIRAM end to the start, map the address in order: DRAM0, DRAM1, DPORT */
|
||||
if (spiram_map_size <= DRAM0_ONLY_CACHE_SIZE) {
|
||||
/* psram need to be mapped vaddr size <= 3MB + 512 KB, only map DRAM0 bus */
|
||||
Cache_Dbus_MMU_Set(MMU_ACCESS_SPIRAM, SPIRAM_MAP_VADDR_START, SPIRAM_MAP_PADDR_START, 64, SPIRAM_MAP_SIZE >> 16, 0);
|
||||
REG_CLR_BIT(EXTMEM_PRO_DCACHE_CTRL1_REG, EXTMEM_PRO_DCACHE_MASK_DRAM0);
|
||||
} else if (spiram_map_size <= DRAM0_DRAM1_CACHE_SIZE) {
|
||||
/* psram need to be mapped vaddr size <= 7MB + 512KB, only map DRAM0 and DRAM1 bus */
|
||||
Cache_Dbus_MMU_Set(MMU_ACCESS_SPIRAM, SPIRAM_MAP_VADDR_START, SPIRAM_MAP_PADDR_START, 64, SPIRAM_MAP_SIZE >> 16, 0);
|
||||
REG_CLR_BIT(EXTMEM_PRO_DCACHE_CTRL1_REG, EXTMEM_PRO_DCACHE_MASK_DRAM1 | EXTMEM_PRO_DCACHE_MASK_DRAM0);
|
||||
} else if (spiram_size <= DRAM0_DRAM1_DPORT_CACHE_SIZE) { // Equivalent to {spiram_map_size < DRAM0_DRAM1_DPORT_CACHE_SIZE - (spiram_size - spiram_map_size)/*bss size*/}
|
||||
/* psram need to be mapped vaddr size <= 10MB + 512KB - bss_page_align_size, map DRAM0, DRAM1, DPORT bus */
|
||||
Cache_Dbus_MMU_Set(MMU_ACCESS_SPIRAM, SPIRAM_MAP_VADDR_START, SPIRAM_MAP_PADDR_START, 64, SPIRAM_MAP_SIZE >> 16, 0);
|
||||
REG_CLR_BIT(EXTMEM_PRO_DCACHE_CTRL1_REG, EXTMEM_PRO_DCACHE_MASK_DRAM1 | EXTMEM_PRO_DCACHE_MASK_DRAM0 | EXTMEM_PRO_DCACHE_MASK_DPORT);
|
||||
} else {
|
||||
/* psram need to be mapped vaddr size > 10MB + 512KB - bss_page_align_size, map DRAM0, DRAM1, DPORT bus ,discard the memory in the end of spiram */
|
||||
Cache_Dbus_MMU_Set(MMU_ACCESS_SPIRAM, FREE_DRAM0_DRAM1_DPORT_CACHE_START, SPIRAM_MAP_PADDR_START, 64, FREE_DRAM0_DRAM1_DPORT_CACHE_SIZE >> 16, 0);
|
||||
REG_CLR_BIT(EXTMEM_PRO_DCACHE_CTRL1_REG, EXTMEM_PRO_DCACHE_MASK_DRAM1 | EXTMEM_PRO_DCACHE_MASK_DRAM0 | EXTMEM_PRO_DCACHE_MASK_DPORT);
|
||||
}
|
||||
Cache_Resume_DCache(0);
|
||||
}
|
||||
|
||||
uint32_t esp_spiram_instruction_access_enabled(void)
|
||||
{
|
||||
return instrcution_in_spiram;
|
||||
return instruction_in_spiram;
|
||||
}
|
||||
|
||||
uint32_t esp_spiram_rodata_access_enabled(void)
|
||||
@ -176,23 +148,22 @@ uint32_t esp_spiram_rodata_access_enabled(void)
|
||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
|
||||
esp_err_t esp_spiram_enable_instruction_access(void)
|
||||
{
|
||||
size_t spiram_size = esp_spiram_get_size();
|
||||
uint32_t pages_in_flash = 0;
|
||||
pages_in_flash += Cache_Count_Flash_Pages(PRO_CACHE_IBUS0, &page0_mapped);
|
||||
pages_in_flash += Cache_Count_Flash_Pages(PRO_CACHE_IBUS1, &page0_mapped);
|
||||
if ((pages_in_flash + pages_for_flash) > (spiram_size >> 16)) {
|
||||
ESP_EARLY_LOGE(TAG, "SPI RAM space not enough for the instructions, has %d pages, need %d pages.", (spiram_size >> 16), (pages_in_flash + pages_for_flash));
|
||||
if ((pages_in_flash + next_map_page_num) > (spiram_size >> 16)) {
|
||||
ESP_EARLY_LOGE(TAG, "SPI RAM space not enough for the instructions, has %d pages, need %d pages.", (spiram_size >> 16), (pages_in_flash + next_map_page_num));
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_EARLY_LOGI(TAG, "Instructions copied and mapped to SPIRAM");
|
||||
uint32_t instr_mmu_offset = ((uint32_t)&_instruction_reserved_start & 0xFFFFFF)/MMU_PAGE_SIZE;
|
||||
uint32_t mmu_value = *(volatile uint32_t *)(DR_REG_MMU_TABLE + PRO_CACHE_IBUS0_MMU_START + instr_mmu_offset*sizeof(uint32_t));
|
||||
mmu_value &= MMU_ADDRESS_MASK;
|
||||
instr_flash2spiram_offs = mmu_value - pages_for_flash;
|
||||
ESP_EARLY_LOGV(TAG, "Instructions from flash page%d copy to SPIRAM page%d, Offset: %d", mmu_value, pages_for_flash, instr_flash2spiram_offs);
|
||||
pages_for_flash = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_IBUS0, IRAM0_ADDRESS_LOW, pages_for_flash, &page0_page);
|
||||
pages_for_flash = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_IBUS1, IRAM1_ADDRESS_LOW, pages_for_flash, &page0_page);
|
||||
instrcution_in_spiram = 1;
|
||||
instr_flash2spiram_offs = mmu_value - next_map_page_num;
|
||||
ESP_EARLY_LOGV(TAG, "Instructions from flash page%d copy to SPIRAM page%d, Offset: %d", mmu_value, next_map_page_num, instr_flash2spiram_offs);
|
||||
next_map_page_num = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_IBUS0, IRAM0_ADDRESS_LOW, next_map_page_num, &page0_page);
|
||||
next_map_page_num = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_IBUS1, IRAM1_ADDRESS_LOW, next_map_page_num, &page0_page);
|
||||
instruction_in_spiram = 1;
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
@ -206,7 +177,7 @@ esp_err_t esp_spiram_enable_rodata_access(void)
|
||||
pages_in_flash += Cache_Count_Flash_Pages(PRO_CACHE_DBUS1, &page0_mapped);
|
||||
pages_in_flash += Cache_Count_Flash_Pages(PRO_CACHE_DBUS2, &page0_mapped);
|
||||
|
||||
if ((pages_in_flash + pages_for_flash) > (esp_spiram_get_size() >> 16)) {
|
||||
if ((pages_in_flash + next_map_page_num) > (spiram_size >> 16)) {
|
||||
ESP_EARLY_LOGE(TAG, "SPI RAM space not enough for the read only data.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@ -215,12 +186,12 @@ esp_err_t esp_spiram_enable_rodata_access(void)
|
||||
uint32_t rodata_mmu_offset = ((uint32_t)&_rodata_reserved_start & 0xFFFFFF)/MMU_PAGE_SIZE;
|
||||
uint32_t mmu_value = *(volatile uint32_t *)(DR_REG_MMU_TABLE + PRO_CACHE_IBUS2_MMU_START + rodata_mmu_offset*sizeof(uint32_t));
|
||||
mmu_value &= MMU_ADDRESS_MASK;
|
||||
rodata_flash2spiram_offs = mmu_value - pages_for_flash;
|
||||
ESP_EARLY_LOGV(TAG, "Rodata from flash page%d copy to SPIRAM page%d, Offset: %d", mmu_value, pages_for_flash, rodata_flash2spiram_offs);
|
||||
pages_for_flash = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_IBUS2, DROM0_ADDRESS_LOW, pages_for_flash, &page0_page);
|
||||
pages_for_flash = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_DBUS0, DRAM0_ADDRESS_LOW, pages_for_flash, &page0_page);
|
||||
pages_for_flash = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_DBUS1, DRAM1_ADDRESS_LOW, pages_for_flash, &page0_page);
|
||||
pages_for_flash = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_DBUS2, DPORT_ADDRESS_LOW, pages_for_flash, &page0_page);
|
||||
rodata_flash2spiram_offs = mmu_value - next_map_page_num;
|
||||
ESP_EARLY_LOGV(TAG, "Rodata from flash page%d copy to SPIRAM page%d, Offset: %d", mmu_value, next_map_page_num, rodata_flash2spiram_offs);
|
||||
next_map_page_num = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_IBUS2, DROM0_ADDRESS_LOW, next_map_page_num, &page0_page);
|
||||
next_map_page_num = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_DBUS0, DRAM0_ADDRESS_LOW, next_map_page_num, &page0_page);
|
||||
next_map_page_num = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_DBUS1, DRAM1_ADDRESS_LOW, next_map_page_num, &page0_page);
|
||||
next_map_page_num = Cache_Flash_To_SPIRAM_Copy(PRO_CACHE_DBUS2, DPORT_ADDRESS_LOW, next_map_page_num, &page0_page);
|
||||
rodata_in_spiram = 1;
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -293,7 +264,7 @@ esp_err_t esp_spiram_init(void)
|
||||
|
||||
spiram_inited = true;
|
||||
|
||||
size_t spiram_size = esp_spiram_get_size();
|
||||
spiram_size = esp_spiram_get_size();
|
||||
|
||||
#if (CONFIG_SPIRAM_SIZE != -1)
|
||||
if (spiram_size != CONFIG_SPIRAM_SIZE) {
|
||||
@ -316,30 +287,58 @@ esp_err_t esp_spiram_init(void)
|
||||
|
||||
esp_err_t esp_spiram_add_to_heapalloc(void)
|
||||
{
|
||||
size_t spiram_size = esp_spiram_get_size();
|
||||
uint32_t size_for_flash = (pages_for_flash << 16);
|
||||
intptr_t vaddr;
|
||||
ESP_EARLY_LOGI(TAG, "Adding pool of %dK of external SPI memory to heap allocator", (spiram_size - (pages_for_flash << 16))/1024);
|
||||
//Add entire external RAM region to heap allocator. Heap allocator knows the capabilities of this type of memory, so there's
|
||||
//no need to explicitly specify them.
|
||||
size_t recycle_pages_size = 0;
|
||||
size_t map_size = 0;
|
||||
intptr_t map_vaddr, map_paddr;
|
||||
ESP_EARLY_LOGI(TAG, "Adding pool of %dK of external SPI memory to heap allocator", (spiram_size - (next_map_page_num << 16))/1024);
|
||||
|
||||
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
if(EXT_BSS_SIZE){
|
||||
ESP_EARLY_LOGI(TAG, "Adding pool of %d Byte(spiram .bss page unused area) of external SPI memory to heap allocator", EXT_BSS_PAGE_ALIGN_SIZE - EXT_BSS_SIZE);
|
||||
esp_err_t err_status = heap_caps_add_region(DPORT_CACHE_ADDRESS_LOW + EXT_BSS_SIZE, FREE_DRAM0_DRAM1_DPORT_CACHE_START - 1);
|
||||
if (err_status != ESP_OK){
|
||||
return err_status;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS || CONFIG_SPIRAM_RODATA
|
||||
/* Part of the physical address space in spiram is mapped by IRAM0/DROM0,
|
||||
so the DPORT_DRAM0_DRAM1 address space of the same size can be released */
|
||||
uint32_t occupied_pages_size = (next_map_page_num << 16);
|
||||
recycle_pages_size = occupied_pages_size - SPIRAM_MAP_PADDR_START;
|
||||
#endif
|
||||
|
||||
// Small size: means DPORT_DRAM0_DRAM1 bus virtrual address space larger than the spiram size
|
||||
if (spiram_size <= DRAM0_DRAM1_DPORT_CACHE_SIZE) {
|
||||
/* cache size <= 10MB + 512KB, map DRAM0, DRAM1, DPORT bus */
|
||||
vaddr = SPIRAM_SMALL_SIZE_MAP_VADDR;
|
||||
return heap_caps_add_region(vaddr + size_for_flash, vaddr + spiram_size - 1);
|
||||
map_vaddr = SPIRAM_MAP_VADDR_START;
|
||||
return heap_caps_add_region(map_vaddr + recycle_pages_size, map_vaddr + spiram_map_size - 1); // pass rodata & instruction section
|
||||
}
|
||||
|
||||
vaddr = DPORT_CACHE_ADDRESS_LOW;
|
||||
Cache_Dbus_MMU_Set(MMU_ACCESS_SPIRAM, vaddr, SPIRAM_SMALL_SIZE_MAP_PADDR, 64, DRAM0_DRAM1_DPORT_CACHE_SIZE >> 16, 0);
|
||||
if (size_for_flash <= SPIRAM_SIZE_EXC_DRAM0_DRAM1_DPORT) {
|
||||
return heap_caps_add_region(vaddr, vaddr + DRAM0_DRAM1_DPORT_CACHE_SIZE - 1);
|
||||
// Middle size: means DPORT_DRAM0_DRAM1 bus virtrual address space less than the
|
||||
// spiram size, but after releasing the virtual address space mapped
|
||||
// from the rodata or instruction copied from the flash, the released
|
||||
// virtual address space is enough to map the abandoned physical address
|
||||
// space in spiram
|
||||
if (recycle_pages_size >= SPIRAM_SIZE_EXC_DRAM0_DRAM1_DPORT) {
|
||||
map_vaddr = SPIRAM_MAP_VADDR_START + recycle_pages_size;
|
||||
map_paddr = SPIRAM_MAP_PADDR_START + recycle_pages_size;
|
||||
map_size = SPIRAM_MAP_SIZE - recycle_pages_size;
|
||||
Cache_Dbus_MMU_Set(MMU_ACCESS_SPIRAM, map_vaddr, map_paddr, 64, map_size >> 16, 0);
|
||||
return heap_caps_add_region(map_vaddr , map_vaddr + map_size - 1);
|
||||
}
|
||||
|
||||
// Largest size
|
||||
return heap_caps_add_region(vaddr + size_for_flash, vaddr + DRAM0_DRAM1_DPORT_CACHE_SIZE -1);
|
||||
// Large size: means after releasing the virtual address space mapped from the rodata
|
||||
// or instruction copied from the flash, the released virtual address space
|
||||
// still not enough to map the abandoned physical address space in spiram,
|
||||
// so use all the virtual address space as much as possible
|
||||
map_vaddr = FREE_DRAM0_DRAM1_DPORT_CACHE_START;
|
||||
map_paddr = SPIRAM_MAP_PADDR_START + recycle_pages_size;
|
||||
map_size = FREE_DRAM0_DRAM1_DPORT_CACHE_SIZE;
|
||||
Cache_Dbus_MMU_Set(MMU_ACCESS_SPIRAM, map_vaddr, map_paddr, 64, map_size >> 16, 0);
|
||||
return heap_caps_add_region(map_vaddr, map_vaddr + FREE_DRAM0_DRAM1_DPORT_CACHE_SIZE -1);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t *dma_heap;
|
||||
|
||||
esp_err_t esp_spiram_reserve_dma_pool(size_t size) {
|
||||
@ -377,4 +376,48 @@ void IRAM_ATTR esp_spiram_writeback_cache(void)
|
||||
|
||||
|
||||
|
||||
uint8_t esp_spiram_get_cs_io(void)
|
||||
{
|
||||
return psram_get_cs_io();
|
||||
}
|
||||
|
||||
/*
|
||||
Simple RAM test. Writes a word every 32 bytes. Takes about a second to complete for 4MiB. Returns
|
||||
true when RAM seems OK, false when test fails. WARNING: Do not run this before the 2nd cpu has been
|
||||
initialized (in a two-core system) or after the heap allocator has taken ownership of the memory.
|
||||
*/
|
||||
bool esp_spiram_test(void)
|
||||
{
|
||||
volatile int *spiram = (volatile int*)(SOC_EXTRAM_DATA_HIGH - spiram_map_size);
|
||||
size_t p;
|
||||
size_t s = spiram_map_size;
|
||||
int errct=0;
|
||||
int initial_err=-1;
|
||||
|
||||
if (SOC_EXTRAM_DATA_SIZE < spiram_map_size) {
|
||||
ESP_EARLY_LOGW(TAG, "Only test spiram from %08x to %08x\n", SOC_EXTRAM_DATA_LOW, SOC_EXTRAM_DATA_HIGH);
|
||||
spiram=(volatile int*)SOC_EXTRAM_DATA_LOW;
|
||||
s = SOC_EXTRAM_DATA_SIZE;
|
||||
}
|
||||
for (p=0; p<(s/sizeof(int)); p+=8) {
|
||||
spiram[p]=p^0xAAAAAAAA;
|
||||
}
|
||||
for (p=0; p<(s/sizeof(int)); p+=8) {
|
||||
if (spiram[p]!=(p^0xAAAAAAAA)) {
|
||||
errct++;
|
||||
if (errct==1) initial_err=p*4;
|
||||
if (errct < 4) {
|
||||
ESP_EARLY_LOGE(TAG, "SPI SRAM error@%08x:%08x/%08x \n", &spiram[p], spiram[p], p^0xAAAAAAAA);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (errct) {
|
||||
ESP_EARLY_LOGE(TAG, "SPI SRAM memory test fail. %d/%d writes failed, first @ %X\n", errct, s/32, initial_err+SOC_EXTRAM_DATA_LOW);
|
||||
return false;
|
||||
} else {
|
||||
ESP_EARLY_LOGI(TAG, "SPI SRAM memory test OK");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -168,6 +168,13 @@ static uint32_t s_psram_id = 0;
|
||||
static void IRAM_ATTR psram_cache_init(psram_cache_mode_t psram_cache_mode, psram_vaddr_mode_t vaddrmode);
|
||||
extern void esp_rom_spi_set_op_mode(int spi_num, esp_rom_spiflash_read_mode_t mode);
|
||||
|
||||
static uint8_t s_psram_cs_io = (uint8_t)-1;
|
||||
|
||||
uint8_t psram_get_cs_io(void)
|
||||
{
|
||||
return s_psram_cs_io;
|
||||
}
|
||||
|
||||
static void psram_set_op_mode(int spi_num, psram_cmd_mode_t mode)
|
||||
{
|
||||
if (mode == PSRAM_CMD_QPI) {
|
||||
@ -375,6 +382,7 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
|
||||
psram_io.psram_spiwp_sd3_io = esp_rom_efuse_get_flash_wp_gpio();
|
||||
}
|
||||
esp_rom_spiflash_select_qio_pins(psram_io.psram_spiwp_sd3_io, spiconfig);
|
||||
s_psram_cs_io = psram_io.psram_cs_io;
|
||||
}
|
||||
|
||||
psram_size_t psram_get_size(void)
|
||||
|
@ -76,5 +76,11 @@ typedef enum {
|
||||
|
||||
esp_err_t esp_spiram_wrap_set(spiram_wrap_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief get psram CS IO
|
||||
*
|
||||
* @return psram CS IO
|
||||
*/
|
||||
uint8_t psram_get_cs_io(void);
|
||||
|
||||
#endif
|
||||
|
@ -29,17 +29,12 @@ typedef struct {
|
||||
uint8_t result[32];
|
||||
} hmac_result;
|
||||
|
||||
static const ets_efuse_block_t key_block = ETS_EFUSE_BLOCK_KEY4;
|
||||
static const char *TAG = "test_hmac";
|
||||
|
||||
static void setup_keyblock(void) {
|
||||
static void setup_keyblock(esp_efuse_block_t key_block, esp_efuse_purpose_t purpose) {
|
||||
const uint8_t key_data[32] = {
|
||||
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
|
||||
};
|
||||
int ets_status = ets_efuse_write_key(key_block,
|
||||
ETS_EFUSE_KEY_PURPOSE_HMAC_UP,
|
||||
key_data, sizeof(key_data));
|
||||
esp_err_t status = esp_efuse_write_key(key_block, purpose, key_data, sizeof(key_data));
|
||||
|
||||
if (ets_status == ESP_OK) {
|
||||
printf("written key!\n");
|
||||
@ -52,10 +47,7 @@ TEST_CASE("HMAC 'downstream' JTAG Enable mode", "[hw_crypto]")
|
||||
{
|
||||
int ets_status;
|
||||
|
||||
const uint8_t key_data[32] = {
|
||||
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
|
||||
};
|
||||
setup_keyblock(EFUSE_BLK_KEY3, ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG);
|
||||
|
||||
// Results calculated with Python:
|
||||
//
|
||||
@ -67,31 +59,13 @@ TEST_CASE("HMAC 'downstream' JTAG Enable mode", "[hw_crypto]")
|
||||
0x8e, 0x6c, 0x3e, 0x8e, 0x6e, 0x17, 0x62, 0x5c, 0x50, 0xac, 0x66, 0xa9, 0xa8, 0x57, 0x94, 0x9b
|
||||
};
|
||||
|
||||
ets_status = ets_efuse_write_key(ETS_EFUSE_BLOCK_KEY3,
|
||||
ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG,
|
||||
key_data, sizeof(key_data));
|
||||
|
||||
if (ets_status == ESP_OK) {
|
||||
ESP_LOGI(TAG, "HMAC_DOWN_JTAG key programmed!");
|
||||
} else {
|
||||
ESP_LOGW(TAG, "HMAC_DOWN_JTAG key programming failed, \
|
||||
maybe written already. Continuing");
|
||||
}
|
||||
|
||||
TEST_ASSERT_MESSAGE(ESP_OK == esp_efuse_batch_write_begin(),
|
||||
"Error programming security efuse.\n");
|
||||
|
||||
ets_status = esp_efuse_set_read_protect(ETS_EFUSE_BLOCK_KEY3);
|
||||
if (ets_status != ESP_OK) {
|
||||
ESP_LOGW(TAG, "EFUSE_BLOCK read protect setting failed. \
|
||||
Not a must prerequisite to run this test case. Continuing");
|
||||
}
|
||||
ets_status = esp_efuse_write_field_cnt(ESP_EFUSE_SOFT_DIS_JTAG, ESP_EFUSE_SOFT_DIS_JTAG[0]->bit_count);
|
||||
|
||||
ets_status = esp_efuse_write_field_bit(ESP_EFUSE_SOFT_DIS_JTAG);
|
||||
if (ets_status != ESP_OK) {
|
||||
ESP_LOGI(TAG, "JTAG Disable temporarily failed. \
|
||||
May be disabled already. Continuing the test.");
|
||||
}
|
||||
TEST_ASSERT_MESSAGE(ets_status == ESP_OK || ets_status == ESP_ERR_EFUSE_CNT_IS_FULL,
|
||||
"JTAG Disable temporarily failed.\n");
|
||||
|
||||
TEST_ASSERT_MESSAGE(ESP_OK == esp_efuse_batch_write_commit(),
|
||||
"Error programming security efuse.\n");
|
||||
@ -110,7 +84,7 @@ TEST_CASE("HMAC 'upstream' MAC generation with zeroes", "[hw_crypto]")
|
||||
{
|
||||
uint8_t hmac[32];
|
||||
|
||||
setup_keyblock();
|
||||
setup_keyblock(EFUSE_BLK_KEY4, ESP_EFUSE_KEY_PURPOSE_HMAC_UP);
|
||||
|
||||
const uint8_t zeroes[128] = { };
|
||||
// Produce the HMAC of various numbers of zeroes
|
||||
@ -205,7 +179,7 @@ TEST_CASE("HMAC 'upstream' MAC generation from data", "[hw_crypto]")
|
||||
{
|
||||
uint8_t hmac[32];
|
||||
|
||||
setup_keyblock();
|
||||
setup_keyblock(EFUSE_BLK_KEY4, ESP_EFUSE_KEY_PURPOSE_HMAC_UP);
|
||||
|
||||
// 257 characters of pseudo-Latin from lipsum.com (not Copyright)
|
||||
const char *message = "Deleniti voluptas explicabo et assumenda. Sed et aliquid minus quis. Praesentium cupiditate quia nemo est. Laboriosam pariatur ut distinctio tenetur. Sunt architecto iure aspernatur soluta ut recusandae. Ut quibusdam occaecati ut qui sit dignissimos eaque..";
|
||||
@ -1005,7 +979,8 @@ TEST_CASE("HMAC 'upstream' wait lock", "[hw_crypto]")
|
||||
// 257 characters of pseudo-Latin from lipsum.com (not Copyright)
|
||||
const char *message = "Deleniti voluptas explicabo et assumenda. Sed et aliquid minus quis. Praesentium cupiditate quia nemo est. Laboriosam pariatur ut distinctio tenetur. Sunt architecto iure aspernatur soluta ut recusandae. Ut quibusdam occaecati ut qui sit dignissimos eaque..";
|
||||
|
||||
setup_keyblock();
|
||||
setup_keyblock(EFUSE_BLK_KEY4, ESP_EFUSE_KEY_PURPOSE_HMAC_UP);
|
||||
|
||||
static const hmac_result results[] = {
|
||||
{ .msglen = 255,
|
||||
.result = { 0x59, 0x52, 0x50, 0x4, 0xb6, 0x28, 0xf9, 0x28, 0x7f, 0x6c, 0x37, 0xba, 0xfb, 0xb2, 0x58, 0xe7, 0xa, 0xac, 0x6c, 0x4a, 0xef, 0x66, 0x6, 0x7b, 0x1, 0x1f, 0x4c, 0xa4, 0xe5, 0xe5, 0x29, 0x5d },
|
||||
|
@ -330,7 +330,7 @@ menu "ESP32S3-Specific"
|
||||
int
|
||||
prompt "RTC slow memory reserved for coprocessor" if ESP32S3_ULP_COPROC_ENABLED
|
||||
default 512 if ESP32S3_ULP_COPROC_ENABLED
|
||||
range 32 8192 if ESP32S3_ULP_COPROC_ENABLED
|
||||
range 32 8176 if ESP32S3_ULP_COPROC_ENABLED
|
||||
default 0 if !ESP32S3_ULP_COPROC_ENABLED
|
||||
range 0 0 if !ESP32S3_ULP_COPROC_ENABLED
|
||||
help
|
||||
|
@ -16,15 +16,33 @@
|
||||
#define ESP_BOOTLOADER_RESERVE_RTC 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 40370000 <- IRAM/Icache -> 40378000 <- D/IRAM (I) -> 403E0000
|
||||
* 3FC88000 <- D/IRAM (D) -> 3FCF0000 <- DRAM/DCache -> 3FD00000
|
||||
*
|
||||
* Startup code uses the IRAM from 0x403BA000 to 0x403E0000, which is not available for static
|
||||
* memory, but can only be used after app starts.
|
||||
*
|
||||
* D cache use the memory from high address, so when it's configured to 16K/32K, the region
|
||||
* 0x3FCF000 ~ (3FD00000 - DATA_CACHE_SIZE) should be available. This region is not used as
|
||||
* static memory, leaving to the heap.
|
||||
*/
|
||||
|
||||
#define SRAM_IRAM_START 0x40370000
|
||||
#define SRAM_DRAM_START 0x3FC80000
|
||||
#define I_D_SRAM_OFFSET (SRAM_IRAM_START - SRAM_DRAM_START)
|
||||
#define SRAM_DRAM_END 0x403BA000 - I_D_SRAM_OFFSET /* 2nd stage bootloader iram_loader_seg start address */
|
||||
#define SRAM_DIRAM_I_START 0x40378000
|
||||
#define SRAM_IRAM_END 0x403BA000
|
||||
#define I_D_SRAM_OFFSET (SRAM_DIRAM_I_START - SRAM_DRAM_START)
|
||||
|
||||
#define SRAM_DRAM_START 0x3FC88000
|
||||
#define SRAM_DRAM_END (SRAM_IRAM_END - I_D_SRAM_OFFSET) /* 2nd stage bootloader iram_loader_seg start address */
|
||||
#define I_D_SRAM_SIZE (SRAM_DRAM_END - SRAM_DRAM_START)
|
||||
|
||||
#define ICACHE_SIZE 0x8000
|
||||
#define SRAM_IRAM_ORG (SRAM_IRAM_START + CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE)
|
||||
#define SRAM_DRAM_ORG (SRAM_DRAM_START + CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE)
|
||||
#define SRAM_IRAM_SIZE (I_D_SRAM_SIZE + ICACHE_SIZE - CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE)
|
||||
|
||||
#define I_D_SRAM_SIZE SRAM_DRAM_END - SRAM_DRAM_ORG
|
||||
#define DCACHE_SIZE 0x10000
|
||||
#define SRAM_DRAM_ORG (SRAM_DRAM_START)
|
||||
|
||||
#if CONFIG_ESP32S3_USE_FIXED_STATIC_RAM_SIZE
|
||||
ASSERT((CONFIG_ESP32S3_FIXED_STATIC_RAM_SIZE <= I_D_SRAM_SIZE), "Fixed static ram data does not fit.")
|
||||
@ -42,11 +60,11 @@ MEMORY
|
||||
*/
|
||||
|
||||
/* IRAM for PRO CPU. */
|
||||
iram0_0_seg (RX) : org = SRAM_IRAM_ORG, len = I_D_SRAM_SIZE
|
||||
iram0_0_seg (RX) : org = SRAM_IRAM_ORG, len = SRAM_IRAM_SIZE
|
||||
|
||||
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
/* Flash mapped instruction data */
|
||||
iram0_2_seg (RX) : org = 0x42000020, len = 0x8000000-0x20
|
||||
iram0_2_seg (RX) : org = 0x42000020, len = 0x800000-0x20
|
||||
|
||||
/**
|
||||
* (0x20 offset above is a convenience for the app binary image generation.
|
||||
@ -65,7 +83,7 @@ MEMORY
|
||||
|
||||
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
/* Flash mapped constant data */
|
||||
drom0_0_seg (R) : org = 0x3C000020, len = 0x8000000-0x20
|
||||
drom0_0_seg (R) : org = 0x3C000020, len = 0x800000-0x20
|
||||
|
||||
/* (See iram0_2_seg for meaning of 0x20 offset in the above.) */
|
||||
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
|
@ -1,6 +1,8 @@
|
||||
/* Default entry point */
|
||||
ENTRY(call_start_cpu0);
|
||||
|
||||
_diram_i_start = 0x40378000;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/**
|
||||
@ -183,7 +185,7 @@ SECTIONS
|
||||
*/
|
||||
.dram0.dummy (NOLOAD):
|
||||
{
|
||||
. = ORIGIN(dram0_0_seg) + _iram_end - _iram_start;
|
||||
. = ORIGIN(dram0_0_seg) + MAX(_iram_end - _diram_i_start, 0);
|
||||
} > dram0_0_seg
|
||||
|
||||
.dram0.data :
|
||||
|
@ -112,7 +112,7 @@ void IRAM_ATTR esp_spiram_init_cache(void)
|
||||
}
|
||||
|
||||
static uint32_t pages_for_flash = 0;
|
||||
static uint32_t instrcution_in_spiram = 0;
|
||||
static uint32_t instruction_in_spiram = 0;
|
||||
static uint32_t rodata_in_spiram = 0;
|
||||
|
||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
|
||||
@ -134,7 +134,7 @@ static uint32_t page0_page = INVALID_PHY_PAGE;
|
||||
|
||||
uint32_t esp_spiram_instruction_access_enabled(void)
|
||||
{
|
||||
return instrcution_in_spiram;
|
||||
return instruction_in_spiram;
|
||||
}
|
||||
|
||||
uint32_t esp_spiram_rodata_access_enabled(void)
|
||||
@ -157,7 +157,7 @@ esp_err_t esp_spiram_enable_instruction_access(void)
|
||||
instr_flash2spiram_offs = mmu_value - pages_for_flash;
|
||||
ESP_EARLY_LOGV(TAG, "Instructions from flash page%d copy to SPIRAM page%d, Offset: %d", mmu_value, pages_for_flash, instr_flash2spiram_offs);
|
||||
pages_for_flash = Cache_Flash_To_SPIRAM_Copy(CACHE_IBUS, IRAM0_CACHE_ADDRESS_LOW, pages_for_flash, &page0_page);
|
||||
instrcution_in_spiram = 1;
|
||||
instruction_in_spiram = 1;
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
@ -92,7 +92,7 @@ config SPIRAM_MALLOC_RESERVE_INTERNAL
|
||||
config SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
bool "Allow .bss segment placed in external memory"
|
||||
default n
|
||||
depends on SPIRAM && IDF_TARGET_ESP32 # TODO ESP32-S2 IDFGH-4320, ESP32-S3 IDF-1974
|
||||
depends on SPIRAM && (IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2) # ESP32-S3 IDF-1974
|
||||
select ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
help
|
||||
If enabled, variables with EXT_RAM_ATTR attribute will be placed in SPIRAM instead of internal DRAM.
|
||||
|
@ -20,13 +20,19 @@
|
||||
* Debug stubs entries IDs
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_DBG_STUB_MAGIC_NUM,
|
||||
ESP_DBG_STUB_TABLE_SIZE,
|
||||
ESP_DBG_STUB_CONTROL_DATA, ///< stubs descriptor entry
|
||||
ESP_DBG_STUB_ENTRY_FIRST,
|
||||
ESP_DBG_STUB_ENTRY_GCOV ///< GCOV entry
|
||||
= ESP_DBG_STUB_ENTRY_FIRST,
|
||||
ESP_DBG_STUB_ENTRY_CAPABILITIES,
|
||||
ESP_DBG_STUB_ENTRY_MAX
|
||||
} esp_dbg_stub_id_t;
|
||||
|
||||
#define ESP_DBG_STUB_MAGIC_NUM_VAL 0xFEEDBEEF
|
||||
#define ESP_DBG_STUB_CAP_GCOV_TASK (1 << 0)
|
||||
|
||||
/**
|
||||
* @brief Initializes debug stubs.
|
||||
*
|
||||
@ -41,10 +47,22 @@ void esp_dbg_stubs_init(void);
|
||||
*
|
||||
* @param id Stub ID.
|
||||
* @param entry Stub entry. Usually it is stub entry function address,
|
||||
* but can be any value meaningfull for OpenOCD command/code.
|
||||
*
|
||||
* but can be any value meaningfull for OpenOCD command/code
|
||||
* such as capabilities
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
esp_err_t esp_dbg_stub_entry_set(esp_dbg_stub_id_t id, uint32_t entry);
|
||||
|
||||
/**
|
||||
* @brief Retrives the corresponding stub entry
|
||||
*
|
||||
* @param id Stub ID.
|
||||
* @param entry Stub entry. Usually it is stub entry function address,
|
||||
* but can be any value meaningfull for OpenOCD command/code
|
||||
* such as capabilities
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
esp_err_t esp_dbg_stub_entry_get(esp_dbg_stub_id_t id, uint32_t *entry);
|
||||
|
||||
#endif //ESP_DBG_STUBS_H_
|
||||
|
@ -76,11 +76,14 @@ void esp_dbg_stubs_init(void)
|
||||
s_dbg_stubs_ctl_data.data_alloc = (uint32_t)esp_dbg_stubs_data_alloc;
|
||||
s_dbg_stubs_ctl_data.data_free = (uint32_t)esp_dbg_stubs_data_free;
|
||||
|
||||
s_stub_entry[ESP_DBG_STUB_MAGIC_NUM] = ESP_DBG_STUB_MAGIC_NUM_VAL;
|
||||
s_stub_entry[ESP_DBG_STUB_TABLE_SIZE] = ESP_DBG_STUB_ENTRY_MAX;
|
||||
s_stub_entry[ESP_DBG_STUB_CONTROL_DATA] = (uint32_t)&s_dbg_stubs_ctl_data;
|
||||
eri_write(ESP_DBG_STUBS_TRAX_REG, (uint32_t)s_stub_entry);
|
||||
ESP_LOGV(TAG, "%s stubs %x", __func__, eri_read(ESP_DBG_STUBS_TRAX_REG));
|
||||
}
|
||||
|
||||
// TODO: add lock mechanism. Not now but in the future ESP_DBG_STUB_ENTRY_CAPABILITIES can be set from different places.
|
||||
esp_err_t esp_dbg_stub_entry_set(esp_dbg_stub_id_t id, uint32_t entry)
|
||||
{
|
||||
if (id < ESP_DBG_STUB_ENTRY_FIRST || id >= ESP_DBG_STUB_ENTRY_MAX) {
|
||||
@ -92,4 +95,15 @@ esp_err_t esp_dbg_stub_entry_set(esp_dbg_stub_id_t id, uint32_t entry)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_dbg_stub_entry_get(esp_dbg_stub_id_t id, uint32_t *entry)
|
||||
{
|
||||
if (id < ESP_DBG_STUB_ENTRY_FIRST || id >= ESP_DBG_STUB_ENTRY_MAX) {
|
||||
ESP_LOGE(TAG, "Invalid stub id %d!", id);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
*entry = s_stub_entry[id];
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -358,8 +358,8 @@ static esp_err_t emac_dm9051_start(esp_eth_mac_t *mac)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
|
||||
/* enable interrupt */
|
||||
MAC_CHECK(dm9051_register_write(emac, DM9051_IMR, IMR_ALL) == ESP_OK, "write IMR failed", err, ESP_FAIL);
|
||||
/* enable only Rx related interrupts as others are processed synchronously */
|
||||
MAC_CHECK(dm9051_register_write(emac, DM9051_IMR, IMR_PAR | IMR_PRI) == ESP_OK, "write IMR failed", err, ESP_FAIL);
|
||||
/* enable rx */
|
||||
uint8_t rcr = 0;
|
||||
MAC_CHECK(dm9051_register_read(emac, DM9051_RCR, &rcr) == ESP_OK, "read RCR failed", err, ESP_FAIL);
|
||||
@ -407,8 +407,11 @@ static void emac_dm9051_task(void *arg)
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t length = 0;
|
||||
while (1) {
|
||||
// block indefinitely until some task notifies me
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
// check if the task receives any notification
|
||||
if (ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(1000)) == 0 && // if no notification ...
|
||||
gpio_get_level(emac->int_gpio_num) == 0) { // ...and no interrupt asserted
|
||||
continue; // -> just continue to check again
|
||||
}
|
||||
/* clear interrupt status */
|
||||
dm9051_register_read(emac, DM9051_ISR, &status);
|
||||
dm9051_register_write(emac, DM9051_ISR, status);
|
||||
|
@ -75,6 +75,9 @@ typedef struct {
|
||||
#endif
|
||||
} emac_esp32_t;
|
||||
|
||||
static esp_err_t esp_emac_alloc_driver_obj(const eth_mac_config_t *config, emac_esp32_t **emac_out_hdl, void **out_descriptors);
|
||||
static void esp_emac_free_driver_obj(emac_esp32_t *emac, void *descriptors);
|
||||
|
||||
static esp_err_t emac_esp32_set_mediator(esp_eth_mac_t *mac, esp_eth_mediator_t *eth)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
@ -335,10 +338,6 @@ static esp_err_t emac_esp32_init(esp_eth_mac_t *mac)
|
||||
esp_err_t ret = ESP_OK;
|
||||
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
|
||||
esp_eth_mediator_t *eth = emac->eth;
|
||||
/* enable peripheral clock */
|
||||
periph_module_enable(PERIPH_EMAC_MODULE);
|
||||
/* init clock, config gpio, etc */
|
||||
emac_hal_lowlevel_init(&emac->hal);
|
||||
/* init gpio used by smi interface */
|
||||
emac_esp32_init_smi_gpio(emac);
|
||||
MAC_CHECK(eth->on_state_changed(eth, ETH_STATE_LLINIT, NULL) == ESP_OK, "lowlevel init failed", err, ESP_FAIL);
|
||||
@ -383,7 +382,6 @@ static esp_err_t emac_esp32_deinit(esp_eth_mac_t *mac)
|
||||
#endif
|
||||
emac_hal_stop(&emac->hal);
|
||||
eth->on_state_changed(eth, ETH_STATE_DEINIT, NULL);
|
||||
periph_module_disable(PERIPH_EMAC_MODULE);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -404,22 +402,8 @@ static esp_err_t emac_esp32_stop(esp_eth_mac_t *mac)
|
||||
static esp_err_t emac_esp32_del(esp_eth_mac_t *mac)
|
||||
{
|
||||
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
|
||||
esp_intr_free(emac->intr_hdl);
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
if (emac->pm_lock) {
|
||||
esp_pm_lock_delete(emac->pm_lock);
|
||||
}
|
||||
#endif
|
||||
vTaskDelete(emac->rx_task_hdl);
|
||||
int i = 0;
|
||||
for (i = 0; i < CONFIG_ETH_DMA_RX_BUFFER_NUM; i++) {
|
||||
free(emac->hal.rx_buf[i]);
|
||||
}
|
||||
for (i = 0; i < CONFIG_ETH_DMA_TX_BUFFER_NUM; i++) {
|
||||
free(emac->hal.tx_buf[i]);
|
||||
}
|
||||
free(emac->hal.descriptors);
|
||||
free(emac);
|
||||
esp_emac_free_driver_obj(emac, emac->hal.descriptors);
|
||||
periph_module_disable(PERIPH_EMAC_MODULE);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -435,87 +419,8 @@ IRAM_ATTR void emac_esp32_isr_handler(void *args)
|
||||
}
|
||||
}
|
||||
|
||||
esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_mac_config_t *config)
|
||||
static void esp_emac_free_driver_obj(emac_esp32_t *emac, void *descriptors)
|
||||
{
|
||||
esp_err_t ret_code = ESP_OK;
|
||||
esp_eth_mac_t *ret = NULL;
|
||||
void *descriptors = NULL;
|
||||
emac_esp32_t *emac = NULL;
|
||||
MAC_CHECK(config, "can't set mac config to null", err, NULL);
|
||||
if (config->flags & ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE) {
|
||||
emac = heap_caps_calloc(1, sizeof(emac_esp32_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
} else {
|
||||
emac = calloc(1, sizeof(emac_esp32_t));
|
||||
}
|
||||
MAC_CHECK(emac, "calloc emac failed", err, NULL);
|
||||
/* alloc memory for ethernet dma descriptor */
|
||||
uint32_t desc_size = CONFIG_ETH_DMA_RX_BUFFER_NUM * sizeof(eth_dma_rx_descriptor_t) +
|
||||
CONFIG_ETH_DMA_TX_BUFFER_NUM * sizeof(eth_dma_tx_descriptor_t);
|
||||
descriptors = heap_caps_calloc(1, desc_size, MALLOC_CAP_DMA);
|
||||
MAC_CHECK(descriptors, "calloc descriptors failed", err, NULL);
|
||||
int i = 0;
|
||||
/* alloc memory for ethernet dma buffer */
|
||||
for (i = 0; i < CONFIG_ETH_DMA_RX_BUFFER_NUM; i++) {
|
||||
emac->rx_buf[i] = heap_caps_calloc(1, CONFIG_ETH_DMA_BUFFER_SIZE, MALLOC_CAP_DMA);
|
||||
if (!(emac->rx_buf[i])) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < CONFIG_ETH_DMA_TX_BUFFER_NUM; i++) {
|
||||
emac->tx_buf[i] = heap_caps_calloc(1, CONFIG_ETH_DMA_BUFFER_SIZE, MALLOC_CAP_DMA);
|
||||
if (!(emac->tx_buf[i])) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
/* initialize hal layer driver */
|
||||
emac_hal_init(&emac->hal, descriptors, emac->rx_buf, emac->tx_buf);
|
||||
emac->sw_reset_timeout_ms = config->sw_reset_timeout_ms;
|
||||
emac->smi_mdc_gpio_num = config->smi_mdc_gpio_num;
|
||||
emac->smi_mdio_gpio_num = config->smi_mdio_gpio_num;
|
||||
emac->flow_control_high_water_mark = FLOW_CONTROL_HIGH_WATER_MARK;
|
||||
emac->flow_control_low_water_mark = FLOW_CONTROL_LOW_WATER_MARK;
|
||||
emac->parent.set_mediator = emac_esp32_set_mediator;
|
||||
emac->parent.init = emac_esp32_init;
|
||||
emac->parent.deinit = emac_esp32_deinit;
|
||||
emac->parent.start = emac_esp32_start;
|
||||
emac->parent.stop = emac_esp32_stop;
|
||||
emac->parent.del = emac_esp32_del;
|
||||
emac->parent.write_phy_reg = emac_esp32_write_phy_reg;
|
||||
emac->parent.read_phy_reg = emac_esp32_read_phy_reg;
|
||||
emac->parent.set_addr = emac_esp32_set_addr;
|
||||
emac->parent.get_addr = emac_esp32_get_addr;
|
||||
emac->parent.set_speed = emac_esp32_set_speed;
|
||||
emac->parent.set_duplex = emac_esp32_set_duplex;
|
||||
emac->parent.set_link = emac_esp32_set_link;
|
||||
emac->parent.set_promiscuous = emac_esp32_set_promiscuous;
|
||||
emac->parent.set_peer_pause_ability = emac_esp32_set_peer_pause_ability;
|
||||
emac->parent.enable_flow_ctrl = emac_esp32_enable_flow_ctrl;
|
||||
emac->parent.transmit = emac_esp32_transmit;
|
||||
emac->parent.receive = emac_esp32_receive;
|
||||
/* Interrupt configuration */
|
||||
if (config->flags & ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE) {
|
||||
ret_code = esp_intr_alloc(ETS_ETH_MAC_INTR_SOURCE, ESP_INTR_FLAG_IRAM,
|
||||
emac_esp32_isr_handler, &emac->hal, &(emac->intr_hdl));
|
||||
} else {
|
||||
ret_code = esp_intr_alloc(ETS_ETH_MAC_INTR_SOURCE, 0,
|
||||
emac_esp32_isr_handler, &emac->hal, &(emac->intr_hdl));
|
||||
}
|
||||
MAC_CHECK(ret_code == ESP_OK, "alloc emac interrupt failed", err, NULL);
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
MAC_CHECK(esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "emac_esp32", &emac->pm_lock) == ESP_OK,
|
||||
"create pm lock failed", err, NULL);
|
||||
#endif
|
||||
/* create rx task */
|
||||
BaseType_t core_num = tskNO_AFFINITY;
|
||||
if (config->flags & ETH_MAC_FLAG_PIN_TO_CORE) {
|
||||
core_num = cpu_hal_get_core_id();
|
||||
}
|
||||
BaseType_t xReturned = xTaskCreatePinnedToCore(emac_esp32_rx_task, "emac_rx", config->rx_task_stack_size, emac,
|
||||
config->rx_task_prio, &emac->rx_task_hdl, core_num);
|
||||
MAC_CHECK(xReturned == pdPASS, "create emac_rx task failed", err, NULL);
|
||||
return &(emac->parent);
|
||||
|
||||
err:
|
||||
if (emac) {
|
||||
if (emac->rx_task_hdl) {
|
||||
vTaskDelete(emac->rx_task_hdl);
|
||||
@ -539,6 +444,110 @@ err:
|
||||
if (descriptors) {
|
||||
free(descriptors);
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t esp_emac_alloc_driver_obj(const eth_mac_config_t *config, emac_esp32_t **emac_out_hdl, void **out_descriptors)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
emac_esp32_t *emac = NULL;
|
||||
void *descriptors = NULL;
|
||||
if (config->flags & ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE) {
|
||||
emac = heap_caps_calloc(1, sizeof(emac_esp32_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
} else {
|
||||
emac = calloc(1, sizeof(emac_esp32_t));
|
||||
}
|
||||
MAC_CHECK(emac, "no mem for esp emac object", err, ESP_ERR_NO_MEM);
|
||||
/* alloc memory for ethernet dma descriptor */
|
||||
uint32_t desc_size = CONFIG_ETH_DMA_RX_BUFFER_NUM * sizeof(eth_dma_rx_descriptor_t) +
|
||||
CONFIG_ETH_DMA_TX_BUFFER_NUM * sizeof(eth_dma_tx_descriptor_t);
|
||||
descriptors = heap_caps_calloc(1, desc_size, MALLOC_CAP_DMA);
|
||||
MAC_CHECK(descriptors, "no mem for descriptors", err, ESP_ERR_NO_MEM);
|
||||
/* alloc memory for ethernet dma buffer */
|
||||
for (int i = 0; i < CONFIG_ETH_DMA_RX_BUFFER_NUM; i++) {
|
||||
emac->rx_buf[i] = heap_caps_calloc(1, CONFIG_ETH_DMA_BUFFER_SIZE, MALLOC_CAP_DMA);
|
||||
MAC_CHECK(emac->rx_buf[i], "no mem for RX DMA buffers", err, ESP_ERR_NO_MEM);
|
||||
}
|
||||
for (int i = 0; i < CONFIG_ETH_DMA_TX_BUFFER_NUM; i++) {
|
||||
emac->tx_buf[i] = heap_caps_calloc(1, CONFIG_ETH_DMA_BUFFER_SIZE, MALLOC_CAP_DMA);
|
||||
MAC_CHECK(emac->tx_buf[i], "no mem for TX DMA buffers", err, ESP_ERR_NO_MEM);
|
||||
}
|
||||
/* alloc PM lock */
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
MAC_CHECK(esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "emac_esp32", &emac->pm_lock) == ESP_OK,
|
||||
"create pm lock failed", err, ESP_FAIL);
|
||||
#endif
|
||||
/* create rx task */
|
||||
BaseType_t core_num = tskNO_AFFINITY;
|
||||
if (config->flags & ETH_MAC_FLAG_PIN_TO_CORE) {
|
||||
core_num = cpu_hal_get_core_id();
|
||||
}
|
||||
BaseType_t xReturned = xTaskCreatePinnedToCore(emac_esp32_rx_task, "emac_rx", config->rx_task_stack_size, emac,
|
||||
config->rx_task_prio, &emac->rx_task_hdl, core_num);
|
||||
MAC_CHECK(xReturned == pdPASS, "create emac_rx task failed", err, ESP_FAIL);
|
||||
|
||||
*out_descriptors = descriptors;
|
||||
*emac_out_hdl = emac;
|
||||
return ESP_OK;
|
||||
err:
|
||||
esp_emac_free_driver_obj(emac, descriptors);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_mac_config_t *config)
|
||||
{
|
||||
esp_err_t ret_code = ESP_OK;
|
||||
esp_eth_mac_t *ret = NULL;
|
||||
void *descriptors = NULL;
|
||||
emac_esp32_t *emac = NULL;
|
||||
MAC_CHECK(config, "can't set mac config to null", err, NULL);
|
||||
ret_code = esp_emac_alloc_driver_obj(config, &emac, &descriptors);
|
||||
MAC_CHECK(ret_code == ESP_OK, "alloc driver object failed", err, NULL);
|
||||
|
||||
/* enable APB to access Ethernet peripheral registers */
|
||||
periph_module_enable(PERIPH_EMAC_MODULE);
|
||||
/* initialize hal layer driver */
|
||||
emac_hal_init(&emac->hal, descriptors, emac->rx_buf, emac->tx_buf);
|
||||
// config emac data interface
|
||||
emac_hal_lowlevel_init(&emac->hal);
|
||||
/* alloc interrupt */
|
||||
if (config->flags & ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE) {
|
||||
ret_code = esp_intr_alloc(ETS_ETH_MAC_INTR_SOURCE, ESP_INTR_FLAG_IRAM,
|
||||
emac_esp32_isr_handler, &emac->hal, &(emac->intr_hdl));
|
||||
} else {
|
||||
ret_code = esp_intr_alloc(ETS_ETH_MAC_INTR_SOURCE, 0,
|
||||
emac_esp32_isr_handler, &emac->hal, &(emac->intr_hdl));
|
||||
}
|
||||
MAC_CHECK(ret_code == ESP_OK, "alloc emac interrupt failed", err_intr, NULL);
|
||||
|
||||
emac->sw_reset_timeout_ms = config->sw_reset_timeout_ms;
|
||||
emac->smi_mdc_gpio_num = config->smi_mdc_gpio_num;
|
||||
emac->smi_mdio_gpio_num = config->smi_mdio_gpio_num;
|
||||
emac->flow_control_high_water_mark = FLOW_CONTROL_HIGH_WATER_MARK;
|
||||
emac->flow_control_low_water_mark = FLOW_CONTROL_LOW_WATER_MARK;
|
||||
emac->parent.set_mediator = emac_esp32_set_mediator;
|
||||
emac->parent.init = emac_esp32_init;
|
||||
emac->parent.deinit = emac_esp32_deinit;
|
||||
emac->parent.start = emac_esp32_start;
|
||||
emac->parent.stop = emac_esp32_stop;
|
||||
emac->parent.del = emac_esp32_del;
|
||||
emac->parent.write_phy_reg = emac_esp32_write_phy_reg;
|
||||
emac->parent.read_phy_reg = emac_esp32_read_phy_reg;
|
||||
emac->parent.set_addr = emac_esp32_set_addr;
|
||||
emac->parent.get_addr = emac_esp32_get_addr;
|
||||
emac->parent.set_speed = emac_esp32_set_speed;
|
||||
emac->parent.set_duplex = emac_esp32_set_duplex;
|
||||
emac->parent.set_link = emac_esp32_set_link;
|
||||
emac->parent.set_promiscuous = emac_esp32_set_promiscuous;
|
||||
emac->parent.set_peer_pause_ability = emac_esp32_set_peer_pause_ability;
|
||||
emac->parent.enable_flow_ctrl = emac_esp32_enable_flow_ctrl;
|
||||
emac->parent.transmit = emac_esp32_transmit;
|
||||
emac->parent.receive = emac_esp32_receive;
|
||||
return &(emac->parent);
|
||||
|
||||
err_intr:
|
||||
periph_module_disable(PERIPH_EMAC_MODULE);
|
||||
err:
|
||||
esp_emac_free_driver_obj(emac, descriptors);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -212,6 +212,11 @@ static esp_err_t dm9051_reset_hw(esp_eth_phy_t *phy)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @note This function is responsible for restarting a new auto-negotiation,
|
||||
* the result of negotiation won't be relected to uppler layers.
|
||||
* Instead, the negotiation result is fetched by linker timer, see `dm9051_get_link()`
|
||||
*/
|
||||
static esp_err_t dm9051_negotiate(esp_eth_phy_t *phy)
|
||||
{
|
||||
phy_dm9051_t *dm9051 = __containerof(phy, phy_dm9051_t, parent);
|
||||
@ -241,7 +246,7 @@ static esp_err_t dm9051_negotiate(esp_eth_phy_t *phy)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (to >= dm9051->autonego_timeout_ms / 100) {
|
||||
if ((to >= dm9051->autonego_timeout_ms / 100) && (dm9051->link_status == ETH_LINK_UP)) {
|
||||
ESP_LOGW(TAG, "Ethernet PHY auto negotiation timeout");
|
||||
}
|
||||
return ESP_OK;
|
||||
|
@ -201,6 +201,11 @@ static esp_err_t dp83848_reset_hw(esp_eth_phy_t *phy)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @note This function is responsible for restarting a new auto-negotiation,
|
||||
* the result of negotiation won't be relected to uppler layers.
|
||||
* Instead, the negotiation result is fetched by linker timer, see `dp83848_get_link()`
|
||||
*/
|
||||
static esp_err_t dp83848_negotiate(esp_eth_phy_t *phy)
|
||||
{
|
||||
phy_dp83848_t *dp83848 = __containerof(phy, phy_dp83848_t, parent);
|
||||
@ -230,8 +235,7 @@ static esp_err_t dp83848_negotiate(esp_eth_phy_t *phy)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Auto negotiation failed, maybe no network cable plugged in, so output a warning */
|
||||
if (to >= dp83848->autonego_timeout_ms / 100) {
|
||||
if ((to >= dp83848->autonego_timeout_ms / 100) && (dp83848->link_status == ETH_LINK_UP)) {
|
||||
ESP_LOGW(TAG, "auto negotiation timeout");
|
||||
}
|
||||
return ESP_OK;
|
||||
|
@ -241,6 +241,11 @@ static esp_err_t ip101_reset_hw(esp_eth_phy_t *phy)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @note This function is responsible for restarting a new auto-negotiation,
|
||||
* the result of negotiation won't be relected to uppler layers.
|
||||
* Instead, the negotiation result is fetched by linker timer, see `ip101_get_link()`
|
||||
*/
|
||||
static esp_err_t ip101_negotiate(esp_eth_phy_t *phy)
|
||||
{
|
||||
phy_ip101_t *ip101 = __containerof(phy, phy_ip101_t, parent);
|
||||
@ -267,8 +272,7 @@ static esp_err_t ip101_negotiate(esp_eth_phy_t *phy)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Auto negotiation failed, maybe no network cable plugged in, so output a warning */
|
||||
if (to >= ip101->autonego_timeout_ms / 100) {
|
||||
if ((to >= ip101->autonego_timeout_ms / 100) && (ip101->link_status == ETH_LINK_UP)) {
|
||||
ESP_LOGW(TAG, "auto negotiation timeout");
|
||||
}
|
||||
return ESP_OK;
|
||||
|
@ -189,10 +189,17 @@ static esp_err_t ksz8041_reset_hw(esp_eth_phy_t *phy)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @note This function is responsible for restarting a new auto-negotiation,
|
||||
* the result of negotiation won't be relected to uppler layers.
|
||||
* Instead, the negotiation result is fetched by linker timer, see `ksz8041_get_link()`
|
||||
*/
|
||||
static esp_err_t ksz8041_negotiate(esp_eth_phy_t *phy)
|
||||
{
|
||||
phy_ksz8041_t *ksz8041 = __containerof(phy, phy_ksz8041_t, parent);
|
||||
esp_eth_mediator_t *eth = ksz8041->eth;
|
||||
/* in case any link status has changed, let's assume we're in link down status */
|
||||
ksz8041->link_status = ETH_LINK_DOWN;
|
||||
/* Restart auto negotiation */
|
||||
bmcr_reg_t bmcr = {
|
||||
.speed_select = 1, /* 100Mbps */
|
||||
@ -205,8 +212,8 @@ static esp_err_t ksz8041_negotiate(esp_eth_phy_t *phy)
|
||||
bmsr_reg_t bmsr;
|
||||
pc2r_reg_t pc2r;
|
||||
uint32_t to = 0;
|
||||
for (to = 0; to < ksz8041->autonego_timeout_ms / 10; to++) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
for (to = 0; to < ksz8041->autonego_timeout_ms / 100; to++) {
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
PHY_CHECK(eth->phy_reg_read(eth, ksz8041->addr, ETH_PHY_BMSR_REG_ADDR, &(bmsr.val)) == ESP_OK,
|
||||
"read BMSR failed", err);
|
||||
PHY_CHECK(eth->phy_reg_read(eth, ksz8041->addr, ETH_PHY_PC2R_REG_ADDR, &(pc2r.val)) == ESP_OK,
|
||||
@ -216,11 +223,9 @@ static esp_err_t ksz8041_negotiate(esp_eth_phy_t *phy)
|
||||
}
|
||||
}
|
||||
/* Auto negotiation failed, maybe no network cable plugged in, so output a warning */
|
||||
if (to >= ksz8041->autonego_timeout_ms / 10) {
|
||||
if ((to >= ksz8041->autonego_timeout_ms / 100) && (ksz8041->link_status == ETH_LINK_UP)) {
|
||||
ESP_LOGW(TAG, "auto negotiation timeout");
|
||||
}
|
||||
/* Updata information about link, speed, duplex */
|
||||
PHY_CHECK(ksz8041_update_link_duplex_speed(ksz8041) == ESP_OK, "update link duplex speed failed", err);
|
||||
return ESP_OK;
|
||||
err:
|
||||
return ESP_FAIL;
|
||||
|
@ -286,6 +286,11 @@ static esp_err_t lan8720_reset_hw(esp_eth_phy_t *phy)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @note This function is responsible for restarting a new auto-negotiation,
|
||||
* the result of negotiation won't be relected to uppler layers.
|
||||
* Instead, the negotiation result is fetched by linker timer, see `lan8720_get_link()`
|
||||
*/
|
||||
static esp_err_t lan8720_negotiate(esp_eth_phy_t *phy)
|
||||
{
|
||||
phy_lan8720_t *lan8720 = __containerof(phy, phy_lan8720_t, parent);
|
||||
@ -315,7 +320,7 @@ static esp_err_t lan8720_negotiate(esp_eth_phy_t *phy)
|
||||
}
|
||||
}
|
||||
/* Auto negotiation failed, maybe no network cable plugged in, so output a warning */
|
||||
if (to >= lan8720->autonego_timeout_ms / 100) {
|
||||
if (to >= lan8720->autonego_timeout_ms / 100 && (lan8720->link_status == ETH_LINK_UP)) {
|
||||
ESP_LOGW(TAG, "auto negotiation timeout");
|
||||
}
|
||||
return ESP_OK;
|
||||
|
@ -195,6 +195,11 @@ static esp_err_t rtl8201_reset_hw(esp_eth_phy_t *phy)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @note This function is responsible for restarting a new auto-negotiation,
|
||||
* the result of negotiation won't be relected to uppler layers.
|
||||
* Instead, the negotiation result is fetched by linker timer, see `rtl8201_get_link()`
|
||||
*/
|
||||
static esp_err_t rtl8201_negotiate(esp_eth_phy_t *phy)
|
||||
{
|
||||
phy_rtl8201_t *rtl8201 = __containerof(phy, phy_rtl8201_t, parent);
|
||||
@ -221,8 +226,7 @@ static esp_err_t rtl8201_negotiate(esp_eth_phy_t *phy)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Auto negotiation failed, maybe no network cable plugged in, so output a warning */
|
||||
if (to >= rtl8201->autonego_timeout_ms / 100) {
|
||||
if ((to >= rtl8201->autonego_timeout_ms / 100) && (rtl8201->link_status == ETH_LINK_UP)) {
|
||||
ESP_LOGW(TAG, "auto negotiation timeout");
|
||||
}
|
||||
return ESP_OK;
|
||||
|
@ -447,7 +447,15 @@ static void inline __attribute__((always_inline)) post_instance_delete(esp_event
|
||||
|
||||
esp_err_t esp_event_loop_create(const esp_event_loop_args_t* event_loop_args, esp_event_loop_handle_t* event_loop)
|
||||
{
|
||||
assert(event_loop_args);
|
||||
if (event_loop_args == NULL) {
|
||||
ESP_LOGE(TAG, "event_loop_args was NULL");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (event_loop == NULL) {
|
||||
ESP_LOGE(TAG, "event_loop was NULL");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_event_loop_instance_t* loop;
|
||||
esp_err_t err = ESP_ERR_NO_MEM; // most likely error
|
||||
|
@ -48,6 +48,7 @@ typedef struct {
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_ARG: event_loop_args or event_loop was NULL
|
||||
* - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list
|
||||
* - ESP_FAIL: Failed to create task loop
|
||||
* - Others: Fail
|
||||
@ -57,7 +58,7 @@ esp_err_t esp_event_loop_create(const esp_event_loop_args_t *event_loop_args, es
|
||||
/**
|
||||
* @brief Delete an existing event loop.
|
||||
*
|
||||
* @param[in] event_loop event loop to delete
|
||||
* @param[in] event_loop event loop to delete, must not be NULL
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
@ -102,7 +103,7 @@ esp_err_t esp_event_loop_delete_default(void);
|
||||
* In cases where waiting on the queue times out, ESP_OK is returned and not ESP_ERR_TIMEOUT, since it is
|
||||
* normal behavior.
|
||||
*
|
||||
* @param[in] event_loop event loop to dispatch posted events from
|
||||
* @param[in] event_loop event loop to dispatch posted events from, must not be NULL
|
||||
* @param[in] ticks_to_run number of ticks to run the loop
|
||||
*
|
||||
* @note encountering an unknown event that has been posted to the loop will only generate a warning, not an error.
|
||||
@ -158,7 +159,7 @@ esp_err_t esp_event_handler_register(esp_event_base_t event_base,
|
||||
* This function behaves in the same manner as esp_event_handler_register, except the additional
|
||||
* specification of the event loop to register the handler to.
|
||||
*
|
||||
* @param[in] event_loop the event loop to register this handler function to
|
||||
* @param[in] event_loop the event loop to register this handler function to, must not be NULL
|
||||
* @param[in] event_base the base id of the event to register the handler for
|
||||
* @param[in] event_id the id of the event to register the handler for
|
||||
* @param[in] event_handler the handler function which gets called when the event is dispatched
|
||||
@ -197,7 +198,7 @@ esp_err_t esp_event_handler_register_with(esp_event_loop_handle_t event_loop,
|
||||
* Each registration yields a distinct instance object which identifies it over the registration
|
||||
* lifetime.
|
||||
*
|
||||
* @param[in] event_loop the event loop to register this handler function to
|
||||
* @param[in] event_loop the event loop to register this handler function to, must not be NULL
|
||||
* @param[in] event_base the base id of the event to register the handler for
|
||||
* @param[in] event_id the id of the event to register the handler for
|
||||
* @param[in] event_handler the handler function which gets called when the event is dispatched
|
||||
@ -263,15 +264,15 @@ esp_err_t esp_event_handler_instance_register(esp_event_base_t event_base,
|
||||
* @note This function is obsolete and will be deprecated soon, please use esp_event_handler_instance_unregister()
|
||||
* instead.
|
||||
*
|
||||
* This function can be used to unregister a handler so that it no longer gets called during dispatch.
|
||||
* Handlers can be unregistered for either: (1) specific events, (2) all events of a certain event base,
|
||||
* or (3) all events known by the system event loop
|
||||
* Unregisters a handler so it will no longer be called during dispatch.
|
||||
* Handlers can be unregistered for any combination of event_base and event_id which were previously registered.
|
||||
* To unregister a handler, the event_base and event_id arguments must match exactly the arguments passed to
|
||||
* esp_event_handler_register() when that handler was registered. Passing ESP_EVENT_ANY_BASE and/or ESP_EVENT_ANY_ID
|
||||
* will only unregister handlers that were registered with the same wildcard arguments.
|
||||
*
|
||||
* - specific events: specify exact event_base and event_id
|
||||
* - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id
|
||||
* - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id
|
||||
*
|
||||
* This function ignores unregistration of handlers that has not been previously registered.
|
||||
* @note When using ESP_EVENT_ANY_ID, handlers registered to specific event IDs using the same base will not be
|
||||
* unregistered. When using ESP_EVENT_ANY_BASE, events registered to specific bases will also not be
|
||||
* unregistered. This avoids accidental unregistration of handlers registered by other users or components.
|
||||
*
|
||||
* @param[in] event_base the base of the event with which to unregister the handler
|
||||
* @param[in] event_id the id of the event with which to unregister the handler
|
||||
@ -294,7 +295,7 @@ esp_err_t esp_event_handler_unregister(esp_event_base_t event_base,
|
||||
* This function behaves in the same manner as esp_event_handler_unregister, except the additional specification of
|
||||
* the event loop to unregister the handler with.
|
||||
*
|
||||
* @param[in] event_loop the event loop with which to unregister this handler function
|
||||
* @param[in] event_loop the event loop with which to unregister this handler function, must not be NULL
|
||||
* @param[in] event_base the base of the event with which to unregister the handler
|
||||
* @param[in] event_id the id of the event with which to unregister the handler
|
||||
* @param[in] event_handler the handler to unregister
|
||||
@ -312,17 +313,18 @@ esp_err_t esp_event_handler_unregister_with(esp_event_loop_handle_t event_loop,
|
||||
/**
|
||||
* @brief Unregister a handler instance from a specific event loop.
|
||||
*
|
||||
* This function can be used to unregister a handler so that it no longer gets called during dispatch.
|
||||
* Handlers can be unregistered for either: (1) specific events, (2) all events of a certain event base,
|
||||
* or (3) all events known by the system event loop
|
||||
* Unregisters a handler instance so it will no longer be called during dispatch.
|
||||
* Handler instances can be unregistered for any combination of event_base and event_id which were previously
|
||||
* registered. To unregister a handler instance, the event_base and event_id arguments must match exactly the
|
||||
* arguments passed to esp_event_handler_instance_register() when that handler instance was registered.
|
||||
* Passing ESP_EVENT_ANY_BASE and/or ESP_EVENT_ANY_ID will only unregister handler instances that were registered
|
||||
* with the same wildcard arguments.
|
||||
*
|
||||
* - specific events: specify exact event_base and event_id
|
||||
* - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id
|
||||
* - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id
|
||||
* @note When using ESP_EVENT_ANY_ID, handlers registered to specific event IDs using the same base will not be
|
||||
* unregistered. When using ESP_EVENT_ANY_BASE, events registered to specific bases will also not be
|
||||
* unregistered. This avoids accidental unregistration of handlers registered by other users or components.
|
||||
*
|
||||
* This function ignores unregistration of handler instances that have not been previously registered.
|
||||
*
|
||||
* @param[in] event_loop the event loop with which to unregister this handler function
|
||||
* @param[in] event_loop the event loop with which to unregister this handler function, must not be NULL
|
||||
* @param[in] event_base the base of the event with which to unregister the handler
|
||||
* @param[in] event_id the id of the event with which to unregister the handler
|
||||
* @param[in] instance the instance object of the registration to be unregistered
|
||||
@ -388,7 +390,7 @@ esp_err_t esp_event_post(esp_event_base_t event_base,
|
||||
* This function behaves in the same manner as esp_event_post_to, except the additional specification of the event loop
|
||||
* to post the event to.
|
||||
*
|
||||
* @param[in] event_loop the event loop to post to
|
||||
* @param[in] event_loop the event loop to post to, must not be NULL
|
||||
* @param[in] event_base the event base that identifies the event
|
||||
* @param[in] event_id the event id that identifies the event
|
||||
* @param[in] event_data the data, specific to the event occurence, that gets passed to the handler
|
||||
@ -441,7 +443,7 @@ esp_err_t esp_event_isr_post(esp_event_base_t event_base,
|
||||
/**
|
||||
* @brief Special variant of esp_event_post_to for posting events from interrupt handlers
|
||||
*
|
||||
* @param[in] event_loop the event loop to post to
|
||||
* @param[in] event_loop the event loop to post to, must not be NULL
|
||||
* @param[in] event_base the event base that identifies the event
|
||||
* @param[in] event_id the event id that identifies the event
|
||||
* @param[in] event_data the data, specific to the event occurence, that gets passed to the handler
|
||||
|
@ -306,6 +306,14 @@ static void test_teardown(void)
|
||||
#define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds
|
||||
#define TIMER_INTERVAL0_SEC (2.0) // sample test interval for the first timer
|
||||
|
||||
TEST_CASE("create and event loop with any NULL argument fails", "[event]")
|
||||
{
|
||||
esp_event_loop_handle_t loop; // with dedicated task
|
||||
esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
|
||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_event_loop_create(NULL, &loop));
|
||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_event_loop_create(&loop_args, NULL));
|
||||
}
|
||||
|
||||
TEST_CASE("can create and delete event loops", "[event]")
|
||||
{
|
||||
/* this test aims to verify that:
|
||||
|
@ -610,6 +610,10 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co
|
||||
esp_transport_ssl_set_client_key_data(ssl, config->client_key_pem, strlen(config->client_key_pem));
|
||||
}
|
||||
|
||||
if (config->client_key_password && config->client_key_password_len > 0) {
|
||||
esp_transport_ssl_set_client_key_password(ssl, config->client_key_password, config->client_key_password_len);
|
||||
}
|
||||
|
||||
if (config->skip_cert_common_name_check) {
|
||||
esp_transport_ssl_skip_common_name_check(ssl);
|
||||
}
|
||||
@ -963,11 +967,18 @@ int esp_http_client_read(esp_http_client_handle_t client, char *buffer, int len)
|
||||
}
|
||||
ESP_LOG_LEVEL(sev, TAG, "esp_transport_read returned:%d and errno:%d ", rlen, errno);
|
||||
}
|
||||
if (rlen < 0 && ridx == 0 && !esp_http_client_is_complete_data_received(client)) {
|
||||
return ESP_FAIL;
|
||||
} else {
|
||||
#ifdef CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS
|
||||
if (rlen == ESP_TLS_ERR_SSL_WANT_READ || errno == EAGAIN) {
|
||||
#else
|
||||
if (errno == EAGAIN) {
|
||||
#endif
|
||||
ESP_LOGD(TAG, "Received EAGAIN! rlen = %d, errno %d", rlen, errno);
|
||||
return ridx;
|
||||
}
|
||||
if (rlen < 0 && ridx == 0 && !esp_http_client_is_complete_data_received(client)) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ridx;
|
||||
}
|
||||
res_buffer->output_ptr = buffer + ridx;
|
||||
http_parser_execute(client->parser, client->parser_settings, res_buffer->data, rlen);
|
||||
|
@ -117,6 +117,8 @@ typedef struct {
|
||||
const char *cert_pem; /*!< SSL server certification, PEM format as string, if the client requires to verify server */
|
||||
const char *client_cert_pem; /*!< SSL client certification, PEM format as string, if the server requires to verify client */
|
||||
const char *client_key_pem; /*!< SSL client key, PEM format as string, if the server requires to verify client */
|
||||
const char *client_key_password; /*!< Client key decryption password string */
|
||||
size_t client_key_password_len; /*!< String length of the password pointed to by client_key_password */
|
||||
const char *user_agent; /*!< The User Agent string to send with HTTP requests */
|
||||
esp_http_client_method_t method; /*!< HTTP Method */
|
||||
int timeout_ms; /*!< Network timeout in milliseconds */
|
||||
|
@ -127,7 +127,7 @@ TEST_CASE("Username and password will not reset if new absolute URL doesnot spec
|
||||
// esp_http_client_set_username sets new username and thus invalidates the original one
|
||||
// which we still reference in the local variable `value` (better forget it)
|
||||
value = NULL;
|
||||
esp_http_client_set_password(client, USERNAME);
|
||||
esp_http_client_set_password(client, (char *)USERNAME); // Need to cast the string literal (argument is not a const char*)
|
||||
//checks if username is set or not
|
||||
r = esp_http_client_get_username(client, &value);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, r);
|
||||
|
@ -332,15 +332,19 @@ esp_err_t httpd_ws_recv_frame(httpd_req_t *req, httpd_ws_frame_t *frame, size_t
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
int read_len = 0, left_len = frame->len;
|
||||
size_t left_len = frame->len;
|
||||
size_t offset = 0;
|
||||
|
||||
while (left_len > 0) {
|
||||
if ((read_len = httpd_recv_with_opt(req, (char *)frame->payload + read_len, left_len, false)) <= 0) {
|
||||
int read_len = httpd_recv_with_opt(req, (char *)frame->payload + offset, left_len, false);
|
||||
if (read_len <= 0) {
|
||||
ESP_LOGW(TAG, LOG_FMT("Failed to receive payload"));
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (left_len -= read_len) {
|
||||
ESP_LOGD(TAG, "recv data length is less than the data length we want. Read again!");
|
||||
}
|
||||
offset += read_len;
|
||||
left_len -= read_len;
|
||||
|
||||
ESP_LOGD(TAG, "Frame length: %d, Bytes Read: %d", frame->len, offset);
|
||||
}
|
||||
|
||||
/* Unmask payload */
|
||||
|
@ -327,6 +327,7 @@ esp_err_t esp_https_ota_perform(esp_https_ota_handle_t https_ota_handle)
|
||||
} else if (data_read > 0) {
|
||||
return _ota_write(handle, (const void *)handle->ota_upgrade_buf, data_read);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "data read %d, errno %d", data_read, errno);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
handle->state = ESP_HTTPS_OTA_SUCCESS;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user