Page 1 of 2

esp_timer: timer queue overflow

Posted: Wed Jul 04, 2018 5:07 pm
by jcsbanks
Using the high resolution timer, all is good for periods above a few microseconds.

If I use a period of 0, after a handful of callbacks, I get esp_timer: timer queue overflow

Obviously it is a bit of a waste to setup a timer with a callback with a time of 0, but it is sometimes convenient to save a lot of redesign with the case of 0, and it seems the queue is not getting cleared up fast enough to allow a callback to setup a further timer with a period of 0.

I can see the error comes from xSemaphoreGiveFromISR(s_timer_semaphore, &need_yield) != pdPASS) in esp_timer.c

Here is my timer setup code:

Code: Select all

bool my_set_timer(uint32_t timer_number, uint32_t time_us, void (*callback)(void *), void *params)
{
	//if (time_us==0) time_us=4;
	//stop & delete previous timer
	if (my_timer_info[timer_number].my_timer)
	{
		printf("Timer %d exists - stopping and deleting\n",timer_number);
		esp_timer_stop(my_timer_info[timer_number].my_timer);
		esp_timer_delete(my_timer_info[timer_number].my_timer);
		my_timer_info[timer_number].my_timer=NULL;
	}	

	//timer arguments
	esp_timer_create_args_t my_timer_args;
    my_timer_args.callback = (esp_timer_cb_t)HRT_callback;        //!< esp_timer_cb_t Function to call when timer expires
    my_timer_args.arg = (void*)(&my_timer_info[timer_number]);    //!< void* Argument to pass to the callback
    my_timer_args.dispatch_method = ESP_TIMER_TASK;				  //!< esp_timer_dispatch_t Call the callback from task or from ISR
	char timer_name[10];
	sprintf(timer_name, "ISOTP%d", timer_number);
    my_timer_args.name = timer_name;							  //!< const char* Timer name, used in esp_timer_dump function

	//create timer handle (esp_timer_create(IN,OUT))
	if (esp_timer_create(&my_timer_args, &my_timer_info[timer_number].my_timer)!=ESP_OK)
	{
		my_timer_info[timer_number].my_timer=NULL;
	}
	if (my_timer_info[timer_number].my_timer==NULL)
	{
		printf("Error esp_timer_create!\n");
		return false;
	}
	
	//info for HRT_callback
	my_timer_info[timer_number].callback=callback;
	my_timer_info[timer_number].params=params;

	//start timer
	if (esp_timer_start_once(my_timer_info[timer_number].my_timer, time_us)!=ESP_OK)
	{
		printf("Error calling esp_timer_start!\n");
		return false;
	}
	else
	{
		//printf("esp_timer_start success\n");
		//printf("timer_number %d, time_us %d\n",timer_number,time_us);
		return true;
	}	
}
Here is the callback code:

Code: Select all

void HRT_callback(struct timer_info* base)
{
	//printf("HRT_callback\n");
	if (base->my_timer)
	{
		esp_timer_stop(base->my_timer);
		esp_timer_delete(base->my_timer);
		base->my_timer = NULL;
	}
	else
	{
		printf("Missing timer handle in HRT_callback!\n");
		return;
	}
	if (base->callback && base->params)
	{
		base->callback(base->params);
	}
	else
	{
		printf("Missing callback or params in HRT_callback!\n");
		return;
	}	
}
Given that I am stopping and deleting the timer in the callback, before making it again, it seems there is an asynchronous process to clear up the queue that means a timer cannot be immediately used again? I tried increasing the FreeRTOS timer queue size from 10 to 20 and task priority from 1 to 24 with no change.

I can work around it. I could also perhaps just do it differently without a timer if the timer value is less than 100us (since the valid timer intervals are in units of 100us and the lowest two valid values are 0 or 100us). I am just curious why this happens most of all.

Re: esp_timer: timer queue overflow

Posted: Thu Sep 06, 2018 9:37 pm
by snahmad75
Did esp32 periodic timer callback works for you.

I am getting queue overflow when i setup for 1ms.

but >=10ms do not overflow.

Any idea why.


I need my callback to be get call every 1ms.

Re: esp_timer: timer queue overflow

Posted: Thu Sep 06, 2018 10:04 pm
by jcsbanks
It works well. I use it for periods between 100us and 100ms, and use 1 and 2ms very frequently.

For the original problem posted previously, I just do the work immediately instead of setting a callback of 0.

Re: esp_timer: timer queue overflow

Posted: Thu Sep 06, 2018 10:10 pm
by snahmad75
Do I have delete esp32 timer evey time callback function get called and reset timer callback again?

Re: esp_timer: timer queue overflow

Posted: Thu Sep 06, 2018 10:16 pm
by jcsbanks
I delete them in the callback and never reuse without deletion because I have a state machine that may or may not start the same or other timers with different durations and callbacks, so not sure what will work best for you. The biggest adventure was keeping track of the timer handles, I ended up passing a structure around to encapsulate it all.

