Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

Return from task

Posted by qyw on August 30, 2015

I use some code which implements tasks that may return. This code should not be changed, should stay portable. Will FreeRTOSv8 delete task automatically after it returns?

If not Here is old topic from FreeRTOS Support Archive. > you can place the return address that is on the inital stack (setup when the task is created) to jump to the delete function. Then it would happen automatically which is ok as long as this is what you expect to happen.

How can I implement this idea?

Another idea I can create wrapper function:

struct delegate { 
    void(*task)(void*);
    void *args;
};
task_wrapper( struct delegate *task )
{
    task->task( task->args );
    vTaskDelete( NULL );
}
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio)
{
    sys_thread_t createdTask;
    struct delegate de = { thread, arg };  // created on stack. It may fail one day. Use malloc, or static...
    int result;
    result = xTaskCreate( task_wrapper, name, stacksize, &de, prio, &createdTask );
    if( result == pdPASS ){
        return createdTask;
    }
    return NULL;
}

but I think i is not good idea.


Return from task

Posted by rtel on August 30, 2015

Which port are you using?


Return from task

Posted by richard_damon on August 30, 2015

FreeRTOS currently (as far as I know) does not spend the resources to make it so that returning from a task causes it to automatically be deleted. Just jumping to the vTaskDelete is NOT enough, as you still need to give vTaskDelete a parmater of 0 to make it delete the current task, thus it would require adding several words onto the stack.

Also, most tasks do not just run and return, and adding a vTaskDelete(0) at the end, or wrapping the task function with a function that calls the task function and then vTaskDelete isn't that bad of an option for the cases you need this behavior. I would say that less than 1% of the tasks I have written would want to terminate themselves, and thus benefit from this, by far the vast majority still have something to do, and after finishing their task, go back and wait to be tasked again. This means that the couple of words that would need to be added to EVERY tasks stack is a lot more expensive then the overhead of the wrapper (and adding vTaskDelete(0) at the end of the task is virtualy free, just a few locations of program space).

I suppose this comes from the basic idea of needing strong guarentees of operation, and the only time I can see wanting to use vTaskDelete is if you also create tasks after startup, which becomes a requirement to dynamically allocate memory at run time for something critical (unless the task isn't really important). I find it much better to instead of creating and destroying tasks, to convert this into a set of tasks to handle all the needs that might come up.

I don't quite understand how not adding vTaskDelete(0) to the end of the function makes it more portable? Do you really have a function that naturally takes a single void* parameter that also need to do NO other syncronization or communication with other tasks?

One big result of doing something like that is the task will most likely need to set some global flag that it has finished which some other task needs to poll to determine that it is done. If the task was blocked by being lower priority, it might as well have just called the function instead of starting a task.


Return from task

Posted by qyw on August 31, 2015

Which port are you using? CM4-F


Return from task

Posted by rtel on August 31, 2015

Try the following:

1) Define a function as follows:

void vDeleteCallingTask( void )
{
     vTaskDelete( NULL );
}

2) Add the following to FreeRTOSConfig.h

extern void vDeleteCallingTask( void );
#define configTASK_RETURN_ADDRESS vDeleteCallingTask

Regards.


Return from task

Posted by qyw on August 31, 2015

It would be cool. But I cannot find any reference to configTASK_RETURN_ADDRESS in FreeRTOSv8.2.2 sources. I am afraid of function will not be called.


Return from task

Posted by qyw on August 31, 2015

Thank you for this short lecture. I agree with you in most cases.

...that less than 1% of the tasks I have written would want to terminate themselves..

I give an example:

sockfd = socket(AF_INET, SOCK_STREAM, 0);
if( sockfd < 0 ){
    // Failed. Now task is worthless.
	debugf("create socket failed\n");
	return;  // from task
}

I don't quite understand how not adding vTaskDelete(0) to the end of the function makes it more portable?

vTaskDelete is not understandable by other OSes. That part of code works under RT-Thread. I have added vTaskDelete(), but I would like to retain compability in future.


Return from task

Posted by rtel on August 31, 2015

It is used in the port.c file for the Cortex-M port. Did you try it?


Return from task

Posted by richard_damon on September 1, 2015

Is that task FOREVER worthless? That would see to imply that if the task can't ever get a socket again, than neither will the whole device you are part of (otherwise it could be better to have the task block until there is another need to try to get a socket and then retry).

Also, for the return to be the actual return from task implies that THIS FUNCTION is the task function, so it has been decided that void task(void* parm) is a "portable" as is assuming that a return from a task is portable for killing it (and as you have found it isn't).

One solution is to make the actual task function something that calls this function and can do the vTaskDelete(0) after it returns. A second is to add a "OS Portability Layer" into the function and call a function something like taskExit() just before the return. taskExit() can be empty for RT-Thread, and call vTaskDelete(0) in FreeRTOS and do whatever else is needed in the next OS that you convert to.

A second major difference looks to be the types of things we do. This application looks to be a "web" based device that is responding on a "best effort" to answer requests. I presume best effort as I suspect that you are allocating a new task for every connection, and if you run out of memory to start the task you just fail. Almost everything I do has firmer requirements that MUST be meet or the device can be considered failed. For something like this, I would have a requirement that I must be able to handle say 4 simulatinous connections, so I would create a pool of 4 tasks sitting on a request queue. (If I have the memory, I might setup a 5th task to have some slack on the requirements). I rarely allocate ANY dynamic memory after the unit finishes startup.


Return from task

Posted by qyw on September 1, 2015

There is no configTASK_RETURN_ADDRESS in FreeRTOSv8.2.2/Source/portable/RVDS/ARM_CM4F/port.c Function vDeleteCallingTask compilies as unused.


Return from task

Posted by rtel on September 1, 2015

I don't think you mentioned you were using RVDS before, I was looking at line 145 in https://sourceforge.net/p/freertos/code/HEAD/tree/tags/V8.2.2/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c

In the RVDS version the return address is hard coded to prvTaskExitError(). You could make that a week symbol so you can override it, or update the file so it can be overridden using the pre-processor as per the GCC version.


Return from task

Posted by qyw on September 1, 2015

Thank you.


Return from task

Posted by qyw on September 6, 2015

Thank you Richard. I ask you to write a short article-post about How to write and manage proper tasks for socket-style network app (like ftp server), advisable with code snippets. Here I've found LwIP apps. Some of them I'd like to port to FreeRTOS+FATFS with backward compability.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS