I need some help with advanced/custom error handling on ESP-IDF v4

leofabri
Posts: 9
Joined: Wed Feb 19, 2020 3:36 pm

I need some help with advanced/custom error handling on ESP-IDF v4

Postby leofabri » Tue Mar 03, 2020 10:51 am

Hello everyone,
I'm quite new to esp-idf and I'm building an app where I really need to intercept exceptions, disable faulty components and do some raw user/app-controlled tracing, but I'm afraid I need a custom error handler.

I hate the idea of modifying the official esp-idf's components just to add something that will need to be re-implemented every time I'll have to update ESP-IDF, but this is all I can think of for now.

This is what I'm changing:

esp-idf/components/freertos/include/xtensa_api.h location: see this
  1.  
  2. /* Typedef for C-callable standard error handler callback */
  3. typedef void (*xt_error_handler_callback)(XtExcFrame *, int core_id, bool is_abort);
  4.  
  1.  
  2. /*
  3. -------------------------------------------------------------------------------
  4.   Call this function to set a callback for the standard error handler.
  5.   The callback will be called by the commonErrorHandler on all errors.
  6.  
  7.     f        - Callback function address, NULL to uninstall callback.
  8.  
  9.   The callback will be passed a pointer to the exception frame, which is created
  10.   on the stack of the thread that caused the exception, the core id and
  11.   a bool to signal if abort() has been called.
  12.  
  13.   The callback is called with watchdogs disabled.
  14. -------------------------------------------------------------------------------
  15. */
  16. extern xt_error_handler_callback xt_set_error_handler_callback(xt_error_handler_callback f);
  17.  
____


esp-idf/components/esp32/panic.c here
  1.  
  2. #if CONFIG_ESP32_PANIC_CALLBACK
  3. /*
  4. * Custom error handler callback registration.
  5. */
  6. xt_error_handler_callback customErrorHandler = NULL;
  7. xt_error_handler_callback xt_set_error_handler_callback(xt_error_handler_callback f)
  8. {
  9. xt_error_handler_callback old = customErrorHandler;
  10. customErrorHandler = f;
  11. return old;
  12. }
  13. #endif //CONFIG_ESP32_PANIC_CALLBACK
  14.  
____

The following one is then added inside of the commonErrorHandler() location: see this
  1.  
  2. #if CONFIG_ESP32_PANIC_CALLBACK
  3. if (customErrorHandler) {
  4.     disableAllWdts();
  5.     customErrorHandler(frame, core_id, abort_called);
  6.     reconfigureAllWdts();
  7. }
  8. #endif
  9.  
____

Finally, I added an entry to KConfig in order to configure the ESP32_PANIC_CALLBACK variable:

Code: Select all

    menu "Custom Error Handling"
        config ESP32_PANIC_CALLBACK
            bool "Support registration of a user defined callback for the panic handler"
            default y
            help
                Use xt_set_error_handler_callback() to register a custom callback.
                The callback is called by the common error handler so catches exceptions,
                panics and abort() calls.
    endmenu
____

Expected results:

This should, in theory, allow me to register a custom handler function, so that inside of my main:
  1.  
  2. #include "freertos/xtensa_api.h" // Forgot to mention but was there
  3.  
  4. // I should be able to set my handler callback calling
  5. xt_set_error_handler_callback(ErrorCallback);
