This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Task class



I'm trying to create a class framework around tasks with the task function being a member function of a class. 

//being debugged so ignore any syntax or formatting errors in sprintf

class AppTask {
private:
    /**
    * Task handle.
    * Within SYS/BIOS tasks are identified by their task handle.  This variable maintains the private handle that is accessible through the \sa get_taskHandle function
    */
    Task_Handle _taskHandle;
    Error_Block _eb;
    char * _taskName;
protected:
    extern "C" Void taskFxn(UArg a0, UArg a1);
    Void systemLog(char *logMsg);
public:
    AppTask(char * taskName);
    virtual ~AppTask();
    Task_Handle get_taskHandle(Void);
    Void get_eb(Error_Block * eb);
    char * get_taskName(Void);
};

AppTask::AppTask(char * taskName) {
    int i;
    char holdBuf[128];
    Error_init(&_eb);
    _taskHandle = Task_create(taskFxn, NULL, &_eb);
    if (_taskHandle == NULL) {
        sprintf(holdBuf,"AppTask::AppTask Failed to create task %s\n",taskName);
        systemLog(holdBuf);
    }
    else
    {
        i = strlen(taskName);
        _taskName =(char *)malloc(i);
        memcpy(_taskName,taskName,i);
        sprintf(holdBuf,"AppTask::AppTask Task name: %s Handle: %d",taskName,_taskHandle);
        systemLog(holdBuf);
    }
}

AppTask::~AppTask() {
    // TODO Auto-generated destructor stub
    char holdBuf[128];
    Task_delete(&_taskHandle)
    sprintf(holdBuf,"AppTask:~AppTask Task %c (%i) destroyed.",_taskName,(int)_taskHandle)
    free(_taskName);
}

Void AppTask:: systemLog(char * logMsg)
{
    System_printf("%s",logMsg);
}
Task_Handle AppTask:: get_taskHandle(Void)
{
    return _taskHandle;
}
Void AppTask:: get_eb(Error_Block * perrorBlock)
{
    memcpy(perrorBLock,&_eb,sizeof (Error_Block));
}
char * AppTask:: get_taskName(Void)
{
    return _taskName;

}

Void AppTask:: taskFxn(UArg a0, UArg a1)
{
    while(1) Task_sleep(10);
}

Task_create does not like being passed a cpp class function pointer.  Any suggestions?

  • Andrew,

    I don't know if this should work or not, but some questions...

    What happens when you call Task_create()?  Do you get a NULL handle returned, or is an error thrown?  

    When is the constructor calling Task_create() being invoked?  This needs to be after the Task module has been started up (within SYS/BIOS' module startup sequence) which usually happens before constructors are called during startup, before main().  But this can vary on some device families.  What device are you running on?

    Scott

  • Right now this entire design is till in the concept stage.  I may move task creation to a member function of the class and invoke it when the system is ready.  I can't get the code to compile as it does not like the fact that the task function is a member function of a class.  I gotta fix that first, then I can move forward.  From what I've read you have to declare the function in an extern "C"  block.  I can't find an example so I'm poking around blind on how to do this.

    Right now I have nothing carved in stone.  I have a concept in my head on how I would like a class to encapsulate a task.  I just gotta figure out how to do it.

  • Andrew,
    can you post the complete error message? There are type checks for functions that you pass to Task_create, and extern "C" might not be enough to make the signature of taskFxn compatible. 

  • Andrew, did you ever get this to work? I am headed down the same path. We are coming from a project that had a C++ "OS" and the TIBios does not. So I would like to port the code by creating object for items in the TIBios.
  • Hi


    Member functions cannot have C linkage (C linkage specifications for member functions are simply ignored). You need to make taskFxn a global function, ideally static so that it is local to the translation unit (namespaces won't work). The idiomatic way is to pass a pointer to your class object as a "user" or "context" parameter, unless the callback mechanism doesn't provide such a parameter, in which case it is broken anyway. For tasks, you have two such parameters, "arg0" and "arg1", so you can choose "arg0":

    class MyTask
    {
        [...]
      public:
        void Run();
        [...]
    };
    
    extern "C" {
      void taskFxn(UArg arg0, UArg arg1)
      {
        MyTask *task = reinterpret_cast<MyTask*>(arg0);
        if(task)
        {
          task->Run();
        }
      }
    }

    You would then need to pass Task_Params to Task_create and set the arg0 member of that parameter struct to a valid pointer to a MyTask object.

  • Thanks this should help. Can I place the TSK_Create in the constructor of the MyClass? I am trying to mimic a Object Oriented OS that we used to use. We would simply derive from the Task Class and the virtual "run' function would be called. Or did place the TIBios call some place else?
  • Edwin McKay said:
    Thanks this should help. Can I place the TSK_Create in the constructor of the MyClass? I am trying to mimic a Object Oriented OS that we used to use. We would simply derive from the Task Class and the virtual "run' function would be called. Or did place the TIBios call some place else?

    That depends a lot on your use case. I don't think I would put the call into the constructor, for the following reasons:

    1. If you compile without exception support, there's no way to report an error.
    2. If you don't carefully restrict how instances of your task class are created, you might end up with temporaries calling TSK_Create.
    3. You would be coupling your task abstraction to a concrete BIOS implementation, which may or may not be a bad thing.

    I think I would apply the strategy pattern to provide the task with the platform-dependent functions, if I needed any.

    In any case, you will have to pay close attention to lifetime management of the task object. If you can use shared_ptr (or some alternative implementation), that will probably make your task (no pun intended) easier.