Skip to content

A cheaper re-map of the process image #89

Open

Description

@markosankovic

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:

  1. SOEM waits for PreOp on every slave. ecx_config_map_group calls ecx_map_coe_soe for every slave in the group, one slave at a time, because EC_MAX_MAPT is 1. ecx_map_coe_soe first calls ecx_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/soem does not set EC_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. Patch ports/soem so that this check accepts a slave in PreOp or above.
  2. Motion Master reads the PDO mapping of every device. DeviceManager::remapProcessImage in libs/node/device_manager.cc calls Device::readFlatPdoMapping for 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 that flatPdoMapping_ holds for the others.
  3. The recorder ring is always rebuilt. ProcessDataRing::allocate in libs/node/process_data_ring.cc calls clear() and then allocates the buffer again, even when nothing changed. With the default recorder.capacity of 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 spdlog timestamps 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.xc calls pdo_init_mapping() only when the communication state changes from PreOp to SafeOp.
  • On the netX side of an Integro, Handle_ESM_AL_Stauts_Changed_Ind in arm_application/Components/cifXApplicationECS/Sources/AppECS_ApplicationFunctions.c calls pdo_mapping_init when 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions