how to restart a task?

runfirst wrote on Tuesday, July 09, 2013:

can a task be stopped , then restarted again?
Not just paussed… if yes, how to do so?

rtel wrote on Tuesday, July 09, 2013:

See: http://www.freertos.org/FreeRTOS_Support_Forum_Archive/June_2013/freertos_xTaskRestart_8491693.html

Regards.

runfirst wrote on Tuesday, July 09, 2013:

Hi Richard
I have done so as the post your replied.
Now I am sure one of tasks of my app has problem. However it was ok without FreeRTOS. What I like to move it to FREERTOS is because it can run tasks. That is much better than my old way.

That task is loop method that sending chars by uart to another machine every 120 seconds, and then get feeback to confirm communication is fine. like heart beat of socket.

As you suggested, I need a flag. Telling another task to do the heart beat testing. In other way, it is a timer.

void vTimers( void * pvParameters )
{
/* Block for 1000ms. */
const portTickType xDelay = 1000 / portTICK_RATE_MS;
uint8_t iClive=0;
int S=0;

     for( ;; )
     {
             STM_EVAL_LEDToggle(LED4);
AliveCount++;
if ((AliveCount-(AliveCount/120)*120)==0)
{
                               S=SendStatus(); //sending string to receiver and then get feedback
if (S==0)
{
STM_EVAL_LEDToggle(LED3);
}
else if (S==2)
{
if (ReConnect()==1)  //here is reconnect to the receiver.
{
                                                            STM_EVAL_LEDToggle(LED2);
}
else
{
                                                            STM_EVAL_LEDToggle(LED1);
}
}
                                      else
                                          {STM_EVAL_LEDToggle(LED5);}
}

         vTaskDelay( xDelay );

     }
}

then in method SendStatus(). it is for sending a string to recveiver machine by uart.
int SendStatus(void)
{

      int k=1,j;
Usart_SendString(USART3,“TEST STATU\r\n”);
FB_On(LEDG);
delay(5000);
for (i = 0; i < RxCounter3 && i < 4000; i++) szTemp_ = RxBuffer3;  //USART3_IRQHandler saving the incoming datas to RxCounter3
for (; i < 4001; i++) szTemp = ’ '; //move datas to szTemp buffer
szTemp = 0;
j=0;
while (strstr(szTemp,“Status OK”)==NULL)
{

       delay(3000);
if (j>=10)
{
k=2;
break;
}
j++;
             Usart_SendString(USART3,“TEST STATU\r\n”); //try more times…

}

return k;
}

This code runs well without FREERTOS. However, there are 2 problems when it is moved to FREERTOS.
First problem, the timer is not accurate. I set 120 seconds above, but it sends status request every 4-5 minutes.

2rd, that is big problem. it is crashed after 1 hour to 1 hour and couple minutes.  I guess it should be stack overflow problem, not sure about this yet.
So what I am thinking is move the SendStatus() out of this task to reduce stack size/heap usage, and then make it to another new task. And I want it can be restarted every 120 seconds. Is it better or not?

Thanks a lot for you help!
Best regards
_

rtel wrote on Tuesday, July 09, 2013:

I’m not sure how the code snippet you posted is expected to work.  You say you want it to run every 120 seconds, but you have three different timing methods:

1) vTaskDelay() which will block for 1 second at a time.

2) delay() - I don’t know what this is doing.  How is the delay function implemented?  If it is trying to use the systick then it won’t work.  If it is a null loop delay then that won’t work accurately in a multi-tasking system either.  Why are you not using vTaskDelay() in place of delay()?

3) An alive count which is incremented no each loop.

It looks like you want the LED to toggle every 1 second and SendStatus() to be called every 120 seconds.  Is this correct?  If so then you could use:

void vATask( void )
{
portTickType xTime;
const portTickType xLEDPeriod = 1000 / portTICK_RATE_HZ;

/* SendStatus is called every 120 times around the loop. */
portBASE_TYPE xCallCount = 0;
const portBASE_TYPE xTimeToCall = 120;

    xTime = xTaskGetTickCount();
   
    for( ;; )
    {
        /* Block until 1000ms (1s) after the task last ran. */
        vTaskDelayUntil( &xTime, xLEDPeriod );
       
        /* Toggle the LED here….*/
       
        xCallCount++;
        if( xCallCount >= xTimeToCall )
        {
            /* Its time to call SendStatus(). */
            SendStatus();
            xCallCount = 0;
        }
    }
}

That would restructure your main task, but you also need to restructure the SendStatus function.

When it crashes, and you stop the debugger, what is it doing.  Why do you think it is overflowing the stack?

Regards.

runfirst wrote on Tuesday, July 09, 2013:

From ur code, i can see timer should be accurate. But i dont think it makes much better difference with mine. I will try later. Btw, after taskdelete() , will it free memory also?

runfirst wrote on Tuesday, July 09, 2013:

Im not sure it causes stack overflow. If i mark this function, it last for more than two hours. So i guess that.

runfirst wrote on Wednesday, July 10, 2013:

Hi Richard

I change code as yours. It has same problem, it freeze after 50 minutes to one hour.
If  I mark  SendStatus();, it runs well. So I am sure problem is in  SendStatus()

However, it is very simple function. is there anything else causes this happen?

runfirst wrote on Wednesday, July 10, 2013:

Continued with above

now it is freezed sooner. I guess it is timer more accurate. So seems something increase the memory by time. Is it possible the buffer?

runfirst wrote on Wednesday, July 10, 2013:

When it is stopped, I click on “stop” and see it is sending out uart datas. it is Usart_SendString(USART3,“TEST STATU\r\n”);
failed at :
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)  //—stop here
  {
  }
}

rtel wrote on Wednesday, July 10, 2013:

In which case the error does not seem to be FreeRTOS related.  Information on debugging a hard fault can be found here http://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html.

runfirst wrote on Wednesday, July 10, 2013:

I had read that post before you replied me.
However I dont really understand what it says.
where do I put the code below?:
static void HardFault_Handler( void ) __attribute__( ( naked ) );

/* The fault handler implementation calls a function called
prvGetRegistersFromStack(). */
static void HardFault_Handler(void)

where do I put :void prvGetRegistersFromStack( uint32_t *pulFaultStackAddress )?

when I build it, it gets error.

runfirst wrote on Thursday, July 11, 2013:

That doesnt really make sense…it is quiet simple app. It was running well without OS.