Fix http client read return value

1.esp_tls: fail connection if esp_tls_conn_new() timeouts
https://gitlab.espressif.cn:6688/espressif/esp-idf/merge_requests/7397

2.esp32:panic: avoid access cache in panichandler

3.Sync https://gitlab.espressif.cn:6688/espressif/esp-idf/merge_requests/7152
Even if frame->exccause != PANIC_RSN_CACHEERR, it is possible that the cache error interrupt status is set. For example, this may happen due to an invalid cache access in the panic$
Check cache error interrupt status instead of frame->exccause to decide whether to do CPU reset or digital reset.
Also remove unnecessary esp_dport_access_int_pause from esp_cache_err_get_cpuid, since the panic handler already calls
esp_dport_access_int_abort on entry.
This commit is contained in:
maojianxin
2020-01-09 16:16:38 +08:00
parent d396624a60
commit c1374ff769
4 changed files with 19 additions and 10 deletions

View File

@ -481,6 +481,7 @@ esp_tls_t *esp_tls_conn_new(const char *hostname, int hostlen, int port, const e
} }
/* esp_tls_conn_new() API establishes connection in a blocking manner thus this loop ensures that esp_tls_conn_new() /* esp_tls_conn_new() API establishes connection in a blocking manner thus this loop ensures that esp_tls_conn_new()
API returns only after connection is established unless there is an error*/ API returns only after connection is established unless there is an error*/
size_t start = xTaskGetTickCount();
while (1) { while (1) {
int ret = esp_tls_low_level_conn(hostname, hostlen, port, cfg, tls); int ret = esp_tls_low_level_conn(hostname, hostlen, port, cfg, tls);
if (ret == 1) { if (ret == 1) {
@ -489,6 +490,14 @@ esp_tls_t *esp_tls_conn_new(const char *hostname, int hostlen, int port, const e
esp_tls_conn_delete(tls); esp_tls_conn_delete(tls);
ESP_LOGE(TAG, "Failed to open new connection"); ESP_LOGE(TAG, "Failed to open new connection");
return NULL; return NULL;
} else if (ret == 0 && cfg->timeout_ms >= 0) {
size_t timeout_ticks = pdMS_TO_TICKS(cfg->timeout_ms);
uint32_t expired = xTaskGetTickCount() - start;
if (expired >= timeout_ticks) {
esp_tls_conn_delete(tls);
ESP_LOGE(TAG, "Failed to open new connection in specified timeout");
return NULL;
}
} }
} }
return NULL; return NULL;

View File

@ -13,9 +13,9 @@
// limitations under the License. // limitations under the License.
/* /*
The cache has an interrupt that can be raised as soon as an access to a cached The cache has an interrupt that can be raised as soon as an access to a cached
region (flash, psram) is done without the cache being enabled. We use that here region (flash, psram) is done without the cache being enabled. We use that here
to panic the CPU, which from a debugging perspective is better than grabbing bad to panic the CPU, which from a debugging perspective is better than grabbing bad
data from the bus. data from the bus.
*/ */
@ -73,7 +73,6 @@ void esp_cache_err_int_init()
int IRAM_ATTR esp_cache_err_get_cpuid() int IRAM_ATTR esp_cache_err_get_cpuid()
{ {
esp_dport_access_int_pause();
const uint32_t pro_mask = const uint32_t pro_mask =
DPORT_PRO_CPU_DISABLED_CACHE_IA_DRAM1 | DPORT_PRO_CPU_DISABLED_CACHE_IA_DRAM1 |
DPORT_PRO_CPU_DISABLED_CACHE_IA_DROM0 | DPORT_PRO_CPU_DISABLED_CACHE_IA_DROM0 |

View File

@ -382,7 +382,7 @@ static void illegal_instruction_helper(XtExcFrame *frame)
panicPutStr("Memory dump at 0x"); panicPutStr("Memory dump at 0x");
panicPutHex(epc); panicPutHex(epc);
panicPutStr(": "); panicPutStr(": ");
panicPutHex(*pepc); panicPutHex(*pepc);
panicPutStr(" "); panicPutStr(" ");
panicPutHex(*(pepc + 1)); panicPutHex(*(pepc + 1));
@ -544,8 +544,9 @@ static void commonErrorHandler_dump(XtExcFrame *frame, int core_id)
panicPutStr("\r\nELF file SHA256: "); panicPutStr("\r\nELF file SHA256: ");
char sha256_buf[65]; char sha256_buf[65];
esp_ota_get_app_elf_sha256(sha256_buf, sizeof(sha256_buf)); // Disable for avoid access cache
panicPutStr(sha256_buf); // esp_ota_get_app_elf_sha256(sha256_buf, sizeof(sha256_buf));
// panicPutStr(sha256_buf);
panicPutStr("\r\n"); panicPutStr("\r\n");
/* With windowed ABI backtracing is easy, let's do it. */ /* With windowed ABI backtracing is easy, let's do it. */
@ -623,7 +624,7 @@ static __attribute__((noreturn)) void commonErrorHandler(XtExcFrame *frame)
rtc_wdt_disable(); rtc_wdt_disable();
#if CONFIG_ESP32_PANIC_PRINT_REBOOT || CONFIG_ESP32_PANIC_SILENT_REBOOT #if CONFIG_ESP32_PANIC_PRINT_REBOOT || CONFIG_ESP32_PANIC_SILENT_REBOOT
panicPutStr("Rebooting...\r\n"); panicPutStr("Rebooting...\r\n");
if (frame->exccause != PANIC_RSN_CACHEERR) { if (esp_cache_err_get_cpuid() == -1) {
esp_restart_noos(); esp_restart_noos();
} else { } else {
// The only way to clear invalid cache access interrupt is to reset the digital part // The only way to clear invalid cache access interrupt is to reset the digital part

View File

@ -742,7 +742,7 @@ esp_err_t esp_http_client_set_url(esp_http_client_handle_t client, const char *u
} else { } else {
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
} }
//Reset path and query if there are no information //Reset path and query if there are no information
if (purl.field_data[UF_PATH].len) { if (purl.field_data[UF_PATH].len) {
@ -825,7 +825,7 @@ int esp_http_client_read(esp_http_client_handle_t client, char *buffer, int len)
ESP_LOGD(TAG, "need_read=%d, byte_to_read=%d, rlen=%d, ridx=%d", need_read, byte_to_read, rlen, ridx); ESP_LOGD(TAG, "need_read=%d, byte_to_read=%d, rlen=%d, ridx=%d", need_read, byte_to_read, rlen, ridx);
if (rlen <= 0) { if (rlen <= 0) {
return ridx; return rlen;
} }
res_buffer->output_ptr = buffer + ridx; res_buffer->output_ptr = buffer + ridx;
http_parser_execute(client->parser, client->parser_settings, res_buffer->data, rlen); http_parser_execute(client->parser, client->parser_settings, res_buffer->data, rlen);