Merge branch 'devel-1.6' into 84-api-call-for-eoe-set-ip-command

This commit is contained in:
Florian Pose 2024-02-05 11:16:27 +01:00
commit 740117c76f
65 changed files with 1449 additions and 567 deletions

View File

@ -6,6 +6,37 @@ stages:
- test
- doc
- deploy
- release
variables:
PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/ethercat/${CI_COMMIT_TAG}"
rtai:
stage: build
image: registry.gitlab.com/etherlab.org/build-container-factory/ethercat-kernels:rtai
script:
- ./bootstrap
- ./configure --enable-8139too --enable-igb --enable-e100 --with-linux-dir=/usr/src/linux-obj/x86_64/0404rtai --enable-rtdm --with-rtai-dir=/usr
- make -j8 all modules
xenomai2:
stage: build
image: registry.gitlab.com/etherlab.org/build-container-factory/ethercat-kernels:xenomai2
script:
- ./bootstrap
- ./configure --disable-8139too --with-linux-dir=/usr/src/linux-obj/x86_64/0318xenomai2 --enable-rtdm --with-xenomai-dir=/usr
- make -j8 all modules
xenomai3:
stage: build
image: registry.gitlab.com/etherlab.org/build-container-factory/ethercat-kernels:xenomai3
script:
- ./bootstrap
- ./configure --enable-8139too --enable-igb --enable-e100 --with-linux-dir=/usr/src/linux-obj/x86_64/0510xenomai3 --enable-rtdm --with-xenomai-dir=/usr
- make -j8 all modules
build:
stage: build
@ -14,6 +45,7 @@ build:
- ./bootstrap
- ./configure --with-linux-dir=/usr/src/linux-obj/$(uname -i)/default --enable-tty --with-devices=2 --enable-ccat
- make -j8 all modules
- make -C lib symbol-version-check
- make DISTCHECK_CONFIGURE_FLAGS="--with-linux-dir=/usr/src/linux-obj/$(uname -i)/default" distcheck
- make dist
- mkdir test_dist && cd test_dist && tar xzf ../ethercat-*.tar.gz && cd ethercat-*/
@ -21,6 +53,10 @@ build:
- ../configure --with-linux-dir=/usr/src/linux-obj/$(uname -i)/default --disable-8139too --enable-tty --with-devices=2 --enable-ccat
- make -j8 all modules
artifacts:
paths:
- ethercat-*.tar.gz
- ethercat-*.tar.bz2
# Build ethercat tool subcommand help output for documentation
commands:
@ -89,12 +125,45 @@ pdf:
update docs server:
stage: deploy
rules:
- if: $CI_COMMIT_BRANCH == "stable-1.5" && $CI_PROJECT_NAMESPACE == "etherlab.org"
- if: $CI_COMMIT_BRANCH == "stable-1.6" && $CI_PROJECT_NAMESPACE == "etherlab.org"
trigger: etherlab.org/docs
upload:
stage: deploy
image: curlimages/curl:latest
rules:
- if: $CI_COMMIT_TAG && $CI_COMMIT_REF_PROTECTED == "true"
dependencies:
- "build"
script:
- echo "$CI_COMMIT_TAG" | grep -qE '^[0-9]+(\.[0-9]+){2}$'
- |
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" \
--header "Content-Type: application/gzip" \
--fail-with-body \
--upload-file "ethercat-${CI_COMMIT_TAG}.tar.gz" \
"${PACKAGE_REGISTRY_URL}/ethercat-${CI_COMMIT_TAG}.tar.gz"
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" \
--header "Content-Type: application/x-bzip2" \
--fail-with-body \
--upload-file "ethercat-${CI_COMMIT_TAG}.tar.bz2" \
"${PACKAGE_REGISTRY_URL}/ethercat-${CI_COMMIT_TAG}.tar.bz2"
release:
stage: release
image: registry.gitlab.com/gitlab-org/release-cli:latest
rules:
- if: $CI_COMMIT_TAG && $CI_COMMIT_REF_PROTECTED == "true"
script:
- |
release-cli create --name "Release $CI_COMMIT_TAG" --tag-name $CI_COMMIT_TAG \
--assets-link "{\"name\":\"ethercat.tar.bz2\",\"url\":\"${PACKAGE_REGISTRY_URL}/ethercat-${CI_COMMIT_TAG}.tar.bz2\",\"link_type\":\"package\",\"filepath\":\"/dist-tarballs/ethercat.tar.bz2\"}" \
--assets-link "{\"name\":\"ethercat.tar.gz\",\"url\":\"${PACKAGE_REGISTRY_URL}/ethercat-${CI_COMMIT_TAG}.tar.gz\",\"link_type\":\"package\",\"filepath\":\"/dist-tarballs/ethercat.tar.gz\"}"
# from 'Workflows/MergeRequest-Pipelines.gitlab-ci.yml', but on all branches
workflow:
rules:
- if: $CI_MERGE_REQUEST_IID
- if: $CI_COMMIT_TAG
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "stable-1.5"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "stable-1.6"

View File

@ -27,4 +27,9 @@ ifeq (@ENABLE_TTY@,1)
obj-m += tty/
endif
ifeq (@ENABLE_RTAI@, 1)
KBUILD_EXTRA_SYMBOLS := \
@RTAI_MODULE_DIR@/Module.symvers
endif
#-----------------------------------------------------------------------------

8
NEWS
View File

@ -4,8 +4,16 @@ vim: spelllang=en spell tw=78
-------------------------------------------------------------------------------
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.
Changes since 1.5.2:
* Added feature flag API.
* Fixed FoE timeout calculation bug.
Changes in 1.5.2:

View File

