Stop timer, delete timer and free resource

Hello,

is it save to do the following:

StaticTimer_t *buffer = ...; // Heap allocated. Short lifetime. Could also be on the task stack.

xTimerCreateStatic(..., buffer);
xTimerStart(buffer, 100);
// Do stuff.
// ...
// Timer not needed anymore.
xTimerStop(buffer, 100);
xTimerDelete(buffer, 100);
delete buffer;

Is it guaranteed, that all timer commands are processed before deleting the buffer?

The StaticTimer_t contains an intrusive linked list:

If the StaticTimer_t buffer is deallocated, freeRTOS cannot access the memory any longer. How is this ensured since all timer functions are pushed to a queue and not processed immediately?

Thank you in advanced!

When those items are pushed onto the queue, the Timer task will wake up and remove and process those items. If the timer task has a higher priority then your current task (which is normal but not required) then I think they will get done before your task runs. This also assumes that no timer callback (or pended function) blocks for any reason (which they are not supposed to do).

I would first say, why are you creating your own ‘static’ buffer dynamically, instead of using the plain dynamic creation function, which wouldn’t have this issue.

Thank you. A coworker of me ran into endless hangs/hard fault because of this.

I will try to reproduce this issue by my own (next year).

We are using C++ so a timer is wrapped in a class object. Following RAII, the constructor creates the timer and the destructor stops and delete the timer. Because we disabled heap allocation in freeRTOS, we use the static timer. Mutex, semaphore, queue, task etc. are all construct/destruct in the same fashion.

E.g. we use a timer to retry operations for a given time, until we break.
E.g. trying to get an acknowledgement from an I2C device. The timer only live in the function scope of i2c::get_acknowledge(time to wait).

As long as the Timer Task is higher priority than any task that does this, and no timer callbacks block, that should work. The non-blocking is important and easy to miss.

Personally, I might make the timer be a member of the i2c object created in the constructor of the i2c driver and destroyed when the destructor of the driver is called (likely never).

Thank you. I will look into this.

Your suggestion is correct. My coworker already applied these changes to our code base.

I debugged through the timer.c code and exactly what you wrote in your first post happend.

So after investigating further, we found the issue: they used blocking methods inside the timer task… ouch.

Thanks for your help. :sunny: