[etherlab-dev] PdServ library
Richard Hacker
ha at igh.de
Thu May 19 01:12:24 CEST 2016
On 14.05.2016 06:11, Philippe Leuba wrote:
> Some updates with the latest release:
> > - pdserv_parameter allows defining a callback to have a chance to
> modify data before copying it, is the updated value expected to be
> reported back to Test Manager ?
> We are able to do it by modifying the 'const src' parameter in the callback
Hmm, that may be possible, but was not intended to be used like that.
The intended use case is for example to change a scaling or an offset
between the "outside world" (aka TestManager) and the cyclic task,
albeit very rare.
Another use case is a set of dependent parameters that are parameterized
by a single value. For example, if you have a many pole filter where you
want to change a frequency using a single parameter and calculate the
coefficients all in one go (otherwise your filter may explode).
The heaviest use case, however, is parameter locking, as explained below.
>
> > - pdserv_event_set allows setting and resetting an event, like a
> state. How to deal with a punctual event, if we set it and reset it
> immediately, it seems not to be sent ?
> Both are now sent, but Test Manager displays both, the second one
> without message.
See my previous reply.
> - I did not like the change where the parameter callback is now called
> from an other thread because this forces the realtime thread to use a
> lock to access the parameter.
As from changeset 487:9b87a3c48ebd, parameter changes asynchronous to
the real time task. That means that a parameter may change while it is
being used.
You are obliged to supply a small helper function that is called when a
parameter is changed. Inside the helper function you can lock a
semaphore, copy data and unlock again. Although every parameter can
store a unique helper function, the helper function may be generic in
nature and shared by all parameters. A priv_data pointer, passed when
registering the parameter, is supplied to the helper function during the
call.
For example:
<code>
semaphore parameter_lock; // in global scope
// Helper function
void copy_parameter(const struct pdvariable* param,
void *dst, const void *src, size_t len,
struct timespec *time, void *priv_data)
{
sem_get((semaphore*)priv_data); // or even sem_get(¶mter_lock)
memcpy(dst, src, len);
sem_put((semaphore*)priv_data);
}
void cyclic_task()
{
while (true) {
sem_get(¶meter_lock); // lock parameters
// calculations using registered parameters
sem_put(¶mter_lock); // unlock parameters
pdserv_update(...);
sleep(delay);
}
}
void init()
{
// ...
pdserv_parameter(pdserv, "/parameter/path1", 0666, pd_double_T,
¶meter1, 1, 0, copy_parameter, ¶meter_lock);
pdserv_parameter(pdserv, "/parameter/path2", 0666, pd_double_T,
¶meter2, 1, 0, copy_parameter, ¶meter_lock);
// ...
}
</code>
Supplying NULL for write_parameter_t is possible but not recommended!
A similar helper function is recommended for signals!
>
> Philippe Leuba
- Richard
More information about the Etherlab-dev
mailing list