Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core 0 panic'ed (InstrFetchProhibited) after call to xTimerResetFromISR / xTimerStartFromISR (IDFGH-14499) #15269

Open
3 tasks done
HackXIt opened this issue Jan 23, 2025 · 4 comments
Assignees
Labels
Awaiting Response awaiting a response from the author Status: Opened Issue is new Type: Bug bugs in IDF

Comments

@HackXIt
Copy link

HackXIt commented Jan 23, 2025

Answers checklist.

  • I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

IDF version.

v5.4.0

Espressif SoC revision.

ESP32-S3 (ESP32-S3FN8) (revision 0.2)

Operating System used.

Linux

How did you build your project?

Command line with idf.py

If you are using Windows, please specify command line type.

None

Development Kit.

Custom board

Power Supply used.

External 5V

What is the expected behavior?

Timer gets started / reset after ISR completes and also gets executed after the timeout has been reached.

What is the actual behavior?

After portYIELD_FROM_ISR() in the interrupt service routine, I get Core 0 panic'ed (InstrFetchProhibited) error.

The ISR gets executed twice due to contact bouncing, which is the purpose of my timer, to de-bounce the GPIO input and use the last state.
After the second execution, the timer should be running for 5000ms (value chosen for debugging purposes) and then execute the callback.

But the panic happens almost immediately after the switch has been flipped.

My hardware in this case is a DIP switch, so it is safe to assume a reasonable delay for debouncing, instead of waiting for the input.

Steps to reproduce.

Code is provided in snippets relevant to the issue.

#define DEBOUNCE_TIME_MS 5000
#define GPIO_A0 GPIO_NUM_39
#define GPIO_A1 GPIO_NUM_40
#define GPIO_A2 GPIO_NUM_41
#define GPIO_A3 GPIO_NUM_42
#define GPIO_SLAVE_ADDR_INPUT_MASK ((1ULL << GPIO_A0) | (1ULL << GPIO_A1) | (1ULL << GPIO_A2) | (1ULL << GPIO_A3))

static StaticTimer_t debounce_timer_buffer = {};

void TA_i2c_slave_init()
{
    // ...
    // Configure I2C slave address GPIOs
    gpio_config_t slave_addr_io_conf = {};
    slave_addr_io_conf.intr_type = GPIO_INTR_ANYEDGE;
    slave_addr_io_conf.mode = GPIO_MODE_INPUT;
    slave_addr_io_conf.pin_bit_mask = GPIO_SLAVE_ADDR_INPUT_MASK;
    // External pull-down on hardware
    slave_addr_io_conf.pull_down_en = 0;
    slave_addr_io_conf.pull_up_en = 0;
    ESP_ERROR_CHECK(gpio_config(&slave_addr_io_conf));
    // Using isr service to allow for other GPIO interrupts on this core (by other components)
    ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_IRAM)); // place in IRAM
    // Create one-shot timer for address change debounce
    i2c_slave_ctx->debounce_timer = xTimerCreateStatic("i2c_debounce", pdMS_TO_TICKS(DEBOUNCE_TIME_MS), pdFALSE, &i2c_slave_ctx, _i2c_slave_debounce_timer_cb, &debounce_timer_buffer);
    if (i2c_slave_ctx->debounce_timer == NULL)
    {
        ESP_LOGE(TAG_I2C_SLAVE, "Failed to create debounce timer");
        vPortFree(i2c_slave_ctx->bytes);
        vPortFree(i2c_slave_ctx);
        return;
    }
    // ...
}

void TA_i2c_slave_start()
{
    // ...
    // Add handlers for address change interrupts
    ESP_ERROR_CHECK(gpio_isr_handler_add(GPIO_A0, _i2c_slave_isr_handler, &i2c_slave_ctx->event_queue));
    ESP_ERROR_CHECK(gpio_isr_handler_add(GPIO_A1, _i2c_slave_isr_handler, &i2c_slave_ctx->event_queue));
    ESP_ERROR_CHECK(gpio_isr_handler_add(GPIO_A2, _i2c_slave_isr_handler, &i2c_slave_ctx->event_queue));
    ESP_ERROR_CHECK(gpio_isr_handler_add(GPIO_A3, _i2c_slave_isr_handler, &i2c_slave_ctx->event_queue));
    // ...
}

