Hi,
Is it possible to obtain pvParameters of a task given the task handle?
I want to get the class object pointer (this) from a FreeRTOScpp task object.
regards,
Hi,
Is it possible to obtain pvParameters of a task given the task handle?
I want to get the class object pointer (this) from a FreeRTOScpp task object.
regards,
Have you had a look at Task tags?
The functionality of the tags is left to the application developer, so there’s nothing stopping you from setting the tag to ‘this’ from within the task constructor…
Just a thought. Might be completely of the mark too…
In principle it is possible, but I would not recommend getting deep into the port code. Too technical and too dependent on the port layer.
Look at pxPortInitialiseStack()
and you will see that the pointer pvParameters
is pushed onto the stack, and it will be popped into a register, e.g. R0 in case of ARM_CM4F
.
This stack will be preserved as long as the task is active.
I understand your question about C++. Can not you use a fixed C function that is used for all tasks?
void vInitialTask( void *pvParameters )
{
CTaskHandle *pxHandle = ( CTaskHandle * ) pvParameters;
pxHandle->vTaskCode();
}
My FreeRTOScpp wrappers do not do anything specifically to map the handle to the object that runs the task, and FreeRTOS doesn’t store that parameter anywhere either (it gets placed on in the stack frame of the call, and that is it).
As SergentSloGin says, you could use something like the Task Tags feature to store the pointer to the Task class in the TCB, so you could do the lookup.
Frankly, its an operation that I haven’t needed to do (go from a FreeRTOS handle to a class pointer) as my code rarely deals with handles except within the wrappers.
Yes, I agree with avoiding handles, but I also would like to avoid globals and tags.
Basically I wanted the ownership of a FreeRTOScpp object e.g. Queue, to belong to the relevant/logical task e.g. commsTask creates and owns txQueue. Rather than use globals, tags or setters/getters at the start of the day (main) for use by other tasks.
Since you are passing the object pointer to the task so it can call the task member function, I thought it would be useful for another task to query it, thereby accessing objects such as queues etc created by that task object.
What I find is that I don’t work with task handes, so other tasks don’t end up with handles to tasks to need to get to the class it represents. Maybe it is because I don’t think of the system as a collection of tasks that might have classes, but the system as a collection of objects of various classes, some of which just happen to have tasks.
My programs are based on the various objects interacting with other objects, and it is an implementation details that there is a class behind it, or that the interaction is done via a FreeRTOS object like a queue. Yes, some classes are very overtly a task and are named in that way, and some interactions are fairly obviously going to use something like a queue, but many times the way the action happens is not overtly tied to some FreeRTOS behavior.
My general structure of a program is that most of the major operating objects, which includes probably 99% of all tasks are created as global objects (as well as objects representing the major system devices). Most Queues, Semaphores, Mutexes and the like, are member variables of the class that deals with them (and generally not a public member). The class provides member functions to interact with other objects that want to ‘talk’ to it, and the fact that this function uses a FreeRTOS object is an implementation detail.
My main function is often, just a call to start the scheduler, the whole system has been created in pre-main constructors, with order controlled by order in the master definition file or with pragmas for devices.
Thankyou Richard.
I thought about my app structure. While my project is a collection of objects, some of which make use of RTOS objects, I was avoiding creating global objects, including device specific, at the start of the day. I was indeed being too RTOS centric in my thinking.
A simple redesign of my object creation and inter-object communications is all that was required.
The concept of trying to avoid the over use of globals is a good practice when done with reason and understanding and not blindly. I have seen code where to avoid the ‘global’ they pack all the previous global variables into a single structure and pass a pointer to that to everything, which precisely follows the ‘rule’ but totally ignores the principle.
The basic ideal is that you want as much as possible to make what interacts with what explicit rather than hidden by the use of globals.
Under FreeRTOS there are a few things that push us to wanting a few more globals than what you might otherwise want.