|
Motion Master 6.0.0-alpha.111
Next-generation motion control software
|
The control-plane locks of one fieldbus driver: one for the bus, one per drive. More...
#include <control_plane_locks.h>
Public Member Functions | |
| ControlPlaneLocks (std::size_t positions) | |
| std::unique_lock< BusLock > | lockBus () |
| Excludes all other control-plane work. For work on the whole bus. | |
| std::shared_lock< BusLock > | lockBusShared () |
| Excludes only work on the whole bus. For reads of what a scan or a re-map produced, which send no frame. | |
| BusIoLock | lockBusIo () |
| Excludes only work on the whole bus, and takes a frame slot. For reads that send frames to several drives and change nothing in the context. | |
| DriveLock | lockDrive (uint16_t position) |
| Excludes work on the whole bus and other work on the same drive. | |
Static Public Attributes | |
| static constexpr std::ptrdiff_t | kFrameSlots = 8 |
The control-plane locks of one fieldbus driver: one for the bus, one per drive.
The mailbox work of different drives runs at the same time. Each drive has its own mailbox, so the work on one drive needs only that drive's lock, with the bus lock held shared. The work on the whole bus, such as a scan or a re-map, holds the bus lock exclusive and so excludes every drive. The order is always the bus lock first, then one drive lock. Nobody holds two drive locks, and an exclusive holder takes no drive lock.
Every lock is held for one transaction or one transfer. Never hold one across a sleep that waits for something other than the bus.
A drive lock and a bus I/O lock also take a frame slot, after every other lock they take. No holder of a slot waits for another lock, so the slots cannot deadlock. An exclusive holder takes no slot, because nothing else on the control plane sends a frame while it holds the bus.
|
explicit |
| positions | The number of drive positions, position 0 included. A position passed to lockDrive must be below it. |
| std::unique_lock< BusLock > mm::comm::ControlPlaneLocks::lockBus | ( | ) |
Excludes all other control-plane work. For work on the whole bus.
| BusIoLock mm::comm::ControlPlaneLocks::lockBusIo | ( | ) |
Excludes only work on the whole bus, and takes a frame slot. For reads that send frames to several drives and change nothing in the context.
| std::shared_lock< BusLock > mm::comm::ControlPlaneLocks::lockBusShared | ( | ) |
Excludes only work on the whole bus. For reads of what a scan or a re-map produced, which send no frame.
| DriveLock mm::comm::ControlPlaneLocks::lockDrive | ( | uint16_t | position | ) |
Excludes work on the whole bus and other work on the same drive.
|
staticconstexpr |
The number of frame slots. SOEM's frame indexes (EC_MAXBUF, set in ports/soem) are shared with the RT thread, which uses one per frame of process data in a cycle. The slots cap the control plane's share, and the RT thread gets the rest.
The cap is small on purpose. The NIC sends frames in order, so the RT frame can wait behind every control-plane frame in flight. A mailbox frame carries the drive's whole mailbox, and a full frame takes about 120 µs at 100 Mbit/s. So eight full frames delay the RT frame by about 1 ms. This was calculated, not measured.
With 32 indexes, eight slots leave the RT thread 24. A frame carries 1486 bytes, and a SOMANET drive maps about 100, so one frame holds about 14 drives. Separate LRD and LWR datagrams, which some devices need, double the frames. So 24 indexes serve about 168 SOMANET drives in the worst case.