Repository navigation
A cheaper re-map of the process image #89
Description
What to do
Make a re-map of the process image cheaper. A re-map runs when a device joins SafeOp or OP from a state below it. Three parts of it cost more than they need to:
- SOEM waits for PreOp on every slave.
ecx_config_map_groupcallsecx_map_coe_soefor every slave in the group, one slave at a time, becauseEC_MAX_MAPTis 1.ecx_map_coe_soefirst callsecx_statecheck(context, slave, EC_STATE_PRE_OP, EC_TIMEOUTSTATE). That call polls the AL status until the slave is in PreOp or until the timeout ends.ports/soemdoes not setEC_TIMEOUTSTATE, so the timeout is the SOEM default of 2 s. A slave in SafeOp is never in PreOp, so it costs the full 2 s. Patchports/soemso that this check accepts a slave in PreOp or above. - Motion Master reads the PDO mapping of every device.
DeviceManager::remapProcessImageinlibs/node/device_manager.cccallsDevice::readFlatPdoMappingfor every device in the set. A device that stayed in SafeOp or OP kept its mapping. Read the mapping only of the devices that are below SafeOp when the re-map starts. Keep the mapping thatflatPdoMapping_holds for the others. - The recorder ring is always rebuilt.
ProcessDataRing::allocateinlibs/node/process_data_ring.cccallsclear()and then allocates the buffer again, even when nothing changed. With the defaultrecorder.capacityof 300000 cycles that is about 38 MB, and the recording before the re-map is lost. Keep the ring when the new image has the same layout as the old one.
Measure a re-map on a bench before and after the change.
Why
A re-map stops process data for the whole bus. transitionToState drops every device that stays in OP to SafeOp before the re-map, so that a missed frame does not trip its sync-manager watchdog, and brings it back to OP afterwards. Every part above makes that pause longer.
The SOEM wait is probably the largest part. Every device that stays exchanging is in SafeOp during the re-map, so each one adds 2 s. This comes from reading the SOEM source. It was not measured.
The recording is lost exactly when it is most useful. A re-map happens when somebody brings a device back after a firmware install or a PDO mapping change, which is often while they look for a fault.
A re-map is rare. It is a commissioning act, not part of normal operation. That is why this is low priority.
Done when
- A re-map with at least one other device in SafeOp or OP is measured before and after the change, and the times are recorded in the pull request. The
spdlogtimestamps of the log lines around "Process data configured" are enough. - A re-map does not wait 2 s for each slave that is in SafeOp or OP.
- A re-map reads the PDO mapping over SDO in Motion Master only for the devices below SafeOp.
- A re-map that produces the same layout keeps the recorder ring and its records.
- A re-map that produces a different layout still rebuilds the ring.
- A test in
libs/node/tests/covers both ring cases.
Notes
The layout check for the ring
Equal byte sizes are not enough. Two layouts can have the same input and output size but map different objects, or the same objects at different offsets. Records written under one layout are wrong when decoded under the other. Compare the entries of the two images: the device, the object address, the bit offset and the bit length.
Which devices to read
Read every device that is below SafeOp when the re-map starts, not only the devices the transition targets. A device that stays in PreOp can have its mapping changed by a direct SDO write to 0x16xx, 0x1Axx, 0x1C12 or 0x1C13 through writeParameter. Device::writePdoMapping refreshes flatPdoMapping_ itself, but a direct write does not.
A device that stays in SafeOp or OP keeps the mapping it had when it joined, even if somebody writes to its mapping objects. The SOMANET firmware applies the mapping only on the transition from PreOp to SafeOp. Checked in somanet_software at develop 48974ce4b:
- On the XMOS side,
sc_drive/module_canopen_interface/src/canopen_interface_service.xccallspdo_init_mapping()only when the communication state changes from PreOp to SafeOp. - On the netX side of an Integro,
Handle_ESM_AL_Stauts_Changed_Indinarm_application/Components/cifXApplicationECS/Sources/AppECS_ApplicationFunctions.ccallspdo_mapping_initwhen the device enters SafeOp.
The firmware does not always refuse the write. _entry_set_value in sdo.c checks the write flag of the entry for the present state, and the dictionaries in sw_applications/*/src/co_dictionary.c differ:
| Dictionary | 0x16xx and 0x1Axx | 0x1C12 and 0x1C13 |
|---|---|---|
| Circulo and Circulo SMM | PreOp only, except 0x1602:01 and 0x1A01:03 on Circulo | PreOp only |
| Integro | every state | PreOp only |
| Node | every state | every state |
So in SafeOp or OP the stored mapping objects can differ from the active mapping. That is a reason not to read the mapping of a device that stays exchanging: the read returns the stored values, not the active ones. SOEM's ecx_readPDOmap reads the stored values as well, so in that case it can size the sync managers for a mapping the device does not use. That case was not tested.
SOEM still reads every mapping
ecx_map_coe_soe reads the PDO mapping of every slave over SDO, with ecx_readPDOmapCA or ecx_readPDOmap, to size its sync managers. That read stays. Part 2 removes only the second read that Motion Master does. It returns only sizes, not the list of mapped objects, so Motion Master cannot use it in place of its own read.
The SOEM patch
ports/soem/portfile.cmake already patches SOEM for the FoE FOE_BUSY branch. Add the PreOp check next to it, with the reason beside it. Raising EC_MAX_MAPT to map slaves in parallel is a different change and is not part of this one.
Out of scope
- Leaving devices below SafeOp out of the image. That is the alternative The decode overwrites the input cells of a drive below SafeOp #80 rejected.
- The retained
ProcessImagethat each re-map adds toProcessData::generations. It is small, and it is what keeps the RT thread from reading a freed image.
Activity