Hans Søndergaard (HSO) wrote:
 > The rt_task_start has the following signature:
 > 
 > int rt_task_start (RT_TASK * task, void(*)(void *cookie) entry, void * 
 > cookie);
 > 
 > but I have not been able to find any example where the cookie parameter is 
 > not NULL.
 > 
 > I am programming an example, where the entry function need some parameters 
 > (five).
 > 
 > Can someone tell me how to do that?

you could pass a pointer to a structure containing the five parameters
as a cookie. If you want to allocate the structure on stack, you should
take care of synchronizing the starting thread with the thread which
calls rt_task_start, using, for instance, a semaphore. For instance:

struct five_parms {
        unsigned parm1;
        int parm2;
        void *parm3;
        long long parm4;
        int parm5;
};

RT_SEM five_parms_done;

void task_entry(void *cookie)
{
        struct five_parms *parms = (struct five_parms *) cookie;
        unsigned parm1;
        int parm2;
        void *parm3;
        long long parm4;
        int parm5;

        parm1 = parms->parm1;
        parm2 = parms->parm2;
        parm3 = parms->parm3;
        parm4 = parms->parm4;
        parm5 = parms->parm5;

        rt_sem_v(&five_parms_done);

        /* Your code here. */
}

void some_other_function(void)
{
        struct five_parms parms;
        RT_TASK task;
        /* Your code here. */
        parms.parm1 = 12;
        parms.parm2 = -42;
        parms.parm3 = NULL;
        parms.parm4 = 20000000000LL;
        parms.parm5 = 1;

        rt_task_start(&task, task_entry, &parms);
        rt_sem_p(&five_parms_done, TM_INFINITE);
}

If you plan to routinely pass 5 arguments to all the tasks you
create, you can go one step further by defining your own wrapper of
rt_task_start. For instance:

typedef void entry_5parms(unsigned, int, void *, long long, int);

struct five_parms {
        unsigned parm1;
        int parm2;
        void *parm3;
        long long parm4;
        int parm5;
        entry_5parms *entry;
};

RT_SEM five_parms_done;

void task_trampoline(void *cookie)
{
        struct five_parms *parms = (struct five_parms *) cookie;
        entry_5parms *entry;
        unsigned parm1;
        int parm2;
        void *parm3;
        long long parm4;
        int parm5;

        parm1 = parms->parm1;
        parm2 = parms->parm2;
        parm3 = parms->parm3;
        parm4 = parms->parm4;
        parm5 = parms->parm5;
        entry = parms->entry;

        rt_sem_v(&five_parms_done);

        entry(parm1, parm2, parm3, parm4, parm5);
}

rt_task_start(RT_TASK *task, entry_5parms *entry, unsigned parm1, 
              int parm2, void *parm3, long long parm4, int parm5)
{
        struct five_parms parms;
        RT_TASK task;
        int err;

        /* Your code here. */
        parms.parm1 = parm1;
        parms.parm2 = parm2;
        parms.parm3 = parm3;
        parms.parm4 = parm4;
        parms.parm5 = parm5;
        parms.entry = entry;

        err = rt_task_start(task, task_trampoline, &parms);

        if (!err)
                rt_sem_p(&five_parms_done, TM_INFINITE);

        return err;
}
            
I have been lazy, and not checked all the return values of all xenomai
services, which real code should do. Also note that I did not show the
initialization of the semaphore, but real code needs that too.

-- 


                                            Gilles Chanteperdrix.

_______________________________________________
Xenomai-help mailing list
Xenomai-help@gna.org
https://mail.gna.org/listinfo/xenomai-help

Reply via email to