|
Motion Master 6.0.0-alpha.111
Next-generation motion control software
|
Classes | |
| class | SoemFieldbusDriver |
| SOEM-backed EtherCAT fieldbus driver. More... | |
| struct | SoemFieldbusDriverConfig |
Construction-time configuration for SoemFieldbusDriver. More... | |
Functions | |
| void | drainMailbox (ecx_contextt *ctx, uint16_t slavePosition) |
| Discards whatever is sitting in a slave's read mailbox, ignoring the contents. | |
| void | reportUnknownMailboxWrites (ecx_contextt *ctx, uint16_t slavePosition) |
| Logs the mailbox writes to a slave that got no frame back, and resets their count. | |
| std::vector< uint8_t > | makeFoeAbortRequest (uint8_t counter) |
| Builds an FoE ERROR request, which aborts a slave's FoE transfer. | |
| void | abortFoeTransfer (ecx_contextt *ctx, uint16_t slavePosition) |
| Ends the FoE transfer a slave may still have in progress. | |
| void | updateMailboxSyncManagers (ecx_contextt *ctx, uint16_t slave, EtherCatState targetState) |
Programs the mailbox sync managers of a slave for targetState. | |
Variables | |
| constexpr int | kLateFrameTimeoutUs = 100'000 |
| How long a register read or write that a state change depends on waits for its frame, in microseconds. | |
| void mm::comm::soem::abortFoeTransfer | ( | ecx_contextt * | ctx, |
| uint16_t | slavePosition | ||
| ) |
Ends the FoE transfer a slave may still have in progress.
SOEM gives up on an FoE transfer without telling the slave. The FoE layer of a SOMANET bootloader (lib_ethercat foe.xc) then stays in the state of that transfer. In the READ state it answers every new READ and WRITE request with mailbox error 0x0008, and only an FoE ERROR request from the master or a power cycle ends that state. AL state transitions do not.
Sends the request, waits up to 100 ms for the slave's answer, and discards the answer and the errors SOEM queued for it. The answer depends on the state the request meets, and none of the answers is of use: a slave in the READ state answers with mailbox error 0x0008, and an idle slave answers with an FoE error. Take the reason for the failed transfer off SOEM's error list before the call, because the call empties it.
Call with the driver's control-plane mutex held.
| void mm::comm::soem::drainMailbox | ( | ecx_contextt * | ctx, |
| uint16_t | slavePosition | ||
| ) |
Discards whatever is sitting in a slave's read mailbox, ignoring the contents.
A transfer that failed can leave its late reply in the mailbox. The next request would then read that reply as its own answer and fail. Reading the mailbox out with a zero timeout before each transfer prevents that. The cost is one FPRD datagram: with a zero timeout, ecx_mbxreceive checks the sync manager status once and returns without touching the mailbox when nothing is waiting.
Draining removes a late reply. It does not end the transfer on the slave. A SOMANET bootloader that is still in the middle of an FoE read rejects every new request until the transfer ends, and abortFoeTransfer is what ends it.
Ownership: ecx_mbxreceive allocates from the context's mailbox pool and transfers the buffer to the caller on success, so each drained message goes back to the pool. This holds because Motion Master never enables the cyclic mailbox handler (ecx_slavembxcyclic), whose path assigns a buffer outside the pool. The count is bounded so that a slave which keeps sending cannot hold the caller here.
Call with the driver's control-plane mutex held.
| std::vector< uint8_t > mm::comm::soem::makeFoeAbortRequest | ( | uint8_t | counter | ) |
Builds an FoE ERROR request, which aborts a slave's FoE transfer.
The request is a complete mailbox message: the 6-byte mailbox header, the FoE opcode ERROR, a reserved byte, the error code 0x8000 ("not defined") and a short error text. All fields are little-endian.
| counter | Mailbox counter (1 to 7) for the mailbox header. Only the low three bits are used. |
| void mm::comm::soem::reportUnknownMailboxWrites | ( | ecx_contextt * | ctx, |
| uint16_t | slavePosition | ||
| ) |
Logs the mailbox writes to a slave that got no frame back, and resets their count.
The SOEM port writes each mailbox message to a SOMANET slave once and counts the writes without a frame in mbxwriteunknowns. Such a write is not repeated, because the slave may have received it, and the caller waits for the answer. A count above 0 in a support log shows that frames come back late or not at all. The count is per slave and only grows, so this logs each write once.
Call with the driver's lock for the slave held.
| void mm::comm::soem::updateMailboxSyncManagers | ( | ecx_contextt * | ctx, |
| uint16_t | slave, | ||
| EtherCatState | targetState | ||
| ) |
Programs the mailbox sync managers of a slave for targetState.
BOOT uses the bootstrap mailbox from the SII, which is larger than the standard one, and PRE-OP uses the standard mailbox. Call before the transition out of INIT. Any other target state leaves the sync managers unchanged.
Call with the driver's control-plane mutex held.
|
constexpr |
How long a register read or write that a state change depends on waits for its frame, in microseconds.
A frame later than EC_TIMEOUTRET is not a lost frame. On a desk PC with a Realtek NIC and no real-time kernel, a frame often comes back later than that (#113). With 2 % of the frames delayed by 25 ms, one such frame on a datagram that waited one EC_TIMEOUTRET did two things to an Integro firmware installation (#115): a read of the AL status made a device that had just reached INIT read as absent, and a sync manager write that left the host after the state request made the slave refuse PRE-OP with AL status 0x0016. A register datagram is safe to send again, so SOEM sends it again every EC_TIMEOUTRET until this expires, and a late answer to an earlier copy is accepted because it carries the same datagram header. The figure is EC_TIMEOUTLATE of ports/soem, the wait a mailbox transfer gives a late frame. A device that is really absent costs this much per datagram, which only the control plane pays.