Getting Guru Meditation Exception while using Hardware Timer

Ritesh
Posts: 1383
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Getting Guru Meditation Exception while using Hardware Timer

Postby Ritesh » Thu Jun 29, 2017 1:17 pm

Hi All,

As we are developing one application on ESP32 and we have used ESP32 2.0 Official Release for SDK base, We are getting Guru Meditation Exception randomly in application while using Hardware Timer.

We have used Hardware Timer based on example provided with some our modifications.

Please find below Hardware Timer code which we are right now using in our application.

Code: Select all

#define ONE_SEC_TIMER_INTERVAL  4999993

/*
 * @brief timer group0 hardware timer0 init
 */
void tg0_timer0_init()
{
    // int timer_group = TIMER_GROUP_0;
    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;
	
	timer_interval = ONE_SEC_TIMER_INTERVAL;
	
	
    /*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_interval);
    /*Enable timer interrupt*/
    timer_enable_intr(timer_group, timer_idx);
    /*Set ISR handler*/
    timer_isr_register(timer_group, timer_idx, low_freq_isr, (void*) timer_idx, ESP_INTR_FLAG_IRAM, NULL);
    /*Start timer counter*/
    timer_start(timer_group, timer_idx);
}

void tg0_timer1_init()
{
    // int timer_group = TIMER_GROUP_0;
    int timer_idx = TIMER_1;
    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;
	
	timer_interval = ONE_SEC_TIMER_INTERVAL;
	
    /*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_interval);
    /*Enable timer interrupt*/
    timer_enable_intr(timer_group, timer_idx);
    /*Set ISR handler*/
    timer_isr_register(timer_group, timer_idx, high_freq_isr, (void*) timer_idx, ESP_INTR_FLAG_IRAM, NULL);
    /*Start timer counter*/
    timer_start(timer_group, timer_idx);
}

/*
 * @brief timer group0 ISR handler
   NOTE : must use IRAM_ATTR in isr function defineation,
 */
void IRAM_ATTR high_freq_isr(void *para)
{
	static char high_freq = 0;
    int timer_idx = (int) para;
    // uint32_t intr_status = TIMERG0.int_st_timers.val;
    // timer_event_t evt;

	if(high_freq == 0)
	{
		if(CHECK_LED_STATUS(WifiLed) == LEDFREQSTAT_HIGH_FRQ)
		{
			// printf("led off for 500 ms in high isr\r\n");
			gpio_set_level(WIFI_LED, 1);
		}
		if(CHECK_LED_STATUS(BLled) == LEDFREQSTAT_HIGH_FRQ)
		{
			// printf("led off for 500 ms in high isr\r\n");
			gpio_set_level(WIFI_LED, 1);
		}
		high_freq = 1;
		timer_high_frq_modified = ONE_SEC_TIMER_INTERVAL/2;
	}
	else if(high_freq == 1)
	{
		if(CHECK_LED_STATUS(WifiLed) == LEDFREQSTAT_HIGH_FRQ)
		{
			// printf("led on for 100 ms in high isr\r\n");
			gpio_set_level(WIFI_LED, 0);
		}
		if(CHECK_LED_STATUS(BLled) == LEDFREQSTAT_HIGH_FRQ)
		{
			// printf("led on for 100 ms in high isr\r\n");
			gpio_set_level(WIFI_LED, 0);
		}
		timer_high_frq_modified = ONE_SEC_TIMER_INTERVAL/10;
		high_freq = 0;
	}

	if (timer_idx==1) {
        TIMERG0.int_clr_timers.t1 = 1;
		timer_set_alarm_value(timer_group, timer_idx, timer_high_frq_modified);
        TIMERG0.hw_timer[1].update=1;
        TIMERG0.hw_timer[1].config.alarm_en = 1;
    }
}

/*
 * @brief timer group0 ISR handler
   NOTE : must use IRAM_ATTR in isr function defineation,
 */
