Compare commits

..

35 Commits

Author SHA1 Message Date
Florian Pose b709e58147 Version bump to 1.6.9 2026-03-26 17:47:12 +01:00
Florian Pose 15883228f9 Merge branch 'fix-suse-16' into 'stable-1.6'
Driver fixes for openSUSE Leap 16.0

See merge request etherlab.org/ethercat!192
2026-03-26 17:45:44 +01:00
Florian Pose 9c63faf50d Fixed igb for SUSE kernel 6.12 2026-03-26 17:38:46 +01:00
Florian Pose bf706b737d Fixed genet for SUSE 16.0. 2026-03-26 17:26:45 +01:00
Florian Pose cf19168844 Cherry-picked MR 188 (injection-semaphore) from 1.7. 2026-03-26 16:41:43 +01:00
Florian Pose 98563a2f0d Merge branch 'no-config-necessary' into 'stable-1.6'
Do not require .config to exist in kernel sources

Closes #198

See merge request etherlab.org/ethercat!186
2026-03-24 17:13:53 +01:00
Florian Pose db526666f3 At least check for Makefile. 2026-03-24 17:07:12 +01:00
Florian Pose 1e61b8400c Minor: Improved comments in DC user example. 2026-03-24 17:05:00 +01:00
Florian Pose 6869c2bab8 Merge branch 'stable-1.6-kernel615' into 'stable-1.6'
tty: Implemented new timer interface since kernel 6.15.

See merge request etherlab.org/ethercat!187
2026-03-16 14:47:06 +01:00
Bernd Kuhls e32e99f8b8 tty: Implemented new timer interface since kernel 6.15.
Signed-off-by: Bernd Kuhls <bernd@kuhls.net>
2026-03-15 20:06:42 +01:00
Florian Pose 7a7d7f051b Merge branch 'calc-dc-after-attach' into 'stable-1.6'
Attach slaves before calculating DCs

Closes #212

See merge request etherlab.org/ethercat!185
2026-03-13 15:17:53 +01:00
Florian Pose 607d0fd1af Merge branch 'discard-eoe' into 'stable-1.6'
Discard EoE traffic if EoE is disabled

See merge request etherlab.org/ethercat!184
2026-03-13 15:16:29 +01:00
Florian Pose 212cb59d58 Do not require .config to exist in kernel sources. 2026-03-12 12:01:21 +01:00
Florian Pose c76b02ae2e Attach slaves before calculating DCs. 2026-03-12 11:36:37 +01:00
Florian Pose c8c23aa448 Discard EoE traffic in CoE statemachine, if EoE is disabled. 2026-03-10 09:24:13 +01:00
Florian Pose 4e5b661674 Merge branch 'fix-6.19' into 'stable-1.6'
Linux 6.19.0 support

Closes #200

See merge request etherlab.org/ethercat!183
2026-03-09 15:02:17 +01:00
Nicola Fontana c42c9cf8bc Linux 6.19.0 support
Commit 89aec171d9d1ab168e43fcf9754b82e4c0aef9b9 (part of linux kernel
6.19.0-rc1) introduced an arbitrarily sized sockaddr struct to be used
instead of the classical one.

Closes #200
2026-03-08 15:54:00 +01:00
Florian Pose 3ccae1d47d Updated NEWS.md 2026-03-03 08:56:21 +01:00
Florian Pose bde53bc4f3 Use /sbin/ip as default 2026-03-03 08:52:53 +01:00
Florian Pose f16c0ff3c3 Merge branch 'custom-paths' into 'stable-1.6'
Allow to customize kmod path and ip command

Closes #206

See merge request etherlab.org/ethercat!182
2026-03-03 08:51:06 +01:00
Nicola Fontana b86d2163f1 Fix #206: allow to customize utilities from configure
`ethercatctl` calls some utilites actually hardcoded in the script.
Provide a way to customize them from configure.

The default values are choosen to be backward compatible with the old
behavior, but more sensible values would be preferred, e.g.:

OPTION      ACTUAL DEFAULT      PREFERRED DEFAULT
kmod-dir    /sbin               $sbindir
ip-cmd      /bin/ip             $sbindir/ip

In a major future release this can be changed.
2026-03-02 12:09:59 +01:00
Nicola Fontana 90f9feb0ad Improve help string consistency
* Move default values from comments to help strings
* Use the "... [default=...]" convention everywhere
* Change "Enable ... driver" to more correct "Build ... driver"
* Fix --enable-dwmac-intel help string
* Fix --enable-fakeuserlib help string
* Change --disable-initd to --enable-initd to avoid confusion with
  `--disable-initd [default=yes]`.
2026-03-02 11:44:15 +01:00
Florian Pose 2543cc55bd Version 1.6.8: Fixed FAKE_EC_HOMEDIR usage. 2025-10-06 17:15:04 +02:00
Florian Pose 6acfd09764
Merge branch 'patch-1' into 'stable-1.6'
Set direction in syncManager when configuring it.

See merge request etherlab.org/ethercat!179
2025-09-09 11:08:42 +02:00
Jannik Becher c5413f81e2 Set direction in syncManager when configuring it.
This is needed when you configured your pdos without the ecrt_slave_config_pdos function.
2025-08-10 09:54:37 +00:00
Florian Pose c1e6b50d12 Merge branch 'news-markdown' into 'stable-1.6'
Converted NEWS to NEWS.md

See merge request etherlab.org/ethercat!178
2025-07-31 13:20:35 +02:00
Florian Pose c324df4348 Version bump to 1.6.7. 2025-07-31 13:13:59 +02:00
Florian Pose 554e39573a Some backtick escapes. 2025-07-31 13:10:23 +02:00
Florian Pose d34e600a21 Re-formatted in markdown. 2025-07-31 13:05:00 +02:00
Florian Pose 516499a4a7 Converted NEWS to NEWS.md 2025-07-31 13:03:28 +02:00
Florian Pose 6489901521 Merge branch '187-fake_lib-ecrt_master_deactivate-is-missing-for-testing-purposes' into 'stable-1.6'
Resolve "fake_lib: ecrt_master_deactivate() is missing for testing purposes"

Closes #187

See merge request etherlab.org/ethercat!177
2025-07-28 15:16:55 +02:00
Florian Pose 49e82079dc Clang-formatted fake library. 2025-07-24 11:49:14 +02:00
Florian Pose 04c4db80c3 Completed API methods in fake library. 2025-07-24 11:25:44 +02:00
Florian Pose b82a66735c Merge branch 'fix_igb_6.4' into 'stable-1.6'
Fix igb for opensuse 15.6 (kernel 6.4)

See merge request etherlab.org/ethercat!176
2025-07-01 11:33:08 +02:00
Bjarne von Horn d978c45ad7 Fix igb for opensuse 15.6 (kernel 6.4) 2025-07-01 10:15:20 +02:00
19 changed files with 2102 additions and 1106 deletions

93
.clang-format Normal file
View File

@ -0,0 +1,93 @@
---
Language: Cpp
AccessModifierOffset: -2
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignConsecutiveMacros: false
AlignEscapedNewlines: DontAlign
AlignOperands: false
AlignTrailingComments: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllArgumentsOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: InlineOnly
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: No
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterCaseLabel: false
AfterClass: true
AfterControlStatement: Never
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterStruct: true
AfterUnion: true
AfterExternBlock: false
BeforeCatch: true
BeforeElse: true
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Custom # Same as 'BraceWrapping'
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: AfterColon
BreakInheritanceList: AfterColon
BreakStringLiterals: true
ColumnLimit: 78
CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 8
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
FixNamespaceComments: true
IncludeBlocks: Preserve
IndentAccessModifiers: true
IndentCaseLabels: true
IndentGotoLabels: true
IndentPPDirectives: None
IndentWidth: 4
InsertBraces: true
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 2
NamespaceIndentation: None
PackConstructorInitializers: Never
PointerAlignment: Right
ReflowComments: true
SortIncludes: false
SortUsingDeclarations: true
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: false
SpaceBeforeInheritanceColon: false
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 2
UseTab: Never
...

491
NEWS
View File

