[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(&paramter_lock)
   memcpy(dst, src, len);
   sem_put((semaphore*)priv_data);
}

void cyclic_task()
{
   while (true) {
      sem_get(&parameter_lock);  // lock parameters
      // calculations using registered parameters
      sem_put(&paramter_lock);   // unlock parameters

      pdserv_update(...);
      sleep(delay);
   }
}

void init()
{
  // ...
  pdserv_parameter(pdserv, "/parameter/path1", 0666, pd_double_T,
    &parameter1, 1, 0, copy_parameter, &parameter_lock);
  pdserv_parameter(pdserv, "/parameter/path2", 0666, pd_double_T,
    &parameter2, 1, 0, copy_parameter, &parameter_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