ESP32 IRAM Timer ISR Cache Access Failure

Gondola
Posts: 4
Joined: Sat Apr 28, 2018 12:08 am

ESP32 IRAM Timer ISR Cache Access Failure

Postby Gondola » Sat Apr 28, 2018 12:13 am

My question is about IRAM safe functions. Within my Timer ISR I am only calling one function. This function is: xTaskNotifyGiveFromISR().

https://www.freertos.org/vTaskNotifyGiveFromISR.html

However, when my device boots and starts connecting to WiFi I receive a Guru Meditation Error: Core 1 panic'ed (Cache disabled but cached memory region accessed) error on 10% of the boots

. I am not calling any other functions within the Timer ISR and I have ensured that the timer creation is putting it into IRAM. Any reason why this would occur? When I run the same code in single core operation I see no issues.

Thanks

ESP_Sprite
Posts: 9708
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32 IRAM Timer ISR Cache Access Failure

Postby ESP_Sprite » Sat Apr 28, 2018 3:48 am

Do you happen to be using PSRAM?

Gondola
Posts: 4
Joined: Sat Apr 28, 2018 12:08 am

Re: ESP32 IRAM Timer ISR Cache Access Failure

Postby Gondola » Mon Apr 30, 2018 1:42 pm

I am not using PSRAM. I am using the ESP-WROOM-32. For some additinoal information I will post the timer initialization, ISR, and Task that is being notified.

Code: Select all

volatile int counter = 0;
#define DETECT_LENGTH   10

void IRAM_ATTR timer_group0_isr(void *para)
{
    int timer_idx = (int) para;
    uint32_t intr_status = TIMERG0.int_st_timers.val;
    
    if((intr_status & BIT(timer_idx)) && timer_idx == TIMER_0) 
    {
        if(REG_GET_BIT(GPIO_IN_REG, 0x08000000) == 0)
        {   
            ++counter;
        }
        else
        {
            counter = 0;
        }

        if(counter == DETECT_LENGTH)
        {
            
            BaseType_t xHigherPriorityTaskWoken = pdFALSE;

            vTaskNotifyGiveFromISR( TaskUART, NULL);

            if( xHigherPriorityTaskWoken == pdTRUE )
            {
                portYIELD_FROM_ISR();
            }
        }
        else
        {
            /* Do Nothing - Actively Counting */
            TIMERG0.hw_timer[timer_idx].update = 1;
            TIMERG0.int_clr_timers.t0 = 1;
            TIMERG0.hw_timer[timer_idx].config.alarm_en = 1;
        }
    }
}

static void UART_handler(void* apParams)
{
    uint32_t notified;
    uint8_t testing[8] = {0};
    uint8_t ct =0;
    
    TaskUART = xTaskGetCurrentTaskHandle();
    timer0_init();

    while(1)
    {

        notified = ulTaskNotifyTake( pdTRUE,     
                                     0xFFFFFFFF ); 

        if( notified == 0 )
        {
            continue;
        }

        counter = 0;

        TIMERG0.hw_timer[TIMER_0].update = 1;
        TIMERG0.int_clr_timers.t0 = 1;
        TIMERG0.hw_timer[TIMER_0].config.alarm_en = 1;
    }
}

