How can I achieve this?

kuku2010 wrote on Thursday, June 28, 2012:

Two threads, one needs to run at the highest possible frequency, but 90% of the time it has nothing to do, taking only a fraction of the tick. If it has nothing to do, I would like to suspend it until next tick, and let the second thread to use up the remaining time of the current tick.

When the next tick comes in, the first thread gets back to work…. repeating the cycles

This way,  the higher priority task can run at the highest frequency

Thanks for any pointer!

richard_damon wrote on Thursday, June 28, 2012:

First, it sounds like the first task needs to be set to the highest priority in your system. Then, the task just needs to call vTaskDelay(1) to delay until the next tick.

A better question comes, is there a way you can set a semaphore when more work is available (can you get an interrupt when it happens and have an ISR give the semaphore), if so, then have the first task wait on a get for that semaphore, then you don’t need to wait for the next tick, but it will run immediately.

kuku2010 wrote on Friday, June 29, 2012:

I was taking the first approach before posting the question, but I didn’t like the idea of vTaskDelay(1), meaning the highest frequency for task 1 is only 1/2 of the tick frequency.

semaphore is not easy since i haven’t found a good sport in ISR to put it in

Any other option?

anonymous wrote on Friday, June 29, 2012:

Why do you assume it would only run at 1/2 the tick frequency?  From what I see, it would run at exactly the tick frequency.

richard_damon wrote on Saturday, June 30, 2012:

vTaskDelay(1) delays till the next tick. In general a call to vTaskDelay(n) waits for n ticks to happen before the task is rescheduled, since you might be part way through the current tick, it cause a delay of between n-1 and n ticks in duration (and thus a vTaskDelay(1) could delay for almost 0 time, if the tick interrupt occurs just after the call is processed). The task needs to be the highest priority, or their could be additional delay imposed due to higher tasks running.

I would really suggest looking again at the semaphore. Note that it is ok for the interrupt to give the semaphore multiple times if that makes the code significantly easier.

kuku2010 wrote on Monday, July 02, 2012:

Considering the nature of my project, I’d rather see task 1 to be paced in a timely fashion, thus semaphore may not work even I can issue it from ISR.

As for the vTaskDelay (1), my understanding was at tick 1, task1 ran for 1/f ticks, then it calls for vTaskDelay (1), so it will not come back to the ready state until 1+1/f, meaning it will miss the second tick. Am I right?

anonymous wrote on Monday, July 02, 2012:

So maybe the following will solve your problem:
Make your Task 1 being the highest priority task in the system. Task 1 should block on waiting for a semaphore with for example xSemaphoreTake function. Once the semaphore is given, Task 1 wakes, does its job and blocks again waiting for the semaphore.

If you want your task to be run in timely manner and you think that waking Task 1 with system tick frequency is suitable, use Tick Hook Function and give the semaphore from void vApplicationTickHook( void ) function. Please note that this function needs some configs to be set and runs in interrupt context. More details can be found in http://www.freertos.org/a00016.html

Hope that helps,
Adam

anonymous wrote on Monday, July 02, 2012:

As for the vTaskDelay (1), my understanding was at tick 1, task1 ran for 1/f ticks, then it calls for vTaskDelay (1), so it will not come back to the ready state until 1+1/f, meaning it will miss the second tick. Am I right?

I dont belive this is right. As Richard said in post 5., vTaskDelay(1) could potentially delay almost 0 time.

kuku2010 wrote on Monday, July 02, 2012:

thank you, richard_damon, adam and https://www.google.com/accounts

If "vTaskDelay(1) could potentially delay almost 0 time. ", shouldn’t it be renamed vTaskDelay(0)?

If vTaskDelay(1) indeed guarantee task 1 to be called every tick, I would avoid semaphore

rtel wrote on Monday, July 02, 2012:

You have the resolution of one tick.  Calling vTaskDelay( 1 ) will delay for nearly an entire tick period if it is called immediately after the last tick interrupt, or practically no time at all if it is called immediately before the next tick interrupt.  You cannot have fractions of a tick.

vTaskDelay( 0 ) is equivalent to taskYIELD().

Generally, I don’t think it is a good idea to have a task run every tick, unless you have a slow tick rate.  It sounds like a candidate for code that would do better in a timer interrupt routine.

Regards.

kuku2010 wrote on Thursday, July 05, 2012:

richardbarry, thanks for your explanation!