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
[email protected]
https://mail.gna.org/listinfo/xenomai-help