IRAM_ATTR static void _i2c_slave_isr_handler(void *arg)
{
    i2c_slave_context_t *slave_ctx = (i2c_slave_context_t *)arg;
    BaseType_t xTaskWoken = 0;
    ESP_DRAM_LOGI(DRAM_STR("i2c_isr_gpio"), "I2C Slave Address GPIOs changed");
    // Start debounce timer, which in effect will send the restart event
    // Timer will get reset on each interrupt, effectively debouncing the address change
    if (xTimerResetFromISR(slave_ctx->debounce_timer, &xTaskWoken) != pdPASS)
    {
        ESP_DRAM_LOGI(DRAM_STR("i2c_isr_gpio"), "Failed to start debounce timer");
    }
    if (xTaskWoken)
    {
        portYIELD_FROM_ISR();
    }
}

// Function not executed in ISR (regular FreeRTOS timer-callback ran from TmrSrv)
static void _i2c_slave_debounce_timer_cb(TimerHandle_t xTimer)
{
    i2c_slave_context_t *context = *(i2c_slave_context_t **)pvTimerGetTimerID(xTimer);
    static i2c_slave_event_t evt = I2C_SLAVE_EVT_RESTART;
    ESP_LOGI(TAG_I2C_SLAVE, "Debounce timer expired");
    // There is no need to check what changed about the address, any state change on the address pins should trigger an I2C restart
    if (xQueueSend(context->event_queue, &evt, DEBOUNCE_TIME_MS) != pdPASS)
    {
        ESP_LOGE(TAG_I2C_SLAVE, "Failed to send restart event");
    }
}

Debug Logs.

I i2c_isr_gpio: I2C Slave Address GPIOs changed
I i2c_isr_gpio: I2C Slave Address GPIOs changed
Guru Meditation Error: Core  0 panic'ed (InstrFetchProhibited). Exception was unhandled.

Core  0 register dump:
PC      : 0x00000000  PS      : 0x00060330  A0      : 0x8037cfba  A1      : 0x3fc9cb80  
A2      : 0x00000000  A3      : 0x00000001  A4      : 0x00060023  A5      : 0x3fc9cd60  
A6      : 0x0000b730  A7      : 0x3fc9d720  A8      : 0x8037cf30  A9      : 0xfffffffe  
A10     : 0x3fc9d720  A11     : 0x0000b730  A12     : 0x00000000  A13     : 0x0000b730  
A14     : 0x00000001  A15     : 0x3fc9cb90  SAR     : 0x00000000  EXCCAUSE: 0x00000014  
EXCVADDR: 0x00000000  LBEG    : 0x40056f5c  LEND    : 0x40056f72  LCOUNT  : 0x00000000  
--- 0x40056f5c: memcpy in ROM
0x40056f72: memcpy in ROM



Backtrace: 0xfffffffd:0x3fc9cb80 0x4037cfb7:0x3fc9cbc0 0x4037c2f9:0x3fc9cbf0
--- 0x4037cfb7: prvTimerTask at /home/rini/esp/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/timers.c:688 (discriminator 1)
0x4037c2f9: vPortTaskWrapper at /home/rini/esp/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:139

More Information.

I wanted to implement a debouncing mechanism for a DIP switch we use for I²C sub-addressing. DIP switch are notoriously bouncy, as such I've implemented the above ISR routine, which will get repeatedly called and reset the timer for the one-shot callback.

As seen in the comments, I simply call xTimerResetFromISR to reset the timer. As stated from the documentation, I could have also used xTimerStartFromISR, which has also been tried.

Both functions should reset the timer value upon being called in quick succession, so only after the last call to the ISR, the timer should start running out. Effectively, this debounces the input, since we only act after some delay as the last input changed.

@HackXIt HackXIt added the Type: Bug bugs in IDF label Jan 23, 2025
@github-actions github-actions bot changed the title Core 0 panic'ed (InstrFetchProhibited) after call to xTimerResetFromISR / xTimerStartFromISR Core 0 panic'ed (InstrFetchProhibited) after call to xTimerResetFromISR / xTimerStartFromISR (IDFGH-14499) Jan 23, 2025
@espressif-bot espressif-bot added the Status: Opened Issue is new label Jan 23, 2025
@HackXIt
Copy link
Author

HackXIt commented Jan 23, 2025

Here's a bit more info on the backtrace:

I i2c_isr_gpio: I2C Slave Address GPIOs changed
I i2c_isr_gpio: I2C Slave Address GPIOs changed
I i2c_isr_gpio: I2C Slave Address GPIOs changed
Guru Meditation Error: Core  0 panic'ed (InstrFetchProhibited). Exception was unhandled.

Core  0 register dump:
PC      : 0x00000000  PS      : 0x00060330  A0      : 0x8037cfba  A1      : 0x3fc9cb80  
A2      : 0x00000000  A3      : 0x00000001  A4      : 0x00060023  A5      : 0x3fc9cd60  
A6      : 0x000025d1  A7      : 0x3fc9d720  A8      : 0x8037cf30  A9      : 0xfffffffe  
A10     : 0x3fc9d720  A11     : 0x000025d1  A12     : 0x00000000  A13     : 0x000025d1  
A14     : 0x00000002  A15     : 0x3fc9cb90  SAR     : 0x00000000  EXCCAUSE: 0x00000014  
EXCVADDR: 0x00000000  LBEG    : 0x40056f5c  LEND    : 0x40056f72  LCOUNT  : 0x00000000  
--- 0x40056f5c: memcpy in ROM
0x40056f72: memcpy in ROM



Backtrace: 0xfffffffd:0x3fc9cb80 0x4037cfb7:0x3fc9cbc0 0x4037c2f9:0x3fc9cbf0
--- 0x4037cfb7: prvTimerTask at /home/rini/esp/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/timers.c:688 (discriminator 1)
0x4037c2f9: vPortTaskWrapper at /home/rini/esp/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:139





ELF file SHA256: 13a85a56a

Entering gdb stub now.
$T0b#e6GNU gdb (esp-gdb) 14.2_20240403
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=aarch64-linux-gnu --target=xtensa-esp-elf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /home/rini/git-stash/Testcenter.TestAutomation.Lex.Solution/Lex.ESP32.CBus.Driver/build/CBusTracerApp.elf...
Remote debugging using /dev/ttyACM1
warning: multi-threaded target stopped without sending a thread-id, using first non-exited thread
0x40374400 in _init ()
(gdb) bt
#0  0x40374400 in _init ()
#1  0x4037cf30 in prvProcessReceivedCommands ()
    at /home/rini/esp/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/timers.c:932
#2  0x4037cfba in prvTimerTask (pvParameters=0x0)
    at /home/rini/esp/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/timers.c:688
#3  0x4037c2fc in vPortTaskWrapper (pxCode=0x4037cfa8 <prvTimerTask>, pvParameters=0x0)
    at /home/rini/esp/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:139
(gdb) frame
#0  0x40374400 in _init ()
(gdb) up
#1  0x4037cf30 in prvProcessReceivedCommands ()
    at /home/rini/esp/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/timers.c:932
932                                 pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
(gdb)

Why this call fails is beyond me, because it is being executed in the TimerService Task of FreeRTOS, which shouldn't be in the ISR.

I also tried both variants:
Dynamically allocated Timer and StaticTimer, they both resulted in the same issue.

Could it be, that the timer is initialized with 5000ms correctly, but due to my reset from ISR it gets set to 0, executing the timer callback immediately after the ISR?

What puzzles me about this issue is that there is no 5-second delay between portYIELD_FROM_ISR() and pxTimer->pxCallbackFunction(..), but rather it happens almost immediately after the last activation of the interrupt.

From the code of the FreeRTOS kernel I understand why the timer gets immediatly called and maybe I should instead be using xTimerChangePeriodFromISR. But the documentation states, that change period requires for the timer to already been started.