@ -1,491 +0,0 @@
-------------------------------------------------------------------------------
vim: spelllang=en spell tw=78
-------------------------------------------------------------------------------
Changes in 1.6.6:
* Added Ethernet drivers for kernels 6.4 and 6.12.
* Added missing functions to fake user library.
* Use sint(32) notation in EtherLab output driver
* Added CONTRIBUTING.md
Changes in 1.6.5:
* Implemented interface changes of Linux 6.15.
Changes in 1.6.4:
* igc: Set RX descriptor writeback threshold to 1
* Avoid rescan on non-responding slave
* Do not touch AL state of EoE slaves
* Warn if FAKE_EC_NAME is not set
* Added configuration switch to disable init.d files
* Fixed FakeEtherCAT operation with muliple masters
* Add UPDOWN_INTERFACES option to ethercat.conf
* Improvements to the build system
* Fix obsolete warnings on bootstrap
* Explicitly check for pkg-config macros
* Many documentation improvements (thanks to Nicola Fontana)
Changes in 1.6.3:
* Fix ccat for aarch64 >= 6.11.0
* Removed domain information from libfakeethercat RtIPC paths
* Remove unnecessary inline statement causing build -O0 problems
* Fixed some compiler warnings
* Added static keywords to internal functions
Changes in 1.6.2:
* Fixed typo in bash completition.
* Directly include soe_error_codes into SoeCommand.cpp
* Fixed check of non-zero bit offset in libfakeethercat
Changes in 1.6.1:
* Added libfakeethercat to simulate Process Data of EtherCAT Slaves.
Changes in 1.6.0:
* Added all native Ethernet drivers for kernels 5.14 and 6.1.
* Dropped support for kernels < 3.0.
* Allow to query the scanning progress via API.
* Added EoE set IP command via command-line-tool.
* Changed the default AL state change timeout from 5 to 10 s.
Changes since 1.5.2:
* Added feature flag API.
* Fixed FoE timeout calculation bug.
Changes in 1.5.2:
* API extensions (find the complete description in include/ecrt.h)
* Added redundancy features; enable using --with-devices.
* Re-designed and seamlessly integrated RTDM interface.
* Added ecrt_sdo_request_index() method to change index and subindex.
* Changed the data types of the shift times in ecrt_slave_config_dc()
to int32_t to correctly display negative shift times.
* Added API for querying CoE emergency requests.
* Added interface to read/write register contents; re-worked register
requests.
* Added interface to select the reference clock and to sync to it.
* Exported ecrt_domain_size() to userspace.
* Added ecrt_slave_config_reg_so_entry_pos() to register non-unique
PDO entries.
* Ethernet drivers
* Added 8139too driver for 3.0, 3.2, 3.4.
* Added r8169 driver for 2.6.36 (J. Kunz), 3.2 (J. Kunz), 3.4 (F. Pose).
* Added e1000 driver for 3.0, 3.4.
* Added e1000e driver for 3.2 (J. Kunz), 3.4 (F. Pose).
* Added e100 driver for 3.0, 3.4.
* Fixes regarding 8139too driver for 2.6.36.
* Some fixes for all e1000 and e1000e drivers.
* General behaviour
* Avoided semaphore locking from userspace/rtdm library: Implemented
datagram ring instead of queue.
* Assign SII to PDI during PREOP transition; Introduced
--enable-sii-assign to switch this on.
* Avoided re-allocating memory in userspace library implementations of
ecrt_sdo_request_state() and in VoE handlers.
* Send sync datagrams only if reference clock is found.
* Adjusted some DC clock discipline parameters.
* Fixed AL status code lookup.
* Fixed some ioctl() return values and permissions.
* Fixed FoE data OpCode, thanks to R. Roesch.
* Fixed and improved cancelling requests when clearing configuration.
* Using common wait queue for requests.
* Removed some unnecessary request types.
* Output slave FSM datagram statistics.
* Removed some state-dependent datagram skip messages.
* Immediately restart slave FSM on several failed requests.
* Reset master state machine when going to orphaned phase.
* Command-line tool:
* Show complete access flag in config view.
* Added EtherLab skin for 'ethercat pdos' command.
* Fixed 'String too large' bug.
* Infrastructure:
* Added AM_PROG_AR necessary for autoconf 1.12.
* Avoided use of AM_CFLAGS, which is not used in some situations.
* Added vmalloc() include fix for ARM architecture, thanks to Andrea
Scian.
* Install ethercat service to multi-user target by default.
* Fixed COPYING.LESSER to be LGPL 2.1 (like in file headers).
* More detailed output of configure script.
* Added rtai_rtdm_dc example, thanks to Graeme Foot.
Changes in 1.5.1:
* Fixed reset of allow_scanning flag if ecrt_master_activate() was not called.
* Fixed missing distribution for r8169 for 2.6.32 and e1000 driver for 2.6.31.
* Added e100 for 2.6.35.
* Added r8169 driver for 2.6.35 (F. Pose).
* Added e1000e driver for 2.6.35 (F. Pose).
* Added fix for ESC port order (DC delay calculation).
* Added e1000 driver for 2.6.35.
Changes in 1.5.0:
* Added a userspace library for accessing the application interface. This
library is licensed under LGPLv2.
* Added distributed clocks support.
* Added watchdog configuration via application interface (thanks to J. Mohre).
* Added VoE mailbox protocol support.
* Added SoE mailbox protocol support.
* Improved the callback mechanism. ecrt_master_callbacks() now takes two
callback functions for sending and receiving datagrams.
ecrt_master_send_ext() is used to execute the sending of non-application
datagrams.
* Separated datagram initialization from filling the payload with zeros.
Introduced new method ec_datagram_zero() for that.
* Added phy_read and phy_write commands to ethercat tool.
* Added e100 driver for Intel PRO/100 NICs.
- Added e100 driver for 2.6.27.
- Added e100 driver for 2.6.28, thanks to Kim. H. Madsen.
- Added e100 driver for 2.6.29, thanks to Andre Puschmann.
- Added e100 driver for 2.6.31.
- Added e100 driver for 2.6.32.
- Added e100 driver for 2.6.33, thanks to J. Kunz.
- Added e100 driver for 2.6.37.
* Added 8139too driver for kernels 2.6.25 (F. Pose), 2.6.26 (M. Luescher),
2.6.27, 2.6.28, 2.6.29 (M. Goetze), 2.6.31 (F. Pose), 2.6.32 (F. Pose),
2.6.33 (J. Kunz), 2.6.34 (Malcolm Lewis), 2.6.35 (B. Benner),
2.6.36 (F. Pose) and 2.6.37 (F. Pose).
* Added e1000 driver for 2.6.26 (M. Luescher), 2.6.27, 2.6.28, 2.6.29, 2.6.32,
2.6.33 (J. Kunz), 2.6.35, 2.6.37.
* Added r8169 driver for 2.6.24, 2.6.27, 2.6.28, 2.6.29, 2.6.31, 2.6.32
(Robbie K), 2.6.33 (J. Kunz), 2.6.35, 2.6.37.
* Added e1000e driver for 2.6.32, 2.6.33, 2.6.34 (thanks to Siwei Zhuang).
* Debug interfaces are created with the Ethernet addresses of the attached
physical device.
* Improved error case return codes of many functions.
* Implemented the File Access over EtherCAT (FoE) mailbox protocol, thanks to
O. Zarges.
* Going to the Bootstrap state is now supported by the state machines and the
command-line tool.
* Added ecrt_open_master() and ecrt_master_reserve() separation for
the userspace library (thanks to Martin Troxler).
* Added bus information interface (methods ecrt_master(),
ecrt_master_get_slave(), ecrt_master_get_sync_manager(),
ecrt_master_get_pdo() and ecrt_master_get_pdo_entry()) to get information
about the currently connected slaves and the PDO entries provided (thanks to
Martin Troxler and Stefan Weiser).
* Added ecrt_master_sdo_download() and ecrt_master_sdo_upload()
methods to let an application transfer SDOs before activating the master
(thanks to Stefan Weiser).
* Fixed SDO upload segment response (thanks to Christoph Peter).
* Fixed SDO upload segment response for 10 bytes mailbox length (thanks to
Joerg Mohre).
* SDO entry access rights are shown in 'ethercat sdos'.
* Added 64-bit data access macros to application header.
* Added debug level for all masters as a module parameter. Thanks to Erwin
Burgstaller.
* Clear slave list on link down.
* Output device link state in 'ethercat master'.
* Added 'ethercat graph' command which outputs the bus topology in
DOT language.
* Changed EC_MAX_SII_SIZE to 4096.
* 'ethercat xml' creates valid XML <EtherCATInfoList> for more than one slave
(thanks to E. Burgstaller).
* Added 'ethercat eoe' command to display Ethernet over EtherCAT statistics.
* Added 'ethercat cstruct' command to output PDO information in C language.
* Significantly improved EoE bandwidth by running EoE processing in a kthread.
* Switched version control from Subversion to Mercurial.
* Implemented CompleteAccess for SDO downloads.
* ethercat tool is now able to handle multiple masters. The --masters option
supports ranges like '0,3,8-10'.
* A sync manager is always enabled, if it contains registered process data.
* Added a configuration switch --enable-wildcards to use 0xffffffff as a
wildcard for vendor ID and product code.
* Added support for systemd.
Changes in 1.4.0:
* Fixed race condition in jiffy-based frame timeout calculation.
* Fixed race condition concerning the ec_slave_config_state->operational flag.
* Fixed wrong calculation of the expected working counter if the process data
of a domain span several datagrams.
* Fixed a kernel oops when a slave configuration is detached while the actual
configuration is in progress.
* Fixed typo in logging output.
* Removed 'bashisms' from init script ('function' keyword).
* Fixed bug in e1000 drivers. Memory was allocated when sending the first
frame.
* Modified licence headers to avoid conflicts with the GPL.
* Restricted licence to GPLv2 only.
* Fixed spelling of 'PDO', 'SDO' (all uppercase) and 'xx over EtherCAT'
(without hyphens).
Changes in 1.4.0-rc3:
* Ported the master thread to the kthread interface.
* Added missing semaphore up() in an ioctl(). In rare cases, the master
semaphore was not released.
* Minor fix in 'slaves' command that fixed duplicate display of supported
mailbox protocols.
* The SDO Information Service is only queried, if the slave has the
corresponding SII bit set.
* Added some missing header files in the command-line-tool code.
* Removed unstable e100, forcedeth, and r8169 drivers.
Changes in version 1.4.0-rc2:
* Fixed a deadlock causing race condition concerning thread signaling when the
master thread had no opportunity to run, but shall be killed immediately
after creation.
* Added missing up()s causing a semaphore being not released in some rare
cases.
* Minor fixes.
* Removed some deprecated files.
Changes in version 1.4.0-rc1:
* Realtime interface changes:
- Replaced ec_slave_t with ec_slave_config_t, separating the bus
configuration from the actual slaves. Therefore, renamed
ecrt_master_get_slave() to ecrt_master_slave_config().
- Replaced slave address string with alias and position values. See
ecrt_master_slave_config().
- Removed ecrt_master_get_slave_by_pos(), because it is no longer
necessary due to alias/position addressing.
- Added ec_slave_config_state_t for the new method
ecrt_slave_config_state().
- Process data memory for a domain can now be allocated externally. This
offers the possibility to use a shared-memory region. Therefore,
added the domain methods ecrt_domain_size() and
ecrt_domain_external_memory().
- PDO entry registration functions do not return a process data pointer,
but an offset in the domain's process data. In addition, an optional bit
position can be requested. This was necessary for the external domain
memory. An additional advantage is, that the returned offset is
immediately valid. If the domain's process data is allocated internally,
the start address can be retrieved with ecrt_domain_data().
- Replaced ecrt_slave_pdo_mapping/add/clear() with
ecrt_slave_config_pdo_assign_add() to add a PDO to a sync manager's PDO
assignment and ecrt_slave_config_pdo_mapping_add() to add a PDO entry to a
PDO's mapping. ecrt_slave_config_pdos() is a convenience function
for both, that uses the new data types ec_pdo_info_t and
ec_pdo_entry_info_t. PDO entries, that are mapped with these functions
can now immediately be registered, even if the bus is offline.
- Renamed ec_bus_status_t, ec_master_status_t to ec_bus_state_t and
ec_master_state_t, respectively. Renamed ecrt_master_get_status() to
ecrt_master_state(), for consistency reasons.
- Added ec_domain_state_t and ec_wc_state_t for a new output parameter
of ecrt_domain_state(). The domain state object does now contain
information, if the process data was exchanged completely.
- Former "PDO registration" meant PDO entry registration in fact, therefore
renamed ec_pdo_reg_t to ec_pdo_entry_reg_t and ecrt_domain_register_pdo()
to ecrt_slave_config_reg_pdo_entry().
- Removed ecrt_domain_register_pdo_range(), because it's functionality can
be reached by specifying an explicit PDO assignment/mapping and
registering the mapped PDO entries.
- Added an SDO access interface, working with SDO requests. These can be
scheduled for reading and writing during realtime operation.
- Exported ecrt_slave_config_sdo(), the generic SDO configuration function.
- Removed the bus_state and bus_tainted flags from ec_master_state_t.
* Device interface changes:
- Moved device output parameter of ecdev_offer() to return value.
* Replaced the Sysfs interface with a new 'ethercat' command-line tool, that
communicates with the master via a character device and ioctls. The device
is created via udev. The tool is able to
- Write alias addresses.
- Show the bus configuration.
- Output binary domain process data.
- Set the master's debug level.
- Show domain information.
- Show master information.
- List PDO assignment/mapping.
- Write an SDO entry.
- List SDO dictionaries.
- Read an SDO entry.
- Output a slave's SII contents.
- Write slave's SII contents.
- Show slaves.
- Request slave states.
- Generate slave information xmls.
* Removed include/ecdb.h.
* Using the timestamp counter is now optional (configure --enable-cycles),
because it is only available on Intel architectures.
* SDO dictionaries will now also be fetched in operation mode.
* SII write requests will now also be processed in operation mode.
* Mapping of PDO entries is now supported.
* Current PDO assignment/mapping is now read via CoE during bus scan, using
direct SDO access, independent of the dictionary.
* Network driver news:
- Added 8139too driver for kernel 2.6.22, thanks to Erwin Burgstaller.
- Added 8139too driver for kernel 2.6.23, thanks to Richard Hacker.
- Added 8139too driver for kernel 2.6.24.
- Added e1000 driver for kernel 2.6.22.
- Added e1000 driver for kernel 2.6.24, thanks to Matthias Luescher.
- Added alpha support for the Realtek r8169 chipset, thanks to Scott
Hassan.
- Fixed unnecessary watchdog executions in e1000 drivers (thanks to
Olav Zarges).
- Fixed missing protection for a spin_lock_irqrestore() call in e1000
drivers from 2.6.20 to 2.6.24 (thanks to Olav Zarges).
* Removed the "bus validation" routines. Slave scanning is now done any time
the bus topology changes, even during realtime operation. Because of this,
the bus_tainted flag was deprecated and removed.
* Slave configuration is not done during ecrt_master_activate() any more, but
later during realtime operation. The state of the configuration can be
queried via the ecrt_domain_state() and ecrt_slave_config_state() functions.
* Added support for slaves that do not support the LRW datagram type. Separate
domains have to be used for inputs and output.
* CoE implementation:
- Use expedites transfer type for SDOs <= 4 byte (thanks to J. Mohre).
- Allow gaps in PDO mapping (thanks to R. Roesch).
- Added some transfer timeouts.
- Asynchronous handling of Emergency requests.
- Bug fixes.
* Sync managers are disabled, if the size is zero.
* Renamed ec_master module parameters main and backup to main_devices and
backup_devices to avoid warnings of some compilers.
* List end evaluate CoE detail flags from general category.
* Added MODPROBE_FLAGS variable in start script and sysconfig file.
* Implemented missing datagram types.
* Changed all occurrences of 'EEPROM' to 'SII'
* Allow multiple sync manager categories in SII.
-------------------------------------------------------------------------------
Changes in version 1.3.2:
* New feature: Read dynamic PDO mapping from SDO dictionary.
* Implemented SII writing workaround for some broken slaves.
* Improved handling for spontaneous AL state changes.
* Master takes mailbox sync manager configurations from EEPROM words
0x0018-0x001b, if no sync manager configurations are provided.
* Calculate checksum when writing EEPROM or alias address.
* Fixed source MAC address setting bug.
* Removed config.kbuild and replaced Kbuild files by Kbuild.in files.
-------------------------------------------------------------------------------
Changes in version 1.3.1:
* Improved EoE handling: Avoided skipping of datagrams and release lock
while processing.
* Added some statistics to the datagram structure.
* Master state machine clears all station addresses with a broadcast datagram
before setting them.
* Added --enable-eoe conditional.
* Minor extensions of the master info file.
* Improved handling of unexpected working counters.
* Create network interfaces for EoE devices with alias as eoeXaY.
* Fixed problems on big-endian systems.
* Added documentation on how to set up an EoE network.
-------------------------------------------------------------------------------
Changes in version 1.3.0:
* Added Intel PRO/1000 Gigabit Ethernet driver (e1000).
* Added testing version of Intel PRO/100 Ethernet driver (e100).
* Added testing version of NVIDIA nForce Ethernet driver (forcedeth).
* Removed "ec_eoeif_count" master module parameter. EoE handlers are created
dynamically instead.
* Added "main" and "backup" parameters to master module to hand over the
MAC addresses of the devices to wait for. This made the ec_device_index
parameter of the Ethernet drivers obsolete. The broadcast MAC address means,
that the master accepts the first device offered by any Ethernet driver.
* Changed format of sysconfig file and accordingly adjusted functionality
of the init script to handle the above MAC address lists.
* Realtime interface changes:
- ecrt_master_run() became obsolete, because the master state machine is now
run in process context.
- Parameter changes in PDO registration functions ecrt_domain_register_pdo()
and ecrt_register_pdo_range(): Replaced slave_address, vendor ID and
product code arguments with a slave pointer, which has to be obtained with
a prior call to ecrt_master_get_slave().
- ecrt_master_get_slave() got additional parameters to check for vendor ID
and product code.
- Removed addressing scheme "X:Y" for ecrt_master_get_slave().
- Added ecrt_master_get_slave_by_pos() to avoid the string handling of
ecrt_master_get_slave().
- Added ecrt_master_get_status() to get status information about the bus.
- Added functions to set up an alternative PDO mapping for a slave, i. e.
ec_slave_pdo_mapping_clear(), ec_slave_pdo_mapping_add() and
ec_slave_pdo_mapping().
* Device interface changes:
- Replaced ecdev_register() and ecdev_unregister() with ecdev_offer() and
ecdev_withdraw(), respectively. The device modules now offer all their
devices to the master. The master then decides, which ones to register.
- Replaced ecdev_link_state() with ecdev_set_link(); added ecdev_get_link().
* All EEPROM write operations from user space are now blocking until
writing has finished. Appropriate error codes are returned.
* Implemented setting of the "Secondary slave address" (alias) via sysfs.
* Implemented SDO reading in operation mode via sysfs.
* Removed annoying eeprom_write_enable file. EEPROM writing always enabled.
* Slave configuration is now done exclusively from the master thread. Removed
ec_master_sync_io(). Userspace threads are now waiting for events in the
state machine.
* Master state machine scheduled with timeout if idle, otherwise is executed
as fast as possible (with schedule()).
* Added dummy module for simulation purposes.
* Limited infinite EEPROM reading, if 0xffff limiter word is missing.
* Init script works now properly on non-SUSE distros (no rc.status dependency
any more).
* Removed EtherCAT line comments from 8139too drivers.
-------------------------------------------------------------------------------
Changes in version 1.2.0:
* Several fixes of bugs and stability issues. Master should now run fine
with kernels 2.6.17 to 2.6.19.
* Realtime interface changes:
- Re-introduced ecrt_domain_queue() to allow datagram queuing apart
from datagram processing. The queuing of a domain's datagrams is not
done in ecrt_domain_process() any more!
- Removed ecrt_master_deactivate(). Its functionality was moved into
ecrt_master_release().
- Removed ecrt_master_prepare(). Its functionality was moved into
ecrt_master_activate().
- Renamed ecdev_start() and ecdev_stop() to ecdev_open() and ecdev_close().
These two functions now take a pointer to ec_device_t as their arguments.
- The data_ptr parameter of ecrt_domain_register_pdo(),
ecrt_domain_register_pdo_list() and ecrt_domain_register_pdo_range() may
not be NULL any more.
- Removed ecrt_slave_pdo_size(). This function was deprecated long before.
- Introduced ECRT_VERSION_MAGIC macro and ecrt_version_magic() function.
* Device interface changes:
- ec_isr_t was replaced by ec_pollfunc_t, the device driver has to supply
a poll function to call its ISR. This was introduced because some network
drivers' interrupt functions have different arguments.
* State machines now try to re-send datagrams on datagram timeout.
* New option -c of the lsec script, displays slave current consumptions and
remaining current.
* Added frame counter in master info file.
-------------------------------------------------------------------------------
Changes in version 1.1.1:
* State change FSM: Clearing of sync managers before PREOP.
* Added modules_install make target.
* Device modules for kernel 2.6.17.
* SDO configurations available in Sysfs.
* FMMU configurations cleared when going to INIT.
* Slave-specific logs only at debug level 1 (for large buses).
* Slave flags (error, online) available in Sysfs.
* Acknowledging of spontaneous state changes in master FSMs.
* ecrt_master_deactivate() deprecated.
* Persistent slave lists. Slave structures are only regenerated on topology
change in IDLE mode.
* SDO reading via Sysfs.
* Added ecrt_domain_register_pdo_range()
* Fetching of SDO dictionary.
* Better timing behaviour when starting up under high CPU load.
* Applied Autotools.
* Improved output of lsec.
* SDO download state machine.
-------------------------------------------------------------------------------
Changes in version 1.1:
* Improved realtime interface.
-------------------------------------------------------------------------------

