xTaskGetTickCount() in milliseconds

dgoffi wrote on Wednesday, January 18, 2012:

Hi at all,
I am reading the API reference about function xTaskGetTickCount().
What I need is for example somethings like this:
TASK1 -> xTaskGetTickCount() = 10 (milliseconds)
TASK2 -> xTaskGetTickCount() = 11
TASK1 -> xTaskGetTickCount() = 12
TASK2 -> xTaskGetTickCount() = 13
and so on….is it possible???
On the reference I read “The constant portTICK_RATE_MS can be used to calculate real time from the tick rate - with the resolution of one tick period”…
In the FreeRTOS’s portmacro.h file I have portTICK_RATE_MS setted as ( ( portTickType ) 1000 / configTICK_RATE_HZ )
and configTICK_RATE_HZ setted as ( (portTickType) 1000). In this case portTICK_RATE_MS = 1.
Thanks in advance…

Davide

richard_damon wrote on Thursday, January 19, 2012:

You question is unclear as to what you are asking. What do you mean by TASK1 -> xTaskGetTickCount() = 10

You can’t MAKE xTaskGetTickCount have certain values at arbitrary times.

If you mean that while xTaskTickCount() has the value 10, you are running TASK1, and when it changes to 11 you want to switch to TASK2, and when it changes to 12 go back to TASK1, all you need to do is make TASK1 and TASK2 the same priority and if preemption is enabled, and both tasks are ready, and are the highest ready tasks, they will alternate like that.

dgoffi wrote on Thursday, January 19, 2012:

Thanks richard_damon for yuor reply…I am sorry for my unclear question but I have not yet clear ideas about freeRTOS. I start learning it from a few days.

With this image I hope I will be more clear, this is my scenario.

Davide

richard_damon wrote on Thursday, January 19, 2012:

Making both tasks the same priority will cause the alternation to happen as you have shown.

Inside the task, I don’t think you understand how things work.

In you example, count will be set ONCE, before entering the loop, and not updated. Even if you move the xTackGetTIckCount into the loop I am not sure it will do what you want. Execution will start, then get the value of count and run the section with the corresponding y value. When that code completes, you will hit the end of the while loop and restart the loop. If you didn’t use up the full tick, you will execute the SAME piece of code as before. If it went past a tick count, it will go into the next section, changing not at the tick interrupt, but on the beginning of the next while loop.

Also, this code is very fragile, as if either task does anything to block, like wait on a queue, FreeRTOS will switch to the other task even though you haven’t reached “its tick”.

What you really need to do is think about what operations need to be done and when first, and then figure out how to place those operations into tasks. Rarely do operational requirements have something like “Do operation 1 continuously for 1 ms, then at the 1 ms time mark change to doing operation 2, and at the next time mark go to operation 3”.

dgoffi wrote on Thursday, January 19, 2012:

Thanks again for your reply.
In the while loop I forgot the update statement of count variable.
Can you make me please some example of the xTaskGetTickCount() use???
And 1 tick how many seconds is???

Davide

rtel wrote on Thursday, January 19, 2012:

The tick count is incremented on each tick interrupt.  xTaskGetTickCount() does nothing more than return the current tick count.  It does not effect scheduling, or the task calling xTaskGetTickCount() in any way.

The tick frequency is set by configTICK_RATE_HZ in FreeRTOSConfig.h.  FreeRTOSConfig.h settings are described here:
http://www.freertos.org/a00110.html

If you set configTICK_RATE_HZ to 1000 (1KHz), then a tick is 1ms (one one thousandth of a second).  If you set configTICK_RATE_HZ to 100 (100Hz), then a tick is 10ms (one one hundredth of a second).  Etc.

Regards.

richard_damon wrote on Thursday, January 19, 2012:

Where I use xTaskGetTickCount is where I want to see how long it has been since a certain event.  One example of this is if one tasks detects an anomalous condition, it may want to inform another task about it. If we detect the condition again shortly thereafter, we don’t want to send another report, or we may fill the communication queue as the second task is still working on correcting the condition. If we get another problem much later we do want to report it.

One way to do this is when we report we do a

lastErrorReport = xPortGetTickCount();

and then when we detect the problem, we can do a test like

if( (xPortGetTickCount() - lastErrorReport) > minPeriodinTicks) { …

Note that you need to be careful how you do the math, as the tick counter will wrap, by doing the math new tick-oldtick you get a measure of the time since the event happened. You can NOT do if newtick > targettick as the wrap around can make this have problems.

You do have a small problem with the wrap around  in that in this case if a second error occurs exactly 1 (or 2 or 3, etc) wraps of the timer from the last report, the report will be delayed by up to the timeout period. Normally this isn’t that big f a problem, you can set the option to make the TickType be an unsigned long instead of an unsigned int if it is more problematical.