So I'm confused about this behaviour.

@HackXIt
Copy link
Author

HackXIt commented Jan 23, 2025

I have also tried the variant shown in the generic_gpio example, which simply uses a queue and sends each state change to the queue.

IRAM_ATTR static void _i2c_slave_isr_handler(void *arg)
{
    uint32_t gpio_num = (uint32_t)arg;
    xQueueSendFromISR(i2c_slave_ctx->gpio_queue, &gpio_num, NULL);
}

static void gpio_task_example(void *arg)
{
    uint32_t io_num;
    for (;;)
    {
        if (xQueueReceive(i2c_slave_ctx->gpio_queue, &io_num, portMAX_DELAY))
        {
            printf("GPIO[%" PRIu32 "] intr, val: %d\n", io_num, gpio_get_level(io_num));
        }
    }
}

void TA_i2c_slave_init()
{
// ...
    // Configure I2C slave address GPIOs
    gpio_config_t slave_addr_io_conf = {};
    slave_addr_io_conf.intr_type = GPIO_INTR_ANYEDGE;
    slave_addr_io_conf.mode = GPIO_MODE_INPUT;
    slave_addr_io_conf.pin_bit_mask = GPIO_SLAVE_ADDR_INPUT_MASK;
    // External pull-down on hardware
    slave_addr_io_conf.pull_down_en = 0;
    slave_addr_io_conf.pull_up_en = 0;
    ESP_ERROR_CHECK(gpio_config(&slave_addr_io_conf));
    // Using isr service to allow for other GPIO interrupts on this core (by other components)
    ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_IRAM)); // must place handlers in IRAM
    i2c_slave_ctx->gpio_queue = xQueueCreate(10, sizeof(uint32_t));
    if (!i2c_slave_ctx->gpio_queue)
    {
        ESP_LOGE(TAG_I2C_SLAVE, "Failed to create GPIO queue");
        vPortFree(i2c_slave_ctx->bytes);
        vPortFree(i2c_slave_ctx);
        return;
    }
    gpio_isr_handler_add(GPIO_A0, _i2c_slave_isr_handler, (void *)GPIO_A0);
    gpio_isr_handler_add(GPIO_A1, _i2c_slave_isr_handler, (void *)GPIO_A1);
    gpio_isr_handler_add(GPIO_A2, _i2c_slave_isr_handler, (void *)GPIO_A2);
    gpio_isr_handler_add(GPIO_A3, _i2c_slave_isr_handler, (void *)GPIO_A3);
    xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL);
// ...
}

This works, according to the logs:

I (129) main_task: Calling app_main()
This is ESP32 chip with 2 CPU cores, WiFi/BLE, silicon revision 2, 8MB external flash
I (149) LexMain: Starting in Test Automation Tracer Mode
I (149) gpio: GPIO[39]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:3 
I (149) gpio: GPIO[40]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:3 
I (159) gpio: GPIO[41]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:3 
I (159) gpio: GPIO[42]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:3 
D (159) intr_alloc: Connected src 16 to int 9 (cpu 0)
D (159) i2c.common: new bus(0) at 0x3fc9d1d8
D (159) intr_alloc: Connected src 42 to int 12 (cpu 0)
I (159) I2CSlave: I2C Slave initialized with address 0x10
I (159) LexMain: START time: 0 ms
I (10159) LexMain: Current Time: 9997 ms
GPIO[1070187728] intr, val: 0
I (20159) LexMain: Current Time: 19997 ms
GPIO[1070187728] intr, val: 0
GPIO[1070187728] intr, val: 0
GPIO[1070187728] intr, val: 0
GPIO[1070187728] intr, val: 0
GPIO[1070187728] intr, val: 0
GPIO[1070187728] intr, val: 0
GPIO[1070187728] intr, val: 0
GPIO[1070187728] intr, val: 0
GPIO[1070187728] intr, val: 0
GPIO[1070187728] intr, val: 0
GPIO[1070187728] intr, val: 0
GPIO[1070187728] intr, val: 0
GPIO[1070187728] intr, val: 0
GPIO[1070187728] intr, val: 0
GPIO[1070187728] intr, val: 0
I (30159) LexMain: Current Time: 29997 ms
GPIO[1070187728] intr, val: 0
GPIO[1070187728] intr, val: 0
GPIO[1070187728] intr, val: 0
I (40159) LexMain: Current Time: 39997 ms

