Getting Guru Meditation Exception while using Hardware Timer
Posted: 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.
So, We have checked exceptions and found that we are getting last back-trace call as timer_set_alarm_value.
Please let me know if anyone has faced this type of issue or any clue/info to solve this issue without using Hardware Timer.
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;
}
}
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.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:?
Please let me know if anyone has faced this type of issue or any clue/info to solve this issue without using Hardware Timer.