Using C++ mutex from esp isr handler results in abort

Zevver
Posts: 14
Joined: Sun Oct 17, 2021 5:18 pm

Using C++ mutex from esp isr handler results in abort

Postby Zevver » Sun Oct 17, 2021 5:43 pm

I have some existing code that uses FreeRtos semaphores which are used for synchronization of a central event queue, which also gets called from the GPIO ISR handler; this code currently uses xSemaphoreTakeFromISR() to be able to properly handle the ISR case.

TL;DR:

C++ std::mutex can not be used from ISR code. Is this to be expected?

Long version:

I'd like to simplify my code and use a regular C++ std::mutex instead; unfortunately the implementation seems not to be able to cope with ISR context, my application aborts with the following stack:

Code: Select all

0x40087778: panic_abort at /opt/toolchains/esp-idf/components/esp_system/panic.c:330
0x40087ff9: esp_system_abort at /opt/toolchains/esp-idf/components/esp_system/system_api.c:106
0x4008c6b1: abort at /opt/toolchains/esp-idf/components/newlib/abort.c:46
0x400832e6: lock_acquire_generic at /opt/toolchains/esp-idf/components/newlib/locks.c:142
0x400834d2: _lock_acquire_recursive at /opt/toolchains/esp-idf/components/newlib/locks.c:170
0x400edbf6: pthread_cond_signal at /opt/toolchains/esp-idf/components/pthread/pthread_cond_var.c:55
0x400ecfd1: __gthread_cond_signal at /builds/idf/crosstool-NG/.build/xtensa-esp32-elf/build/build-cc-gcc-final/xtensa-esp32-elf/no-rtti/libstdc++-v3/include/xt
0x400d6e58: Evq::push(event const&) at /home/ico/sandbox/nowos/icos/esp/main/src/bios/evq.cpp:87
0x400836fe: drv::gpio::gpio_isr_handler(void*) at /home/ico/sandbox/nowos/icos/esp/main/src/drv/gpio/esp32.cpp:16
Indeed, the abort itself lives in newlib/locks.c:

Code: Select all

    if (!xPortCanYield()) {                     
        /* In ISR Context */
        if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX) {
            abort(); /* recursive mutexes make no sense in ISR context */
        }  
This all matches with the documentation at https://docs.espressif.com/projects/esp ... hread.html, where it notes that std::mutex is implemented in terms of pthread primitives, which are again implemented using xSemaphoreCreateMutex().

It seems that this is just a limitation of the implementation - but would it not make sense to have the implementation build on top of xSemaphoreTakeFromISR() instead to allow std::mutex to be used from more contexts?

Who is online

Users browsing this forum: Bing [Bot] and 71 guests