But it's a bit undesirable, since it fills up a queue with irrelevant values, where only the last one matters in my case.

@HackXIt
Copy link
Author

HackXIt commented Jan 23, 2025

If I run the code like this, it works:

#define DEBOUNCE_TIME_MS 5000
#define GPIO_A0 GPIO_NUM_39
#define GPIO_A1 GPIO_NUM_40
#define GPIO_A2 GPIO_NUM_41
#define GPIO_A3 GPIO_NUM_42
#define GPIO_SLAVE_ADDR_INPUT_MASK ((1ULL << GPIO_A0) | (1ULL << GPIO_A1) | (1ULL << GPIO_A2) | (1ULL << GPIO_A3))

typedef struct i2c_slave_context
{
    i2c_slave_dev_handle_t handle;
    QueueHandle_t event_queue;
    QueueHandle_t gpio_queue;
    TimerHandle_t debounce_timer;
    // ...
} i2c_slave_context_t;

static StaticTimer_t debounce_timer_buffer = {};
static i2c_slave_context_t *i2c_slave_ctx = NULL;

IRAM_ATTR static void _i2c_slave_isr_handler(void *arg)
{
    uint32_t gpio_num = (uint32_t)arg;
    xQueueSendFromISR(i2c_slave_ctx->gpio_queue, &gpio_num, NULL);
}

static void _i2c_slave_debounce_timer_cb(TimerHandle_t xTimer)
{
    i2c_slave_context_t *context = (i2c_slave_context_t *)pvTimerGetTimerID(xTimer);
    static i2c_slave_event_t evt = I2C_SLAVE_EVT_RESTART;
    ESP_LOGI(TAG_I2C_SLAVE, "Debounce timer expired");
    // There is no need to check if the address changed, any state change on the address pins should trigger an I2C restart
    if (xQueueSend(context->event_queue, &evt, DEBOUNCE_TIME_MS) != pdPASS)
    {
        ESP_LOGE(TAG_I2C_SLAVE, "Failed to send restart event");
    }
}

static void gpio_task_example(void *arg)
{
    uint32_t io_num;
    for (;;)
    {
        if (xQueueReceive(i2c_slave_ctx->gpio_queue, &io_num, portMAX_DELAY))
        {
            printf("GPIO[%" PRIu32 "] intr, val: %d\n", io_num, gpio_get_level(io_num));
            xTimerStart(i2c_slave_ctx->debounce_timer, DEBOUNCE_TIME_MS);
        }
    }
}

void TA_i2c_slave_init()
{
    // ...
    // Configure I2C slave address GPIOs
    gpio_config_t slave_addr_io_conf = {};
    slave_addr_io_conf.intr_type = GPIO_INTR_ANYEDGE;
    slave_addr_io_conf.mode = GPIO_MODE_INPUT;
    slave_addr_io_conf.pin_bit_mask = GPIO_SLAVE_ADDR_INPUT_MASK;
    // External pull-down on hardware
    slave_addr_io_conf.pull_down_en = 0;
    slave_addr_io_conf.pull_up_en = 0;
    ESP_ERROR_CHECK(gpio_config(&slave_addr_io_conf));
    // Using isr service to allow for other GPIO interrupts on this core (by other components)
    ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_IRAM)); // must place handlers in IRAM
    i2c_slave_ctx->gpio_queue = xQueueCreate(10, sizeof(uint32_t));
    if (!i2c_slave_ctx->gpio_queue)
    {
        ESP_LOGE(TAG_I2C_SLAVE, "Failed to create GPIO queue");
        vPortFree(i2c_slave_ctx->bytes);
        vPortFree(i2c_slave_ctx);
        return;
    }
    gpio_isr_handler_add(GPIO_A0, _i2c_slave_isr_handler, (void *)GPIO_A0);
    gpio_isr_handler_add(GPIO_A1, _i2c_slave_isr_handler, (void *)GPIO_A1);
    gpio_isr_handler_add(GPIO_A2, _i2c_slave_isr_handler, (void *)GPIO_A2);
    gpio_isr_handler_add(GPIO_A3, _i2c_slave_isr_handler, (void *)GPIO_A3);
    // Create one-shot timer for address change debounce
    i2c_slave_ctx->debounce_timer = xTimerCreateStatic("i2c_debounce", pdMS_TO_TICKS(DEBOUNCE_TIME_MS), pdFALSE, i2c_slave_ctx, _i2c_slave_debounce_timer_cb, &debounce_timer_buffer);
    if (i2c_slave_ctx->debounce_timer == NULL)
    {
        ESP_LOGE(TAG_I2C_SLAVE, "Failed to create debounce timer");
        vPortFree(i2c_slave_ctx->bytes);
        vPortFree(i2c_slave_ctx);
        return;
    }
    xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL);
    // ...
}

