0

I have a specific task routine which performs some operations in a specific order, and these operations handle few volatile variables. There is a specific interrupt which updates these volatile variables asynchronously. Hence, the task routine should restart if such an interrupt occurs. Normally FreeRTOS will resume the task, but this will result in wrong derived values, hence the requirement for restarting the routine. I also cannot keep the task routine under critical section, because I should not be missing any interrupts.

Is there a way in FreeRTOS with which I can achieve this? Like a vtaskRestart API. I could have deleted the task and re-created it, but this adds a lot of memory management complications, which I would like to avoid. Currently my only option is to add checks in the routine on a flag to see if a context switch have occured and if yes, restart, else continue.

Googling did not fetch any clue on this. Seems like people never faced such a problem or may be its that this design is poor. In FreeRTOS forum, few who asked for a task-restart didn't seem to have this same problem. stackOverflow didn't have a result on freertos + task + restart. So, this could be the first post with this tag combination ;)

Can someone please tell me if this is directly possible in FreeRTOS?

Vishnu S
  • 13
  • 6

2 Answers2

0

You can use semaphore for this purpose. If you decide using semaphore, you should do the steps below.

  • Firstly, you should create a binary semaphore.
  • The semaphore must be given in the interrupt routine with xSemaphoreGiveFromISR( Example_xSemaphore, &xHigherPriorityTaskWoken );
  • And, you must check taking semaphore in the task.

    void vExample_Task( void * pvParameters ) {
    for( ;; ) {
    if (xSemaphoreTake( Example_xSemaphore, Example_PROCESS_TIME)==pdTRUE) {

    } } }

parloid
  • 68
  • 1
  • 7
  • Thanks parloid for the response. I understand this mechanism, infact my task is using a binary semaphore and it is on this semTake that the task is blocked, till an interrupt releases the semaphore for the task to continue. But, I did not understand how this would solve my problem. Where should I try to take the semaphore, and block my task? The interrupt which updates my variables may come or may not come, while these variables are being processed. I am looking for a mechanism where the routine has to be restarted if a specific interrupt occurs. – Vishnu S Dec 18 '13 at 16:25
0

For this purpose you should use a queue and use the queue peek function to yield at your volatile data.

I'm using it as I have a real time timer and this way I make the time available to all my task, without any blocking.

Here it how it goes: Declare the queue:

xQueueHandle     RTC_Time_Queue;

Create the queue of 1 element:

RTC_Time_Queue = xQueueCreate( 1, sizeof(your volatile struct) );

Overwrite the queue everytime your interrupt occurs:

xQueueOverwriteFromISR(RTC_Time_Queue, (void*) &time);

And from other task peek the queue:

xQueuePeek(RTC_GetReadQueue(), (void*) &TheTime, 0);

The 0 at the end of xQueuePeek means you don't want to wait if the queue is empty. The queue peek won't delete the value in the queue so it will be present every time you peek and the code will never stop.

Also you should avoid having variable being accessed from ISR and the RTOS code as you may get unexpected corruption.

Damien
  • 1,492
  • 10
  • 32
  • Thanks Damien, but this looks like a good alternative for volatile variables, otherwise I am not sure if this will solve the problem I have described. Here again, I wouldn't know when exactly in the task should I peek the queue. Say I do it while I do my calculations, but what if I get those interrupts after I finish the calculation and before I take action based on this calculation? Hence I am not sure how I can use QueuePeek to resolve this problem. Thanks for your input. – Vishnu S Jan 29 '14 at 08:36
  • I see your problem, I had a similar one where I wanted to have a task restart but I haven't really find a good solution to that. Ultimately you can delete and recreate the task. – Damien Feb 21 '14 at 02:23