void IRAM_ATTR low_freq_isr(void *para)
{
	static char low_freq = 0;
    int timer_idx = (int) para;
    // uint32_t intr_status = TIMERG0.int_st_timers.val;
    // timer_event_t evt;
	// timer_interval_modified = ONE_SEC_TIMER_INTERVAL/2;
	if(low_freq == 0)
	{
		if(CHECK_LED_STATUS(WifiLed) == LEDFREQSTAT_LOW_FRQ)
		{
			// printf("led off for 2000 ms in low isr\r\n");
			gpio_set_level(WIFI_LED, 1);
		}
		if(CHECK_LED_STATUS(BLled) == LEDFREQSTAT_LOW_FRQ)
		{
			// printf("led off for 2000 ms in low isr\r\n");
			gpio_set_level(WIFI_LED, 1);
		}
		low_freq = 1;
		timer_low_frq_modified = ONE_SEC_TIMER_INTERVAL*2;
	}
	else if(low_freq == 1)
	{
		if(CHECK_LED_STATUS(WifiLed) == LEDFREQSTAT_LOW_FRQ)
		{
			// printf("led on for 100 ms in low isr\r\n");
			gpio_set_level(WIFI_LED, 0);
		}
		if(CHECK_LED_STATUS(BLled) == LEDFREQSTAT_LOW_FRQ)
		{
			// printf("led on for 100 ms in low isr\r\n");
			gpio_set_level(WIFI_LED, 0);
		}
		timer_low_frq_modified = ONE_SEC_TIMER_INTERVAL/10;
		low_freq = 0;
	}

	if (timer_idx==0) {
        TIMERG0.int_clr_timers.t0 = 1;
		timer_set_alarm_value(timer_group, timer_idx, timer_low_frq_modified);
        TIMERG0.hw_timer[0].update=1;
        TIMERG0.hw_timer[0].config.alarm_en = 1;
    }
}
So, We have checked exceptions and found that we are getting last back-trace call as timer_set_alarm_value.
xtensa-esp32-elf-addr2line.exe -pfia -e /e/build/app-template.elf 0x4011271e:0x3ffb05e0 0x400814e0:0x3ffb0600
0x4011271e: timer_set_alarm_value at E:/esp-idf-v2.0/components/driver/timer.c:264
0x400814e0: _xt_lowint1 at xtensa_vectors.o:?
After that we have replaced Hardware Timer with Software Timer using xTimerCreate and it works fine without any issue. So, It seems like issue might be Hardware Timer Component which we are using in our application code for Timer feature.

Please let me know if anyone has faced this type of issue or any clue/info to solve this issue without using Hardware Timer.
Regards,
Ritesh Prajapati

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: Getting Guru Meditation Exception while using Hardware Timer

Postby WiFive » Thu Jun 29, 2017 6:40 pm

timer_set_alarm_value is not IRAM_ATTR function. Check methods inside ISR in example


https://github.com/espressif/esp-idf/bl ... ple_main.c

Ritesh
Posts: 1383
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: Getting Guru Meditation Exception while using Hardware Timer

Postby Ritesh » Thu Jun 29, 2017 11:14 pm

WiFive wrote:timer_set_alarm_value is not IRAM_ATTR function. Check methods inside ISR in example


https://github.com/espressif/esp-idf/bl ... ple_main.c
Hi,

I didn't get your point. We have followed Hardware Timer concept based on example provided with some ISR related modifications.

So that timer_set_alarm_value has been called from timer init API.

Please explain in details why Exception has been generated while using Hardware Timer.
Regards,
Ritesh Prajapati

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: Getting Guru Meditation Exception while using Hardware Timer

Postby WiFive » Fri Jun 30, 2017 12:12 am

Check inside your 2 ISR for timer_set_alarm_value

Ritesh
Posts: 1383
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: Getting Guru Meditation Exception while using Hardware Timer

Postby Ritesh » Fri Jun 30, 2017 1:29 am

WiFive wrote:Check inside your 2 ISR for timer_set_alarm_value
So, How can I set alarm value in my both ISR calls?
Regards,
Ritesh Prajapati

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: Getting Guru Meditation Exception while using Hardware Timer

Postby WiFive » Fri Jun 30, 2017 5:27 am

Do it the way the example does in the ISR by setting timer struct members directly. Which is what I said the first time.

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

Re: Getting Guru Meditation Exception while using Hardware Timer

Postby ESP_igrr » Fri Jun 30, 2017 5:52 am

Alternatively, replace ESP_INTR_FLAG_IRAM with ESP_INTR_FLAG_DEFAULT when you are registering the interrupt. Then the interrupt will be automatically disabled at times when cache is disabled. You will be able to call non-IRAM functions from ISR in this case.

Ritesh
Posts: 1383
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: Getting Guru Meditation Exception while using Hardware Timer

Postby Ritesh » Fri Jun 30, 2017 7:17 am

WiFive wrote:Do it the way the example does in the ISR by setting timer struct members directly. Which is what I said the first time.
Hi,

Thanks for quick reply. I will check and let you know result for that.
Regards,
Ritesh Prajapati

Ritesh
Posts: 1383
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: Getting Guru Meditation Exception while using Hardware Timer

Postby Ritesh » Fri Jun 30, 2017 7:17 am

ESP_igrr wrote:Alternatively, replace ESP_INTR_FLAG_IRAM with ESP_INTR_FLAG_DEFAULT when you are registering the interrupt. Then the interrupt will be automatically disabled at times when cache is disabled. You will be able to call non-IRAM functions from ISR in this case.
Hi,

Thanks for quick reply. I will check and let you know result for that.
Regards,
Ritesh Prajapati

Who is online

Users browsing this forum: No registered users and 117 guests