Get pvParameters from task via FreeRTOScpp

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.

  1. The stack used for main is reused for the interrupt stack in some of the more popular ports, so that isn’t available. Also moving the memory requirements from not as easily counted stack usage to easily measured static memory usage is helpful.
  2. In a similar manner, the other place the objects could be placed would be the heap, and again static memory usage is easier to see than heap usage.
  3. Many of the objects rather than being fully global, can be file static (and that file may have minimal actual code) and be passed via pointer/reference into the constructors of the objects that need to know about them.
  4. The objects that do remain as truly global should mostly be the major actors that your system software documentation describes, so the implicit interactions are well documented.
  5. The interactions of these objects should be done via an API implemented in the classes, which is a different type of interaction then having a global struct that random code just peeks and pokes at.