xTimerChangePeriodFromISR overhead? BUG?

seagull_kamome wrote on Wednesday, June 20, 2018:

Hi FreeRTOS developer team.
I’m still testing the kernel.

static TimerHandle_t tm;
static TickType_t volatile isr_tick, tm_tick;
static uint32_t volatile flags = 1;

static void my_systick_handler(void) {
	xPortSysTickHandler();
	if (flags == 0) {
		isr_tick = xTaskGetTickCountFromISR();
		BaseType_t woken = pdFALSE;
		xTimerChangePeriodFromISR(tm, 100, &woken);
		//xTimerStartFromISR(tm, &woken);
		flags = 1;
		portYIELD_FROM_ISR(woken);
	}
}

static void tm_callback(TimerHandle_t tmr) {
	tm_tick = xTaskGetTickCount();
}

static void test_task_main(void* args __unused) {
	isr_tick = tm_tick = 0;
	tm = xTimerCreate("TM", 100, pdFALSE, (void*)1, tm_callback);
	TickType_t t1 = xTaskGetTickCount();
	flags = 0;
	vTaskDelay(1000);

	// I expected "t1=0 isr_tick=1 tm_tick=100".
	// xTimerStartFromISR seems oKay, but I got "t1=0 isr_tick=0 tm_tick=193" for xTimerChangePeriodFromISR.
	// what's an extra 93 ticks? why is isr_tick not one but zero?
	configPRINTF("t1=%d isr_tick=%d tm_tick=%d ", t1, isr_tick, tm_tick);
	vTaskDelete(NULL);
}

Why does xTimerChangePeriodFromISR makes extra 93ms?
Is it a unavoidable overhead? or BUG?

rtel wrote on Wednesday, June 20, 2018:

static void my_systick_handler(void) {
xPortSysTickHandler();
if (flags == 0) {
isr_tick = xTaskGetTickCountFromISR();
BaseType_t woken = pdFALSE;
xTimerChangePeriodFromISR(tm, 100, &woken);
//xTimerStartFromISR(tm, &woken);
flags = 1;
portYIELD_FROM_ISR(woken);
}
}

This is not a recommended way of adding code to the systick handler -
please use the tick hook function instead.
https://www.freertos.org/a00016.html

static void tm_callback(TimerHandle_t tmr) {
tm_tick = xTaskGetTickCount();
}

static void test_task_main(void* args __unused) {
isr_tick = tm_tick = 0;
tm = xTimerCreate(“TM”, 100, pdFALSE, (void*)1, tm_callback);
TickType_t t1 = xTaskGetTickCount();
flags = 0;
vTaskDelay(1000);

 // I expected "t1=0 isr_tick=1 tm_tick=100".
 // xTimerStartFromISR seems oKay, but I got "t1=0 isr_tick=0 tm_tick=193" for xTimerChangePeriodFromISR.
 // what's an extra 93 ticks? why is isr_tick not one but zero?
 configPRINTF("t1=%d isr_tick=%d tm_tick=%d ", t1, isr_tick, tm_tick);
 vTaskDelete(NULL);

}

Why does xTimerChangePeriodFromISR makes extra 93ms?
Is it a unavoidable overhead? or BUG?

I will have to set this up to try and replicate it - but either 93ms is
an age, not just a little bit of overhead, so something else is going on
here.

Why did you replace the tick handler?
What other tasks are running?
What is the priority of the Timer task?

rtel wrote on Wednesday, June 20, 2018:

Also - what is the tick frequency and have you validated it is what you
think it is?

seagull_kamome wrote on Thursday, June 21, 2018:

This is not a recommended way of adding code to the systick handler -
please use the tick hook function instead.

I knew it, but thank you. That code I posted is used for only testing.

Why did you replace the tick handler?

Just for test. I’m writing an evaluation report of FreeRTOS for our project
that considering to move into it.
XXXFromISR APIs need any ISR. A systick handler looks handy for a portable
automated test, I thought.

What other tasks are running?
What is the priority of the Timer task?

Logging task at priority 15, Timer task at 15 and that test_task
has priority 2. also Idle at 0. configMAX_PRIORITY is 16.

That Logging task was created based aws_logging_task_dynamimc_buffers.c,
but using a static ring buffer and direct task notifiy instead of malloc/queue.

I had tried to move Logging task’s priority into 14. But no result changed.

Also - what is the tick frequency and have you validated it is what you
think it is?

Tick frequency is 1k Hz. I have no validated it with scope yet.
However, I think it is no big matter, because xTimerStartFromISR gives me
a correct result “t1=0 isr_tick=0 tm_tick=100”.

rtel wrote on Thursday, June 21, 2018:

With the priorities as you have then the logging task could prevent the
task you are taking the times from from executing. Try setting the
logging task to priority 0 so it is lower than the test task. Also, the
time discrepancy is so large I wonder if your logging might be blocking
the system by either disabling interrupts or using semi-hosting?

Sorry if you said already - but which dev board are you using?

rtel wrote on Thursday, June 21, 2018:

I’ve just tried running your exact code and, as expected, got the result you expected to get. Screenshot attached.

seagull_kamome wrote on Thursday, June 21, 2018:

I took a task trace. and, now I understand that using a systick handler is really bad idea when TICKLESS_IDLE enabled. I’m very sory. This is totally my mistake.
I have tried to disable configTICKLESS_IDLE, and got a result I expedted.

Thank you.