esp32: Add macro to check a condition without abort

Closes https://github.com/espressif/esp-idf/issues/2325
This commit is contained in:
Roland Dobai 2018-09-24 08:49:39 +02:00
parent a7bdd288f0
commit d4e572bdb1
5 changed files with 44 additions and 10 deletions

View File

@ -455,23 +455,23 @@ static void main_task(void* args)
//Initialize task wdt if configured to do so //Initialize task wdt if configured to do so
#ifdef CONFIG_TASK_WDT_PANIC #ifdef CONFIG_TASK_WDT_PANIC
ESP_ERROR_CHECK(esp_task_wdt_init(CONFIG_TASK_WDT_TIMEOUT_S, true)) ESP_ERROR_CHECK(esp_task_wdt_init(CONFIG_TASK_WDT_TIMEOUT_S, true));
#elif CONFIG_TASK_WDT #elif CONFIG_TASK_WDT
ESP_ERROR_CHECK(esp_task_wdt_init(CONFIG_TASK_WDT_TIMEOUT_S, false)) ESP_ERROR_CHECK(esp_task_wdt_init(CONFIG_TASK_WDT_TIMEOUT_S, false));
#endif #endif
//Add IDLE 0 to task wdt //Add IDLE 0 to task wdt
#ifdef CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0 #ifdef CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0
TaskHandle_t idle_0 = xTaskGetIdleTaskHandleForCPU(0); TaskHandle_t idle_0 = xTaskGetIdleTaskHandleForCPU(0);
if(idle_0 != NULL){ if(idle_0 != NULL){
ESP_ERROR_CHECK(esp_task_wdt_add(idle_0)) ESP_ERROR_CHECK(esp_task_wdt_add(idle_0));
} }
#endif #endif
//Add IDLE 1 to task wdt //Add IDLE 1 to task wdt
#ifdef CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 #ifdef CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1
TaskHandle_t idle_1 = xTaskGetIdleTaskHandleForCPU(1); TaskHandle_t idle_1 = xTaskGetIdleTaskHandleForCPU(1);
if(idle_1 != NULL){ if(idle_1 != NULL){
ESP_ERROR_CHECK(esp_task_wdt_add(idle_1)) ESP_ERROR_CHECK(esp_task_wdt_add(idle_1));
} }
#endif #endif

View File

@ -78,6 +78,9 @@ const char *esp_err_to_name_r(esp_err_t code, char *buf, size_t buflen);
/** @cond */ /** @cond */
void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) __attribute__((noreturn)); void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) __attribute__((noreturn));
/** @cond */
void _esp_error_check_failed_without_abort(esp_err_t rc, const char *file, int line, const char *function, const char *expression);
#ifndef __ASSERT_FUNC #ifndef __ASSERT_FUNC
/* This won't happen on IDF, which defines __ASSERT_FUNC in assert.h, but it does happen when building on the host which /* This won't happen on IDF, which defines __ASSERT_FUNC in assert.h, but it does happen when building on the host which
uses /usr/include/assert.h or equivalent. uses /usr/include/assert.h or equivalent.
@ -119,6 +122,27 @@ void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const cha
} while(0); } while(0);
#endif #endif
/**
* Macro which can be used to check the error code. Prints the error code, error location, and the failed statement to
* serial output.
* In comparison with ESP_ERROR_CHECK(), this prints the same error message but isn't terminating the program.
*/
#ifdef NDEBUG
#define ESP_ERROR_CHECK_WITHOUT_ABORT(x) ({ \
esp_err_t __err_rc = (x); \
__err_rc; \
})
#else
#define ESP_ERROR_CHECK_WITHOUT_ABORT(x) ({ \
esp_err_t __err_rc = (x); \
if (__err_rc != ESP_OK) { \
_esp_error_check_failed_without_abort(__err_rc, __FILE__, __LINE__, \
__ASSERT_FUNC, #x); \
} \
__err_rc; \
})
#endif //NDEBUG
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -663,9 +663,9 @@ void esp_clear_watchpoint(int no)
} }
} }
void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) static void esp_error_check_failed_print(const char *msg, esp_err_t rc, const char *file, int line, const char *function, const char *expression)
{ {
ets_printf("ESP_ERROR_CHECK failed: esp_err_t 0x%x", rc); ets_printf("%s failed: esp_err_t 0x%x", msg, rc);
#ifdef CONFIG_ESP_ERR_TO_NAME_LOOKUP #ifdef CONFIG_ESP_ERR_TO_NAME_LOOKUP
ets_printf(" (%s)", esp_err_to_name(rc)); ets_printf(" (%s)", esp_err_to_name(rc));
#endif //CONFIG_ESP_ERR_TO_NAME_LOOKUP #endif //CONFIG_ESP_ERR_TO_NAME_LOOKUP
@ -673,5 +673,15 @@ void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const cha
if (spi_flash_cache_enabled()) { // strings may be in flash cache if (spi_flash_cache_enabled()) { // strings may be in flash cache
ets_printf("file: \"%s\" line %d\nfunc: %s\nexpression: %s\n", file, line, function, expression); ets_printf("file: \"%s\" line %d\nfunc: %s\nexpression: %s\n", file, line, function, expression);
} }
}
void _esp_error_check_failed_without_abort(esp_err_t rc, const char *file, int line, const char *function, const char *expression)
{
esp_error_check_failed_print("ESP_ERROR_CHECK_WITHOUT_ABORT", rc, file, line, function, expression);
}
void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression)
{
esp_error_check_failed_print("ESP_ERROR_CHECK", rc, file, line, function, expression);
invoke_abort(); invoke_abort();
} }

View File

@ -196,7 +196,7 @@ esp_err_t esp_task_wdt_init(uint32_t timeout, bool panic)
twdt_config->panic = panic; twdt_config->panic = panic;
//Register Interrupt and ISR //Register Interrupt and ISR
ESP_ERROR_CHECK(esp_intr_alloc(ETS_TG0_WDT_LEVEL_INTR_SOURCE, 0, task_wdt_isr, NULL, &twdt_config->intr_handle)) ESP_ERROR_CHECK(esp_intr_alloc(ETS_TG0_WDT_LEVEL_INTR_SOURCE, 0, task_wdt_isr, NULL, &twdt_config->intr_handle));
//Configure hardware timer //Configure hardware timer
periph_module_enable(PERIPH_TIMG0_MODULE); periph_module_enable(PERIPH_TIMG0_MODULE);
@ -244,7 +244,7 @@ esp_err_t esp_task_wdt_deinit()
TIMERG0.wdt_config0.en=0; //Disable timer TIMERG0.wdt_config0.en=0; //Disable timer
TIMERG0.wdt_wprotect=0; //Enable write protection TIMERG0.wdt_wprotect=0; //Enable write protection
ESP_ERROR_CHECK(esp_intr_free(twdt_config->intr_handle)) //Unregister interrupt ESP_ERROR_CHECK(esp_intr_free(twdt_config->intr_handle)); //Unregister interrupt
free(twdt_config); //Free twdt_config free(twdt_config); //Free twdt_config
twdt_config = NULL; twdt_config = NULL;
portEXIT_CRITICAL(&twdt_spinlock); portEXIT_CRITICAL(&twdt_spinlock);
@ -286,7 +286,7 @@ esp_err_t esp_task_wdt_add(TaskHandle_t handle)
//If idle task, register the idle hook callback to appropriate core //If idle task, register the idle hook callback to appropriate core
for(int i = 0; i < portNUM_PROCESSORS; i++){ for(int i = 0; i < portNUM_PROCESSORS; i++){
if(handle == xTaskGetIdleTaskHandleForCPU(i)){ if(handle == xTaskGetIdleTaskHandleForCPU(i)){
ESP_ERROR_CHECK(esp_register_freertos_idle_hook_for_cpu(idle_hook_cb, i)) ESP_ERROR_CHECK(esp_register_freertos_idle_hook_for_cpu(idle_hook_cb, i));
break; break;
} }
} }

View File

@ -77,7 +77,7 @@ static void can_receive_task(void *arg)
xSemaphoreTake(rx_sem, portMAX_DELAY); xSemaphoreTake(rx_sem, portMAX_DELAY);
for (int i = 0; i < NO_OF_MSGS; i++) { for (int i = 0; i < NO_OF_MSGS; i++) {
//Receive message and print message data //Receive message and print message data
ESP_ERROR_CHECK(can_receive(&rx_message, portMAX_DELAY)) ESP_ERROR_CHECK(can_receive(&rx_message, portMAX_DELAY));
ESP_LOGI(EXAMPLE_TAG, "Msg received - Data = %d", rx_message.data[0]); ESP_LOGI(EXAMPLE_TAG, "Msg received - Data = %d", rx_message.data[0]);
} }
//Indicate to control task all messages received for this iteration //Indicate to control task all messages received for this iteration