Here is my ErrorCallback
  1. void Boot::ErrorCallback(XtExcFrame *frame, int core_id, bool is_abort)
  2. {
  3.   boot_data.crash_data.core_id = core_id;
  4.   boot_data.crash_data.is_abort = is_abort;
  5.  
  6.   // Save registers:
  7.   for (int i = 0; i < 24; i++)
  8.     boot_data.crash_data.reg[i] = ((uint32_t *)frame)[i + 1];
  9.  
  10. // Save backtrace:
  11. // (see panic.c::doBacktrace() for code template)
  12. #define _adjusted_pc(pc) (((pc)&0x80000000) ? (((pc)&0x3fffffff) | 0x40000000) : (pc))
  13.   uint32_t i = 0, pc = frame->pc, sp = frame->a1;
  14.   boot_data.crash_data.bt[0].pc = _adjusted_pc(pc);
  15.   pc = frame->a0;
  16.   while (++i < SENSE_BT_LEVELS)
  17.   {
  18.     uint32_t psp = sp;
  19.     if (!esp_stack_ptr_is_sane(sp))
  20.       break;
  21.     sp = *((uint32_t *)(sp - 0x10 + 4));
  22.     boot_data.crash_data.bt[i].pc = _adjusted_pc(pc - 3);
  23.     pc = *((uint32_t *)(psp - 0x10));
  24.     if (pc < 0x40000000)
  25.       break;
  26.   }
  27. }
  28.  

Issues with the code above:

- The code seems to be compiling successfully until I get an "undefined reference error" when I call the xt_set_error_handler_callback(ErrorCallback):

Code: Select all

cmd.exe /C "cd . && C:\Users\me\.espressif\tools\xtensa-esp32-elf\esp-2019r2-8.2.0\xtensa-esp32-elf\bin\xtensa-esp32-elf-g++.exe  -mlongcalls -Wno-frame-address  -nostdlib @CMakeFiles\app.elf.rsp  -o app.elf  && cd ."
c:/users/me/.espressif/tools/xtensa-esp32-elf/esp-2019r2-8.2.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.2.0/../../../../xtensa-esp32-elf/bin/ld.exe: esp-idf/main/libmain.a(app_boot.cpp.obj):(.literal._ZN4BootC2Ev+0x38): undefined reference to `xt_set_error_handler_callback(void (*)(XtExcFrame*, int, bool))'
c:/users/me/.espressif/tools/xtensa-esp32-elf/esp-2019r2-8.2.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.2.0/../../../../xtensa-esp32-elf/bin/ld.exe: esp-idf/main/libmain.a(app_boot.cpp.obj): in function `Boot::Boot()':
c:\development\app\build/../main/app_boot.cpp:158: undefined reference to `xt_set_error_handler_callback(void (*)(XtExcFrame*, int, bool))'
and I can't really tell if there is a problem with CMake.txt (shouldn't freertos be imported automatically?) or if maybe I'm missing something. I also tried to fullclean but that didn't change anything :cry:

- I would love to find a different solution so that I don't have to adjust those files inside esp-idf every time I have to perform an update. Suggestion are very welcome :D

Some help would be really appreciated, thank you in advance.
Last edited by leofabri on Tue Mar 03, 2020 2:17 pm, edited 2 times in total.

boarchuz
Posts: 604
Joined: Tue Aug 21, 2018 5:28 am

Re: I need some help with advanced/custom error handling on ESP-IDF v4

Postby boarchuz » Tue Mar 03, 2020 1:58 pm

Does app_boot.cpp have

Code: Select all

extern "C" {
#include "freertos/xtensa_api.h"
}
?

Your project can include a local, customised version of the component that will take priority over the original.

leofabri
Posts: 9
Joined: Wed Feb 19, 2020 3:36 pm

Re: I need some help with advanced/custom error handling on ESP-IDF v4

Postby leofabri » Tue Mar 03, 2020 2:16 pm

boarchuz wrote:
Tue Mar 03, 2020 1:58 pm
Does app_boot.cpp have

Code: Select all

extern "C" {
#include "freertos/xtensa_api.h"
}
?

Your project can include a local, customised version of the component that will take priority over the original.
Hi, thank you for asking. Yes, I forgot to mention it, but the app_boot.cpp file does have that included. That's the reason why I can't really tell why this doesn't work.

I should probably try to make that a custom component, that's a good idea and I will give it a shot. Frankly speaking, if I'm currently unsure about how to do that :D

Who is online

Users browsing this forum: jesper and 88 guests