505
NEWS.md Normal file
View File

@ -0,0 +1,505 @@
# Version 1.6.9
- Protect datagram injection mechanism against re-ordering.
- Fixed for genet and igb drivers for openSUSE Leap 16.0 kernel 6.12.
- tty: Implemented new timer interface since kernel 6.15.
- Do not require .config to exist in kernel sources.
- Fix: Attach slaves before calculating DCs.
- Discard EoE traffic in CoE statemachine, if EoE is disabled.
- Support for Linux 6.19
- Added `--with-kmod-dir` and `--with-ip-cmd` configuration switches
to specify the paths of the tools used in the `ethercatctl` script.
- Changed the default path of the `ip` command to `/sbin/ip`.
# Version 1.6.8
- Fixed usage of `FAKE_EC_HOMEDIR` variable in fake library.
# Version 1.6.7
- Completed API methods in fake library
- Fix igb for openSUSE 15.6 (kernel 6.4)
# Version 1.6.6
- Added Ethernet drivers for kernels 6.4 and 6.12.
- Added missing functions to fake user library.
- Use sint(32) notation in EtherLab output driver
- Added CONTRIBUTING.md
# Version 1.6.5
- Implemented interface changes of Linux 6.15.
# Version 1.6.4
- igc: Set RX descriptor write-back threshold to 1
- Avoid rescan on non-responding slave
- Do not touch AL state of EoE slaves
- Warn if `FAKE_EC_NAME` is not set
- Added configuration switch to disable init.d files
- Fixed FakeEtherCAT operation with multiple masters
- Add `UPDOWN_INTERFACES` option to `ethercat.conf`
- Improvements to the build system
- Fix obsolete warnings on bootstrap
- Explicitly check for pkg-config macros
- Many documentation improvements (thanks to Nicola Fontana)
# Version 1.6.3
- Fix ccat for aarch64 >= 6.11.0
- Removed domain information from libfakeethercat RtIPC paths
- Remove unnecessary inline statement causing build `-O0` problems
- Fixed some compiler warnings
- Added static keywords to internal functions
# Version 1.6.2
- Fixed typo in bash completion.
- Directly include `soe_error_codes` into `SoeCommand.cpp`
- Fixed check of non-zero bit offset in libfakeethercat
# Version 1.6.1
- Added libfakeethercat to simulate Process Data of EtherCAT Slaves.
# Version 1.6.0
- Added all native Ethernet drivers for kernels 5.14 and 6.1.
- Dropped support for kernels < 3.0.
- Allow to query the scanning progress via API.
- Added EoE set IP command via command-line-tool.
- Changed the default AL state change timeout from 5 to 10 s.
# Back-ports since version 1.5.2
- Added feature flag API.
- Fixed FoE timeout calculation bug.
# Version 1.5.2
- API extensions (find the complete description in `include/ecrt.h`)
- Added redundancy features; enable using `--with-devices`.
- Re-designed and seamlessly integrated RTDM interface.
- Added `ecrt_sdo_request_index()` method to change index and subindex.
- Changed the data types of the shift times in `ecrt_slave_config_dc()`
to `int32_t` to correctly display negative shift times.
- Added API for querying CoE emergency requests.
- Added interface to read/write register contents; re-worked register
requests.
- Added interface to select the reference clock and to sync to it.
- Exported `ecrt_domain_size()` to userspace.
- Added `ecrt_slave_config_reg_so_entry_pos()` to register non-unique
PDO entries.
- Ethernet drivers
- Added 8139too driver for 3.0, 3.2, 3.4.
- Added r8169 driver for 2.6.36 (J. Kunz), 3.2 (J. Kunz), 3.4 (F. Pose).
- Added e1000 driver for 3.0, 3.4.
- Added e1000e driver for 3.2 (J. Kunz), 3.4 (F. Pose).
- Added e100 driver for 3.0, 3.4.
- Fixes regarding 8139too driver for 2.6.36.
- Some fixes for all e1000 and e1000e drivers.
- General behaviour
- Avoided semaphore locking from userspace/rtdm library: Implemented
datagram ring instead of queue.
- Assign SII to PDI during PREOP transition; Introduced
`--enable-sii-assign` to switch this on.
- Avoided re-allocating memory in userspace library implementations of
`ecrt_sdo_request_state()` and in VoE handlers.
- Send sync datagrams only if reference clock is found.
- Adjusted some DC clock discipline parameters.
- Fixed AL status code lookup.
- Fixed some `ioctl()` return values and permissions.
- Fixed FoE data OpCode, thanks to R. Roesch.
- Fixed and improved cancelling requests when clearing configuration.
- Using common wait queue for requests.
- Removed some unnecessary request types.
- Output slave FSM datagram statistics.
- Removed some state-dependent datagram skip messages.
- Immediately restart slave FSM on several failed requests.
- Reset master state machine when going to orphaned phase.
- Command-line tool:
- Show complete access flag in config view.
- Added EtherLab skin for `ethercat pdos` command.
- Fixed 'String too large' bug.
- Infrastructure:
- Added `AM_PROG_AR` necessary for autoconf 1.12.
- Avoided use of `AM_CFLAGS`, which is not used in some situations.
- Added vmalloc() include fix for ARM architecture, thanks to Andrea
Scian.
- Install ethercat service to multi-user target by default.
- Fixed COPYING.LESSER to be LGPL 2.1 (like in file headers).
- More detailed output of configure script.
- Added `rtai_rtdm_dc` example, thanks to Graeme Foot.
# Version 1.5.1
- Fixed reset of `allow_scanning` flag if `ecrt_master_activate()` was not
called.
- Fixed missing distribution for r8169 for 2.6.32 and e1000 driver for 2.6.31.
- Added e100 for 2.6.35.
- Added r8169 driver for 2.6.35 (F. Pose).
- Added e1000e driver for 2.6.35 (F. Pose).
- Added fix for ESC port order (DC delay calculation).
- Added e1000 driver for 2.6.35.
# Version 1.5.0
- Added a userspace library for accessing the application interface. This
library is licensed under LGPLv2.
- Added distributed clocks support.
- Added watchdog configuration via application interface (thanks to J. Mohre).
- Added VoE mailbox protocol support.
- Added SoE mailbox protocol support.
- Improved the callback mechanism. `ecrt_master_callbacks()` now takes two
callback functions for sending and receiving datagrams.
`ecrt_master_send_ext()` is used to execute the sending of non-application
datagrams.
- Separated datagram initialization from filling the payload with zeros.
Introduced new method `ec_datagram_zero()` for that.
- Added `phy_read` and `phy_write` commands to `ethercat` tool.
- Added e100 driver for Intel PRO/100 NICs.
- Added e100 driver for 2.6.27.
- Added e100 driver for 2.6.28, thanks to Kim. H. Madsen.
- Added e100 driver for 2.6.29, thanks to Andre Puschmann.
- Added e100 driver for 2.6.31.
- Added e100 driver for 2.6.32.
- Added e100 driver for 2.6.33, thanks to J. Kunz.
- Added e100 driver for 2.6.37.
- Added 8139too driver for kernels 2.6.25 (F. Pose), 2.6.26 (M. Luescher),
2.6.27, 2.6.28, 2.6.29 (M. Goetze), 2.6.31 (F. Pose), 2.6.32 (F. Pose),
2.6.33 (J. Kunz), 2.6.34 (Malcolm Lewis), 2.6.35 (B. Benner),
2.6.36 (F. Pose) and 2.6.37 (F. Pose).
- Added e1000 driver for 2.6.26 (M. Luescher), 2.6.27, 2.6.28, 2.6.29, 2.6.32,
2.6.33 (J. Kunz), 2.6.35, 2.6.37.
- Added r8169 driver for 2.6.24, 2.6.27, 2.6.28, 2.6.29, 2.6.31, 2.6.32
(Robbie K), 2.6.33 (J. Kunz), 2.6.35, 2.6.37.
- Added e1000e driver for 2.6.32, 2.6.33, 2.6.34 (thanks to Siwei Zhuang).
- Debug interfaces are created with the Ethernet addresses of the attached
physical device.
- Improved error case return codes of many functions.
- Implemented the File Access over EtherCAT (FoE) mailbox protocol, thanks to
O. Zarges.
- Going to the Bootstrap state is now supported by the state machines and the
command-line tool.
- Added `ecrt_open_master()` and `ecrt_master_reserve()` separation for
the userspace library (thanks to Martin Troxler).
- Added bus information interface (methods `ecrt_master()`,
`ecrt_master_get_slave()`, `ecrt_master_get_sync_manager()`,
`ecrt_master_get_pdo()` and `ecrt_master_get_pdo_entry()`) to get
information about the currently connected slaves and the PDO entries
provided (thanks to Martin Troxler and Stefan Weiser).
- Added `ecrt_master_sdo_download()` and `ecrt_master_sdo_upload()`
methods to let an application transfer SDOs before activating the master
(thanks to Stefan Weiser).
- Fixed SDO upload segment response (thanks to Christoph Peter).
- Fixed SDO upload segment response for 10 bytes mailbox length (thanks to
Joerg Mohre).
- SDO entry access rights are shown in `ethercat sdos`.
- Added 64-bit data access macros to application header.
- Added debug level for all masters as a module parameter. Thanks to Erwin
Burgstaller.
- Clear slave list on link down.
- Output device link state in `ethercat master`.
- Added `ethercat graph` command which outputs the bus topology in
DOT language.
- Changed `EC_MAX_SII_SIZE` to 4096.
- `ethercat xml` creates valid XML <EtherCATInfoList> for more than one slave
(thanks to E. Burgstaller).
- Added `ethercat eoe` command to display Ethernet over EtherCAT statistics.
- Added `ethercat cstruct` command to output PDO information in C language.
- Significantly improved EoE bandwidth by running EoE processing in a kthread.
- Switched version control from Subversion to Mercurial.
- Implemented CompleteAccess for SDO downloads.
- ethercat tool is now able to handle multiple masters. The `--masters` option
supports ranges like `0,3,8-10`.
- A sync manager is always enabled, if it contains registered process data.
- Added a configuration switch `--enable-wildcards` to use `0xffffffff` as a
wildcard for vendor ID and product code.
- Added support for systemd.
# Version 1.4.0
- Fixed race condition in jiffy-based frame timeout calculation.
- Fixed race condition concerning the `ec_slave_config_state->operational`
flag.
- Fixed wrong calculation of the expected working counter if the process data
of a domain span several datagrams.
- Fixed a kernel oops when a slave configuration is detached while the actual
configuration is in progress.
- Fixed typo in logging output.
- Removed 'bashisms' from init script ('function' keyword).
- Fixed bug in e1000 drivers. Memory was allocated when sending the first
frame.
- Modified licence headers to avoid conflicts with the GPL.
- Restricted licence to GPLv2 only.
- Fixed spelling of 'PDO', 'SDO' (all uppercase) and 'xx over EtherCAT'
(without hyphens).
# Version 1.4.0-rc3
- Ported the master thread to the kthread interface.
- Added missing semaphore `up()` in an `ioctl()`. In rare cases, the master
semaphore was not released.
- Minor fix in `slaves` command that fixed duplicate display of supported
mailbox protocols.
- The SDO Information Service is only queried, if the slave has the
corresponding SII bit set.
- Added some missing header files in the command-line-tool code.
- Removed unstable e100, forcedeth, and r8169 drivers.
# Version 1.4.0-rc2
- Fixed a deadlock causing race condition concerning thread signaling when the
master thread had no opportunity to run, but shall be killed immediately
after creation.
- Added missing `up()`s causing a semaphore being not released in some rare
cases.
- Minor fixes.
- Removed some deprecated files.
# Version 1.4.0-rc1
- Realtime interface changes:
- Replaced `ec_slave_t` with `ec_slave_config_t`, separating the bus
configuration from the actual slaves. Therefore, renamed
`ecrt_master_get_slave()` to `ecrt_master_slave_config()`.
- Replaced slave address string with alias and position values. See
`ecrt_master_slave_config()`.
- Removed `ecrt_master_get_slave_by_pos()`, because it is no longer
necessary due to alias/position addressing.
- Added `ec_slave_config_state_t` for the new method
`ecrt_slave_config_state()`.
- Process data memory for a domain can now be allocated externally. This
offers the possibility to use a shared-memory region. Therefore,
added the domain methods `ecrt_domain_size()` and
`ecrt_domain_external_memory()`.
- PDO entry registration functions do not return a process data pointer,
but an offset in the domain's process data. In addition, an optional bit
position can be requested. This was necessary for the external domain
memory. An additional advantage is, that the returned offset is
immediately valid. If the domain's process data is allocated internally,
the start address can be retrieved with `ecrt_domain_data()`.
- Replaced `ecrt_slave_pdo_mapping/add/clear()` with
`ecrt_slave_config_pdo_assign_add()` to add a PDO to a sync manager's
PDO assignment and `ecrt_slave_config_pdo_mapping_add()` to add a PDO
entry to a PDO's mapping. `ecrt_slave_config_pdos()` is a convenience
function for both, that uses the new data types `ec_pdo_info_t` and
`ec_pdo_entry_info_t`. PDO entries, that are mapped with these functions
can now immediately be registered, even if the bus is offline.
- Renamed `ec_bus_status_t`, `ec_master_status_t` to `ec_bus_state_t` and
`ec_master_state_t`, respectively. Renamed `ecrt_master_get_status()` to
`ecrt_master_state()`, for consistency reasons.
- Added `ec_domain_state_t` and `ec_wc_state_t` for a new output parameter
of `ecrt_domain_state()`. The domain state object does now contain
information, if the process data was exchanged completely.
- Former "PDO registration" meant PDO entry registration in fact, therefore
renamed `ec_pdo_reg_t` to `ec_pdo_entry_reg_t` and
`ecrt_domain_register_pdo()` to `ecrt_slave_config_reg_pdo_entry()`.
- Removed `ecrt_domain_register_pdo_range()`, because it's functionality
can be reached by specifying an explicit PDO assignment/mapping and
registering the mapped PDO entries.
- Added an SDO access interface, working with SDO requests. These can be
scheduled for reading and writing during realtime operation.
- Exported `ecrt_slave_config_sdo()`, the generic SDO configuration
function.
- Removed the `bus_state` and `bus_tainted` flags from
`ec_master_state_t`.
- Device interface changes:
- Moved device output parameter of `ecdev_offer()` to return value.
- Replaced the Sysfs interface with a new `ethercat` command-line tool, that
communicates with the master via a character device and ioctls. The device
is created via udev. The tool is able to
- Write alias addresses.
- Show the bus configuration.
- Output binary domain process data.
- Set the master's debug level.
- Show domain information.
- Show master information.
- List PDO assignment/mapping.
- Write an SDO entry.
- List SDO dictionaries.
- Read an SDO entry.
- Output a slave's SII contents.
- Write slave's SII contents.
- Show slaves.
- Request slave states.
- Generate slave information xmls.
- Removed include/ecdb.h.
- Using the timestamp counter is now optional (configure `--enable-cycles`),
because it is only available on Intel architectures.
- SDO dictionaries will now also be fetched in operation mode.
- SII write requests will now also be processed in operation mode.
- Mapping of PDO entries is now supported.
- Current PDO assignment/mapping is now read via CoE during bus scan, using
direct SDO access, independent of the dictionary.
- Network driver news:
- Added 8139too driver for kernel 2.6.22, thanks to Erwin Burgstaller.
- Added 8139too driver for kernel 2.6.23, thanks to Richard Hacker.
- Added 8139too driver for kernel 2.6.24.
- Added e1000 driver for kernel 2.6.22.
- Added e1000 driver for kernel 2.6.24, thanks to Matthias Luescher.
- Added alpha support for the Realtek r8169 chipset, thanks to Scott
Hassan.
- Fixed unnecessary watchdog executions in e1000 drivers (thanks to
Olav Zarges).
- Fixed missing protection for a `spin_lock_irqrestore()` call in e1000
drivers from 2.6.20 to 2.6.24 (thanks to Olav Zarges).
- Removed the "bus validation" routines. Slave scanning is now done any time
the bus topology changes, even during realtime operation. Because of this,
the `bus_tainted` flag was deprecated and removed.
- Slave configuration is not done during `ecrt_master_activate()` any more,
but later during realtime operation. The state of the configuration can be
queried via the `ecrt_domain_state()` and `ecrt_slave_config_state()`
functions.
- Added support for slaves that do not support the LRW datagram type. Separate
domains have to be used for inputs and output.
- CoE implementation:
- Use expedites transfer type for SDOs <= 4 byte (thanks to J. Mohre).
- Allow gaps in PDO mapping (thanks to R. Roesch).
- Added some transfer timeouts.
- Asynchronous handling of Emergency requests.
- Bug fixes.
- Sync managers are disabled, if the size is zero.
- Renamed `ec_master` module parameters main and backup to `main_devices` and
`backup_devices` to avoid warnings of some compilers.
- List end evaluate CoE detail flags from general category.
- Added `MODPROBE_FLAGS` variable in start script and sysconfig file.
- Implemented missing datagram types.
- Changed all occurrences of 'EEPROM' to 'SII'
- Allow multiple sync manager categories in SII.
# Version 1.3.2
- New feature: Read dynamic PDO mapping from SDO dictionary.
- Implemented SII writing workaround for some broken slaves.
- Improved handling for spontaneous AL state changes.
- Master takes mailbox sync manager configurations from EEPROM words
0x0018-0x001b, if no sync manager configurations are provided.
- Calculate checksum when writing EEPROM or alias address.
- Fixed source MAC address setting bug.
- Removed config.kbuild and replaced Kbuild files by Kbuild.in files.
# Version 1.3.1
- Improved EoE handling: Avoided skipping of datagrams and release lock
while processing.
- Added some statistics to the datagram structure.
- Master state machine clears all station addresses with a broadcast datagram
before setting them.
- Added `--enable-eoe` conditional.
- Minor extensions of the master info file.
- Improved handling of unexpected working counters.
- Create network interfaces for EoE devices with alias as eoeXaY.
- Fixed problems on big-endian systems.
- Added documentation on how to set up an EoE network.
# Version 1.3.0
- Added Intel PRO/1000 Gigabit Ethernet driver (e1000).
- Added testing version of Intel PRO/100 Ethernet driver (e100).
- Added testing version of NVIDIA nForce Ethernet driver (forcedeth).
- Removed `ec_eoeif_count` master module parameter. EoE handlers are created
dynamically instead.
- Added "main" and "backup" parameters to master module to hand over the
MAC addresses of the devices to wait for. This made the `ec_device_index`
parameter of the Ethernet drivers obsolete. The broadcast MAC address means,
that the master accepts the first device offered by any Ethernet driver.
- Changed format of sysconfig file and accordingly adjusted functionality
of the init script to handle the above MAC address lists.
- Realtime interface changes:
- `ecrt_master_run()` became obsolete, because the master state machine is
now run in process context.
- Parameter changes in PDO registration functions
`ecrt_domain_register_pdo()` and `ecrt_register_pdo_range()`: Replaced
`slave_address`, vendor ID and product code arguments with a slave
pointer, which has to be obtained with a prior call to
`ecrt_master_get_slave()`.
- `ecrt_master_get_slave()` got additional parameters to check for vendor ID
and product code.
- Removed addressing scheme "X:Y" for `ecrt_master_get_slave()`.
- Added `ecrt_master_get_slave_by_pos()` to avoid the string handling of
`ecrt_master_get_slave()`.
- Added `ecrt_master_get_status()` to get status information about the bus.
- Added functions to set up an alternative PDO mapping for a slave, i. e.
`ec_slave_pdo_mapping_clear()`, `ec_slave_pdo_mapping_add()` and
`ec_slave_pdo_mapping()`.
- Device interface changes:
- Replaced `ecdev_register()` and `ecdev_unregister()` with `ecdev_offer()`
and `ecdev_withdraw()`, respectively. The device modules now offer all
their devices to the master. The master then decides, which ones to
register.
- Replaced `ecdev_link_state()` with `ecdev_set_link()`; added
`ecdev_get_link()`.
- All EEPROM write operations from user space are now blocking until
writing has finished. Appropriate error codes are returned.
- Implemented setting of the "Secondary slave address" (alias) via sysfs.
- Implemented SDO reading in operation mode via sysfs.
- Removed annoying `eeprom_write_enable` file. EEPROM writing always enabled.
- Slave configuration is now done exclusively from the master thread. Removed
`ec_master_sync_io()`. Userspace threads are now waiting for events in the
state machine.
- Master state machine scheduled with timeout if idle, otherwise is executed
as fast as possible (with `schedule()`).
- Added dummy module for simulation purposes.
- Limited infinite EEPROM reading, if 0xffff limiter word is missing.
- Init script works now properly on non-SUSE distros (no rc.status dependency
any more).
- Removed EtherCAT line comments from 8139too drivers.
# Version 1.2.0
- Several fixes of bugs and stability issues. Master should now run fine
with kernels 2.6.17 to 2.6.19.
- Realtime interface changes:
- Re-introduced `ecrt_domain_queue()` to allow datagram queuing apart
from datagram processing. The queuing of a domain's datagrams is not
done in `ecrt_domain_process()` any more!
- Removed `ecrt_master_deactivate()`. Its functionality was moved into
`ecrt_master_release()`.
- Removed `ecrt_master_prepare()`. Its functionality was moved into
`ecrt_master_activate()`.
- Renamed `ecdev_start()` and `ecdev_stop()` to `ecdev_open()` and
`ecdev_close()`. These two functions now take a pointer to `ec_device_t`
as their arguments.
- The `data_ptr` parameter of `ecrt_domain_register_pdo()`,
`ecrt_domain_register_pdo_list()` and `ecrt_domain_register_pdo_range()`
may not be NULL any more.
- Removed `ecrt_slave_pdo_size()`. This function was deprecated long before.
- Introduced `ECRT_VERSION_MAGIC` macro and `ecrt_version_magic()` function.
- Device interface changes:
- `ec_isr_t` was replaced by `ec_pollfunc_t`, the device driver has to
supply a poll function to call its ISR. This was introduced because some
network drivers' interrupt functions have different arguments.
- State machines now try to re-send datagrams on datagram timeout.
- New option `-c` of the `lsec` script, displays slave current consumptions and
remaining current.
- Added frame counter in master info file.
# Version 1.1.1
- State change FSM: Clearing of sync managers before PREOP.
- Added `modules_install` make target.
- Device modules for kernel 2.6.17.
- SDO configurations available in Sysfs.
- FMMU configurations cleared when going to INIT.
- Slave-specific logs only at debug level 1 (for large buses).
- Slave flags (error, online) available in Sysfs.
- Acknowledging of spontaneous state changes in master FSMs.
- `ecrt_master_deactivate()` deprecated.
- Persistent slave lists. Slave structures are only regenerated on topology
change in IDLE mode.
- SDO reading via Sysfs.
- Added `ecrt_domain_register_pdo_range()`
- Fetching of SDO dictionary.
- Better timing behaviour when starting up under high CPU load.
- Applied Autotools.
- Improved output of `lsec`.
- SDO download state machine.
# Version 1.1
- Improved realtime interface.
vim: spelllang=en spell tw=78

