Quality RTOS & Embedded Software

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




Loading

Initializing local variables

Posted by Marcel van Lieshout on June 25, 2013
I must be overlooking something (again). I have several functions using local (= on the task's stack) variables. What is the best way to initialise these at first use(where needed).

Without an RTOS, one would simply declare the variables-to-be-initialised-once as static, but this doesn't work when multiple tasks are using the function re-entrantly.

I was thinking about setting some flags as TaskTag. But maybe there is a simpler way?

RE: Initializing local variables

Posted by pcalton on June 25, 2013
If you have multiple tasks calling a function and you expect that function to operate using the data for the calling task then you need to give the function some method of finding the correct data to use.

There are many different ways to accomplish what I think you are asking about. Which method you use determines how the data should be initialized.

example: You could declare the data on the task stack and pass the function a reference to the data

void myFunc(uint32_t* pdata)
{
uint32_t data_to_use = *pdata;
}

void myTask(void *pvParameters)
{
uint32_t taskdata = 123;
// alternatively pass in the initial value via pvParameters
uint32_t taskdata2 = *((uint32_t*)pvParameters);
while(1)
{
myFunc(&taskdata);
}
}

RE: Initializing local variables

Posted by Marcel van Lieshout on June 25, 2013
Yes, but passing a pointer down to a subsubsubsub...subfunction is quite cumbersome.

RE: Initializing local variables

Posted by Richard Damon on June 26, 2013
One option to avoid having to pass it everywhere would be to use vTaskSetApplicationTaskTag to store the pointer to the data in the TCB and xTaskGetApplicationTaskTag to get the pointer later without needing to pass it everywhere. (remember you can use NULL as id of the current task).

RE: Initializing local variables

Posted by Marcel van Lieshout on June 26, 2013
Yes, I found that out already (see first post ;) ), but was looking for an easier way to define some Task Local Storage. Perhaps a definable amount of stackspace with a volatile global pointer to it that is set at task switch. With proper warnings to access this storage only from the running task, not from any isr.

RE: Initializing local variables

Posted by Richard on June 26, 2013
I'm not really sure what this thread is about. If each task has its own stack variables then they can be initialised when they are declared, and each task has its own copy.

With regards to thread local storage, I was considering this just this morning in relation to another feature request (Newlib re-entrancy). I'm not convinced of its usefulness yet though, so if you have a compelling use case for it let me know.

Regards.

RE: Initializing local variables

Posted by Marcel van Lieshout on June 26, 2013
But when you initialize a variable in that way in a common subsubsub-function (not the never-ending-task-function), the init takes place each time the function is entered. Normal alternative would be to declare the local variable as static to have it initialized just once. But once-per-task is a different matter.

RE: Initializing local variables

Posted by Richard on June 26, 2013
Ok - understand. You want a function scope variable that maintains its value between calls, but on a per task basis.

Regards.

RE: Initializing local variables

Posted by Marcel van Lieshout on June 26, 2013
Correct. Accessible from any point at any time. Tasklocal. With minimal overhead and no protection.

I can malloc() a block and put it's pointer in TaskTag, but I was wondering if there is an easier way without having to call GetTaskTag each time this subsubsubfunction executes. It are high-use functions and I want to avoid the overhead involved with GetTaskTag.

RE: Initializing local variables

Posted by Richard on June 26, 2013
Well the way thread local storage normally works, in systems like Windows and Unix, is to have three functions. The first function assigns a key to a malloced block. The second returns a pointer to the malloced block when you pass it the key. The third frees the block and key. So that is not really more efficient that using the TaskTag value anyway.

Regards.

RE: Initializing local variables

Posted by Marcel van Lieshout on June 26, 2013
Then TaskTag it is.

Thanks all! :)

RE: Initializing local variables

Posted by Richard Damon on June 26, 2013
To get true "Task Local Storage", would require a compiler that supports it, as it becomes a new storage type distinct from global/automatic, so is a language issue. This would typically be implemented with a method similar to the TaskTag where the pointer is part of the context that is saved for each task.

IF your compiler provides for it, there should be in the documentation, instructions for how to connect it up to your RTOS, which would then use the set/get task tag operations. This documentation will likely also provide instructions for other connections to make the library thread safe.

Without direct support for it, you can fake it by having those functions that need it set a pointer to a struct type from getTaskTag (where the struct defines those variables that are part of the Thread Local Storage).


[ 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