Re: esp_timer: timer queue overflow

Posted: Tue Sep 25, 2018 8:48 am
by snahmad75
My use case is below. I am getting timer queue overflow some time. any idea?
Kindly help me I need reliable way to get accurate 1 millisecond timer function callback to perform some task such as led fading and can message time stamp increment. need to solution to avoid queue overflow. I also found I have now two identical esp32 hardware. one shows overflow somtime and one does not. I think it could be I am keep too busy CPU1 which cause this overflow.


esp_timer_handle_t __periodic_timer = nullptr;
static void periodic_timer_callback(void* arg)
{
// perform my tasks.

}

void start ()
{
esp_timer_create_args_t periodic_timer_args;
periodic_timer_args.callback = &periodic_timer_callback;

ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &__periodic_timer));
// The timer has been created but is not running yet

// Start the timers with 1ms
ESP_ERROR_CHECK(esp_timer_start_periodic(__periodic_timer, 1000));

}

void stop ()
{
if (__periodic_timer) {
ESP_ERROR_CHECK(esp_timer_stop(__periodic_timer));
ESP_ERROR_CHECK(esp_timer_delete(__periodic_timer));
__periodic_timer = nullptr;
}

}

Re: esp_timer: timer queue overflow

Posted: Fri Sep 28, 2018 10:11 am
by snahmad75
Still getting this esp timer overflow some time.

It could be due to too many debug logs.
Is this to do with cpu speed mhz settings

I am using latest code ESP-IDF SDK version= 3.2

Have you try latest code.

I am getting this ESP log : "Task Queue is Full" time to time.

Kindly help I am struck.

Re: esp_timer: timer queue overflow

Posted: Fri Sep 28, 2018 11:02 am
by ESP_Sprite
Any chance that whatever you're doing in the timer callback takes longer than your timer interval? The way the timer works is that every time it fires, it pushes an event in the timer queue. A task blocks on this queue and executes the callback every time it sees an event. If your callbacks take longer than the timer period, the queue will fill up because the timer fires more often than the callback can run.

Re: esp_timer: timer queue overflow

Posted: Fri Sep 28, 2018 11:16 am
by snahmad75
Thanks for reply.

I only fade 3/4 leds. It could be that CPU is very busy with other Tasks/Threads. taking all time. I am running in single mode cpu.
WiFi and all threads are using cpu=0. I will investigate more. I need better CPU stats showing.

I guess I can show cpu stats for esp timer as well.

Re: esp_timer: timer queue overflow

Posted: Sat Sep 29, 2018 3:28 pm
by snahmad75
I got this crash/assert now after running my Esp32 firmware for a while.

I am using latest code ESP-IDF 3.2 version. Should I try stable release 3.1.

Kindly do reply. We need esp timer to perform certain tasks such as every one millisecond fade leds to indicate TX and RX data and power leds.


assertion "time_after_timebase_us > s_timer_us_per_overflow" failed: file "C:/Work/Library/esp32/esp-idf/components/esp32/esp_timer_esp32.c", line 232, function: esp_timer_impl_set_alarm
abort() was called at PC 0x400d9717 on core 0
0x400d9717: __assert_func at /home/jeroen/esp8266/esp32/newlib_xtensa-2.2.0-bin/newlib_xtensa-2.2.0/xtensa-esp32-elf/newlib/libc/stdlib/../../../.././newlib/libc/stdlib/assert.c:63 (discriminator 8)


Backtrace: 0x40091078:0x3ffbc4d0 0x4009123b:0x3ffbc4f0 0x400d9717:0x3ffbc510 0x40082f83:0x3ffbc540 0x400817de:0x3ffbc560 0x400d2865:0x3ffbc580 0x400d2927:0x3ffbc5a0
0x40091078: invoke_abort at C:/Work/Library/esp32/esp-idf/components/esp32/panic.c:649

0x4009123b: abort at C:/Work/Library/esp32/esp-idf/components/esp32/panic.c:649

0x400d9717: __assert_func at /home/jeroen/esp8266/esp32/newlib_xtensa-2.2.0-bin/newlib_xtensa-2.2.0/xtensa-esp32-elf/newlib/libc/stdlib/../../../.././newlib/libc/stdlib/assert.c:63 (discriminator 8)

0x40082f83: esp_timer_impl_set_alarm at C:/Work/Library/esp32/esp-idf/components/esp32/esp_timer_esp32.c:340

0x400817de: timer_insert at C:/Work/Library/esp32/esp-idf/components/esp32/esp_timer.c:412

0x400d2865: timer_process_alarm at C:/Work/Library/esp32/esp-idf/components/esp32/esp_timer.c:412

0x400d2927: timer_task at C:/Work/Library/esp32/esp-idf/components/esp32/esp_timer.c:412