static void timer0_init(TaskHandle_t hdl)
{
    int timer_group = TIMER_GROUP_0;
    test.timer_idx = TIMER_0;
    test.wakeupHandle = hdl;
    
    int timer_idx = TIMER_0;
    timer_config_t config;
    config.alarm_en = 1;
    config.auto_reload = 1;
    config.counter_dir = TIMER_COUNT_UP;
    config.divider = TIMER_DIVIDER;
    config.intr_type = TIMER_INTR_SEL;
    config.counter_en = TIMER_PAUSE;
    /*Configure timer*/
    timer_init(timer_group, timer_idx, &config);
    /*Stop timer counter*/
    timer_pause(timer_group, timer_idx);
    /*Load counter value */
    timer_set_counter_value(timer_group, timer_idx, 0x00000000ULL);
    /*Set alarm value*/
    timer_set_alarm_value(timer_group, timer_idx, (TIMER_INTERVAL0_SEC * TIMER_SCALE) - TIMER_FINE_ADJ);
    /*Enable timer interrupt*/
    timer_enable_intr(timer_group, timer_idx);
    /*Set ISR handler*/
    timer_isr_register(timer_group, timer_idx, &timer_group0_isr, (void*) timer_idx, ESP_INTR_FLAG_IRAM, NULL);
    /*Start timer counter*/
    timer_start(timer_group, timer_idx);
}

ESP_Sprite
Posts: 9708
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32 IRAM Timer ISR Cache Access Failure

Postby ESP_Sprite » Mon Apr 30, 2018 2:20 pm

Huh, your ISR coding is indeed textbook correct. Do you have UART_handler task pinned to a specific core?

Gondola
Posts: 4
Joined: Sat Apr 28, 2018 12:08 am

Re: ESP32 IRAM Timer ISR Cache Access Failure

Postby Gondola » Mon Apr 30, 2018 2:23 pm

No, the handler is not pinned to any specific core:

Code: Select all

xTaskCreate(&UART_handler, "uart_task", 8192, NULL, configMAX_PRIORITIES-1, NULL);
What is the reason why I would need to pin it to a specific one?

Gondola
Posts: 4
Joined: Sat Apr 28, 2018 12:08 am

Re: ESP32 IRAM Timer ISR Cache Access Failure

Postby Gondola » Mon Apr 30, 2018 3:02 pm

Alright,

I pinned the UART_handler task to Core 0 using:

Code: Select all

xTaskCreatePinnedToCore(&UART_handler, "uart_task", 8192, NULL, configMAX_PRIORITIES-1, NULL,0);
Now I no longer see the Cache Access Error. I am not quite sure why this works.

ESP_Sprite
Posts: 9708
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32 IRAM Timer ISR Cache Access Failure

Postby ESP_Sprite » Tue May 01, 2018 2:46 am

It's because an interrupt on one core notifying a task on the other is somewhat of a convoluted process: the notification code will raise another interrupt on the core the to-be-notified task is running on. The other core will use that to switch contexts if needed. What I think is going on is that this cross-core interrupt somehow touches something that's in flash and as such craps out when the flash is not there. So making sure the interrupt is on the same core as the thread to be notified bypasses this cross-core-interrupt business and makes it work.

However, the fact that you get the crashes with the unpinned task does indicate we have a bug somewhere. Are you perhaps willing to share your project with us so we can look deeper into what is going wrong here?

vonnieda
Posts: 145
Joined: Tue Nov 07, 2017 3:42 pm

Re: ESP32 IRAM Timer ISR Cache Access Failure

Postby vonnieda » Tue May 01, 2018 3:11 am

Could be the same as this issue I've been struggling with for quite some time now: https://github.com/espressif/esp-idf/issues/1651

ESP_Sprite
Posts: 9708
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32 IRAM Timer ISR Cache Access Failure

Postby ESP_Sprite » Tue May 01, 2018 8:23 am

Hard to say at this point; it may have something to do with it. At the moment, all I know is that there's some smell of suspicion at the cross-core interrupt, but nothing concrete.

ESP_igrr
Posts: 2071
Joined: Tue Dec 01, 2015 8:37 am

Re: ESP32 IRAM Timer ISR Cache Access Failure

Postby ESP_igrr » Wed May 02, 2018 1:42 am

I think using "configMAX_PRIORITIES-1" is the issue here. This makes the task same priority as IPC tasks, which are used during flash writes to prevent other tasks from running. Lower the priority of your task or make sure task code is also placed into IRAM.

Who is online

Users browsing this forum: No registered users and 81 guests