|
Motion Master 6.0.0-alpha.111
Next-generation motion control software
|
Keeps a reference-counted set of SDO parameters fresh by polling them off-thread. More...
#include <parameter_refresher.h>
Public Member Functions | |
| ParameterRefresher (DeviceManager &deviceManager) | |
Constructs a refresher over deviceManager. Does not start the workers — call start(). | |
| ~ParameterRefresher () | |
| Stops the workers (if running) and joins them. | |
| ParameterRefresher (const ParameterRefresher &)=delete | |
| ParameterRefresher & | operator= (const ParameterRefresher &)=delete |
| void | acquire (uint16_t devicePosition, uint16_t index, uint8_t subindex, std::chrono::milliseconds period) |
Adds a reference to keeping (devicePosition, index, subindex) fresh. | |
| void | release (uint16_t devicePosition, uint16_t index, uint8_t subindex) |
Drops a reference previously taken with acquire. The object stops being polled when its last reference is released. A release with no matching acquire is ignored. | |
| void | start () |
| Starts the worker threads. Idempotent. | |
| void | stop () |
| Stops and joins the worker threads. Idempotent. | |
| std::size_t | trackedCount () const |
| Number of distinct objects currently tracked (reference count > 0). For tests/UI. | |
| void | pollDue () |
| Polls the due objects on the calling thread, one pass, with no worker running. | |
Keeps a reference-counted set of SDO parameters fresh by polling them off-thread.
A monitoring that samples objects which are not PDO-mapped cannot read them from the process image — they have to be fetched over SDO, which is far too slow to do on the sampling tick. The refresher decouples the two: a fixed pool of worker threads reads each object with Device::readParameter (a live SDO upload into the object's parameter cell), and the sampler then reads only that cell.
Different drives are read at the same time. Both fieldbus drivers let the mailbox work of different drives run at the same time, and no two workers read one drive at the same time. So a slow drive, or a drive that does not answer, delays only its own objects. The pool is small on purpose: over SOEM every mailbox transaction holds one of a few frame slots for the whole bus, and the HTTP workers and the procedures need the rest of them.
The refresher uses at most half of the control-plane time of a drive. After each read, it reads nothing more from that drive for as long as that read took. So other calls to the drive always find free gaps, on a slow drive and on a fast one. A slow drive pays for this with a longer refresh period.
Entries are reference-counted by (devicePosition, index, subindex): several monitorings asking for the same object poll it once, and it stops being polled only when the last one releases it. The effective poll period of an entry is the shortest period any requester asked for, clamped to a floor (SDO is slow; there is no point hammering the mailbox).
All public methods are thread-safe. The class is non-copyable and non-movable (it owns threads and a mutex).
|
explicit |
Constructs a refresher over deviceManager. Does not start the workers — call start().
| mm::node::ParameterRefresher::~ParameterRefresher | ( | ) |
Stops the workers (if running) and joins them.
|
delete |
| void mm::node::ParameterRefresher::acquire | ( | uint16_t | devicePosition, |
| uint16_t | index, | ||
| uint8_t | subindex, | ||
| std::chrono::milliseconds | period | ||
| ) |
Adds a reference to keeping (devicePosition, index, subindex) fresh.
First reference starts polling the object; later references only raise the count and, if period is shorter than the current one, tighten the poll period. Pair every call with a release. period is clamped to an internal floor.
| devicePosition | 1-based bus position. |
| index | CoE object index. |
| subindex | CoE object subindex. |
| period | Desired maximum time between polls of this object. |
|
delete |
| void mm::node::ParameterRefresher::pollDue | ( | ) |
Polls the due objects on the calling thread, one pass, with no worker running.
A read closes its drive until the read's duration has passed again, so one pass reads at most one object per drive. For tests, which drive the schedule without threads.
| void mm::node::ParameterRefresher::release | ( | uint16_t | devicePosition, |
| uint16_t | index, | ||
| uint8_t | subindex | ||
| ) |
Drops a reference previously taken with acquire. The object stops being polled when its last reference is released. A release with no matching acquire is ignored.
| void mm::node::ParameterRefresher::start | ( | ) |
Starts the worker threads. Idempotent.
| void mm::node::ParameterRefresher::stop | ( | ) |
Stops and joins the worker threads. Idempotent.
| std::size_t mm::node::ParameterRefresher::trackedCount | ( | ) | const |
Number of distinct objects currently tracked (reference count > 0). For tests/UI.