esp_timer: timer queue overflow

jcsbanks
Posts: 305
Joined: Tue Mar 28, 2017 8:03 pm

esp_timer: timer queue overflow

Postby jcsbanks » Wed Jul 04, 2018 5:07 pm

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.

snahmad75
Posts: 445
Joined: Wed Jan 24, 2018 6:32 pm

Re: esp_timer: timer queue overflow

Postby snahmad75 » Thu Sep 06, 2018 9:37 pm

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.

jcsbanks
Posts: 305
Joined: Tue Mar 28, 2017 8:03 pm

Re: esp_timer: timer queue overflow

Postby jcsbanks » Thu Sep 06, 2018 10:04 pm

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.

snahmad75
Posts: 445
Joined: Wed Jan 24, 2018 6:32 pm

Re: esp_timer: timer queue overflow

Postby snahmad75 » Thu Sep 06, 2018 10:10 pm

Do I have delete esp32 timer evey time callback function get called and reset timer callback again?

jcsbanks
Posts: 305
Joined: Tue Mar 28, 2017 8:03 pm

Re: esp_timer: timer queue overflow

Postby jcsbanks » Thu Sep 06, 2018 10:16 pm

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.

snahmad75
Posts: 445
Joined: Wed Jan 24, 2018 6:32 pm

Re: esp_timer: timer queue overflow

Postby snahmad75 » Tue Sep 25, 2018 8:48 am

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;
}

}

snahmad75
Posts: 445
Joined: Wed Jan 24, 2018 6:32 pm

Re: esp_timer: timer queue overflow

Postby snahmad75 » Fri Sep 28, 2018 10:11 am

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.

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

Re: esp_timer: timer queue overflow

Postby ESP_Sprite » Fri Sep 28, 2018 11:02 am

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.

snahmad75
Posts: 445
Joined: Wed Jan 24, 2018 6:32 pm

Re: esp_timer: timer queue overflow

Postby snahmad75 » Fri Sep 28, 2018 11:16 am

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.

snahmad75
Posts: 445
Joined: Wed Jan 24, 2018 6:32 pm

Re: esp_timer: timer queue overflow

Postby snahmad75 » Sat Sep 29, 2018 3:28 pm

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

Who is online

Users browsing this forum: No registered users and 93 guests