Output:

I (130) main_task: Calling app_main()
This is ESP32 chip with 2 CPU cores, WiFi/BLE, silicon revision 2, 8MB external flash
I (150) LexMain: Starting in Test Automation Tracer Mode
I (150) gpio: GPIO[39]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:3 
I (150) gpio: GPIO[40]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:3 
I (160) gpio: GPIO[41]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:3 
I (160) gpio: GPIO[42]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:3 
D (160) intr_alloc: Connected src 16 to int 9 (cpu 0)
D (160) i2c.common: new bus(0) at 0x3fc9e3a4
D (160) intr_alloc: Connected src 42 to int 12 (cpu 0)
I (160) I2CSlave: I2C Slave initialized with address 0x16
I (160) LexMain: START time: 0 ms
I (10160) LexMain: Current Time: 9997 ms
GPIO[1070192280] intr, val: 0  <--- I only switched one input - As you can see, it bounces tremendously
GPIO[1070192280] intr, val: 0  <--- I don't know why the value is always zero, I think that's a bug inherited from the example code
GPIO[1070192280] intr, val: 0  <--- Value is also zero if the pin is actually high, so no idea why
GPIO[1070192280] intr, val: 0
GPIO[1070192280] intr, val: 0
GPIO[1070192280] intr, val: 0
GPIO[1070192280] intr, val: 0
I (18460) I2CSlave: Debounce timer expired
D (18460) I2CSlave: Processing I2C event: TX
D (18460) I2CSlave: TX Register 0x00 has size 32
D (18460) i2c.slave: del i2c bus(0)
D (18460) i2c.common: delete bus 0
I i2c_isr_gpio: Restarting I2C Slave with address 0x12 (Previous: 0x16)  <--- Address changed
D (18460) i2c.common: new bus(0) at 0x3fc9e3a4
D (18460) intr_alloc: Connected src 42 to int 12 (cpu 0)
I (20160) LexMain: Current Time: 19997 ms

This is the least desired solution.

I just did it to prove that the timer would be working, it only causes a panic directly after the ISR, WHICH SHOULD NOT HAPPEN when I'm using a FromISR function. The timer itself should not be called from ISR, but I think that is what's happening, otherwise I can't explain the InstrProhibited.

@ESP-Marius
Copy link
Collaborator

ESP-Marius commented Jan 24, 2025

From the backtrace it looks like it tries to call the timer callback, but it points to NULL.

Is it possible you are simply corrupting the timer struct memory somewhere? You gpio_task_example task is probably having a stackoverflow, as 2000 bytes of stack is usually insufficient if using printf. Does the problem go away if you increase it to 4000?

I tried a simplified example, which just tested reseting the timer from an ISR and that seem to work as expected at least.

@espressif-bot espressif-bot added the Awaiting Response awaiting a response from the author label Jan 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting Response awaiting a response from the author Status: Opened Issue is new Type: Bug bugs in IDF
Projects
None yet
Development

No branches or pull requests

3 participants