@ -1,6 +1,6 @@
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
#
# Copyright (C) 2006-2023 Florian Pose, Ingenieurgemeinschaft IgH
# Copyright (C) 2006-2024 Florian Pose, Ingenieurgemeinschaft IgH
#
# This file is part of the IgH EtherCAT Master.
#
@ -17,7 +17,7 @@
# with the IgH EtherCAT Master; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_PREREQ(2.59)
@ -31,7 +31,7 @@ AC_PREREQ(2.59)
# - Update version number below
# - make dist-bzip2
#
AC_INIT([ethercat],[1.5.2],[fp@igh.de])
AC_INIT([ethercat],[1.6.0],[fp@igh.de])
AC_CONFIG_AUX_DIR([autoconf])
AM_INIT_AUTOMAKE([-Wall -Wno-override -Werror dist-bzip2 subdir-objects foreign])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
@ -42,18 +42,18 @@ AC_PROG_SED
PKG_PROG_PKG_CONFIG
PKG_INSTALLDIR()
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Global
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AM_PROG_CC_C_O
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AC_PROG_CXX
AC_PROG_LIBTOOL
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Kernel modules
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_MSG_CHECKING([whether to build kernel modules])
@ -82,9 +82,9 @@ fi
AM_CONDITIONAL(ENABLE_KERNEL, test "x$enablekernel" = "x1")
AC_SUBST(ENABLE_KERNEL,[$enablekernel])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Linux sources
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
if test "x$enablekernel" = "x1"; then
@ -146,9 +146,9 @@ AC_MSG_RESULT([$LINUX_SOURCE_DIR (Kernel $linuxversion)])
fi
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Linux module installation subdirectory
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_ARG_WITH([module-dir],
AC_HELP_STRING(
@ -163,9 +163,9 @@ AC_SUBST(INSTALL_MOD_DIR,[$moddir])
AC_MSG_CHECKING([for Linux modules installation directory])
AC_MSG_RESULT([$INSTALL_MOD_DIR])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Generic Ethernet driver
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_ARG_ENABLE([generic],
AS_HELP_STRING([--enable-generic],
@ -186,9 +186,9 @@ AC_ARG_ENABLE([generic],
AM_CONDITIONAL(ENABLE_GENERIC, test "x$enablegeneric" = "x1")
AC_SUBST(ENABLE_GENERIC,[$enablegeneric])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# 8139too driver
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_ARG_ENABLE([8139too],
AS_HELP_STRING([--enable-8139too],
@ -241,9 +241,9 @@ fi
AC_SUBST(KERNEL_8139TOO,[$kernel8139too])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# e100 driver
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_ARG_ENABLE([e100],
AS_HELP_STRING([--enable-e100],
@ -296,9 +296,9 @@ fi
AC_SUBST(KERNEL_E100,[$kernele100])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# e1000 driver
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_ARG_ENABLE([e1000],
AS_HELP_STRING([--enable-e1000],
@ -351,9 +351,9 @@ fi
AC_SUBST(KERNEL_E1000,[$kernele1000])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# e1000e driver
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_ARG_ENABLE([e1000e],
AS_HELP_STRING([--enable-e1000e],
@ -426,9 +426,9 @@ fi
AC_SUBST(KERNEL_E1000E,[$kernele1000e])
AC_SUBST(E1000E_LAYOUT, [$e1000elayout])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# genet driver
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_ARG_ENABLE([genet],
AS_HELP_STRING([--enable-genet],
@ -474,9 +474,9 @@ fi
AC_SUBST(KERNEL_GENET,[$kernelgenet])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# igb driver
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_ARG_ENABLE([igb],
AS_HELP_STRING([--enable-igb],
@ -521,9 +521,10 @@ if test "x${enableigb}" = "x1"; then
fi
AC_SUBST(KERNEL_IGB,[$kerneligb])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# igc driver
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_ARG_ENABLE([igc],
AS_HELP_STRING([--enable-igc],
@ -568,9 +569,9 @@ fi
AC_SUBST(KERNEL_IGC,[$kerneligc])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# r8169 driver
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_ARG_ENABLE([r8169],
AS_HELP_STRING([--enable-r8169],
@ -632,9 +633,9 @@ fi
AC_SUBST(KERNEL_R8169,[$kernel_r8169])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# CCAT driver
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_MSG_CHECKING([whether to build the CCAT driver])
@ -663,9 +664,9 @@ fi
AM_CONDITIONAL(ENABLE_CCAT, test "x$enableccat" = "x1")
AC_SUBST(ENABLE_CCAT,[$enableccat])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# RTAI path (optional)
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_ARG_WITH([rtai-dir],
AC_HELP_STRING(
@ -694,6 +695,7 @@ else
rtai_lxrt_cflags=`$rtaidir/bin/rtai-config --lxrt-cflags`
rtai_lxrt_ldflags=`$rtaidir/bin/rtai-config --lxrt-ldflags`
rtai_module_dir=`$rtaidir/bin/rtai-config --module-dir`
fi
AC_SUBST(RTAI_DIR,[$rtaidir])
@ -702,10 +704,11 @@ AC_SUBST(ENABLE_RTAI,[$rtai])
AC_SUBST(RTAI_LXRT_CFLAGS,[$rtai_lxrt_cflags])
AC_SUBST(RTAI_LXRT_LDFLAGS,[$rtai_lxrt_ldflags])
AC_SUBST(RTAI_MODULE_DIR,[$rtai_module_dir])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Xenomai path (optional)
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_ARG_WITH([xenomai-dir],
AC_HELP_STRING(
@ -722,28 +725,61 @@ AC_ARG_WITH([xenomai-dir],
]
)
AC_ARG_WITH([xenomai-config],
AC_HELP_STRING(
[--with-xenomai-config=<CMD>],
[Xenomai config invokation, default to xenomai-dir/bin/xeno-config]
),
[
xenomaiconfig=[$withval]
],
[
xenomaiconfig="$xenomaidir/bin/xeno-config"
]
)
AC_MSG_CHECKING([for Xenomai path])
if test -z "${xenomaidir}"; then
AC_MSG_RESULT([not specified.])
else
if test \! -r ${xenomaidir}/include/xeno_config.h; then
if test \! -x ${xenomaiconfig}; then
AC_MSG_ERROR([no Xenomai installation found in ${xenomaidir}!])
fi
AC_MSG_RESULT([$xenomaidir])
xeno_native_cflags=`$xenomaidir/bin/xeno-config --skin native --cflags`
xeno_native_ldflags=`$xenomaidir/bin/xeno-config --skin native --ldflags`
xeno_posix_cflags=`$xenomaidir/bin/xeno-config --skin posix --cflags`
xeno_posix_ldflags=`$xenomaidir/bin/xeno-config --skin posix --ldflags`
xeno_rtdm_cflags=`$xenomaidir/bin/xeno-config --skin rtdm --cflags`
xeno_rtdm_ldflags=`$xenomaidir/bin/xeno-config --skin rtdm --ldflags`
xenomai_ver=`$xenomaiconfig --version`
xenomai_ver=${xenomai_ver##\"}
xenomai_ver=${xenomai_ver%%\"}
echo "xenomai version: " $xenomai_ver
if test ${xenomai_ver%%.*} -gt 2; then
xeno_alchemy_cflags=`$xenomaiconfig --skin alchemy --cflags`
xeno_alchemy_ldflags=`$xenomaiconfig --skin alchemy --auto-init-solib --ldflags`
xeno_posix_ldflags=`$xenomaiconfig --skin posix --auto-init-solib --ldflags`
xeno_rtdm_ldflags=`$xenomaiconfig --skin rtdm --auto-init-solib --ldflags`
xeno_v3=1
xeno=0
AC_DEFINE([EC_RTDM_XENOMAI_V3], [1], [Use Xenomai3 RTDM flavour])
else
xeno_native_cflags=`$xenomaiconfig --skin native --cflags`
xeno_native_ldflags=`$xenomaiconfig --skin native --ldflags`
xeno_posix_ldflags=`$xenomaiconfig --skin posix --ldflags`
xeno_rtdm_ldflags=`$xenomaiconfig --skin rtdm --ldflags`
fi
xeno_posix_cflags=`$xenomaiconfig --skin posix --cflags`
xeno_rtdm_cflags=`$xenomaiconfig --skin rtdm --cflags`
fi
AC_SUBST(XENOMAI_DIR,[$xenomaidir])
AM_CONDITIONAL(ENABLE_XENOMAI, test "x$xeno" = "x1")
AC_SUBST(ENABLE_XENOMAI,[$xeno])
AM_CONDITIONAL(ENABLE_XENOMAI_V3, test "x$xeno_v3" = "x1")
AC_SUBST(ENABLE_XENOMAI_V3,[$xeno_v3])
AC_SUBST(XENOMAI_ALCHEMY_CFLAGS,[$xeno_alchemy_cflags])
AC_SUBST(XENOMAI_ALCHEMY_LDFLAGS,[$xeno_alchemy_ldflags])
AC_SUBST(XENOMAI_NATIVE_CFLAGS,[$xeno_native_cflags])
AC_SUBST(XENOMAI_NATIVE_LDFLAGS,[$xeno_native_ldflags])
AC_SUBST(XENOMAI_POSIX_CFLAGS,[$xeno_posix_cflags])
@ -751,9 +787,9 @@ AC_SUBST(XENOMAI_POSIX_LDFLAGS,[$xeno_posix_ldflags])
AC_SUBST(XENOMAI_RTDM_CFLAGS,[$xeno_rtdm_cflags])
AC_SUBST(XENOMAI_RTDM_LDFLAGS,[$xeno_rtdm_ldflags])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# RTDM interface (optional)
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_ARG_ENABLE([rtdm],
AC_HELP_STRING(
@ -785,9 +821,9 @@ fi
AM_CONDITIONAL(ENABLE_RTDM, test "x$rtdm" = "x1")
AC_SUBST(ENABLE_RTDM,[$rtdm])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Debug interface
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_MSG_CHECKING([whether to build the debug interface])
@ -817,9 +853,9 @@ fi
AM_CONDITIONAL(ENABLE_DEBUG_IF, test "x$dbg" = "x1")
AC_SUBST(ENABLE_DEBUG_IF,[$dbg])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Debug ring
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_MSG_CHECKING([whether to build the debug ring])
@ -846,9 +882,9 @@ else
AC_MSG_RESULT([no])
fi
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Ethernet over EtherCAT support
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_MSG_CHECKING([whether to build with EoE support])
@ -878,9 +914,9 @@ fi
AM_CONDITIONAL(ENABLE_EOE, test "x$eoe" = "x1")
AC_SUBST(ENABLE_EOE,[$eoe])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# CPU timestamp counter support
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_MSG_CHECKING([whether to use the CPU timestamp counter])
@ -907,9 +943,9 @@ else
AC_MSG_RESULT([no])
fi
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# High-resolution timer support
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_MSG_CHECKING([whether to use high-resolution timers for scheduling])
@ -936,9 +972,9 @@ else
AC_MSG_RESULT([no])
fi
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Read alias address from register
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_MSG_CHECKING([whether to read alias addresses from registers])
@ -965,7 +1001,7 @@ else
AC_MSG_RESULT([no])
fi
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Command-line tool
#-----------------------------------------------------------------------------
@ -995,9 +1031,9 @@ fi
AM_CONDITIONAL(BUILD_TOOL, test "x$tool" = "x1")
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Userspace library generation
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_MSG_CHECKING([whether to build the userspace library])
@ -1025,9 +1061,9 @@ fi
AM_CONDITIONAL(ENABLE_USERLIB, test "x$userlib" = "x1")
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# TTY driver
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_MSG_CHECKING([whether to build the tty driver])
@ -1056,9 +1092,9 @@ fi
AM_CONDITIONAL(ENABLE_TTY, test "x$tty" = "x1")
AC_SUBST(ENABLE_TTY,[$tty])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Slave identification wildcards
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_MSG_CHECKING([whether to allow identification wildcards])
@ -1086,9 +1122,9 @@ else
AC_MSG_RESULT([no])
fi
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Redundancy (number of devices)
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_ARG_WITH([devices],
AC_HELP_STRING(
@ -1118,9 +1154,9 @@ fi
AC_DEFINE_UNQUOTED([EC_MAX_NUM_DEVICES], $devices,
[Max. number of Ethernet devices per master])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# SII assignment
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_MSG_CHECKING([whether to assign the SII to PDI])
@ -1147,9 +1183,9 @@ else
AC_MSG_RESULT([no])
fi
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# syslog output in realtime context
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_MSG_CHECKING([whether to syslog in realtime context])
@ -1176,9 +1212,9 @@ else
AC_MSG_RESULT([no])
fi
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# systemd service support
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_ARG_WITH([systemdsystemunitdir],
AS_HELP_STRING([--with-systemdsystemunitdir=DIR],
@ -1205,7 +1241,7 @@ esac
AM_CONDITIONAL(HAVE_SYSTEMD, test "x$with_systemdsystemunitdir" != "x")
AC_SUBST(systemdsystemunitdir,[$with_systemdsystemunitdir])
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------
AC_CONFIG_FILES([
Doxyfile
@ -1257,6 +1293,7 @@ AC_CONFIG_FILES([
tty/Kbuild
tty/Makefile
])
AC_OUTPUT
#------------------------------------------------------------------------------
#-----------------------------------------------------------------------------

View File

@ -59,6 +59,7 @@
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/irq_work.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <net/pkt_sched.h>
@ -331,6 +332,7 @@ struct e1000_adapter {
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
enum e1000_state_t {

View File

@ -33,6 +33,7 @@
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/irq_work.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <net/pkt_sched.h>
@ -304,6 +305,7 @@ struct e1000_adapter {
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
enum e1000_state_t {

View File

@ -33,6 +33,7 @@
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/irq_work.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <net/pkt_sched.h>
@ -304,6 +305,7 @@ struct e1000_adapter {
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
enum e1000_state_t {

View File

@ -33,6 +33,7 @@
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/irq_work.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <net/pkt_sched.h>
@ -304,6 +305,7 @@ struct e1000_adapter {
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
enum e1000_state_t {

View File

@ -33,6 +33,7 @@
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/irq_work.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <net/pkt_sched.h>
@ -304,6 +305,7 @@ struct e1000_adapter {
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
enum e1000_state_t {

View File

@ -1253,6 +1253,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
// offer device to EtherCAT master module
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev);
if (err) {
ecdev_withdraw(adapter->ecdev);
@ -1332,6 +1333,7 @@ static void e1000_remove(struct pci_dev *pdev)
if (adapter->ecdev) {
ecdev_close(adapter->ecdev);
irq_work_sync(&adapter->ec_watchdog_kicker);
ecdev_withdraw(adapter->ecdev);
} else {
unregister_netdev(netdev);
@ -3857,12 +3859,20 @@ void e1000_update_stats(struct e1000_adapter *adapter)
}
}
static void ec_kick_watchdog(struct irq_work *work)
{
struct e1000_adapter *adapter =
container_of(work, struct e1000_adapter, ec_watchdog_kicker);
schedule_work(&adapter->watchdog_task);
}
void ec_poll(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
e1000_watchdog(&adapter->watchdog_task.work);
adapter->ec_watchdog_jiffies = jiffies;
irq_work_queue(&adapter->ec_watchdog_kicker);
}
e1000_intr(0, netdev);

View File

@ -1234,6 +1234,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
// offer device to EtherCAT master module
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev);
if (err) {
ecdev_withdraw(adapter->ecdev);
@ -1313,6 +1314,7 @@ static void e1000_remove(struct pci_dev *pdev)
if (adapter->ecdev) {
ecdev_close(adapter->ecdev);
irq_work_sync(&adapter->ec_watchdog_kicker);
ecdev_withdraw(adapter->ecdev);
} else {
unregister_netdev(netdev);
@ -3835,12 +3837,20 @@ void e1000_update_stats(struct e1000_adapter *adapter)
}
}
static void ec_kick_watchdog(struct irq_work *work)
{
struct e1000_adapter *adapter =
container_of(work, struct e1000_adapter, ec_watchdog_kicker);
schedule_work(&adapter->watchdog_task);
}
void ec_poll(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
e1000_watchdog(&adapter->watchdog_task.work);
adapter->ec_watchdog_jiffies = jiffies;
irq_work_queue(&adapter->ec_watchdog_kicker);
}
e1000_intr(0, netdev);

View File

@ -1234,6 +1234,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
// offer device to EtherCAT master module
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev);
if (err) {
ecdev_withdraw(adapter->ecdev);
@ -1313,6 +1314,7 @@ static void e1000_remove(struct pci_dev *pdev)
if (adapter->ecdev) {
ecdev_close(adapter->ecdev);
irq_work_sync(&adapter->ec_watchdog_kicker);
ecdev_withdraw(adapter->ecdev);
} else {
unregister_netdev(netdev);
@ -3834,12 +3836,20 @@ void e1000_update_stats(struct e1000_adapter *adapter)
}
}
static void ec_kick_watchdog(struct irq_work *work)
{
struct e1000_adapter *adapter =
container_of(work, struct e1000_adapter, ec_watchdog_kicker);
schedule_work(&adapter->watchdog_task);
}
void ec_poll(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
e1000_watchdog(&adapter->watchdog_task.work);
adapter->ec_watchdog_jiffies = jiffies;
irq_work_queue(&adapter->ec_watchdog_kicker);
}
e1000_intr(0, netdev);

View File

@ -1234,6 +1234,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
// offer device to EtherCAT master module
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev);
if (err) {
ecdev_withdraw(adapter->ecdev);
@ -1313,6 +1314,7 @@ static void e1000_remove(struct pci_dev *pdev)
if (adapter->ecdev) {
ecdev_close(adapter->ecdev);
irq_work_sync(&adapter->ec_watchdog_kicker);
ecdev_withdraw(adapter->ecdev);
} else {
unregister_netdev(netdev);
@ -3834,12 +3836,20 @@ void e1000_update_stats(struct e1000_adapter *adapter)
}
}
static void ec_kick_watchdog(struct irq_work *work)
{
struct e1000_adapter *adapter =
container_of(work, struct e1000_adapter, ec_watchdog_kicker);
schedule_work(&adapter->watchdog_task);
}
void ec_poll(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
e1000_watchdog(&adapter->watchdog_task.work);
adapter->ec_watchdog_jiffies = jiffies;
irq_work_queue(&adapter->ec_watchdog_kicker);
}
e1000_intr(0, netdev);

View File

@ -1234,6 +1234,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
// offer device to EtherCAT master module
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev);
if (err) {
ecdev_withdraw(adapter->ecdev);
@ -1313,6 +1314,7 @@ static void e1000_remove(struct pci_dev *pdev)
if (adapter->ecdev) {
ecdev_close(adapter->ecdev);
irq_work_sync(&adapter->ec_watchdog_kicker);
ecdev_withdraw(adapter->ecdev);
} else {
unregister_netdev(netdev);
@ -3835,12 +3837,20 @@ void e1000_update_stats(struct e1000_adapter *adapter)
}
}
static void ec_kick_watchdog(struct irq_work *work)
{
struct e1000_adapter *adapter =
container_of(work, struct e1000_adapter, ec_watchdog_kicker);
schedule_work(&adapter->watchdog_task);
}
void ec_poll(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
e1000_watchdog(&adapter->watchdog_task.work);
adapter->ec_watchdog_jiffies = jiffies;
irq_work_queue(&adapter->ec_watchdog_kicker);
}
e1000_intr(0, netdev);

View File

@ -41,6 +41,7 @@
#include <linux/if_vlan.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/irq_work.h>
#include <linux/pci.h>
#include <linux/mdio.h>
@ -474,6 +475,7 @@ struct igb_adapter {
/* EtherCAT device variables */
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
#define IGB_FLAG_HAS_MSI (1 << 0)

View File

@ -16,6 +16,7 @@
#include <linux/if_vlan.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/irq_work.h>
#include <linux/pci.h>
#include <linux/mdio.h>
@ -671,6 +672,7 @@ struct igb_adapter {
/* EtherCAT device variables */
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
/* flags controlling PTP/1588 function */

View File

@ -16,6 +16,7 @@
#include <linux/if_vlan.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/irq_work.h>
#include <linux/pci.h>
#include <linux/mdio.h>
@ -671,6 +672,7 @@ struct igb_adapter {
/* EtherCAT device variables */
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
/* flags controlling PTP/1588 function */

View File

@ -16,6 +16,7 @@
#include <linux/if_vlan.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/irq_work.h>
#include <linux/pci.h>
#include <linux/mdio.h>
@ -671,6 +672,7 @@ struct igb_adapter {
/* EtherCAT device variables */
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
/* flags controlling PTP/1588 function */

View File

@ -16,6 +16,7 @@
#include <linux/if_vlan.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/irq_work.h>
#include <linux/pci.h>
#include <linux/mdio.h>
@ -673,6 +674,7 @@ struct igb_adapter {
/* EtherCAT device variables */
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
/* flags controlling PTP/1588 function */

View File

@ -2126,6 +2126,14 @@ static const struct net_device_ops igb_netdev_ops = {
.ndo_features_check = passthru_features_check,
};
static void ec_kick_watchdog(struct irq_work *work)
{
struct igb_adapter *adapter =
container_of(work, struct igb_adapter, ec_watchdog_kicker);
schedule_work(&adapter->watchdog_task);
}
/**
* ec_poll - EtherCAT poll routine
* @netdev: net device structure
@ -2140,12 +2148,8 @@ void ec_poll(struct net_device *netdev)
int budget = 64;
if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
struct e1000_hw *hw = &adapter->hw;
bool link;
hw->mac.get_link_status = true;
link = igb_has_link(adapter);
ecdev_set_link(adapter->ecdev, link);
adapter->ec_watchdog_jiffies = jiffies;
irq_work_queue(&adapter->ec_watchdog_kicker);
}
for (i = 0; i < adapter->num_q_vectors; i++) {
@ -2605,6 +2609,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev);
if (err) {
ecdev_withdraw(adapter->ecdev);
@ -2868,6 +2873,7 @@ static void igb_remove(struct pci_dev *pdev)
if (adapter->ecdev) {
ecdev_close(adapter->ecdev);
irq_work_sync(&adapter->ec_watchdog_kicker);
ecdev_withdraw(adapter->ecdev);
}
@ -4336,8 +4342,16 @@ static void igb_watchdog_task(struct work_struct *work)
int i;
u32 connsw;
if (adapter->ecdev)
hw->mac.get_link_status = true;
link = igb_has_link(adapter);
if (adapter->ecdev) {
ecdev_set_link(adapter->ecdev, link);
return;
}
if (adapter->flags & IGB_FLAG_NEED_LINK_UPDATE) {
if (time_after(jiffies, (adapter->link_check_timeout + HZ)))
adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE;

View File

@ -3045,6 +3045,14 @@ static const struct net_device_ops igb_netdev_ops = {
.ndo_xdp_xmit = igb_xdp_xmit,
};
static void ec_kick_watchdog(struct irq_work *work)
{
struct igb_adapter *adapter =
container_of(work, struct igb_adapter, ec_watchdog_kicker);
schedule_work(&adapter->watchdog_task);
}
/**
* ec_poll - EtherCAT poll routine
* @netdev: net device structure
@ -3059,12 +3067,8 @@ void ec_poll(struct net_device *netdev)
int budget = 64;
if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
struct e1000_hw *hw = &adapter->hw;
bool link;
hw->mac.get_link_status = true;
link = igb_has_link(adapter);
ecdev_set_link(adapter->ecdev, link);
adapter->ec_watchdog_jiffies = jiffies;
irq_work_queue(&adapter->ec_watchdog_kicker);
}
for (i = 0; i < adapter->num_q_vectors; i++) {
@ -3560,6 +3564,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev);
if (err) {
ecdev_withdraw(adapter->ecdev);
@ -3864,6 +3869,7 @@ static void igb_remove(struct pci_dev *pdev)
if (adapter->ecdev) {
ecdev_close(adapter->ecdev);
irq_work_sync(&adapter->ec_watchdog_kicker);
ecdev_withdraw(adapter->ecdev);
}
@ -5525,8 +5531,16 @@ static void igb_watchdog_task(struct work_struct *work)
u32 connsw;
u16 phy_data, retry_count = 20;
if (adapter->ecdev)
hw->mac.get_link_status = true;
link = igb_has_link(adapter);
if (adapter->ecdev) {
ecdev_set_link(adapter->ecdev, link);
return;
}
if (adapter->flags & IGB_FLAG_NEED_LINK_UPDATE) {
if (time_after(jiffies, (adapter->link_check_timeout + HZ)))
adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE;

View File

@ -3055,6 +3055,14 @@ static const struct net_device_ops igb_netdev_ops = {
.ndo_xdp_xmit = igb_xdp_xmit,
};
static void ec_kick_watchdog(struct irq_work *work)
{
struct igb_adapter *adapter =
container_of(work, struct igb_adapter, ec_watchdog_kicker);
schedule_work(&adapter->watchdog_task);
}
/**
* ec_poll - EtherCAT poll routine
* @netdev: net device structure
@ -3069,12 +3077,8 @@ void ec_poll(struct net_device *netdev)
int budget = 64;
if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
struct e1000_hw *hw = &adapter->hw;
bool link;
hw->mac.get_link_status = true;
link = igb_has_link(adapter);
ecdev_set_link(adapter->ecdev, link);
adapter->ec_watchdog_jiffies = jiffies;
irq_work_queue(&adapter->ec_watchdog_kicker);
}
for (i = 0; i < adapter->num_q_vectors; i++) {
@ -3570,6 +3574,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev);
if (err) {
ecdev_withdraw(adapter->ecdev);
@ -3874,6 +3879,7 @@ static void igb_remove(struct pci_dev *pdev)
if (adapter->ecdev) {
ecdev_close(adapter->ecdev);
irq_work_sync(&adapter->ec_watchdog_kicker);
ecdev_withdraw(adapter->ecdev);
}
@ -5535,8 +5541,16 @@ static void igb_watchdog_task(struct work_struct *work)
u32 connsw;
u16 phy_data, retry_count = 20;
if (adapter->ecdev)
hw->mac.get_link_status = true;
link = igb_has_link(adapter);
if (adapter->ecdev) {
ecdev_set_link(adapter->ecdev, link);
return;
}
if (adapter->flags & IGB_FLAG_NEED_LINK_UPDATE) {
if (time_after(jiffies, (adapter->link_check_timeout + HZ)))
adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE;

View File

@ -3044,6 +3044,14 @@ static const struct net_device_ops igb_netdev_ops = {
.ndo_xdp_xmit = igb_xdp_xmit,
};
static void ec_kick_watchdog(struct irq_work *work)
{
struct igb_adapter *adapter =
container_of(work, struct igb_adapter, ec_watchdog_kicker);
schedule_work(&adapter->watchdog_task);
}
/**
* ec_poll - EtherCAT poll routine
* @netdev: net device structure
@ -3058,12 +3066,8 @@ void ec_poll(struct net_device *netdev)
int budget = 64;
if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
struct e1000_hw *hw = &adapter->hw;
bool link;
hw->mac.get_link_status = true;
link = igb_has_link(adapter);
ecdev_set_link(adapter->ecdev, link);
adapter->ec_watchdog_jiffies = jiffies;
irq_work_queue(&adapter->ec_watchdog_kicker);
}
for (i = 0; i < adapter->num_q_vectors; i++) {
@ -3559,6 +3563,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev);
if (err) {
ecdev_withdraw(adapter->ecdev);
@ -3863,6 +3868,7 @@ static void igb_remove(struct pci_dev *pdev)
if (adapter->ecdev) {
ecdev_close(adapter->ecdev);
irq_work_sync(&adapter->ec_watchdog_kicker);
ecdev_withdraw(adapter->ecdev);
}
@ -5533,8 +5539,16 @@ static void igb_watchdog_task(struct work_struct *work)
u32 connsw;
u16 phy_data, retry_count = 20;
if (adapter->ecdev)
hw->mac.get_link_status = true;
link = igb_has_link(adapter);
if (adapter->ecdev) {
ecdev_set_link(adapter->ecdev, link);
return;
}
if (adapter->flags & IGB_FLAG_NEED_LINK_UPDATE) {
if (time_after(jiffies, (adapter->link_check_timeout + HZ)))
adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE;

View File

@ -3070,6 +3070,14 @@ static const struct net_device_ops igb_netdev_ops = {
.ndo_xdp_xmit = igb_xdp_xmit,
};
static void ec_kick_watchdog(struct irq_work *work)
{
struct igb_adapter *adapter =
container_of(work, struct igb_adapter, ec_watchdog_kicker);
schedule_work(&adapter->watchdog_task);
}
/**
* ec_poll - EtherCAT poll routine
* @netdev: net device structure
@ -3084,12 +3092,8 @@ void ec_poll(struct net_device *netdev)
int budget = 64;
if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
struct e1000_hw *hw = &adapter->hw;
bool link;
hw->mac.get_link_status = true;
link = igb_has_link(adapter);
ecdev_set_link(adapter->ecdev, link);
adapter->ec_watchdog_jiffies = jiffies;
irq_work_queue(&adapter->ec_watchdog_kicker);
}
for (i = 0; i < adapter->num_q_vectors; i++) {
@ -3578,6 +3582,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev);
if (err) {
ecdev_withdraw(adapter->ecdev);
@ -3890,6 +3895,7 @@ static void igb_remove(struct pci_dev *pdev)
if (adapter->ecdev) {
ecdev_close(adapter->ecdev);
irq_work_sync(&adapter->ec_watchdog_kicker);
ecdev_withdraw(adapter->ecdev);
}
@ -5566,8 +5572,16 @@ static void igb_watchdog_task(struct work_struct *work)
u32 connsw;
u16 phy_data, retry_count = 20;
if (adapter->ecdev)
hw->mac.get_link_status = true;
link = igb_has_link(adapter);
if (adapter->ecdev) {
ecdev_set_link(adapter->ecdev, link);
return;
}
if (adapter->flags & IGB_FLAG_NEED_LINK_UPDATE) {
if (time_after(jiffies, (adapter->link_check_timeout + HZ)))
adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE;

View File

@ -5,6 +5,7 @@
#define _IGC_H_
#include "../ecdev.h"
#include <linux/irq_work.h>
#include <linux/kobject.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
@ -268,6 +269,7 @@ struct igc_adapter {
/* EtherCAT device variables */
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
void igc_up(struct igc_adapter *adapter);

View File

@ -5,6 +5,7 @@
#define _IGC_H_
#include "../ecdev.h"
#include <linux/irq_work.h>
#include <linux/kobject.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
@ -283,6 +284,7 @@ struct igc_adapter {
/* EtherCAT device variables */
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
void igc_up(struct igc_adapter *adapter);

View File

@ -5576,8 +5576,16 @@ static void igc_watchdog_task(struct work_struct *work)
u32 link;
int i;
if (adapter->ecdev)
hw->mac.get_link_status = true;
link = igc_has_link(adapter);
if (adapter->ecdev) {
ecdev_set_link(adapter->ecdev, link);
return;
}
if (adapter->flags & IGC_FLAG_NEED_LINK_UPDATE) {
if (time_after(jiffies, (adapter->link_check_timeout + HZ)))
adapter->flags &= ~IGC_FLAG_NEED_LINK_UPDATE;
@ -6537,6 +6545,14 @@ static const struct net_device_ops igc_netdev_ops = {
.ndo_xsk_wakeup = igc_xsk_wakeup,
};
static void ec_kick_watchdog(struct irq_work *work)
{
struct igc_adapter *adapter =
container_of(work, struct igc_adapter, ec_watchdog_kicker);
schedule_work(&adapter->watchdog_task);
}
/**
* ec_poll - EtherCAT poll routine
* @netdev: net device structure
@ -6551,13 +6567,8 @@ void ec_poll(struct net_device *netdev)
int budget = 64;
if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
struct igc_hw *hw = &adapter->hw;
bool link;
hw->mac.get_link_status = true;
link = igc_has_link(adapter);
ecdev_set_link(adapter->ecdev, link);
adapter->ec_watchdog_jiffies = jiffies;
irq_work_queue(&adapter->ec_watchdog_kicker);
}
for (i = 0; i < adapter->num_q_vectors; i++) {
@ -6910,6 +6921,7 @@ static int igc_probe(struct pci_dev *pdev,
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev);
if (err) {
ecdev_withdraw(adapter->ecdev);
@ -6976,6 +6988,7 @@ static void igc_remove(struct pci_dev *pdev)
if (adapter->ecdev) {
ecdev_close(adapter->ecdev);
irq_work_sync(&adapter->irq_work);
ecdev_withdraw(adapter->ecdev);
}

View File

@ -5641,8 +5641,16 @@ static void igc_watchdog_task(struct work_struct *work)
u32 link;
int i;
if (adapter->ecdev)
hw->mac.get_link_status = true;
link = igc_has_link(adapter);
if (adapter->ecdev) {
ecdev_set_link(adapter->ecdev, link);
return;
}
if (adapter->flags & IGC_FLAG_NEED_LINK_UPDATE) {
if (time_after(jiffies, (adapter->link_check_timeout + HZ)))
adapter->flags &= ~IGC_FLAG_NEED_LINK_UPDATE;
@ -6657,6 +6665,14 @@ static const struct net_device_ops igc_netdev_ops = {
.ndo_xsk_wakeup = igc_xsk_wakeup,
};
static void ec_kick_watchdog(struct irq_work *work)
{
struct igc_adapter *adapter =
container_of(work, struct igc_adapter, ec_watchdog_kicker);
schedule_work(&adapter->watchdog_task);
}
/**
* ec_poll - EtherCAT poll routine
* @netdev: net device structure
@ -6671,13 +6687,8 @@ void ec_poll(struct net_device *netdev)
int budget = 64;
if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
struct igc_hw *hw = &adapter->hw;
bool link;
hw->mac.get_link_status = true;
link = igc_has_link(adapter);
ecdev_set_link(adapter->ecdev, link);
adapter->ec_watchdog_jiffies = jiffies;
irq_work_queue(&adapter->ec_watchdog_kicker);
}
for (i = 0; i < adapter->num_q_vectors; i++) {
@ -7050,6 +7061,7 @@ static int igc_probe(struct pci_dev *pdev,
adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
if (adapter->ecdev) {
init_irq_work(&adapter->ec_watchdog_kicker, ec_kick_watchdog);
err = ecdev_open(adapter->ecdev);
if (err) {
ecdev_withdraw(adapter->ecdev);
@ -7116,6 +7128,7 @@ static void igc_remove(struct pci_dev *pdev)
if (adapter->ecdev) {
ecdev_close(adapter->ecdev);
irq_work_sync(&adapter->irq_work);
ecdev_withdraw(adapter->ecdev);
}

View File

@ -21,6 +21,7 @@
#include <linux/in.h>
#include <linux/io.h>
#include <linux/ip.h>
#include <linux/irq_work.h>
#include <linux/tcp.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
@ -35,7 +36,7 @@
#include "../ecdev.h"
#define MODULENAME "r8169"
#define MODULENAME "ec_r8169"
#define FIRMWARE_8168D_1 "rtl_nic/rtl8168d-1.fw"
#define FIRMWARE_8168D_2 "rtl_nic/rtl8168d-2.fw"
@ -633,6 +634,7 @@ struct rtl8169_private {
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);
@ -5079,6 +5081,7 @@ static void rtl_remove_one(struct pci_dev *pdev)
if (tp->ecdev) {
ecdev_close(tp->ecdev);
irq_work_sync(&tp->ec_watchdog_kicker);
ecdev_withdraw(tp->ecdev);
} else {
unregister_netdev(tp->dev);
@ -5369,6 +5372,14 @@ done:
rtl_rar_set(tp, mac_addr);
}
static void ec_kick_watchdog(struct irq_work *work)
{
struct rtl8169_private *tp =
container_of(work, struct rtl8169_private, ec_watchdog_kicker);
phy_mac_interrupt(tp->phydev);
}
static void ec_poll(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@ -5387,8 +5398,7 @@ static void ec_poll(struct net_device *dev)
rtl_rx(dev, tp, 100);
if (status & LinkChg)
phy_mac_interrupt(tp->phydev);
irq_work_queue(&tp->ec_watchdog_kicker);
rtl_ack_events(tp, status);
}
@ -5588,6 +5598,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pm_runtime_put_sync(&pdev->dev);
if (tp->ecdev) {
init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog);
rc = ecdev_open(tp->ecdev);
if (rc) {
ecdev_withdraw(tp->ecdev);

View File

@ -21,6 +21,7 @@
#include <linux/in.h>
#include <linux/io.h>
#include <linux/ip.h>
#include <linux/irq_work.h>
#include <linux/tcp.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
@ -653,6 +654,7 @@ struct rtl8169_private {
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);
@ -5048,6 +5050,7 @@ static void rtl_remove_one(struct pci_dev *pdev)
if (tp->ecdev) {
ecdev_close(tp->ecdev);
irq_work_sync(&tp->ec_watchdog_kicker);
ecdev_withdraw(tp->ecdev);
} else {
unregister_netdev(tp->dev);
@ -5338,6 +5341,14 @@ done:
rtl_rar_set(tp, mac_addr);
}
static void ec_kick_watchdog(struct irq_work *work)
{
struct rtl8169_private *tp =
container_of(work, struct rtl8169_private, ec_watchdog_kicker);
phy_mac_interrupt(tp->phydev);
}
static void ec_poll(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@ -5356,7 +5367,7 @@ static void ec_poll(struct net_device *dev)
rtl_rx(dev, tp, 100);
if (status & LinkChg)
phy_mac_interrupt(tp->phydev);
irq_work_queue(&tp->ec_watchdog_kicker);
rtl_ack_events(tp, status);
}
@ -5560,6 +5571,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pm_runtime_put_sync(&pdev->dev);
if (tp->ecdev) {
init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog);
rc = ecdev_open(tp->ecdev);
if (rc) {
ecdev_withdraw(tp->ecdev);

View File

@ -21,6 +21,7 @@
#include <linux/in.h>
#include <linux/io.h>
#include <linux/ip.h>
#include <linux/irq_work.h>
#include <linux/tcp.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
@ -641,6 +642,7 @@ struct rtl8169_private {
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);
@ -5041,6 +5043,7 @@ static void rtl_remove_one(struct pci_dev *pdev)
if (tp->ecdev) {
ecdev_close(tp->ecdev);
irq_work_sync(&tp->ec_watchdog_kicker);
ecdev_withdraw(tp->ecdev);
} else {
unregister_netdev(tp->dev);
@ -5331,6 +5334,14 @@ done:
rtl_rar_set(tp, mac_addr);
}
static void ec_kick_watchdog(struct irq_work *work)
{
struct rtl8169_private *tp =
container_of(work, struct rtl8169_private, ec_watchdog_kicker);
phy_mac_interrupt(tp->phydev);
}
static void ec_poll(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@ -5349,7 +5360,7 @@ static void ec_poll(struct net_device *dev)
rtl_rx(dev, tp, 100);
if (status & LinkChg)
phy_mac_interrupt(tp->phydev);
irq_work_queue(&tp->ec_watchdog_kicker);
rtl_ack_events(tp, status);
}
@ -5552,6 +5563,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pm_runtime_put_sync(&pdev->dev);
if (tp->ecdev) {
init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog);
rc = ecdev_open(tp->ecdev);
if (rc) {
ecdev_withdraw(tp->ecdev);

View File

@ -21,6 +21,7 @@
#include <linux/in.h>
#include <linux/io.h>
#include <linux/ip.h>
#include <linux/irq_work.h>
#include <linux/tcp.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
@ -630,6 +631,7 @@ struct rtl8169_private {
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);
@ -4919,6 +4921,7 @@ static void rtl_remove_one(struct pci_dev *pdev)
if (tp->ecdev) {
ecdev_close(tp->ecdev);
irq_work_sync(&tp->ec_watchdog_kicker);
ecdev_withdraw(tp->ecdev);
} else {
unregister_netdev(tp->dev);
@ -5189,6 +5192,14 @@ static bool rtl_aspm_is_safe(struct rtl8169_private *tp)
return false;
}
static void ec_kick_watchdog(struct irq_work *work)
{
struct rtl8169_private *tp =
container_of(work, struct rtl8169_private, ec_watchdog_kicker);
phy_mac_interrupt(tp->phydev);
}
static void ec_poll(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@ -5207,7 +5218,7 @@ static void ec_poll(struct net_device *dev)
rtl_rx(dev, tp, 100);
if (status & LinkChg)
phy_mac_interrupt(tp->phydev);
irq_work_queue(&tp->ec_watchdog_kicker);
rtl_ack_events(tp, status);
}
@ -5416,6 +5427,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pm_runtime_put_sync(&pdev->dev);
if (tp->ecdev) {
init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog);
rc = ecdev_open(tp->ecdev);
if (rc) {
ecdev_withdraw(tp->ecdev);

View File

@ -40,6 +40,11 @@ SUBDIRS += \
xenomai \
xenomai_posix
endif
if ENABLE_XENOMAI_V3
SUBDIRS += \
xenomai \
xenomai_posix
endif
if ENABLE_RTAI
SUBDIRS += \

View File

@ -38,7 +38,7 @@ RT_TASK *task;
const static unsigned int cycle_us = 1000; /* 1 ms */
static int run = 1;
static volatile sig_atomic_t run = 1;
/****************************************************************************/

View File

@ -38,7 +38,7 @@ RT_TASK *task;
static unsigned int cycle_ns = 1000000; /* 1 ms */
static int run = 1;
static volatile sig_atomic_t run = 1;
/****************************************************************************/

View File

@ -100,7 +100,7 @@ static unsigned int blink = 0;
// Analog in --------------------------
static ec_pdo_entry_info_t el3102_pdo_entries[] = {
static const ec_pdo_entry_info_t el3102_pdo_entries[] = {
{0x3101, 1, 8}, // channel 1 status
{0x3101, 2, 16}, // channel 1 value
{0x3102, 1, 8}, // channel 2 status
@ -109,12 +109,12 @@ static ec_pdo_entry_info_t el3102_pdo_entries[] = {
{0x6401, 2, 16} // channel 2 value (alt.)
};
static ec_pdo_info_t el3102_pdos[] = {
static const ec_pdo_info_t el3102_pdos[] = {
{0x1A00, 2, el3102_pdo_entries},
{0x1A01, 2, el3102_pdo_entries + 2}
};
static ec_sync_info_t el3102_syncs[] = {
static const ec_sync_info_t el3102_syncs[] = {
{2, EC_DIR_OUTPUT},
{3, EC_DIR_INPUT, 2, el3102_pdos},
{0xff}
@ -122,17 +122,17 @@ static ec_sync_info_t el3102_syncs[] = {
// Analog out -------------------------
static ec_pdo_entry_info_t el4102_pdo_entries[] = {
static const ec_pdo_entry_info_t el4102_pdo_entries[] = {
{0x3001, 1, 16}, // channel 1 value
{0x3002, 1, 16}, // channel 2 value
};
static ec_pdo_info_t el4102_pdos[] = {
static const ec_pdo_info_t el4102_pdos[] = {
{0x1600, 1, el4102_pdo_entries},
{0x1601, 1, el4102_pdo_entries + 1}
};
static ec_sync_info_t el4102_syncs[] = {
static const ec_sync_info_t el4102_syncs[] = {
{2, EC_DIR_OUTPUT, 2, el4102_pdos},
{3, EC_DIR_INPUT},
{0xff}
@ -140,21 +140,21 @@ static ec_sync_info_t el4102_syncs[] = {
// Digital out ------------------------
static ec_pdo_entry_info_t el2004_channels[] = {
static const ec_pdo_entry_info_t el2004_channels[] = {
{0x3001, 1, 1}, // Value 1
{0x3001, 2, 1}, // Value 2
{0x3001, 3, 1}, // Value 3
{0x3001, 4, 1} // Value 4
};
static ec_pdo_info_t el2004_pdos[] = {
static const ec_pdo_info_t el2004_pdos[] = {
{0x1600, 1, &el2004_channels[0]},
{0x1601, 1, &el2004_channels[1]},
{0x1602, 1, &el2004_channels[2]},
{0x1603, 1, &el2004_channels[3]}
};
static ec_sync_info_t el2004_syncs[] = {
static const ec_sync_info_t el2004_syncs[] = {
{0, EC_DIR_OUTPUT, 4, el2004_pdos},
{1, EC_DIR_INPUT},
{0xff}

View File

@ -25,13 +25,26 @@ ec_xenomai_example_SOURCES = main.c
ec_xenomai_example_CFLAGS = \
-Wall \
-I$(top_srcdir)/include \
-I$(top_srcdir)/include
ec_xenomai_example_LDFLAGS = \
-L$(top_builddir)/lib/.libs -lethercat_rtdm
if ENABLE_XENOMAI_V3
ec_xenomai_example_CFLAGS += \
-DXENOMAI_API_V3 \
$(XENOMAI_ALCHEMY_CFLAGS)
ec_xenomai_example_LDFLAGS += \
$(XENOMAI_ALCHEMY_LDFLAGS)
else
ec_xenomai_example_CFLAGS += \
$(XENOMAI_NATIVE_CFLAGS) \
$(XENOMAI_RTDM_CFLAGS)
ec_xenomai_example_LDFLAGS = \
-L$(top_builddir)/lib/.libs -lethercat_rtdm \
ec_xenomai_example_LDFLAGS += \
$(XENOMAI_NATIVE_LDFLAGS) \
$(XENOMAI_RTDM_LDFLAGS)
endif
#------------------------------------------------------------------------------

View File

@ -29,19 +29,25 @@
#include <sys/types.h>
#include <unistd.h>
#include <sys/mman.h>
#ifdef XENOMAI_API_V3
#include <alchemy/task.h>
#include <alchemy/sem.h>
enum {T_FPU = 0};
#else
#include <rtdm/rtdm.h>
#include <native/task.h>
#include <native/sem.h>
#include <native/mutex.h>
#include <native/timer.h>
#include <rtdk.h>
#endif
#include <pthread.h>
#include "ecrt.h"
RT_TASK my_task;
static int run = 1;
static volatile sig_atomic_t run = 1;
/****************************************************************************/
@ -84,14 +90,14 @@ const static ec_pdo_entry_reg_t domain1_regs[] = {
* Revision number: 0x00100000
*/
ec_pdo_entry_info_t slave_1_pdo_entries[] = {
const ec_pdo_entry_info_t slave_1_pdo_entries[] = {
{0x7000, 0x01, 1}, /* Output */
{0x7010, 0x01, 1}, /* Output */
{0x7020, 0x01, 1}, /* Output */
{0x7030, 0x01, 1}, /* Output */
};
ec_pdo_info_t slave_1_pdos[] = {
const ec_pdo_info_t slave_1_pdos[] = {
{0x1600, 1, slave_1_pdo_entries + 0}, /* Channel 1 */
{0x1601, 1, slave_1_pdo_entries + 1}, /* Channel 2 */
{0x1602, 1, slave_1_pdo_entries + 2}, /* Channel 3 */
@ -201,8 +207,10 @@ int main(int argc, char *argv[])
ec_slave_config_t *sc;
int ret;
#ifndef XENOMAI_API_V3
/* Perform auto-init of rt_print buffers if the task doesn't do so */
rt_print_auto_init(1);
#endif
signal(SIGTERM, signal_handler);
signal(SIGINT, signal_handler);

View File

@ -29,6 +29,11 @@ ec_xenomai_posix_example_CFLAGS = \
$(XENOMAI_POSIX_CFLAGS) \
$(XENOMAI_RTDM_CFLAGS)
if ENABLE_XENOMAI_V3
ec_xenomai_posix_example_CFLAGS += \
-DXENOMAI_API_V3
endif
ec_xenomai_posix_example_LDFLAGS = \
-L$(top_builddir)/lib/.libs -lethercat_rtdm \
$(XENOMAI_POSIX_LDFLAGS) \

View File

@ -32,8 +32,10 @@
#include <sys/mman.h>
#include <time.h>
#ifndef XENOMAI_API_V3
#include <rtdm/rtdm.h>
#include <rtdk.h>
#endif
#include "ecrt.h"
@ -43,7 +45,7 @@ static unsigned int cycle_us = 1000; /* 1 ms */
static pthread_t cyclic_thread;
static int run = 1;
static volatile sig_atomic_t run = 1;
/****************************************************************************/
@ -86,21 +88,21 @@ const static ec_pdo_entry_reg_t domain1_regs[] = {
* Revision number: 0x00100000
*/
ec_pdo_entry_info_t slave_1_pdo_entries[] = {
const ec_pdo_entry_info_t slave_1_pdo_entries[] = {
{0x7000, 0x01, 1}, /* Output */
{0x7010, 0x01, 1}, /* Output */
{0x7020, 0x01, 1}, /* Output */
{0x7030, 0x01, 1}, /* Output */
};
ec_pdo_info_t slave_1_pdos[] = {
const ec_pdo_info_t slave_1_pdos[] = {
{0x1600, 1, slave_1_pdo_entries + 0}, /* Channel 1 */
{0x1601, 1, slave_1_pdo_entries + 1}, /* Channel 2 */
{0x1602, 1, slave_1_pdo_entries + 2}, /* Channel 3 */
{0x1603, 1, slave_1_pdo_entries + 3}, /* Channel 4 */
};
ec_sync_info_t slave_1_syncs[] = {
const ec_sync_info_t slave_1_syncs[] = {
{0, EC_DIR_OUTPUT, 4, slave_1_pdos + 0, EC_WD_ENABLE},
{0xff}
};
@ -271,7 +273,7 @@ int main(int argc, char *argv[])
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
pthread_attr_setinheritsched(&thattr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedpolicy(&thattr, SCHED_FIFO);
pthread_setschedparam(cyclic_thread, SCHED_FIFO, &param);
pthread_attr_setschedparam(&thattr, &param);
ret = pthread_create(&cyclic_thread, &thattr, &my_thread, NULL);
if (ret) {

View File

@ -180,7 +180,7 @@
/** EtherCAT realtime interface minor version number.
*/
#define ECRT_VER_MINOR 5
#define ECRT_VER_MINOR 6
/** EtherCAT realtime interface version word generator.
*/
@ -409,10 +409,10 @@ typedef struct {
* \see ecrt_master().
*/
typedef struct {
unsigned int slave_count; /**< Number of slaves in the bus. */
unsigned int link_up : 1; /**< \a true, if the network link is up. */
uint8_t scan_busy; /**< \a true, while the master is scanning the bus */
uint64_t app_time; /**< Application time. */
unsigned int slave_count; /**< Number of slaves in the bus. */
unsigned int link_up : 1; /**< \a true, if the network link is up. */
uint8_t scan_busy; /**< \a true, while the master is scanning the bus */
uint64_t app_time; /**< Application time. */
} ec_master_info_t;
/****************************************************************************/
@ -424,10 +424,11 @@ typedef struct {
* \see ecrt_master_scan_progress().
*/
typedef struct {
unsigned int slave_count; /**< Number of slaves detected. */
unsigned int scan_index; /**< Index of the slave that is currently scanned.
If it is less than the \a slave_count, the
network scan is in progress. */
unsigned int slave_count; /**< Number of slaves detected. */
unsigned int scan_index; /**< Index of the slave that is currently
scanned. If it is less than the \a
slave_count, the network scan is in progress.
*/
} ec_master_scan_progress_t;
/****************************************************************************/
@ -559,9 +560,9 @@ typedef struct {
Zero means, that the default mapping shall be
used (this can only be done if the slave is
present at bus configuration time). */
ec_pdo_entry_info_t *entries; /**< Array of PDO entries to map. Can either
be \a NULL, or must contain at
least \a n_entries values. */
ec_pdo_entry_info_t const *entries; /**< Array of PDO entries to map. Can
either be \a NULL, or must contain
at least \a n_entries values. */
} ec_pdo_info_t;
/****************************************************************************/
@ -578,8 +579,8 @@ typedef struct {
but can also be \a 0xff to mark the end of the list. */
ec_direction_t dir; /**< Sync manager direction. */
unsigned int n_pdos; /**< Number of PDOs in \a pdos. */
ec_pdo_info_t *pdos; /**< Array with PDOs to assign. This must contain
at least \a n_pdos PDOs. */
ec_pdo_info_t const *pdos; /**< Array with PDOs to assign. This must
contain at least \a n_pdos PDOs. */
ec_watchdog_mode_t watchdog_mode; /**< Watchdog mode. */
} ec_sync_info_t;
@ -601,8 +602,8 @@ typedef struct {
(byte-)offset in the process data. */
unsigned int *bit_position; /**< Pointer to a variable to store a bit
position (0-7) within the \a offset. Can be
NULL, in which case an error is raised if the
PDO entry does not byte-align. */
NULL, in which case an error is raised if
the PDO entry does not byte-align. */
} ec_pdo_entry_reg_t;
/****************************************************************************/
@ -835,7 +836,7 @@ EC_PUBLIC_API int ecrt_master(
*
* \return 0 in case of success, else < 0
*/
int ecrt_master_scan_progress(
EC_PUBLIC_API int ecrt_master_scan_progress(
ec_master_t *master, /**< EtherCAT master */
ec_master_scan_progress_t *progress /**< Structure that will output
the progress information. */
@ -927,7 +928,7 @@ EC_PUBLIC_API int ecrt_master_sdo_download(
uint16_t slave_position, /**< Slave position. */
uint16_t index, /**< Index of the SDO. */
uint8_t subindex, /**< Subindex of the SDO. */
uint8_t *data, /**< Data buffer to download. */
const uint8_t *data, /**< Data buffer to download. */
size_t data_size, /**< Size of the data buffer. */
uint32_t *abort_code /**< Abort code of the SDO download. */
);
@ -946,7 +947,7 @@ EC_PUBLIC_API int ecrt_master_sdo_download_complete(
ec_master_t *master, /**< EtherCAT master. */
uint16_t slave_position, /**< Slave position. */
uint16_t index, /**< Index of the SDO. */
uint8_t *data, /**< Data buffer to download. */
const uint8_t *data, /**< Data buffer to download. */
size_t data_size, /**< Size of the data buffer. */
uint32_t *abort_code /**< Abort code of the SDO download. */
);
@ -984,7 +985,7 @@ EC_PUBLIC_API int ecrt_master_write_idn(
uint16_t slave_position, /**< Slave position. */
uint8_t drive_no, /**< Drive number. */
uint16_t idn, /**< SoE IDN (see ecrt_slave_config_idn()). */
uint8_t *data, /**< Pointer to data to write. */
const uint8_t *data, /**< Pointer to data to write. */
size_t data_size, /**< Size of data to write. */
uint16_t *error_code /**< Pointer to variable, where an SoE error code
can be stored. */
@ -1169,6 +1170,9 @@ EC_PUBLIC_API void ecrt_master_sync_reference_clock(
* The reference clock will by synchronized to the time passed in the
* sync_time parameter.
*
* Has to be called by the application after ecrt_master_activate()
* has returned.
*
* \ingroup ApplicationInterfaceRT
*/
EC_PUBLIC_API void ecrt_master_sync_reference_clock_to(
@ -1180,6 +1184,9 @@ EC_PUBLIC_API void ecrt_master_sync_reference_clock_to(
*
* All slave clocks synchronized to the reference clock.
*
* Has to be called by the application after ecrt_master_activate()
* has returned.
*
* \ingroup ApplicationInterfaceRT
*/
EC_PUBLIC_API void ecrt_master_sync_slave_clocks(
@ -1203,7 +1210,7 @@ EC_PUBLIC_API void ecrt_master_sync_slave_clocks(
* \retval -EIO Slave synchronization datagram was not received.
*/
EC_PUBLIC_API int ecrt_master_reference_clock_time(
ec_master_t *master, /**< EtherCAT master. */
const ec_master_t *master, /**< EtherCAT master. */
uint32_t *time /**< Pointer to store the queried system time. */
);
@ -1230,7 +1237,7 @@ EC_PUBLIC_API void ecrt_master_sync_monitor_queue(
* \return Upper estimation of the maximum time difference in ns.
*/
EC_PUBLIC_API uint32_t ecrt_master_sync_monitor_process(
ec_master_t *master /**< EtherCAT master. */
const ec_master_t *master /**< EtherCAT master. */
);
/** Retry configuring slaves.
@ -1239,6 +1246,8 @@ EC_PUBLIC_API uint32_t ecrt_master_sync_monitor_process(
* OP state. In general, this is not necessary, because it is automatically
* done by the master. But with special slaves, that can be reconfigured by
* the vendor during runtime, it can be useful.
*
* \ingroup ApplicationInterfaceRT
*/
EC_PUBLIC_API void ecrt_master_reset(
ec_master_t *master /**< EtherCAT master. */
@ -1654,7 +1663,7 @@ EC_PUBLIC_API int ecrt_slave_config_emerg_clear(
* \return Number of overruns since last clear, or negative error code.
*/
EC_PUBLIC_API int ecrt_slave_config_emerg_overruns(
ec_slave_config_t *sc /**< Slave configuration. */
const ec_slave_config_t *sc /**< Slave configuration. */
);
/** Create an SDO request to exchange SDOs during realtime operation.
@ -1684,7 +1693,7 @@ EC_PUBLIC_API ec_sdo_request_t *ecrt_slave_config_create_sdo_request(
*
* \return New SoE request, or NULL on error.
*/
ec_soe_request_t *ecrt_slave_config_create_soe_request(
EC_PUBLIC_API ec_soe_request_t *ecrt_slave_config_create_soe_request(
ec_slave_config_t *sc, /**< Slave configuration. */
uint8_t drive_no, /**< Drive number. */
uint16_t idn, /**< Sercos ID-Number. */
@ -2022,8 +2031,8 @@ EC_PUBLIC_API void ecrt_sdo_request_timeout(
*
* This function returns a pointer to the request's internal SDO data memory.
*
* - After a read operation was successful, integer data can be evaluated using
* the EC_READ_*() macros as usual. Example:
* - After a read operation was successful, integer data can be evaluated
* using the EC_READ_*() macros as usual. Example:
* \code
* uint16_t value = EC_READ_U16(ecrt_sdo_request_data(sdo)));
* \endcode
@ -2042,7 +2051,7 @@ EC_PUBLIC_API void ecrt_sdo_request_timeout(
* \return Pointer to the internal SDO data memory.
*/
EC_PUBLIC_API uint8_t *ecrt_sdo_request_data(
ec_sdo_request_t *req /**< SDO request. */
const ec_sdo_request_t *req /**< SDO request. */
);
/** Returns the current SDO data size.
@ -2103,7 +2112,7 @@ EC_PUBLIC_API void ecrt_sdo_request_read(
* ecrt_soe_request_state() returns EC_REQUEST_BUSY, this may lead to
* unexpected results.
*/
void ecrt_soe_request_idn(
EC_PUBLIC_API void ecrt_soe_request_idn(
ec_soe_request_t *req, /**< IDN request. */
uint8_t drive_no, /**< SDO index. */
uint16_t idn /**< SoE IDN. */
@ -2117,7 +2126,7 @@ void ecrt_soe_request_idn(
* The timeout is permanently stored in the request object and is valid until
* the next call of this method.
*/
void ecrt_soe_request_timeout(
EC_PUBLIC_API void ecrt_soe_request_timeout(
ec_soe_request_t *req, /**< SoE request. */
uint32_t timeout /**< Timeout in milliseconds. Zero means no
timeout. */
@ -2146,8 +2155,8 @@ void ecrt_soe_request_timeout(
*
* \return Pointer to the internal IDN data memory.
*/
uint8_t *ecrt_soe_request_data(
ec_soe_request_t *req /**< SoE request. */
EC_PUBLIC_API uint8_t *ecrt_soe_request_data(
const ec_soe_request_t *req /**< SoE request. */
);
/** Returns the current IDN data size.
@ -2158,7 +2167,7 @@ uint8_t *ecrt_soe_request_data(
*
* \return IDN data size in bytes.
*/
size_t ecrt_soe_request_data_size(
EC_PUBLIC_API size_t ecrt_soe_request_data_size(
const ec_soe_request_t *req /**< SoE request. */
);
@ -2166,8 +2175,9 @@ size_t ecrt_soe_request_data_size(
*
* \return Request state.
*/
ec_request_state_t ecrt_soe_request_state(
ec_soe_request_t *req /**< SoE request. */
EC_PUBLIC_API ec_request_state_t ecrt_soe_request_state(
ec_soe_request_t *req /**< SoE request. Not const, because the
internal data size may be updated. */
);
/** Schedule an SoE IDN write operation.
@ -2175,7 +2185,7 @@ ec_request_state_t ecrt_soe_request_state(
* \attention This method may not be called while ecrt_soe_request_state()
* returns EC_REQUEST_BUSY.
*/
void ecrt_soe_request_write(
EC_PUBLIC_API void ecrt_soe_request_write(
ec_soe_request_t *req /**< SoE request. */
);
@ -2188,7 +2198,7 @@ void ecrt_soe_request_write(
* ecrt_soe_request_data() must be considered as invalid while
* ecrt_soe_request_state() returns EC_REQUEST_BUSY.
*/
void ecrt_soe_request_read(
EC_PUBLIC_API void ecrt_soe_request_read(
ec_soe_request_t *req /**< SoE request. */
);
@ -2244,7 +2254,7 @@ EC_PUBLIC_API void ecrt_voe_handler_received_header(
* \return Pointer to the internal memory.
*/
EC_PUBLIC_API uint8_t *ecrt_voe_handler_data(
ec_voe_handler_t *voe /**< VoE handler. */
const ec_voe_handler_t *voe /**< VoE handler. */
);
/** Returns the current data size.
@ -2346,22 +2356,16 @@ EC_PUBLIC_API ec_request_state_t ecrt_voe_handler_execute(
* \return Pointer to the internal memory.
*/
EC_PUBLIC_API uint8_t *ecrt_reg_request_data(
ec_reg_request_t *req /**< Register request. */
const ec_reg_request_t *req /**< Register request. */
);
/** Get the current state of the register request.
*
* \return Request state.
*/
#ifdef __KERNEL__
ec_request_state_t ecrt_reg_request_state(
const ec_reg_request_t *req /**< Register request. */
);
#else
EC_PUBLIC_API ec_request_state_t ecrt_reg_request_state(
ec_reg_request_t *req /**< Register request. */
);
#endif
/** Schedule an register write operation.
*

View File

@ -70,15 +70,18 @@ libethercat_la_CFLAGS = -fno-strict-aliasing -Wall -I$(top_srcdir) \
# 3:0:2
#
libethercat_la_LDFLAGS = -version-info 3:0:2 \
-Wl,--version-script=$(srcdir)/libethercat.map \
-fvisibility=hidden
libethercat_la_DEPENDENCIES = libethercat.map
pkgconfig_DATA = libethercat.pc
cmakedir = $(libdir)/cmake/ethercat
cmake_DATA = ethercat-config.cmake
EXTRA_DIST = ethercat-config.cmake.in
EXTRA_DIST = ethercat-config.cmake.in libethercat.map
CLEANFILES = $(cmake_DATA)
@ -90,7 +93,7 @@ if ENABLE_RTDM
lib_LTLIBRARIES += libethercat_rtdm.la
libethercat_rtdm_la_SOURCES = $(libethercat_la_SOURCES)
libethercat_rtdm_la_CFLAGS = $(libethercat_la_CFLAGS) -DUSE_RTDM
libethercat_rtdm_la_CFLAGS = $(libethercat_la_CFLAGS)
libethercat_rtdm_la_LDFLAGS = $(libethercat_la_LDFLAGS)
if ENABLE_XENOMAI
@ -98,6 +101,14 @@ libethercat_rtdm_la_CFLAGS += $(XENOMAI_RTDM_CFLAGS)
libethercat_rtdm_la_LDFLAGS += $(XENOMAI_RTDM_LDFLAGS)
endif
if ENABLE_XENOMAI_V3
libethercat_rtdm_la_CFLAGS += $(XENOMAI_RTDM_CFLAGS)
libethercat_rtdm_la_LDFLAGS += $(XENOMAI_RTDM_LDFLAGS)
libethercat_rtdm_la_CFLAGS += -DUSE_RTDM_XENOMAI_V3
else
libethercat_rtdm_la_CFLAGS += -DUSE_RTDM
endif
if ENABLE_RTAI
libethercat_rtdm_la_CFLAGS += $(RTAI_LXRT_CFLAGS)
libethercat_rtdm_la_LDFLAGS += $(RTAI_LXRT_LDFLAGS)
@ -111,3 +122,17 @@ endif
ethercat-config.cmake: $(srcdir)/ethercat-config.cmake.in Makefile
$(SED) -e 's,%libdir%,$(libdir),' -e 's,%includedir%,$(includedir),' $< > $@
#-----------------------------------------------------------------------------
.PHONY: symbol-version-check
# check whether all symbols marked with EC_PUBLIC_API are listed in
# libethercat.map
symbol-version-check: libethercat.la
readelf --dyn-syms --wide $(builddir)/.libs/libethercat.so | \
awk '$$4 == "FUNC" && $$7 != "UND" && $$8 !~ /@LIBETHERCAT/ { print "Unversioned symbol: " $$8; err = 1; } END { exit err; }'
#-----------------------------------------------------------------------------

View File

@ -79,8 +79,10 @@ ec_master_t *ecrt_open_master(unsigned int master_index)
master->first_config = NULL;
snprintf(path, MAX_PATH_LEN - 1,
#ifdef USE_RTDM
#if defined(USE_RTDM)
"EtherCAT%u",
#elif defined(USE_RTDM_XENOMAI_V3)
"/dev/rtdm/EtherCAT%u",
#else
"/dev/EtherCAT%u",
#endif

107
lib/libethercat.map Normal file
View File

@ -0,0 +1,107 @@
LIBETHERCAT_1.5.2 {
global:
ecrt_domain_data;
ecrt_domain_process;
ecrt_domain_queue;
ecrt_domain_reg_pdo_entry_list;
ecrt_domain_size;
ecrt_domain_state;
ecrt_master;
ecrt_master_activate;
ecrt_master_application_time;
ecrt_master_create_domain;
ecrt_master_deactivate;
ecrt_master_get_pdo;
ecrt_master_get_pdo_entry;
ecrt_master_get_slave;
ecrt_master_get_sync_manager;
ecrt_master_link_state;
ecrt_master_read_idn;
ecrt_master_receive;
ecrt_master_reference_clock_time;
ecrt_master_reserve;
ecrt_master_reset;
ecrt_master_sdo_download;
ecrt_master_sdo_download_complete;
ecrt_master_sdo_upload;
ecrt_master_select_reference_clock;
ecrt_master_send;
ecrt_master_set_send_interval;
ecrt_master_slave_config;
ecrt_master_state;
ecrt_master_sync_monitor_process;
ecrt_master_sync_monitor_queue;
ecrt_master_sync_reference_clock;
ecrt_master_sync_slave_clocks;
ecrt_master_write_idn;
ecrt_open_master;
ecrt_reg_request_data;
ecrt_reg_request_read;
ecrt_reg_request_state;
ecrt_reg_request_write;
ecrt_release_master;
ecrt_request_master;
ecrt_sdo_request_data;
ecrt_sdo_request_data_size;
ecrt_sdo_request_index;
ecrt_sdo_request_read;
ecrt_sdo_request_state;
ecrt_sdo_request_timeout;
ecrt_sdo_request_write;
ecrt_slave_config_complete_sdo;
ecrt_slave_config_create_reg_request;
ecrt_slave_config_create_sdo_request;
ecrt_slave_config_create_soe_request;
ecrt_slave_config_create_voe_handler;
ecrt_slave_config_dc;
ecrt_slave_config_emerg_clear;
ecrt_slave_config_emerg_overruns;
ecrt_slave_config_emerg_pop;
ecrt_slave_config_emerg_size;
ecrt_slave_config_idn;
ecrt_slave_config_pdo_assign_add;
ecrt_slave_config_pdo_assign_clear;
ecrt_slave_config_pdo_mapping_add;
ecrt_slave_config_pdo_mapping_clear;
ecrt_slave_config_pdos;
ecrt_slave_config_reg_pdo_entry;
ecrt_slave_config_reg_pdo_entry_pos;
ecrt_slave_config_sdo;
ecrt_slave_config_sdo16;
ecrt_slave_config_sdo32;
ecrt_slave_config_sdo8;
ecrt_slave_config_state;
ecrt_slave_config_sync_manager;
ecrt_slave_config_watchdog;
ecrt_version_magic;
ecrt_voe_handler_data;
ecrt_voe_handler_data_size;
ecrt_voe_handler_execute;
ecrt_voe_handler_read;
ecrt_voe_handler_read_nosync;
ecrt_voe_handler_received_header;
ecrt_voe_handler_send_header;
ecrt_voe_handler_write;
};
LIBETHERCAT_1.5.3 {
global:
ecrt_master_sync_reference_clock_to;
ecrt_read_lreal;
ecrt_read_real;
ecrt_slave_config_flag;
ecrt_soe_request_data;
ecrt_soe_request_data_size;
ecrt_soe_request_idn;
ecrt_soe_request_read;
ecrt_soe_request_state;
ecrt_soe_request_timeout;
ecrt_soe_request_write;
ecrt_write_lreal;
ecrt_write_real;
} LIBETHERCAT_1.5.2;
LIBETHERCAT_1.6 {
global:
ecrt_master_scan_progress;
} LIBETHERCAT_1.5.3;

View File

@ -405,9 +405,9 @@ int ecrt_master_get_pdo_entry(ec_master_t *master, uint16_t slave_position,
/****************************************************************************/
int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position,
uint16_t index, uint8_t subindex, uint8_t *data,
size_t data_size, uint32_t *abort_code)
int ecrt_master_sdo_download(ec_master_t *master,
uint16_t slave_position, uint16_t index, uint8_t subindex,
const uint8_t *data, size_t data_size, uint32_t *abort_code)
{
ec_ioctl_slave_sdo_download_t download;
int ret;
@ -417,7 +417,7 @@ int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position,
download.sdo_entry_subindex = subindex;
download.complete_access = 0;
download.data_size = data_size;
download.data = data;
download.data = (uint8_t *) data; // will only be read in ioctl()
ret = ioctl(master->fd, EC_IOCTL_SLAVE_SDO_DOWNLOAD, &download);
if (EC_IOCTL_IS_ERROR(ret)) {
@ -435,7 +435,7 @@ int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position,
/****************************************************************************/
int ecrt_master_sdo_download_complete(ec_master_t *master,
uint16_t slave_position, uint16_t index, uint8_t *data,
uint16_t slave_position, uint16_t index, const uint8_t *data,
size_t data_size, uint32_t *abort_code)
{
ec_ioctl_slave_sdo_download_t download;
@ -446,7 +446,7 @@ int ecrt_master_sdo_download_complete(ec_master_t *master,
download.sdo_entry_subindex = 0;
download.complete_access = 1;
download.data_size = data_size;
download.data = data;
download.data = (uint8_t *) data; // will only be read in ioctl()
ret = ioctl(master->fd, EC_IOCTL_SLAVE_SDO_DOWNLOAD, &download);
if (EC_IOCTL_IS_ERROR(ret)) {
@ -493,7 +493,7 @@ int ecrt_master_sdo_upload(ec_master_t *master, uint16_t slave_position,
/****************************************************************************/
int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position,
uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size,
uint8_t drive_no, uint16_t idn, const uint8_t *data, size_t data_size,
uint16_t *error_code)
{
ec_ioctl_slave_soe_write_t io;
@ -503,7 +503,7 @@ int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position,
io.drive_no = drive_no;
io.idn = idn;
io.data_size = data_size;
io.data = data;
io.data = (uint8_t *) data; // will only be read in ioctl()
ret = ioctl(master->fd, EC_IOCTL_SLAVE_SOE_WRITE, &io);
if (EC_IOCTL_IS_ERROR(ret)) {
@ -742,7 +742,8 @@ void ecrt_master_sync_slave_clocks(ec_master_t *master)
/****************************************************************************/
int ecrt_master_reference_clock_time(ec_master_t *master, uint32_t *time)
int ecrt_master_reference_clock_time(const ec_master_t *master,
uint32_t *time)
{
int ret;
@ -770,7 +771,7 @@ void ecrt_master_sync_monitor_queue(ec_master_t *master)
/****************************************************************************/
uint32_t ecrt_master_sync_monitor_process(ec_master_t *master)
uint32_t ecrt_master_sync_monitor_process(const ec_master_t *master)
{
uint32_t time_diff;
int ret;

View File

@ -48,14 +48,14 @@ void ec_reg_request_clear(ec_reg_request_t *reg)
* Application interface.
****************************************************************************/
uint8_t *ecrt_reg_request_data(ec_reg_request_t *reg)
uint8_t *ecrt_reg_request_data(const ec_reg_request_t *reg)
{
return reg->data;
}
/****************************************************************************/
ec_request_state_t ecrt_reg_request_state(ec_reg_request_t *reg)
ec_request_state_t ecrt_reg_request_state(const ec_reg_request_t *reg)
{
ec_ioctl_reg_request_t io;
int ret;

View File

@ -86,7 +86,7 @@ void ecrt_sdo_request_timeout(ec_sdo_request_t *req, uint32_t timeout)
/****************************************************************************/
uint8_t *ecrt_sdo_request_data(ec_sdo_request_t *req)
uint8_t *ecrt_sdo_request_data(const ec_sdo_request_t *req)
{
return req->data;
}

View File

@ -523,7 +523,7 @@ int ecrt_slave_config_emerg_clear(ec_slave_config_t *sc)
/****************************************************************************/
int ecrt_slave_config_emerg_overruns(ec_slave_config_t *sc)
int ecrt_slave_config_emerg_overruns(const ec_slave_config_t *sc)
{
ec_ioctl_sc_emerg_t io;
int ret;

View File

@ -86,7 +86,7 @@ void ecrt_soe_request_timeout(ec_soe_request_t *req, uint32_t timeout)
/****************************************************************************/
uint8_t *ecrt_soe_request_data(ec_soe_request_t *req)
uint8_t *ecrt_soe_request_data(const ec_soe_request_t *req)
{
return req->data;
}

View File

@ -86,7 +86,7 @@ void ecrt_voe_handler_received_header(const ec_voe_handler_t *voe,
/****************************************************************************/
uint8_t *ecrt_voe_handler_data(ec_voe_handler_t *voe)
uint8_t *ecrt_voe_handler_data(const ec_voe_handler_t *voe)
{
return voe->data;
}

View File

@ -78,18 +78,24 @@ endif
ifeq (@ENABLE_RTDM@,1)
ifeq (@ENABLE_XENOMAI_V3@, 1)
ec_master-objs += rtdm_xenomai_v3.o
else
ec_master-objs += rtdm.o
endif
ifeq (@ENABLE_XENOMAI@, 1)
CFLAGS_rtdm.o := -I@XENOMAI_DIR@/include
CFLAGS_rtdm.o := @XENOMAI_RTDM_CFLAGS@
CFLAGS_rtdm-ioctl.o := @XENOMAI_RTDM_CFLAGS@
endif
ifeq (@ENABLE_RTAI@, 1)
CFLAGS_rtdm.o := -I@RTAI_DIR@/include
CFLAGS_rtdm-ioctl.o := -I@RTAI_DIR@/include
endif
ec_master-objs += rtdm-ioctl.o
CFLAGS_rtdm-ioctl.o := -DEC_IOCTL_RTDM
CFLAGS_rtdm-ioctl.o += -DEC_IOCTL_RTDM
endif # ENABLE_RTDM

View File

@ -60,6 +60,8 @@ noinst_HEADERS = \
reg_request.c reg_request.h \
rtdm-ioctl.c \
rtdm.c rtdm.h \
rtdm_details.h \
rtdm_xenomai_v3.c \
sdo.c sdo.h \
sdo_entry.c sdo_entry.h \
sdo_request.c sdo_request.h \

View File

@ -160,7 +160,7 @@ int ec_coe_emerg_ring_clear_ring(
* \return Number of overruns.
*/
int ec_coe_emerg_ring_overruns(
ec_coe_emerg_ring_t *ring /**< Emergency ring. */
const ec_coe_emerg_ring_t *ring /**< Emergency ring. */
)
{
return ring->overruns;

View File

@ -63,7 +63,7 @@ int ec_coe_emerg_ring_size(ec_coe_emerg_ring_t *, size_t);
void ec_coe_emerg_ring_push(ec_coe_emerg_ring_t *, const u8 *);
int ec_coe_emerg_ring_pop(ec_coe_emerg_ring_t *, u8 *);
int ec_coe_emerg_ring_clear_ring(ec_coe_emerg_ring_t *);
int ec_coe_emerg_ring_overruns(ec_coe_emerg_ring_t *);
int ec_coe_emerg_ring_overruns(const ec_coe_emerg_ring_t *);
/****************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@ -843,9 +843,14 @@ long ec_ioctl(ec_master_t *, ec_ioctl_context_t *, unsigned int,
#ifdef EC_RTDM
long ec_ioctl_rtdm(ec_master_t *, ec_ioctl_context_t *, unsigned int,
long ec_ioctl_rtdm_rt(ec_master_t *, ec_ioctl_context_t *, unsigned int,
void __user *);
long ec_ioctl_rtdm_nrt(ec_master_t *, ec_ioctl_context_t *, unsigned int,
void __user *);
#ifndef EC_RTDM_XENOMAI_V3
int ec_rtdm_mmap(ec_ioctl_context_t *, void **);
#endif
#endif

View File

@ -2769,7 +2769,8 @@ void ecrt_master_application_time(ec_master_t *master, uint64_t app_time)
/****************************************************************************/
int ecrt_master_reference_clock_time(ec_master_t *master, uint32_t *time)
int ecrt_master_reference_clock_time(const ec_master_t *master,
uint32_t *time)
{
if (!master->dc_ref_clock) {
return -ENXIO;
@ -2829,7 +2830,7 @@ void ecrt_master_sync_monitor_queue(ec_master_t *master)
/****************************************************************************/
uint32_t ecrt_master_sync_monitor_process(ec_master_t *master)
uint32_t ecrt_master_sync_monitor_process(const ec_master_t *master)
{
if (master->sync_mon_datagram.state == EC_DATAGRAM_RECEIVED) {
return EC_READ_U32(master->sync_mon_datagram.data) & 0x7fffffff;
@ -2841,7 +2842,7 @@ uint32_t ecrt_master_sync_monitor_process(ec_master_t *master)
/****************************************************************************/
int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position,
uint16_t index, uint8_t subindex, uint8_t *data,
uint16_t index, uint8_t subindex, const uint8_t *data,
size_t data_size, uint32_t *abort_code)
{
ec_sdo_request_t request;
@ -2920,7 +2921,7 @@ int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position,
/****************************************************************************/
int ecrt_master_sdo_download_complete(ec_master_t *master,
uint16_t slave_position, uint16_t index, uint8_t *data,
uint16_t slave_position, uint16_t index, const uint8_t *data,
size_t data_size, uint32_t *abort_code)
{
ec_sdo_request_t request;
@ -3084,7 +3085,7 @@ int ecrt_master_sdo_upload(ec_master_t *master, uint16_t slave_position,
/****************************************************************************/
int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position,
uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size,
uint8_t drive_no, uint16_t idn, const uint8_t *data, size_t data_size,
uint16_t *error_code)
{
ec_soe_request_t request;

View File

@ -75,7 +75,7 @@ void ec_reg_request_clear(
* Application interface.
****************************************************************************/
uint8_t *ecrt_reg_request_data(ec_reg_request_t *reg)
uint8_t *ecrt_reg_request_data(const ec_reg_request_t *reg)
{
return reg->data;
}

View File

@ -33,6 +33,7 @@
#include "master.h"
#include "ioctl.h"
#include "rtdm.h"
#include "rtdm_details.h"
/** Set to 1 to enable device operations debugging.
*/
@ -40,20 +41,12 @@
/****************************************************************************/
/** Context structure for an open RTDM file handle.
*/
typedef struct {
rtdm_user_info_t *user_info; /**< RTDM user data. */
ec_ioctl_context_t ioctl_ctx; /**< Context structure. */
} ec_rtdm_context_t;
/****************************************************************************/
int ec_rtdm_open(struct rtdm_dev_context *, rtdm_user_info_t *, int);
int ec_rtdm_close(struct rtdm_dev_context *, rtdm_user_info_t *);
int ec_rtdm_ioctl(struct rtdm_dev_context *, rtdm_user_info_t *,
static int ec_rtdm_open(struct rtdm_dev_context *, rtdm_user_info_t *, int);
static int ec_rtdm_close(struct rtdm_dev_context *, rtdm_user_info_t *);
static int ec_rtdm_ioctl_nrt_handler(struct rtdm_dev_context *, rtdm_user_info_t *,
unsigned int, void __user *);
static int ec_rtdm_ioctl_rt_handler(struct rtdm_dev_context *, rtdm_user_info_t *,
unsigned int, void __user *);
/****************************************************************************/
/** Initialize an RTDM device.
@ -82,8 +75,8 @@ int ec_rtdm_dev_init(
"EtherCAT%u", master->index);
rtdm_dev->dev->open_nrt = ec_rtdm_open;
rtdm_dev->dev->ops.close_nrt = ec_rtdm_close;
rtdm_dev->dev->ops.ioctl_rt = ec_rtdm_ioctl;
rtdm_dev->dev->ops.ioctl_nrt = ec_rtdm_ioctl;
rtdm_dev->dev->ops.ioctl_rt = ec_rtdm_ioctl_rt_handler;
rtdm_dev->dev->ops.ioctl_nrt = ec_rtdm_ioctl_nrt_handler;
rtdm_dev->dev->device_class = RTDM_CLASS_EXPERIMENTAL;
rtdm_dev->dev->device_sub_class = 222;
rtdm_dev->dev->driver_name = "EtherCAT";
@ -132,7 +125,7 @@ void ec_rtdm_dev_clear(
*
* \return Always zero (success).
*/
int ec_rtdm_open(
static int ec_rtdm_open(
struct rtdm_dev_context *context, /**< Context. */
rtdm_user_info_t *user_info, /**< User data. */
int oflags /**< Open flags. */
@ -143,7 +136,7 @@ int ec_rtdm_open(
ec_rtdm_dev_t *rtdm_dev = (ec_rtdm_dev_t *) context->device->device_data;
#endif
ctx->user_info = user_info;
ctx->user_fd = user_info;
ctx->ioctl_ctx.writable = oflags & O_WRONLY || oflags & O_RDWR;
ctx->ioctl_ctx.requested = 0;
ctx->ioctl_ctx.process_data = NULL;
@ -162,7 +155,7 @@ int ec_rtdm_open(
*
* \return Always zero (success).
*/
int ec_rtdm_close(
static int ec_rtdm_close(
struct rtdm_dev_context *context, /**< Context. */
rtdm_user_info_t *user_info /**< User data. */
)
@ -187,7 +180,7 @@ int ec_rtdm_close(
*
* \return ioctl() return code.
*/
int ec_rtdm_ioctl(
static int ec_rtdm_ioctl_nrt_handler(
struct rtdm_dev_context *context, /**< Context. */
rtdm_user_info_t *user_info, /**< User data. */
unsigned int request, /**< Request. */
@ -202,7 +195,32 @@ int ec_rtdm_ioctl(
" on RTDM device %s.\n", request, _IOC_NR(request),
context->device->device_name);
#endif
return ec_ioctl_rtdm(rtdm_dev->master, &ctx->ioctl_ctx, request, arg);
return ec_ioctl_rtdm_nrt(rtdm_dev->master, &ctx->ioctl_ctx, request, arg);
}
static int ec_rtdm_ioctl_rt_handler(
struct rtdm_dev_context *context, /**< Context. */
rtdm_user_info_t *user_info, /**< User data. */
unsigned int request, /**< Request. */
void __user *arg /**< Argument. */
)
{
int result;
ec_rtdm_context_t *ctx = (ec_rtdm_context_t *) context->dev_private;
ec_rtdm_dev_t *rtdm_dev = (ec_rtdm_dev_t *) context->device->device_data;
#if DEBUG
EC_MASTER_INFO(rtdm_dev->master, "ioctl(request = %u, ctl = %02x)"
" on RTDM device %s.\n", request, _IOC_NR(request),
context->device->device_name);
#endif
result = ec_ioctl_rtdm_rt(rtdm_dev->master, &ctx->ioctl_ctx, request, arg);
if (result == -ENOTTY) {
/* Try again with nrt ioctl handler above in secondary mode. */
return -ENOSYS;
}
return result;
}
/****************************************************************************/
@ -220,7 +238,7 @@ int ec_rtdm_mmap(
container_of(ioctl_ctx, ec_rtdm_context_t, ioctl_ctx);
int ret;
ret = rtdm_mmap_to_user(ctx->user_info,
ret = rtdm_mmap_to_user(ctx->user_fd,
ioctl_ctx->process_data, ioctl_ctx->process_data_size,
PROT_READ | PROT_WRITE,
user_address,

64
master/rtdm_details.h Normal file
View File

@ -0,0 +1,64 @@
/*****************************************************************************
*
* Copyright (C) 2024 Bjarne von Horn <vh@igh.de>
*
* This file is part of the IgH EtherCAT master.
*
* The IgH EtherCAT master is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; version 2 of the License.
*
* The IgH EtherCAT master is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with the IgH EtherCAT master. If not, see <http://www.gnu.org/licenses/>.
*
* The license mentioned above concerns the source code only. Using the
* EtherCAT technology and brand is only permitted in compliance with the
* industrial property and similar rights of Beckhoff Automation GmbH.
*
****************************************************************************/
#ifndef __EC_RTDM_DETAILS_H__
#define __EC_RTDM_DETAILS_H__
#include "../config.h"
#include "ioctl.h"
#include <linux/kernel.h>
#ifdef EC_RTDM_XENOMAI_V3
#include <rtdm/driver.h>
#define EC_RTDM_USERFD_T struct rtdm_fd
#else // EC_RTDM_XENOMAI_V3
#include <rtdm/rtdm_driver.h>
#define EC_RTDM_USERFD_T rtdm_user_info_t
#endif // EC_RTDM_XENOMAI_V3
/****************************************************************************/
/** Context structure for an open RTDM file handle.
*/
typedef struct ec_rtdm_context {
EC_RTDM_USERFD_T *user_fd; /**< RTDM user data. */
ec_ioctl_context_t ioctl_ctx; /**< Context structure. */
} ec_rtdm_context_t;
/****************************************************************************/
static inline EC_RTDM_USERFD_T *ec_ioctl_to_rtdm(ec_ioctl_context_t *ctx)
{
return container_of(ctx, ec_rtdm_context_t, ioctl_ctx)->user_fd;
}
#endif // __EC_RTDM_DETAILS_H__

178
master/rtdm_xenomai_v3.c Normal file
View File

@ -0,0 +1,178 @@
/*****************************************************************************
*
* $Id$
*
* Copyright (C) 2009-2010 Moehwald GmbH B. Benner
* 2011 IgH Andreas Stewering-Bone
* 2012 Florian Pose <fp@igh-essen.com>
*
* This file is part of the IgH EtherCAT master.
*
* The IgH EtherCAT master is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; version 2 of the License.
*
* The IgH EtherCAT master is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with the IgH EtherCAT master. If not, see <http://www.gnu.org/licenses/>.
*
* The license mentioned above concerns the source code only. Using the
* EtherCAT technology and brand is only permitted in compliance with the
* industrial property and similar rights of Beckhoff Automation GmbH.
*
****************************************************************************/
/** \file
* RTDM interface.
*/
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <rtdm/driver.h>
#include "master.h"
#include "ioctl.h"
#include "rtdm.h"
#include "rtdm_details.h"
/** Set to 1 to enable device operations debugging.
*/
#define DEBUG_RTDM 0
static int ec_rtdm_open(struct rtdm_fd *fd, int oflags)
{
struct ec_rtdm_context *ctx = rtdm_fd_to_private(fd);
#if DEBUG_RTDM
struct rtdm_device *dev = rtdm_fd_device(fd);
ec_rtdm_dev_t *rtdm_dev = dev->device_data;
#endif
ctx->user_fd = fd;
ctx->ioctl_ctx.writable = oflags & O_WRONLY || oflags & O_RDWR;
ctx->ioctl_ctx.requested = 0;
ctx->ioctl_ctx.process_data = NULL;
ctx->ioctl_ctx.process_data_size = 0;
#if DEBUG_RTDM
EC_MASTER_INFO(rtdm_dev->master, "RTDM device %s opened.\n",
dev->name);
#endif
return 0;
}
static void ec_rtdm_close(struct rtdm_fd *fd)
{
struct ec_rtdm_context *ctx = rtdm_fd_to_private(fd);
struct rtdm_device *dev = rtdm_fd_device(fd);
ec_rtdm_dev_t *rtdm_dev = dev->device_data;
if (ctx->ioctl_ctx.requested)
ecrt_release_master(rtdm_dev->master);
if (ctx->ioctl_ctx.process_data)
vfree(ctx->ioctl_ctx.process_data);
#if DEBUG_RTDM
EC_MASTER_INFO(rtdm_dev->master, "RTDM device %s closed.\n",
dev->name);
#endif
}
static int ec_rtdm_ioctl_rt_handler(struct rtdm_fd *fd, unsigned int request,
void __user *arg)
{
int result;
struct ec_rtdm_context *ctx = rtdm_fd_to_private(fd);
struct rtdm_device *dev = rtdm_fd_device(fd);
ec_rtdm_dev_t *rtdm_dev = dev->device_data;
result = ec_ioctl_rtdm_rt(rtdm_dev->master, &ctx->ioctl_ctx, request, arg);
if (result == -ENOTTY)
/* Try again with nrt ioctl handler below in secondary mode. */
return -ENOSYS;
return result;
}
static int ec_rtdm_ioctl_nrt_handler(struct rtdm_fd *fd, unsigned int request,
void __user *arg)
{
struct ec_rtdm_context *ctx = rtdm_fd_to_private(fd);
struct rtdm_device *dev = rtdm_fd_device(fd);
ec_rtdm_dev_t *rtdm_dev = dev->device_data;
return ec_ioctl_rtdm_nrt(rtdm_dev->master, &ctx->ioctl_ctx, request, arg);
}
static int ec_rtdm_mmap(struct rtdm_fd *fd, struct vm_area_struct *vma)
{
struct ec_rtdm_context *ctx = (struct ec_rtdm_context *) rtdm_fd_to_private(fd);
return rtdm_mmap_kmem(vma, (void *)ctx->ioctl_ctx.process_data);
}
static struct rtdm_driver ec_rtdm_driver = {
.profile_info = RTDM_PROFILE_INFO(ec_rtdm,
RTDM_CLASS_EXPERIMENTAL,
222,
0),
.device_flags = RTDM_NAMED_DEVICE,
.device_count = 1,
.context_size = sizeof(struct ec_rtdm_context),
.ops = {
.open = ec_rtdm_open,
.close = ec_rtdm_close,
.ioctl_rt = ec_rtdm_ioctl_rt_handler,
.ioctl_nrt = ec_rtdm_ioctl_nrt_handler,
.mmap = ec_rtdm_mmap,
},
};
int ec_rtdm_dev_init(ec_rtdm_dev_t *rtdm_dev, ec_master_t *master)
{
struct rtdm_device *dev;
int ret;
rtdm_dev->master = master;
rtdm_dev->dev = kzalloc(sizeof(struct rtdm_device), GFP_KERNEL);
if (!rtdm_dev->dev) {
EC_MASTER_ERR(master,
"Failed to reserve memory for RTDM device.\n");
return -ENOMEM;
}
dev = rtdm_dev->dev;
dev->driver = &ec_rtdm_driver;
dev->device_data = rtdm_dev;
dev->label = "EtherCAT%u";
ret = rtdm_dev_register(dev);
if (ret) {
EC_MASTER_ERR(master, "Initialization of RTDM interface failed"
" (return value %i).\n", ret);
kfree(dev);
return ret;
}
EC_MASTER_INFO(master, "Registered RTDM device %s.\n", dev->name);
return 0;
}
void ec_rtdm_dev_clear(ec_rtdm_dev_t *rtdm_dev)
{
rtdm_dev_unregister(rtdm_dev->dev);
EC_MASTER_INFO(rtdm_dev->master, "Unregistered RTDM device %s.\n",
rtdm_dev->dev->name);
kfree(rtdm_dev->dev);
}

View File

@ -194,7 +194,7 @@ void ecrt_sdo_request_timeout(ec_sdo_request_t *req, uint32_t timeout)
/****************************************************************************/
uint8_t *ecrt_sdo_request_data(ec_sdo_request_t *req)
uint8_t *ecrt_sdo_request_data(const ec_sdo_request_t *req)
{
return req->data;
}

View File

@ -1121,7 +1121,7 @@ int ecrt_slave_config_emerg_clear(ec_slave_config_t *sc)
/****************************************************************************/
int ecrt_slave_config_emerg_overruns(ec_slave_config_t *sc)
int ecrt_slave_config_emerg_overruns(const ec_slave_config_t *sc)
{
return ec_coe_emerg_ring_overruns(&sc->emerg_ring);
}

View File

@ -279,7 +279,7 @@ void ecrt_soe_request_timeout(ec_soe_request_t *req, uint32_t timeout)
/****************************************************************************/
uint8_t *ecrt_soe_request_data(ec_soe_request_t *req)
uint8_t *ecrt_soe_request_data(const ec_soe_request_t *req)
{
return req->data;
}

View File

@ -134,7 +134,7 @@ void ecrt_voe_handler_received_header(const ec_voe_handler_t *voe,
/****************************************************************************/
uint8_t *ecrt_voe_handler_data(ec_voe_handler_t *voe)
uint8_t *ecrt_voe_handler_data(const ec_voe_handler_t *voe)
{
return voe->datagram.data + EC_MBOX_HEADER_SIZE + EC_VOE_HEADER_SIZE;
}