Discussion:
[etherlab-dev] PdServ library
Philippe Leuba
2016-04-11 09:04:24 UTC
Permalink
Hi,

First, I want to congratulate you for this very good and efficient library and the accompanying Test Manager and DLS.

But I face some issues:
- pdserv_parameter allows defining an access mode, but I did not see any effect in Test Manager
- 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 ?
- 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 ?

Best regards

Philippe Leuba
Philippe Leuba
2016-05-14 04:11:50 UTC
Permalink
Post by Philippe Leuba
- 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
Post by Philippe Leuba
- 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.

- 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.

Philippe Leuba
Richard Hacker
2016-05-18 22:25:14 UTC
Permalink
Post by Philippe Leuba
Hi,
First, I want to congratulate you for this very good and efficient
library and the accompanying Test Manager and DLS.
Thank you :)
Post by Philippe Leuba
- pdserv_parameter allows defining an access mode, but I did not see any
effect in Test Manager
At the moment the access mode is not used. It is reserved for future use.
Post by Philippe Leuba
- 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 ?
Test Manager will always get the updated value.
Post by Philippe Leuba
- 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 ?
pdserv_event_set() is used to report "process errors", such as
monitoring whether a value exceeds a limit or a timer has timed out
waiting for something to occur. It converts a signal, aka a stream of
values, into an event with a time stamp.

The event's state is managed internally for every element of the vector.
A change from false (the default state) from a previous call to true in
the current call will set the event. Likewise a change from true to
false will reset the event. Any change is logged to syslog, as well as
notifying clients such as dls, TestManager and pdcom clients.

Calling pdserv_event_set() with no change in the "state" parameter from
one call to another has no effect.

A typical use is inside your cyclic loop:

<code>
while (true) {
// ...
// read pressure from sensor
// ..
pdserv_event_set(overpressure_event, 0, pressure > 5, current_time);
// ...

pdserv_update_statistics(...);
pdserv_update(...);
sleep(delay);
}
</code>

From the description above, two consecutive calls in the same
calculation cycle, once with true and once with false, does not make
much sense and the result thereof is not guaranteed. There can only be
one change in one calculation cycle.
Post by Philippe Leuba
Best regards
Philippe Leuba
Richard Hacker
2016-05-18 23:12:24 UTC
Permalink
Post by Philippe Leuba
Post by Philippe Leuba
- 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.
Post by Philippe Leuba
Post by Philippe Leuba
- 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.
Post by Philippe Leuba
- 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!
Post by Philippe Leuba
Philippe Leuba
- Richard

Loading...