View File

@ -24,13 +24,11 @@ AC_PREREQ([2.59])
# #
# Release procedure # Release procedure
# - Update Ethernet drivers up to release kernel version # - Update Ethernet drivers up to release kernel version
# - Write NEWS entry with changes since last release # - Write NEWS.md entry with changes since last release
# - Check for complete Doxygen comments # - Check for complete Doxygen comments
# - Update the ChangeLog -> git log > ChangeLog
# - Update version number below # - Update version number below
# - make dist-bzip2
# #
AC_INIT([ethercat], [1.6.6], [fp@igh.de]) AC_INIT([ethercat], [1.6.9], [fp@igh.de])
AC_CONFIG_AUX_DIR([autoconf]) AC_CONFIG_AUX_DIR([autoconf])
AM_INIT_AUTOMAKE([-Wall -Wno-override -Werror dist-bzip2 subdir-objects foreign]) AM_INIT_AUTOMAKE([-Wall -Wno-override -Werror dist-bzip2 subdir-objects foreign])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
@ -61,7 +59,7 @@ AC_MSG_CHECKING([whether to build kernel modules])
AC_ARG_ENABLE([kernel], AC_ARG_ENABLE([kernel],
AS_HELP_STRING([--enable-kernel], AS_HELP_STRING([--enable-kernel],
[Enable building kernel modules]), [Enable building kernel modules [default=yes]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) enablekernel=1 yes) enablekernel=1
@ -92,7 +90,7 @@ if test "x$enablekernel" = "x1"; then
AC_ARG_WITH([linux-dir], AC_ARG_WITH([linux-dir],
AS_HELP_STRING([--with-linux-dir=<DIR>], AS_HELP_STRING([--with-linux-dir=<DIR>],
[Linux kernel sources @<:@running kernel@:>@]), [Linux kernel sources [running kernel]]),
[ [
sourcedir=[$withval] sourcedir=[$withval]
], ],
@ -109,9 +107,9 @@ AC_ARG_WITH([linux-dir],
AC_MSG_CHECKING([for Linux kernel sources]) AC_MSG_CHECKING([for Linux kernel sources])
if test \! -r ${sourcedir}/.config; then if test \! -r ${sourcedir}/Makefile; then
echo echo
AC_MSG_ERROR([No configured Linux kernel sources in $sourcedir]) AC_MSG_ERROR([No Linux kernel sources in $sourcedir])
fi fi
# Try to get kernel release string # Try to get kernel release string
@ -129,7 +127,7 @@ fi
if test -z "$kernelrelease"; then if test -z "$kernelrelease"; then
echo echo
AC_MSG_ERROR([Failed to extract Linux kernel version!]) AC_MSG_ERROR([Failed to extract Linux kernel version! Does ${sourcedir} contain prepared kernel sources?])
fi fi
if test ${kernelrelease%%.*} -gt 2; then if test ${kernelrelease%%.*} -gt 2; then
@ -152,7 +150,7 @@ fi
AC_ARG_WITH([module-dir], AC_ARG_WITH([module-dir],
AS_HELP_STRING([--with-module-dir=<DIR>], AS_HELP_STRING([--with-module-dir=<DIR>],
[Linux module installation dir. Default: ethercat]), [Linux module installation dir [default=ethercat]]),
[moddir=[$withval]], [moddir=[$withval]],
[moddir="ethercat"] [moddir="ethercat"]
) )
@ -169,7 +167,7 @@ AC_MSG_CHECKING([whether to verify native driver resources])
AC_ARG_ENABLE([driver-resource-verifying], AC_ARG_ENABLE([driver-resource-verifying],
AS_HELP_STRING([--enable-driver-resource-verifying], AS_HELP_STRING([--enable-driver-resource-verifying],
[Verify resource (de-)allocation in native drivers]), [Verify resource (de-)allocation in native drivers [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) enableverifying=1 yes) enableverifying=1
@ -198,7 +196,7 @@ AC_SUBST(ENABLE_DRIVER_RESOURCE_VERIFYING, [$enableverifying])
AC_ARG_ENABLE([generic], AC_ARG_ENABLE([generic],
AS_HELP_STRING([--enable-generic], AS_HELP_STRING([--enable-generic],
[Enable generic Ethernet driver]), [Build generic Ethernet driver [default=enable-kernel]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) enablegeneric=1 yes) enablegeneric=1
@ -221,7 +219,7 @@ AC_SUBST(ENABLE_GENERIC, [$enablegeneric])
AC_ARG_ENABLE([8139too], AC_ARG_ENABLE([8139too],
AS_HELP_STRING([--enable-8139too], AS_HELP_STRING([--enable-8139too],
[Enable 8139too driver]), [Build 8139too driver [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) enable8139too=1 yes) enable8139too=1
@ -232,7 +230,7 @@ AC_ARG_ENABLE([8139too],
;; ;;
esac esac
], ],
[enable8139too=0] # disabled by default [enable8139too=0]
) )
AM_CONDITIONAL(ENABLE_8139TOO, test "x$enable8139too" = "x1") AM_CONDITIONAL(ENABLE_8139TOO, test "x$enable8139too" = "x1")
@ -274,7 +272,7 @@ AC_SUBST(KERNEL_8139TOO, [$kernel8139too])
AC_ARG_ENABLE([e100], AC_ARG_ENABLE([e100],
AS_HELP_STRING([--enable-e100], AS_HELP_STRING([--enable-e100],
[Enable e100 driver]), [Build e100 driver [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) enablee100=1 yes) enablee100=1
@ -285,7 +283,7 @@ AC_ARG_ENABLE([e100],
;; ;;
esac esac
], ],
[enablee100=0] # disabled by default [enablee100=0]
) )
AM_CONDITIONAL(ENABLE_E100, test "x$enablee100" = "x1") AM_CONDITIONAL(ENABLE_E100, test "x$enablee100" = "x1")
@ -327,7 +325,7 @@ AC_SUBST(KERNEL_E100, [$kernele100])
AC_ARG_ENABLE([e1000], AC_ARG_ENABLE([e1000],
AS_HELP_STRING([--enable-e1000], AS_HELP_STRING([--enable-e1000],
[Enable e1000 driver]), [Build e1000 driver [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) enablee1000=1 yes) enablee1000=1
@ -338,7 +336,7 @@ AC_ARG_ENABLE([e1000],
;; ;;
esac esac
], ],
[enablee1000=0] # disabled by default [enablee1000=0]
) )
AM_CONDITIONAL(ENABLE_E1000, test "x$enablee1000" = "x1") AM_CONDITIONAL(ENABLE_E1000, test "x$enablee1000" = "x1")
@ -380,7 +378,7 @@ AC_SUBST(KERNEL_E1000, [$kernele1000])
AC_ARG_ENABLE([e1000e], AC_ARG_ENABLE([e1000e],
AS_HELP_STRING([--enable-e1000e], AS_HELP_STRING([--enable-e1000e],
[Enable e1000e driver]), [Build e1000e driver [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) enablee1000e=1 yes) enablee1000e=1
@ -391,7 +389,7 @@ AC_ARG_ENABLE([e1000e],
;; ;;
esac esac
], ],
[enablee1000e=0] # disabled by default [enablee1000e=0]
) )
AM_CONDITIONAL(ENABLE_E1000E, test "x$enablee1000e" = "x1") AM_CONDITIONAL(ENABLE_E1000E, test "x$enablee1000e" = "x1")
@ -453,7 +451,7 @@ AC_SUBST(E1000E_LAYOUT, [$e1000elayout])
AC_ARG_ENABLE([genet], AC_ARG_ENABLE([genet],
AS_HELP_STRING([--enable-genet], AS_HELP_STRING([--enable-genet],
[Enable genet driver (for Raspi 4)]), [Build genet driver for Raspi 4 [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) enablegenet=1 yes) enablegenet=1
@ -464,7 +462,7 @@ AC_ARG_ENABLE([genet],
;; ;;
esac esac
], ],
[enablegenet=0] # disabled by default [enablegenet=0]
) )
AM_CONDITIONAL(ENABLE_GENET, test "x$enablegenet" = "x1") AM_CONDITIONAL(ENABLE_GENET, test "x$enablegenet" = "x1")
@ -499,7 +497,7 @@ AC_SUBST(KERNEL_GENET, [$kernelgenet])
AC_ARG_ENABLE([igb], AC_ARG_ENABLE([igb],
AS_HELP_STRING([--enable-igb], AS_HELP_STRING([--enable-igb],
[Enable igb driver]), [Build igb driver [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) enableigb=1 yes) enableigb=1
@ -510,7 +508,7 @@ AC_ARG_ENABLE([igb],
;; ;;
esac esac
], ],
[enableigb=0] # disabled by default [enableigb=0]
) )
AM_CONDITIONAL(ENABLE_IGB, test "x$enableigb" = "x1") AM_CONDITIONAL(ENABLE_IGB, test "x$enableigb" = "x1")
@ -546,7 +544,7 @@ AC_SUBST(KERNEL_IGB, [$kerneligb])
AC_ARG_ENABLE([igc], AC_ARG_ENABLE([igc],
AS_HELP_STRING([--enable-igc], AS_HELP_STRING([--enable-igc],
[Enable igc driver]), [Build igc driver [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) enableigc=1 yes) enableigc=1
@ -557,7 +555,7 @@ AC_ARG_ENABLE([igc],
;; ;;
esac esac
], ],
[enableigc=0] # disabled by default [enableigc=0]
) )
AM_CONDITIONAL(ENABLE_IGC, test "x$enableigc" = "x1") AM_CONDITIONAL(ENABLE_IGC, test "x$enableigc" = "x1")
@ -608,7 +606,7 @@ has_r8169_leds=0
AC_ARG_ENABLE([r8169], AC_ARG_ENABLE([r8169],
AS_HELP_STRING([--enable-r8169], AS_HELP_STRING([--enable-r8169],
[Enable r8169 driver]), [Build r8169 driver [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) enable_r8169=1 yes) enable_r8169=1
@ -619,7 +617,7 @@ AC_ARG_ENABLE([r8169],
;; ;;
esac esac
], ],
[enable_r8169=0] # disabled by default [enable_r8169=0]
) )
AM_CONDITIONAL(ENABLE_R8169, test "x$enable_r8169" = "x1") AM_CONDITIONAL(ENABLE_R8169, test "x$enable_r8169" = "x1")
@ -683,7 +681,7 @@ enablestmmac=0
AC_ARG_ENABLE([stmmac-pci], AC_ARG_ENABLE([stmmac-pci],
AS_HELP_STRING([--enable-stmmac-pci], AS_HELP_STRING([--enable-stmmac-pci],
[Enable stmmac driver]), [Build stmmac driver [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) enablestmmacpci=1 yes) enablestmmacpci=1
@ -695,7 +693,7 @@ AC_ARG_ENABLE([stmmac-pci],
;; ;;
esac esac
], ],
[enablestmmacpci=0] # disabled by default [enablestmmacpci=0]
) )
AM_CONDITIONAL(ENABLE_STMMACPCI, test "x$enablestmmacpci" = "x1") AM_CONDITIONAL(ENABLE_STMMACPCI, test "x$enablestmmacpci" = "x1")
@ -703,7 +701,7 @@ AC_SUBST(ENABLE_STMMACPCI, [$enablestmmacpci])
AC_ARG_ENABLE([dwmac-intel], AC_ARG_ENABLE([dwmac-intel],
AS_HELP_STRING([--enable-dwmac-intel], AS_HELP_STRING([--enable-dwmac-intel],
[Enable stmmac driver]), [Build dwmac intel driver [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) enabledwmacintel=1 yes) enabledwmacintel=1
@ -715,7 +713,7 @@ AC_ARG_ENABLE([dwmac-intel],
;; ;;
esac esac
], ],
[enabledwmacintel=0] # disabled by default [enabledwmacintel=0]
) )
AM_CONDITIONAL(ENABLE_DWMACINTEL, test "x$enabledwmacintel" = "x1") AM_CONDITIONAL(ENABLE_DWMACINTEL, test "x$enabledwmacintel" = "x1")
@ -766,7 +764,7 @@ AC_MSG_CHECKING([whether to build the CCAT driver])
AC_ARG_ENABLE([ccat], AC_ARG_ENABLE([ccat],
AS_HELP_STRING([--enable-ccat], AS_HELP_STRING([--enable-ccat],
[Enable CCAT driver]), [Build CCAT driver [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) enableccat=1 yes) enableccat=1
@ -777,7 +775,7 @@ AC_ARG_ENABLE([ccat],
;; ;;
esac esac
], ],
[enableccat=0] # disabled by default [enableccat=0]
) )
if test "x${enableccat}" = "x1"; then if test "x${enableccat}" = "x1"; then
@ -850,7 +848,7 @@ AC_ARG_WITH([xenomai-dir],
AC_ARG_WITH([xenomai-config], AC_ARG_WITH([xenomai-config],
AS_HELP_STRING([--with-xenomai-config=<CMD>], AS_HELP_STRING([--with-xenomai-config=<CMD>],
[Xenomai config invokation, default to xenomai-dir/bin/xeno-config]), [Xenomai config invocation [default=xenomai-dir/bin/xeno-config]]),
[ [
xenomaiconfig=[$withval] xenomaiconfig=[$withval]
], ],
@ -948,7 +946,7 @@ AC_MSG_CHECKING([whether to build the debug interface])
AC_ARG_ENABLE([debug-if], AC_ARG_ENABLE([debug-if],
AS_HELP_STRING([--enable-debug-if], AS_HELP_STRING([--enable-debug-if],
[Create a debug interface for each master @<:@NO@:>@]), [Create a debug interface for each master [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) dbg=1 yes) dbg=1
@ -980,7 +978,7 @@ AC_MSG_CHECKING([whether to build the debug ring])
AC_ARG_ENABLE([debug-ring], AC_ARG_ENABLE([debug-ring],
AS_HELP_STRING([--enable-debug-ring], AS_HELP_STRING([--enable-debug-ring],
[Create a debug ring to record frames @<:@NO@:>@]), [Create a debug ring to record frames [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) debugring=1 yes) debugring=1
@ -1009,7 +1007,7 @@ AC_MSG_CHECKING([whether to build with EoE support])
AC_ARG_ENABLE([eoe], AC_ARG_ENABLE([eoe],
AS_HELP_STRING([--enable-eoe], AS_HELP_STRING([--enable-eoe],
[Enable EoE support (default: yes)]), [Enable EoE support [default=yes]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) eoe=1 yes) eoe=1
@ -1041,7 +1039,7 @@ AC_MSG_CHECKING([whether to use the CPU timestamp counter])
AC_ARG_ENABLE([cycles], AC_ARG_ENABLE([cycles],
AS_HELP_STRING([--enable-cycles], AS_HELP_STRING([--enable-cycles],
[Use CPU timestamp counter (default: no)]), [Use CPU timestamp counter [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) cycles=1 yes) cycles=1
@ -1070,7 +1068,7 @@ AC_MSG_CHECKING([whether to use high-resolution timers for scheduling])
AC_ARG_ENABLE([hrtimer], AC_ARG_ENABLE([hrtimer],
AS_HELP_STRING([--enable-hrtimer], AS_HELP_STRING([--enable-hrtimer],
[Use high-resolution timer for scheduling (default: no)]), [Use high-resolution timer for scheduling [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) hrtimer=1 yes) hrtimer=1
@ -1099,7 +1097,7 @@ AC_MSG_CHECKING([whether to read alias addresses from registers])
AC_ARG_ENABLE([regalias], AC_ARG_ENABLE([regalias],
AS_HELP_STRING([--enable-regalias], AS_HELP_STRING([--enable-regalias],
[Read alias adresses from register (default: no)]), [Read alias adresses from register [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) regalias=1 yes) regalias=1
@ -1128,7 +1126,7 @@ AC_MSG_CHECKING([whether to build the command-line tool])
AC_ARG_ENABLE([tool], AC_ARG_ENABLE([tool],
AS_HELP_STRING([--enable-tool], AS_HELP_STRING([--enable-tool],
[Build command-line tool (default: yes)]), [Build command-line tool [default=yes]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) tool=1 yes) tool=1
@ -1158,7 +1156,7 @@ AC_MSG_CHECKING([whether to build the userspace library])
AC_ARG_ENABLE([userlib], AC_ARG_ENABLE([userlib],
AS_HELP_STRING([--enable-userlib], AS_HELP_STRING([--enable-userlib],
[Generation of the userspace library (default: yes)]), [Generation of userspace library [default=yes]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) userlib=1 yes) userlib=1
@ -1188,7 +1186,7 @@ AC_MSG_CHECKING([whether to build the fake userspace library])
AC_ARG_ENABLE([fakeuserlib], AC_ARG_ENABLE([fakeuserlib],
AS_HELP_STRING([--enable-fakeuserlib], AS_HELP_STRING([--enable-fakeuserlib],
[Generation of the userspace library (default: no)]), [Generation of fake userspace library [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) fakeuserlib=1 yes) fakeuserlib=1
@ -1219,7 +1217,7 @@ AC_MSG_CHECKING([whether to build the tty driver])
AC_ARG_ENABLE([tty], AC_ARG_ENABLE([tty],
AS_HELP_STRING([--enable-tty], AS_HELP_STRING([--enable-tty],
[Generation of the ec_tty module (default: no)]), [Generation of the ec_tty module [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) tty=1 yes) tty=1
@ -1250,7 +1248,7 @@ AC_MSG_CHECKING([whether to allow identification wildcards])
AC_ARG_ENABLE([wildcards], AC_ARG_ENABLE([wildcards],
AS_HELP_STRING([--enable-wildcards], AS_HELP_STRING([--enable-wildcards],
[Enable vendor ID / product code wildcards (default: no)]), [Enable vendor ID / product code wildcards [default=no]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) wildcards=1 yes) wildcards=1
@ -1278,7 +1276,7 @@ fi
AC_ARG_WITH([devices], AC_ARG_WITH([devices],
AS_HELP_STRING([--with-devices=<NUMBER>], AS_HELP_STRING([--with-devices=<NUMBER>],
[Number of Ethernet devices per master. Default: 1]), [Number of Ethernet devices per master [default=1]]),
[ [
devices=[$withval] devices=[$withval]
], ],
@ -1310,7 +1308,7 @@ AC_MSG_CHECKING([whether to assign the SII to PDI])
AC_ARG_ENABLE([sii-assign], AC_ARG_ENABLE([sii-assign],
AS_HELP_STRING([--enable-sii-assign], AS_HELP_STRING([--enable-sii-assign],
[Enable SII assignment to PDI (default: yes)]), [Enable SII assignment to PDI [default=yes]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) siiassign=1 yes) siiassign=1
@ -1339,7 +1337,7 @@ AC_MSG_CHECKING([whether to syslog in realtime context])
AC_ARG_ENABLE([rt-syslog], AC_ARG_ENABLE([rt-syslog],
AS_HELP_STRING([--enable-rt-syslog], AS_HELP_STRING([--enable-rt-syslog],
[Enable RT syslog (default: yes)]), [Enable RT syslog [default=yes]]),
[ [
case "${enableval}" in case "${enableval}" in
yes) rtsyslog=1 yes) rtsyslog=1
@ -1365,8 +1363,8 @@ fi
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
AC_ARG_ENABLE([initd], AC_ARG_ENABLE([initd],
AS_HELP_STRING([--disable-initd], AS_HELP_STRING([--enable-initd],
[Disable /etc/init.d script support (default: enabled)]) [Install /etc/init.d scripts [default=yes]])
) )
AM_CONDITIONAL(HAVE_INITD, test "x$enable_initd" != "xno") AM_CONDITIONAL(HAVE_INITD, test "x$enable_initd" != "xno")
@ -1399,6 +1397,32 @@ esac
AM_CONDITIONAL(HAVE_SYSTEMD, test "x$with_systemdsystemunitdir" != "x") AM_CONDITIONAL(HAVE_SYSTEMD, test "x$with_systemdsystemunitdir" != "x")
AC_SUBST(systemdsystemunitdir, [$with_systemdsystemunitdir]) AC_SUBST(systemdsystemunitdir, [$with_systemdsystemunitdir])
#-----------------------------------------------------------------------------
# System utilities
#-----------------------------------------------------------------------------
AC_ARG_WITH([kmod-dir],
AS_HELP_STRING([--with-kmod-dir=<DIR>],
[Path to kernel module utilities [default=/sbin]]),
[kmoddir=[$withval]],
[kmoddir="/sbin"]
)
AC_MSG_CHECKING([for path to kernel modules])
AC_MSG_RESULT([$kmoddir])
AC_SUBST(kmoddir, [$kmoddir])
AC_ARG_WITH([ip-cmd],
AS_HELP_STRING([--with-ip-cmd=<CMD>],
['ip' command to use [default=/sbin/ip]]),
[ipcmd=[$withval]],
[ipcmd="/sbin/ip"]
)
AC_MSG_CHECKING([for ip command])
AC_MSG_RESULT([$ipcmd])
AC_SUBST(ipcmd, [$ipcmd])
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
AC_CONFIG_FILES([ AC_CONFIG_FILES([

View File

@ -234,7 +234,11 @@ int ec_gen_device_create_socket(
sa.sll_family = AF_PACKET; sa.sll_family = AF_PACKET;
sa.sll_protocol = htons(ETH_P_ETHERCAT); sa.sll_protocol = htons(ETH_P_ETHERCAT);
sa.sll_ifindex = desc->ifindex; sa.sll_ifindex = desc->ifindex;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 19, 0)
ret = kernel_bind(dev->socket, (struct sockaddr_unsized *) &sa, sizeof(sa));
#else
ret = kernel_bind(dev->socket, (struct sockaddr *) &sa, sizeof(sa)); ret = kernel_bind(dev->socket, (struct sockaddr *) &sa, sizeof(sa));
#endif
if (ret) { if (ret) {
printk(KERN_ERR PFX "Failed to bind() socket to interface" printk(KERN_ERR PFX "Failed to bind() socket to interface"
" (ret = %i).\n", ret); " (ret = %i).\n", ret);

View File

@ -2459,7 +2459,11 @@ static int bcmgenet_rx_poll(struct napi_struct *napi, int budget)
if (ring->dim.use_dim) { if (ring->dim.use_dim) {
dim_update_sample(ring->dim.event_ctr, ring->dim.packets, dim_update_sample(ring->dim.event_ctr, ring->dim.packets,
ring->dim.bytes, &dim_sample); ring->dim.bytes, &dim_sample);
#ifdef CONFIG_SUSE_KERNEL
net_dim(&ring->dim.dim, &dim_sample);
#else
net_dim(&ring->dim.dim, dim_sample); net_dim(&ring->dim.dim, dim_sample);
#endif
} }
return work_done; return work_done;

View File

@ -18,6 +18,19 @@
#include "igb-6.4-ethercat.h" #include "igb-6.4-ethercat.h"
#ifdef CONFIG_SUSE_KERNEL
#include <linux/suse_version.h>
#else
# ifndef SUSE_VERSION
# define SUSE_VERSION 0
# endif
# ifndef SUSE_PATCHLEVEL
# define SUSE_PATCHLEVEL 0
# endif
#endif
struct igb_stats { struct igb_stats {
char stat_string[ETH_GSTRING_LEN]; char stat_string[ETH_GSTRING_LEN];
int sizeof_stat; int sizeof_stat;
@ -3278,6 +3291,22 @@ static u32 igb_get_rxfh_indir_size(struct net_device *netdev)
return IGB_RETA_SIZE; return IGB_RETA_SIZE;
} }
#if SUSE_VERSION == 15 && SUSE_PATCHLEVEL >= 6
static int igb_get_rxfh(struct net_device *netdev,
struct ethtool_rxfh_param *rxfh)
{
struct igb_adapter *adapter = netdev_priv(netdev);
int i;
rxfh->hfunc = ETH_RSS_HASH_TOP;
if (!rxfh->indir)
return 0;
for (i = 0; i < IGB_RETA_SIZE; i++)
rxfh->indir[i] = adapter->rss_indir_tbl[i];
return 0;
}
#else
static int igb_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, static int igb_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
u8 *hfunc) u8 *hfunc)
{ {
@ -3293,6 +3322,7 @@ static int igb_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
return 0; return 0;
} }
#endif
void igb_write_rss_indir_tbl(struct igb_adapter *adapter) void igb_write_rss_indir_tbl(struct igb_adapter *adapter)
{ {
@ -3329,6 +3359,50 @@ void igb_write_rss_indir_tbl(struct igb_adapter *adapter)
} }
} }
#if SUSE_VERSION == 15 && SUSE_PATCHLEVEL >= 6
static int igb_set_rxfh(struct net_device *netdev,
struct ethtool_rxfh_param *rxfh,
struct netlink_ext_ack *extack)
{
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
int i;
u32 num_queues;
/* We do not allow change in unsupported parameters */
if (rxfh->key ||
(rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
rxfh->hfunc != ETH_RSS_HASH_TOP))
return -EOPNOTSUPP;
if (!rxfh->indir)
return 0;
num_queues = adapter->rss_queues;
switch (hw->mac.type) {
case e1000_82576:
/* 82576 supports 2 RSS queues for SR-IOV */
if (adapter->vfs_allocated_count)
num_queues = 2;
break;
default:
break;
}
/* Verify user input. */
for (i = 0; i < IGB_RETA_SIZE; i++)
if (rxfh->indir[i] >= num_queues)
return -EINVAL;
for (i = 0; i < IGB_RETA_SIZE; i++)
adapter->rss_indir_tbl[i] = rxfh->indir[i];
igb_write_rss_indir_tbl(adapter);
return 0;
}
#else
static int igb_set_rxfh(struct net_device *netdev, const u32 *indir, static int igb_set_rxfh(struct net_device *netdev, const u32 *indir,
const u8 *key, const u8 hfunc) const u8 *key, const u8 hfunc)
{ {
@ -3369,6 +3443,7 @@ static int igb_set_rxfh(struct net_device *netdev, const u32 *indir,
return 0; return 0;
} }
#endif
static unsigned int igb_max_channels(struct igb_adapter *adapter) static unsigned int igb_max_channels(struct igb_adapter *adapter)
{ {

View File

@ -2513,6 +2513,9 @@ static int igb_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *dev, struct net_device *dev,
const unsigned char *addr, u16 vid, const unsigned char *addr, u16 vid,
u16 flags, u16 flags,
#ifdef CONFIG_SUSE_KERNEL
bool *notified,
#endif
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
/* guarantee we can provide a unique filter for the unicast address */ /* guarantee we can provide a unique filter for the unicast address */

View File

@ -1,6 +1,6 @@
/***************************************************************************** /*****************************************************************************
* *
* Copyright (C) 2007-2022 Florian Pose, Ingenieurgemeinschaft IgH * Copyright (C) 2007-2026 Florian Pose, Ingenieurgemeinschaft IgH
* *
* This file is part of the IgH EtherCAT Master. * This file is part of the IgH EtherCAT Master.
* *
@ -300,8 +300,14 @@ int main(int argc, char **argv)
if (off_counter_out < 0) if (off_counter_out < 0)
return -1; return -1;
// configure SYNC signals for this slave // configure SYNC0/SYNC1 interrupts for this slave
ecrt_slave_config_dc(sc, 0x0700, PERIOD_NS, 4400000, 0, 0); ecrt_slave_config_dc(sc,
0x0700, // AssignActivate (see vendor docs)
PERIOD_NS, // SYNC0 cycle time [ns]
4400000, // SYNC0 shift time [ns]
0, // SYNC1 cycle time [ns]
0 // SYNC1 shift time [ns]
);
printf("Activating master...\n"); printf("Activating master...\n");
if (ecrt_master_activate(master)) if (ecrt_master_activate(master))

View File

@ -233,7 +233,11 @@ static void __exit cleanup_mini_module(void)
{ {
printk(KERN_INFO PFX "Stopping...\n"); printk(KERN_INFO PFX "Stopping...\n");
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
timer_delete_sync(&timer);
#else
del_timer_sync(&timer); del_timer_sync(&timer);
#endif
free_serial_devices(); free_serial_devices();

View File

@ -9,14 +9,16 @@ data level by running two applications back to back.
## Supported features ## Supported features
Currently, only a very limited subset of libethercat functionality is Although the library implements the complete API (to avoid undefined
supported: references), most function calls will just do nothing and return no error.
However, some methods have a bit of logic implemented to simulate a working
master. This is what is possible:
- Creating master and domain instances - Creating master and domain instances
- Activating master, `send`/`receive`. - Activating master, `send()` and `receive()`.
- Processing and queuing domains - Processing and queuing domains
- Configuring PDOs - Configuring PDOs
- Configuring SDOs using `ecrt_slave_config_sdo*` - Configuring SDOs using `ecrt_slave_config_sdo*()`
The SDO config does not do anything, but when activating the master the SDO The SDO config does not do anything, but when activating the master the SDO
config will be dumped into a JSON file. config will be dumped into a JSON file.

File diff suppressed because it is too large Load Diff

View File

@ -35,194 +35,209 @@
struct Offset struct Offset
{ {
int bytes; int bytes;
int bits; int bits;
constexpr Offset(int bytes, constexpr Offset(int bytes, int bits):
int bits) : bytes(bytes), bits(bits) {} bytes(bytes),
bits(bits)
{}
constexpr bool operator!=(const Offset &other) const noexcept constexpr bool operator!=(const Offset &other) const noexcept
{ {
return bytes != other.bytes || bits != other.bits; return bytes != other.bytes || bits != other.bits;
} }
}; };
constexpr Offset NotFound(-1, -1); constexpr Offset NotFound(-1, -1);
struct pdo struct pdo
{ {
std::vector<ec_pdo_entry_info_t> entries; std::vector<ec_pdo_entry_info_t> entries;
size_t sizeInBytes() const; size_t sizeInBytes() const;
Offset findEntry(uint16_t idx, uint8_t subindex) const; Offset findEntry(uint16_t idx, uint8_t subindex) const;
Offset findEntryByPos(unsigned int) const;
}; };
struct syncManager struct syncManager
{ {
ec_direction_t dir; ec_direction_t dir;
std::map<uint16_t /* index */, pdo> pdos; std::map<uint16_t /* index */, pdo> pdos;
}; };
class ec_address class ec_address
{ {
uint32_t value; private:
uint32_t value;
public: public:
ec_address(uint16_t alias, /**< Slave alias. */ ec_address(
uint16_t position /**< Slave position. */) uint16_t alias, /**< Slave alias. */
: value(static_cast<uint32_t>(alias) << 16 | position) uint16_t position /**< Slave position. */):
{ value(static_cast<uint32_t>(alias) << 16 | position)
} {}
uint16_t getAlias() const { return value >> 16; } uint16_t getAlias() const { return value >> 16; }
uint16_t getPosition() const { return value & 0xFFFF; } uint16_t getPosition() const { return value & 0xFFFF; }
uint32_t getCombined() const { return value; } uint32_t getCombined() const { return value; }
bool operator<(const ec_address &other) const noexcept bool operator<(const ec_address &other) const noexcept
{ {
return value < other.value; return value < other.value;
} }
bool operator==(const ec_address &other) const noexcept bool operator==(const ec_address &other) const noexcept
{ {
return value == other.value; return value == other.value;
} }
}; };
class sdo_address class sdo_address
{ {
uint32_t value; private:
uint32_t value;
public: public:
sdo_address(uint16_t index, /**< Slave alias. */ sdo_address(
uint8_t subindex /**< Slave position. */) uint16_t index, /**< Slave alias. */
: value(static_cast<uint32_t>(index) << 8 | subindex) uint8_t subindex /**< Slave position. */):
{ value(static_cast<uint32_t>(index) << 8 | subindex)
} {}
uint16_t getIndex() const { return value >> 8; } uint16_t getIndex() const { return value >> 8; }
uint8_t getSubIndex() const { return value & 0xFF; } uint8_t getSubIndex() const { return value & 0xFF; }
uint32_t getCombined() const { return value; } uint32_t getCombined() const { return value; }
bool operator<(const sdo_address &other) const noexcept bool operator<(const sdo_address &other) const noexcept
{ {
return value < other.value; return value < other.value;
} }
bool operator==(const sdo_address &other) const noexcept bool operator==(const sdo_address &other) const noexcept
{ {
return value == other.value; return value == other.value;
} }
}; };
struct ec_slave_config struct ec_slave_config
{ {
ec_address address; ec_address address;
uint32_t vendor_id; /**< Expected vendor ID. */ uint32_t vendor_id; /**< Expected vendor ID. */
uint32_t product_code; /**< Expected product code. */ uint32_t product_code; /**< Expected product code. */
std::map<unsigned int, syncManager> sync_managers; std::map<unsigned int, syncManager> sync_managers;
std::map<sdo_address, std::basic_string<uint8_t>> sdos; std::map<sdo_address, std::basic_string<uint8_t>> sdos;
ec_slave_config( ec_slave_config(
ec_address address, ec_address address,
uint32_t vendor_id, /**< Expected vendor ID. */ uint32_t vendor_id, /**< Expected vendor ID. */
uint32_t product_code /**< Expected product code. */) uint32_t product_code /**< Expected product code. */):
: address(address), vendor_id(vendor_id), product_code(product_code) address(address),
{ vendor_id(vendor_id),
} product_code(product_code)
{}
void dumpJson(std::ostream &out, int indent) const; void dumpJson(std::ostream &out, int indent) const;
}; };
struct ec_domain struct ec_domain
{ {
private:
private: struct PdoMap
struct PdoMap
{
size_t offset;
size_t size_bytes;
ec_address slave_address;
unsigned int syncManager;
uint16_t pdo_index;
ec_direction_t dir;
PdoMap(
size_t offset,
size_t size_bytes,
ec_address slave_address,
unsigned int syncManager,
uint16_t pdo_index,
ec_direction_t dir)
: offset(offset), size_bytes(size_bytes), slave_address(slave_address), syncManager(syncManager), pdo_index(pdo_index), dir(dir)
{ {
size_t offset;
size_t size_bytes;
ec_address slave_address;
unsigned int syncManager;
uint16_t pdo_index;
ec_direction_t dir;
PdoMap(size_t offset,
size_t size_bytes,
ec_address slave_address,
unsigned int syncManager,
uint16_t pdo_index,
ec_direction_t dir):
offset(offset),
size_bytes(size_bytes),
slave_address(slave_address),
syncManager(syncManager),
pdo_index(pdo_index),
dir(dir)
{}
};
std::vector<uint8_t> data;
std::vector<unsigned char> connected;
std::vector<PdoMap> mapped_pdos;
rtipc_group *rt_group;
const char *prefix;
ec_master_t *master;
bool activated_ = false;
size_t numSlaves = 0;
public:
explicit ec_domain(
struct rtipc *rtipc,
const char *prefix,
ec_master_t *master);
uint8_t *getData() const
{
if (!activated_) {
return nullptr;
}
return const_cast<uint8_t *>(data.data());
} }
};
std::vector<uint8_t> data; size_t getSize() const { return data.size(); }
std::vector<unsigned char> connected;
std::vector<PdoMap> mapped_pdos;
rtipc_group *rt_group;
const char *prefix;
ec_master_t *master;
bool activated_ = false;
size_t numSlaves = 0;
public: int activate();
explicit ec_domain(struct rtipc *rtipc, const char *prefix, ec_master_t *master); int process();
int queue();
uint8_t *getData() const size_t getNumSlaves() const { return numSlaves; }
{
if (!activated_)
return nullptr;
return const_cast<uint8_t *>(data.data());
}
int activate(); ssize_t
int process(); map(ec_slave_config const &config,
int queue(); unsigned int syncManager,
uint16_t pdo_index);
size_t getNumSlaves() const { return numSlaves; } ec_master_t *getMaster() const { return master; }
ssize_t map(ec_slave_config const &config, unsigned int syncManager,
uint16_t pdo_index);
ec_master_t *getMaster() const { return master; }
}; };
struct ec_master struct ec_master
{ {
private: private:
struct RtIpcDeleter struct RtIpcDeleter
{
void operator()(struct rtipc *r) const
{ {
rtipc_exit(r); void operator()(struct rtipc *r) const { rtipc_exit(r); }
} };
};
std::string rt_ipc_dir; std::string rt_ipc_dir;
std::string rt_ipc_name; std::string rt_ipc_name;
std::list<ec_domain> domains; std::list<ec_domain> domains;
std::map<ec_address, ec_slave_config> slaves; std::map<ec_address, ec_slave_config> slaves;
std::unique_ptr<struct rtipc, RtIpcDeleter> rt_ipc; std::unique_ptr<struct rtipc, RtIpcDeleter> rt_ipc;
int id_; int id_;
public: public:
explicit ec_master(int id); explicit ec_master(int id);
int activate(); int activate();
ec_domain *createDomain(); int deactivate();
int getNoSlaves() const { return slaves.size(); } ec_domain *createDomain();
int getId() const { return id_; }
ec_slave_config_t *slave_config( int getNoSlaves() const { return slaves.size(); }
uint16_t alias, /**< Slave alias. */ int getId() const { return id_; }
uint16_t position, /**< Slave position. */
uint32_t vendor_id, /**< Expected vendor ID. */ ec_slave_config_t *slave_config(
uint32_t product_code /**< Expected product code. */ uint16_t alias, /**< Slave alias. */
); uint16_t position, /**< Slave position. */
uint32_t vendor_id, /**< Expected vendor ID. */
uint32_t product_code /**< Expected product code. */
);
}; };

View File

@ -539,6 +539,16 @@ void ec_fsm_coe_dict_response(
return; return;
} }
#ifndef EC_EOE
if (mbox_prot == EC_MBOX_TYPE_EOE) {
// discard EoE message and wait for the next reponse
ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_coe_dict_check;
return;
}
#endif
if (mbox_prot != EC_MBOX_TYPE_COE) { if (mbox_prot != EC_MBOX_TYPE_COE) {
EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n", EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
mbox_prot); mbox_prot);
@ -821,6 +831,16 @@ void ec_fsm_coe_dict_desc_response(
return; return;
} }
#ifndef EC_EOE
if (mbox_prot == EC_MBOX_TYPE_EOE) {
// discard EoE message and wait for the next reponse
ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_coe_dict_desc_check;
return;
}
#endif
if (mbox_prot != EC_MBOX_TYPE_COE) { if (mbox_prot != EC_MBOX_TYPE_COE) {
EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n", EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
mbox_prot); mbox_prot);
@ -1057,6 +1077,16 @@ void ec_fsm_coe_dict_entry_response(
return; return;
} }
#ifndef EC_EOE
if (mbox_prot == EC_MBOX_TYPE_EOE) {
// discard EoE message and wait for the next reponse
ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_coe_dict_entry_check;
return;
}
#endif
if (mbox_prot != EC_MBOX_TYPE_COE) { if (mbox_prot != EC_MBOX_TYPE_COE) {
EC_SLAVE_ERR(slave, "Received mailbox protocol" EC_SLAVE_ERR(slave, "Received mailbox protocol"
" 0x%02X as response.\n", mbox_prot); " 0x%02X as response.\n", mbox_prot);
@ -1574,6 +1604,16 @@ void ec_fsm_coe_down_response(
return; return;
} }
#ifndef EC_EOE
if (mbox_prot == EC_MBOX_TYPE_EOE) {
// discard EoE message and wait for the next reponse
ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_coe_down_check;
return;
}
#endif
if (mbox_prot != EC_MBOX_TYPE_COE) { if (mbox_prot != EC_MBOX_TYPE_COE) {
request->errno = EIO; request->errno = EIO;
fsm->state = ec_fsm_coe_error; fsm->state = ec_fsm_coe_error;
@ -1752,6 +1792,16 @@ void ec_fsm_coe_down_seg_response(
return; return;
} }
#ifndef EC_EOE
if (mbox_prot == EC_MBOX_TYPE_EOE) {
// discard EoE message and wait for the next reponse
ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_coe_down_check;
return;
}
#endif
if (mbox_prot != EC_MBOX_TYPE_COE) { if (mbox_prot != EC_MBOX_TYPE_COE) {
request->errno = EIO; request->errno = EIO;
fsm->state = ec_fsm_coe_error; fsm->state = ec_fsm_coe_error;
@ -2114,10 +2164,15 @@ void ec_fsm_coe_up_response(
return; return;
} }
if (master->debug_level) { #ifndef EC_EOE
EC_SLAVE_DBG(slave, 1, "Upload response:\n"); if (mbox_prot == EC_MBOX_TYPE_EOE) {
ec_print_data(data, rec_size); // discard EoE message and wait for the next reponse
ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_coe_up_check;
return;
} }
#endif
if (mbox_prot != EC_MBOX_TYPE_COE) { if (mbox_prot != EC_MBOX_TYPE_COE) {
request->errno = EIO; request->errno = EIO;
@ -2135,6 +2190,11 @@ void ec_fsm_coe_up_response(
return; return;
} }
if (master->debug_level) {
EC_SLAVE_DBG(slave, 1, "Upload response:\n");
ec_print_data(data, rec_size);
}
if (rec_size < 6) { if (rec_size < 6) {
request->errno = EIO; request->errno = EIO;
fsm->state = ec_fsm_coe_error; fsm->state = ec_fsm_coe_error;
@ -2411,10 +2471,15 @@ void ec_fsm_coe_up_seg_response(
return; return;
} }
if (master->debug_level) { #ifndef EC_EOE
EC_SLAVE_DBG(slave, 1, "Upload segment response:\n"); if (mbox_prot == EC_MBOX_TYPE_EOE) {
ec_print_data(data, rec_size); // discard EoE message and wait for the next reponse
ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_coe_up_seg_check;
return;
} }
#endif
if (mbox_prot != EC_MBOX_TYPE_COE) { if (mbox_prot != EC_MBOX_TYPE_COE) {
EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n", EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
@ -2432,6 +2497,12 @@ void ec_fsm_coe_up_seg_response(
return; return;
} }
if (master->debug_level) {
EC_SLAVE_DBG(slave, 1, "Upload segment response:\n");
ec_print_data(data, rec_size);
}
if (rec_size < 10) { if (rec_size < 10) {
EC_SLAVE_ERR(slave, "Received currupted SDO upload" EC_SLAVE_ERR(slave, "Received currupted SDO upload"
" segment response!\n"); " segment response!\n");

View File

@ -989,11 +989,12 @@ void ec_fsm_master_state_scan_slave(
master->scan_index = master->slave_count; master->scan_index = master->slave_count;
wake_up_interruptible(&master->scan_queue); wake_up_interruptible(&master->scan_queue);
ec_master_calc_dc(master);
// Attach slave configurations // Attach slave configurations
ec_master_attach_slave_configs(master); ec_master_attach_slave_configs(master);
// Calculate DC (needs attached slaves due to reference clock selection)
ec_master_calc_dc(master);
#ifdef EC_EOE #ifdef EC_EOE
// check if EoE processing has to be started // check if EoE processing has to be started
ec_master_eoe_start(master); ec_master_eoe_start(master);

View File

@ -61,6 +61,23 @@
rt_mutex_lock_interruptible(lock, 0) rt_mutex_lock_interruptible(lock, 0)
#endif #endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 47)
#define smp_store_release(p, v) \
do { \
smp_mb(); \
ACCESS_ONCE(*p) = (v); \
} while (0)
#define smp_load_acquire(p) \
({ \
typeof(*p) ___p1 = ACCESS_ONCE(*p); \
smp_mb(); \
___p1; \
})
#endif
#include "master.h" #include "master.h"
/****************************************************************************/ /****************************************************************************/
@ -195,6 +212,7 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
master->phase = EC_ORPHANED; master->phase = EC_ORPHANED;
master->active = 0; master->active = 0;
master->config_changed = 0; master->config_changed = 0;
master->injection_seq_fsm = 0; master->injection_seq_fsm = 0;
master->injection_seq_rt = 0; master->injection_seq_rt = 0;
@ -1596,6 +1614,7 @@ static int ec_master_idle_thread(void *priv_data)
static int ec_master_operation_thread(void *priv_data) static int ec_master_operation_thread(void *priv_data)
{ {
ec_master_t *master = (ec_master_t *) priv_data; ec_master_t *master = (ec_master_t *) priv_data;
unsigned int seq_rt;
EC_MASTER_DBG(master, 1, "Operation thread running" EC_MASTER_DBG(master, 1, "Operation thread running"
" with fsm interval = %u us, max data size=%zu\n", " with fsm interval = %u us, max data size=%zu\n",
@ -1604,7 +1623,11 @@ static int ec_master_operation_thread(void *priv_data)
while (!kthread_should_stop()) { while (!kthread_should_stop()) {
ec_datagram_output_stats(&master->fsm_datagram); ec_datagram_output_stats(&master->fsm_datagram);
if (master->injection_seq_rt == master->injection_seq_fsm) { /* Use smp_load_acquire() to prevent re-ordering.
* https://gitlab.com/etherlab.org/ethercat/-/work_items/168 */
seq_rt = smp_load_acquire(&master->injection_seq_rt);
if (seq_rt == master->injection_seq_fsm) { // was injected
// output statistics // output statistics
ec_master_output_stats(master); ec_master_output_stats(master);
@ -1616,7 +1639,9 @@ static int ec_master_operation_thread(void *priv_data)
if (ec_fsm_master_exec(&master->fsm)) { if (ec_fsm_master_exec(&master->fsm)) {
// Inject datagrams (let the RT thread queue them, see // Inject datagrams (let the RT thread queue them, see
// ecrt_master_send()) // ecrt_master_send())
master->injection_seq_fsm++; // re-ordering-safe version of `master->injection_seq_fsm++`
smp_store_release(&master->injection_seq_fsm,
master->injection_seq_fsm + 1);
} }
ec_master_exec_slave_fsms(master); ec_master_exec_slave_fsms(master);
@ -2436,11 +2461,14 @@ int ecrt_master_send(ec_master_t *master)
{ {
ec_datagram_t *datagram, *n; ec_datagram_t *datagram, *n;
ec_device_index_t dev_idx; ec_device_index_t dev_idx;
unsigned int seq_fsm;
if (master->injection_seq_rt != master->injection_seq_fsm) { seq_fsm = smp_load_acquire(&master->injection_seq_fsm);
if (master->injection_seq_rt != seq_fsm) {
// inject datagram produced by master FSM // inject datagram produced by master FSM
ec_master_queue_datagram(master, &master->fsm_datagram); ec_master_queue_datagram(master, &master->fsm_datagram);
master->injection_seq_rt = master->injection_seq_fsm;
smp_store_release(&master->injection_seq_rt, seq_fsm);
} }
ec_master_inject_external_datagrams(master); ec_master_inject_external_datagrams(master);

View File

@ -68,6 +68,8 @@ endif
# Any precious variable used inside script_templates should appear here # Any precious variable used inside script_templates should appear here
expand_script = $(SED) \ expand_script = $(SED) \
-e 's,[@]VERSION[@],$(VERSION),g' \ -e 's,[@]VERSION[@],$(VERSION),g' \
-e 's,[@]ipcmd[@],$(ipcmd),g' \
-e 's,[@]kmoddir[@],$(kmoddir),g' \
-e 's,[@]bindir[@],$(bindir),g' \ -e 's,[@]bindir[@],$(bindir),g' \
-e 's,[@]sbindir[@],$(sbindir),g' \ -e 's,[@]sbindir[@],$(sbindir),g' \
-e 's,[@]sysconfdir[@],$(sysconfdir),g' -e 's,[@]sysconfdir[@],$(sysconfdir),g'

View File

@ -25,13 +25,13 @@
# #
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
LSMOD=/sbin/lsmod LSMOD="@kmoddir@/lsmod"
MODPROBE=/sbin/modprobe MODPROBE="@kmoddir@/modprobe"
RMMOD=/sbin/rmmod RMMOD="@kmoddir@/rmmod"
MODINFO=/sbin/modinfo MODINFO="@kmoddir@/modinfo"
IP=/bin/ip IP="@ipcmd@"
ETHERCAT=@bindir@/ethercat ETHERCAT="@bindir@/ethercat"
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
@ -39,7 +39,7 @@ if [ "$1" = "-c" ]; then
ETHERCAT_CONFIG="$2" ETHERCAT_CONFIG="$2"
COMMAND="$3" COMMAND="$3"
else else
ETHERCAT_CONFIG=@sysconfdir@/ethercat.conf ETHERCAT_CONFIG="@sysconfdir@/ethercat.conf"
COMMAND="$1" COMMAND="$1"
fi fi

View File

@ -292,7 +292,11 @@ static int ec_tty_init(ec_tty_t *t, int minor,
static void ec_tty_clear(ec_tty_t *tty) static void ec_tty_clear(ec_tty_t *tty)
{ {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
timer_delete_sync(&tty->timer);
#else
del_timer_sync(&tty->timer); del_timer_sync(&tty->timer);
#endif
tty_unregister_device(tty_driver, tty->minor); tty_unregister_device(tty_driver, tty->minor);
} }
@ -367,10 +371,14 @@ static void ec_tty_wakeup(struct timer_list *t)
static void ec_tty_wakeup(unsigned long data) static void ec_tty_wakeup(unsigned long data)
#endif #endif
{ {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
ec_tty_t *tty = timer_container_of(tty, t, timer);
#else
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
ec_tty_t *tty = from_timer(tty, t, timer); ec_tty_t *tty = from_timer(tty, t, timer);
#else #else
ec_tty_t *tty = (ec_tty_t *) data; ec_tty_t *tty = (ec_tty_t *) data;
#endif
#endif #endif
size_t to_recv; size_t to_recv;