From 6200ecca77f6fc7b280cde8046d36aaa9a2738df Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Thu, 1 Feb 2024 17:44:20 +0100 Subject: [PATCH 01/36] Limited line length to 78. --- configure.ac | 132 ++++++++++++++++++++++++++------------------------- 1 file changed, 67 insertions(+), 65 deletions(-) diff --git a/configure.ac b/configure.ac index e3ca699e..c6f7997c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- # # Copyright (C) 2006-2023 Florian Pose, Ingenieurgemeinschaft IgH # @@ -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) @@ -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( @@ -703,9 +704,9 @@ AC_SUBST(ENABLE_RTAI,[$rtai]) AC_SUBST(RTAI_LXRT_CFLAGS,[$rtai_lxrt_cflags]) AC_SUBST(RTAI_LXRT_LDFLAGS,[$rtai_lxrt_ldflags]) -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- # Xenomai path (optional) -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- AC_ARG_WITH([xenomai-dir], AC_HELP_STRING( @@ -751,9 +752,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 +786,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 +818,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 +847,9 @@ else AC_MSG_RESULT([no]) fi -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- # Ethernet over EtherCAT support -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- AC_MSG_CHECKING([whether to build with EoE support]) @@ -878,9 +879,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 +908,9 @@ else AC_MSG_RESULT([no]) fi -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- # High-resolution timer support -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- AC_MSG_CHECKING([whether to use high-resolution timers for scheduling]) @@ -936,9 +937,9 @@ else AC_MSG_RESULT([no]) fi -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- # Read alias address from register -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- AC_MSG_CHECKING([whether to read alias addresses from registers]) @@ -965,7 +966,7 @@ else AC_MSG_RESULT([no]) fi -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- # Command-line tool #----------------------------------------------------------------------------- @@ -995,9 +996,9 @@ fi AM_CONDITIONAL(BUILD_TOOL, test "x$tool" = "x1") -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- # Userspace library generation -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- AC_MSG_CHECKING([whether to build the userspace library]) @@ -1025,9 +1026,9 @@ fi AM_CONDITIONAL(ENABLE_USERLIB, test "x$userlib" = "x1") -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- # TTY driver -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- AC_MSG_CHECKING([whether to build the tty driver]) @@ -1056,9 +1057,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 +1087,9 @@ else AC_MSG_RESULT([no]) fi -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- # Redundancy (number of devices) -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- AC_ARG_WITH([devices], AC_HELP_STRING( @@ -1118,9 +1119,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 +1148,9 @@ else AC_MSG_RESULT([no]) fi -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- # syslog output in realtime context -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- AC_MSG_CHECKING([whether to syslog in realtime context]) @@ -1176,9 +1177,9 @@ else AC_MSG_RESULT([no]) fi -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- # systemd service support -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- AC_ARG_WITH([systemdsystemunitdir], AS_HELP_STRING([--with-systemdsystemunitdir=DIR], @@ -1205,7 +1206,7 @@ esac AM_CONDITIONAL(HAVE_SYSTEMD, test "x$with_systemdsystemunitdir" != "x") AC_SUBST(systemdsystemunitdir,[$with_systemdsystemunitdir]) -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- AC_CONFIG_FILES([ Doxyfile @@ -1257,6 +1258,7 @@ AC_CONFIG_FILES([ tty/Kbuild tty/Makefile ]) + AC_OUTPUT -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- From eb05547c771270fa0aa7714109a64072eba24524 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Thu, 1 Feb 2024 18:20:45 +0100 Subject: [PATCH 02/36] Version bump to 1.6.0. --- NEWS | 8 ++++++++ configure.ac | 4 ++-- include/ecrt.h | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index fba9edc5..d4bb398d 100644 --- a/NEWS +++ b/NEWS @@ -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: diff --git a/configure.ac b/configure.ac index c6f7997c..22341d6c 100644 --- a/configure.ac +++ b/configure.ac @@ -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. # @@ -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])]) diff --git a/include/ecrt.h b/include/ecrt.h index 9cdd10e1..554f74d1 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -175,7 +175,7 @@ /** EtherCAT realtime interface minor version number. */ -#define ECRT_VER_MINOR 5 +#define ECRT_VER_MINOR 6 /** EtherCAT realtime interface version word generator. */ From 13cef2b9816417b6d607983438985cb35dc792a6 Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Fri, 2 Feb 2024 08:47:45 +0100 Subject: [PATCH 03/36] Add const to pointers to pdo and pdo_entry infos Fixes #85 --- examples/user/main.c | 18 +++++++++--------- examples/xenomai/main.c | 4 ++-- examples/xenomai_posix/main.c | 6 +++--- include/ecrt.h | 4 ++-- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/examples/user/main.c b/examples/user/main.c index 7feffc74..8c7083a3 100644 --- a/examples/user/main.c +++ b/examples/user/main.c @@ -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} diff --git a/examples/xenomai/main.c b/examples/xenomai/main.c index e76dff20..ca3d8674 100644 --- a/examples/xenomai/main.c +++ b/examples/xenomai/main.c @@ -84,14 +84,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 */ diff --git a/examples/xenomai_posix/main.c b/examples/xenomai_posix/main.c index 28f9254f..71593b75 100644 --- a/examples/xenomai_posix/main.c +++ b/examples/xenomai_posix/main.c @@ -86,21 +86,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} }; diff --git a/include/ecrt.h b/include/ecrt.h index 554f74d1..ab3f8035 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -547,7 +547,7 @@ 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 + 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; @@ -566,7 +566,7 @@ 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 + 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; From 6b95e428446dfcbf512879da97f1b9db9a4c7b9b Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Fri, 2 Feb 2024 09:41:18 +0100 Subject: [PATCH 04/36] add release pipeline with dist tarballs Fixes #9 --- .gitlab-ci.yml | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4d9a40c0..fbe468a3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,6 +6,10 @@ stages: - test - doc - deploy + - release + +variables: + PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/ethercat/${CI_COMMIT_TAG}" build: stage: build @@ -21,6 +25,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: @@ -92,6 +100,39 @@ update docs server: - if: $CI_COMMIT_BRANCH == "stable-1.5" && $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: From 8bf902b02a27104e93de0446b52d9b7a9123f635 Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Fri, 2 Feb 2024 09:49:11 +0100 Subject: [PATCH 05/36] update conditions in CI --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fbe468a3..0257dd08 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -97,7 +97,7 @@ 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: @@ -138,4 +138,4 @@ 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" From 984cb49633adc0c5df413b2c60631dcc6e1560ff Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Fri, 2 Feb 2024 10:04:44 +0100 Subject: [PATCH 06/36] Add missing EC_PUBLIC_API declarations --- include/ecrt.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/ecrt.h b/include/ecrt.h index ab3f8035..4515c844 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -823,7 +823,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. */ @@ -1672,7 +1672,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. */ @@ -2056,7 +2056,7 @@ void ecrt_soe_request_timeout( * * \return Pointer to the internal IDN data memory. */ -uint8_t *ecrt_soe_request_data( +EC_PUBLIC_API uint8_t *ecrt_soe_request_data( ec_soe_request_t *req /**< SoE request. */ ); @@ -2068,7 +2068,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. */ ); @@ -2076,7 +2076,7 @@ size_t ecrt_soe_request_data_size( * * \return Request state. */ -ec_request_state_t ecrt_soe_request_state( +EC_PUBLIC_API ec_request_state_t ecrt_soe_request_state( ec_soe_request_t *req /**< SoE request. */ ); @@ -2085,7 +2085,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. */ ); @@ -2098,7 +2098,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. */ ); From df354272a862681838dbe722304661a1cb66d169 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Fri, 2 Feb 2024 10:15:47 +0100 Subject: [PATCH 07/36] Minor: Fixed indentation. --- include/ecrt.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/include/ecrt.h b/include/ecrt.h index 4515c844..eae389ac 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -397,10 +397,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; /****************************************************************************/ @@ -412,10 +412,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; /****************************************************************************/ @@ -589,8 +590,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; /****************************************************************************/ From 0829b3f8023efc6e26ffee848fa918da4ffa3814 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Fri, 2 Feb 2024 10:18:34 +0100 Subject: [PATCH 08/36] Minor: Broke long lines. --- include/ecrt.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/ecrt.h b/include/ecrt.h index eae389ac..915654a2 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -548,9 +548,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 const *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; /****************************************************************************/ @@ -567,8 +567,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 const *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; @@ -1933,8 +1933,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 From 4ce4d08b7ba39f0a8f3ee844d0bee83dadb4a0c1 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Fri, 2 Feb 2024 10:56:09 +0100 Subject: [PATCH 09/36] Made some more pointer arguments const in API. --- include/ecrt.h | 31 ++++++++++++++----------------- lib/master.c | 21 +++++++++++---------- lib/reg_request.c | 4 ++-- lib/sdo_request.c | 2 +- lib/slave_config.c | 2 +- lib/soe_request.c | 2 +- lib/voe_handler.c | 2 +- master/coe_emerg_ring.c | 2 +- master/coe_emerg_ring.h | 2 +- master/master.c | 11 ++++++----- master/reg_request.c | 2 +- master/sdo_request.c | 2 +- master/slave_config.c | 2 +- master/soe_request.c | 2 +- master/voe_handler.c | 2 +- 15 files changed, 44 insertions(+), 45 deletions(-) diff --git a/include/ecrt.h b/include/ecrt.h index 915654a2..90f0feff 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -916,7 +916,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. */ ); @@ -935,7 +935,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. */ ); @@ -973,7 +973,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. */ @@ -1192,7 +1192,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. */ ); @@ -1219,7 +1219,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. @@ -1228,6 +1228,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. */ @@ -1643,7 +1645,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. @@ -1953,7 +1955,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. @@ -2058,7 +2060,7 @@ void ecrt_soe_request_timeout( * \return Pointer to the internal IDN data memory. */ EC_PUBLIC_API uint8_t *ecrt_soe_request_data( - ec_soe_request_t *req /**< SoE request. */ + const ec_soe_request_t *req /**< SoE request. */ ); /** Returns the current IDN data size. @@ -2078,7 +2080,8 @@ EC_PUBLIC_API size_t ecrt_soe_request_data_size( * \return Request state. */ EC_PUBLIC_API ec_request_state_t ecrt_soe_request_state( - ec_soe_request_t *req /**< SoE request. */ + ec_soe_request_t *req /**< SoE request. Not const, because the + internal data size may be updated. */ ); /** Schedule an SoE IDN write operation. @@ -2155,7 +2158,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. @@ -2257,22 +2260,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. * diff --git a/lib/master.c b/lib/master.c index b02cdd86..f2d846e1 100644 --- a/lib/master.c +++ b/lib/master.c @@ -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; diff --git a/lib/reg_request.c b/lib/reg_request.c index db824f92..6fb04c98 100644 --- a/lib/reg_request.c +++ b/lib/reg_request.c @@ -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; diff --git a/lib/sdo_request.c b/lib/sdo_request.c index 4f9df6de..6271f642 100644 --- a/lib/sdo_request.c +++ b/lib/sdo_request.c @@ -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; } diff --git a/lib/slave_config.c b/lib/slave_config.c index 6b3b2e44..4ac132a9 100644 --- a/lib/slave_config.c +++ b/lib/slave_config.c @@ -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; diff --git a/lib/soe_request.c b/lib/soe_request.c index 1516ec93..d95a4ef1 100644 --- a/lib/soe_request.c +++ b/lib/soe_request.c @@ -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; } diff --git a/lib/voe_handler.c b/lib/voe_handler.c index a743ff26..f0ae45c9 100644 --- a/lib/voe_handler.c +++ b/lib/voe_handler.c @@ -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; } diff --git a/master/coe_emerg_ring.c b/master/coe_emerg_ring.c index 6e19b982..b0026c3b 100644 --- a/master/coe_emerg_ring.c +++ b/master/coe_emerg_ring.c @@ -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; diff --git a/master/coe_emerg_ring.h b/master/coe_emerg_ring.h index 2f00c01d..36ab2c41 100644 --- a/master/coe_emerg_ring.h +++ b/master/coe_emerg_ring.h @@ -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 *); /****************************************************************************/ diff --git a/master/master.c b/master/master.c index 0e06367a..8a8c7744 100644 --- a/master/master.c +++ b/master/master.c @@ -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; diff --git a/master/reg_request.c b/master/reg_request.c index 627061be..29f7d4e2 100644 --- a/master/reg_request.c +++ b/master/reg_request.c @@ -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; } diff --git a/master/sdo_request.c b/master/sdo_request.c index 3a4c66c6..d0de57db 100644 --- a/master/sdo_request.c +++ b/master/sdo_request.c @@ -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; } diff --git a/master/slave_config.c b/master/slave_config.c index b68cfd14..d09d4055 100644 --- a/master/slave_config.c +++ b/master/slave_config.c @@ -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); } diff --git a/master/soe_request.c b/master/soe_request.c index 7acd50bf..20aa231a 100644 --- a/master/soe_request.c +++ b/master/soe_request.c @@ -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; } diff --git a/master/voe_handler.c b/master/voe_handler.c index 68df5397..bc09069e 100644 --- a/master/voe_handler.c +++ b/master/voe_handler.c @@ -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; } From 5fd05393bb3c1e00871edea88fe1096bf40b0fb4 Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Fri, 2 Feb 2024 11:50:02 +0100 Subject: [PATCH 10/36] Add missing EC_PUBLIC_API declarations --- include/ecrt.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/ecrt.h b/include/ecrt.h index 90f0feff..1df3afac 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -2016,7 +2016,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. */ @@ -2030,7 +2030,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. */ From 71f8041248bbf9ae0cfa96bc4a999ca6b9f839a5 Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Fri, 2 Feb 2024 11:51:52 +0100 Subject: [PATCH 11/36] Add symbol map file. Fixes #88 --- lib/Makefile.am | 3 ++ lib/libethercat.map | 107 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 lib/libethercat.map diff --git a/lib/Makefile.am b/lib/Makefile.am index aa7ad970..d0eaf6b0 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -70,8 +70,11 @@ 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 diff --git a/lib/libethercat.map b/lib/libethercat.map new file mode 100644 index 00000000..fb1693f0 --- /dev/null +++ b/lib/libethercat.map @@ -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; From a297dd7fae6c689ade89919e5adb97a1ed8f21bc Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Fri, 2 Feb 2024 11:52:09 +0100 Subject: [PATCH 12/36] add symbol version check target --- .gitlab-ci.yml | 1 + lib/Makefile.am | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0257dd08..47f1478f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -18,6 +18,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-*/ diff --git a/lib/Makefile.am b/lib/Makefile.am index d0eaf6b0..6780a453 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -114,3 +114,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; }' + +#----------------------------------------------------------------------------- From 023d989ee3b8b99f7ed4d0025aa0157a02d9fc2a Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Fri, 17 Nov 2017 12:21:10 +0900 Subject: [PATCH 13/36] Support Xenomai version 3 From 9567f460411d9a832c24b3ef65252f6f4f902fef Mon Sep 17 00:00:00 2001 Xenomai version 3 has different RTDM interface with version 2 and has Alchemy interface instead of native API. This supports RTDM of Xenomai version 3 and to use Alchemy interface. Signed-off-by: Joonyoung Shim --- configure.ac | 27 ++- lib/Makefile.am | 10 +- lib/common.c | 4 +- lib/master.c | 2 +- master/Kbuild.in | 5 + master/Makefile.am | 1 + master/rtdm_xenomai_v3.c | 350 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 392 insertions(+), 7 deletions(-) create mode 100644 master/rtdm_xenomai_v3.c diff --git a/configure.ac b/configure.ac index 22341d6c..c222f240 100644 --- a/configure.ac +++ b/configure.ac @@ -733,18 +733,37 @@ else 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` + xenomai_ver=`grep -R "VERSION_STRING" ${xenomaidir}/include/xeno_config.h | awk '{print $3}'` + xenomai_ver=${xenomai_ver##\"} + xenomai_ver=${xenomai_ver%%\"} + echo "xenomai version: " $xenomai_ver + + if test ${xenomai_ver%%.*} -gt 2; then + xeno_alchemy_cflags=`$xenomaidir/bin/xeno-config --skin alchemy --cflags` + xeno_alchemy_ldflags=`$xenomaidir/bin/xeno-config --skin alchemy --auto-init-solib --ldflags` + xeno_posix_ldflags=`$xenomaidir/bin/xeno-config --skin posix --auto-init-solib --ldflags` + xeno_rtdm_ldflags=`$xenomaidir/bin/xeno-config --skin rtdm --auto-init-solib --ldflags` + xeno_v3=1 + xeno=0 + else + xeno_native_cflags=`$xenomaidir/bin/xeno-config --skin native --cflags` + xeno_native_ldflags=`$xenomaidir/bin/xeno-config --skin native --ldflags` + xeno_posix_ldflags=`$xenomaidir/bin/xeno-config --skin posix --ldflags` + xeno_rtdm_ldflags=`$xenomaidir/bin/xeno-config --skin rtdm --ldflags` + fi + 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` 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]) diff --git a/lib/Makefile.am b/lib/Makefile.am index 6780a453..af2af89e 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -93,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 @@ -101,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) diff --git a/lib/common.c b/lib/common.c index 041a6019..4dbdee72 100644 --- a/lib/common.c +++ b/lib/common.c @@ -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 diff --git a/lib/master.c b/lib/master.c index f2d846e1..9ea1b457 100644 --- a/lib/master.c +++ b/lib/master.c @@ -564,7 +564,7 @@ int ecrt_master_activate(ec_master_t *master) master->process_data_size = io.process_data_size; if (master->process_data_size) { -#ifdef USE_RTDM +#if defined(USE_RTDM) || defined(USE_RTDM_XENOMAI_V3) /* memory-mapping was already done in kernel. The user-space addess is * provided in the ioctl data. */ diff --git a/master/Kbuild.in b/master/Kbuild.in index 393e68d5..a0c9be6d 100644 --- a/master/Kbuild.in +++ b/master/Kbuild.in @@ -78,7 +78,12 @@ endif ifeq (@ENABLE_RTDM@,1) +ifeq (@ENABLE_XENOMAI_V3@, 1) +ec_master-objs += rtdm_xenomai_v3.o +CFLAGS_rtdm.o := -I@XENOMAI_DIR@/include +else ec_master-objs += rtdm.o +endif ifeq (@ENABLE_XENOMAI@, 1) CFLAGS_rtdm.o := -I@XENOMAI_DIR@/include diff --git a/master/Makefile.am b/master/Makefile.am index c1f768ef..65371f72 100644 --- a/master/Makefile.am +++ b/master/Makefile.am @@ -60,6 +60,7 @@ noinst_HEADERS = \ reg_request.c reg_request.h \ rtdm-ioctl.c \ rtdm.c rtdm.h \ + rtdm_xenomai_v3.c \ sdo.c sdo.h \ sdo_entry.c sdo_entry.h \ sdo_request.c sdo_request.h \ diff --git a/master/rtdm_xenomai_v3.c b/master/rtdm_xenomai_v3.c new file mode 100644 index 00000000..54ff066a --- /dev/null +++ b/master/rtdm_xenomai_v3.c @@ -0,0 +1,350 @@ +/***************************************************************************** + * + * $Id$ + * + * Copyright (C) 2009-2010 Moehwald GmbH B. Benner + * 2011 IgH Andreas Stewering-Bone + * 2012 Florian Pose + * + * 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 . + * + * 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 +#include +#include + +#include "master.h" +#include "ioctl.h" +#include "rtdm.h" + +/** Set to 1 to enable device operations debugging. + */ +#define DEBUG_RTDM 0 + +struct ec_rtdm_context { + struct rtdm_fd *fd; + ec_ioctl_context_t ioctl_ctx; /**< Context structure. */ +}; + +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->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 +} + +#if DEBUG_RTDM +struct ec_ioctl_desc { + unsigned int cmd; + const char *name; +}; + +#define EC_IOCTL_DEF(ioctl) \ + [_IOC_NR(ioctl)] = { \ + .cmd = ioctl, \ + .name = #ioctl \ + } + +static const struct ec_ioctl_desc ec_ioctls[] = { + EC_IOCTL_DEF(EC_IOCTL_MODULE), + EC_IOCTL_DEF(EC_IOCTL_MASTER), + EC_IOCTL_DEF(EC_IOCTL_SLAVE), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SYNC), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SYNC_PDO), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SYNC_PDO_ENTRY), + EC_IOCTL_DEF(EC_IOCTL_DOMAIN), + EC_IOCTL_DEF(EC_IOCTL_DOMAIN_FMMU), + EC_IOCTL_DEF(EC_IOCTL_DOMAIN_DATA), + EC_IOCTL_DEF(EC_IOCTL_MASTER_DEBUG), + EC_IOCTL_DEF(EC_IOCTL_MASTER_RESCAN), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_STATE), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SDO), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SDO_ENTRY), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SDO_UPLOAD), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SDO_DOWNLOAD), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SII_READ), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SII_WRITE), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_REG_READ), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_REG_WRITE), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_FOE_READ), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_FOE_WRITE), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SOE_READ), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SOE_WRITE), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_EOE_IP_PARAM), + EC_IOCTL_DEF(EC_IOCTL_CONFIG), + EC_IOCTL_DEF(EC_IOCTL_CONFIG_PDO), + EC_IOCTL_DEF(EC_IOCTL_CONFIG_PDO_ENTRY), + EC_IOCTL_DEF(EC_IOCTL_CONFIG_SDO), + EC_IOCTL_DEF(EC_IOCTL_CONFIG_IDN), +#ifdef EC_EOE + EC_IOCTL_DEF(EC_IOCTL_EOE_HANDLER), +#endif + EC_IOCTL_DEF(EC_IOCTL_SLAVE_DICT_UPLOAD), + EC_IOCTL_DEF(EC_IOCTL_REQUEST), + EC_IOCTL_DEF(EC_IOCTL_CREATE_DOMAIN), + EC_IOCTL_DEF(EC_IOCTL_CREATE_SLAVE_CONFIG), + EC_IOCTL_DEF(EC_IOCTL_SELECT_REF_CLOCK), + EC_IOCTL_DEF(EC_IOCTL_ACTIVATE), + EC_IOCTL_DEF(EC_IOCTL_DEACTIVATE), + EC_IOCTL_DEF(EC_IOCTL_SEND), + EC_IOCTL_DEF(EC_IOCTL_RECEIVE), + EC_IOCTL_DEF(EC_IOCTL_MASTER_STATE), + EC_IOCTL_DEF(EC_IOCTL_MASTER_LINK_STATE), + EC_IOCTL_DEF(EC_IOCTL_APP_TIME), + EC_IOCTL_DEF(EC_IOCTL_SYNC_REF), + EC_IOCTL_DEF(EC_IOCTL_SYNC_SLAVES), + EC_IOCTL_DEF(EC_IOCTL_REF_CLOCK_TIME), + EC_IOCTL_DEF(EC_IOCTL_SYNC_MON_QUEUE), + EC_IOCTL_DEF(EC_IOCTL_SYNC_MON_PROCESS), + EC_IOCTL_DEF(EC_IOCTL_RESET), + EC_IOCTL_DEF(EC_IOCTL_SC_SYNC), + EC_IOCTL_DEF(EC_IOCTL_SC_WATCHDOG), + EC_IOCTL_DEF(EC_IOCTL_SC_ADD_PDO), + EC_IOCTL_DEF(EC_IOCTL_SC_CLEAR_PDOS), + EC_IOCTL_DEF(EC_IOCTL_SC_ADD_ENTRY), + EC_IOCTL_DEF(EC_IOCTL_SC_CLEAR_ENTRIES), + EC_IOCTL_DEF(EC_IOCTL_SC_REG_PDO_ENTRY), + EC_IOCTL_DEF(EC_IOCTL_SC_REG_PDO_POS), + EC_IOCTL_DEF(EC_IOCTL_SC_DC), + EC_IOCTL_DEF(EC_IOCTL_SC_SDO), + EC_IOCTL_DEF(EC_IOCTL_SC_EMERG_SIZE), + EC_IOCTL_DEF(EC_IOCTL_SC_EMERG_POP), + EC_IOCTL_DEF(EC_IOCTL_SC_EMERG_CLEAR), + EC_IOCTL_DEF(EC_IOCTL_SC_EMERG_OVERRUNS), + EC_IOCTL_DEF(EC_IOCTL_SC_SDO_REQUEST), + EC_IOCTL_DEF(EC_IOCTL_SC_REG_REQUEST), + EC_IOCTL_DEF(EC_IOCTL_SC_VOE), + EC_IOCTL_DEF(EC_IOCTL_SC_STATE), + EC_IOCTL_DEF(EC_IOCTL_SC_IDN), + EC_IOCTL_DEF(EC_IOCTL_DOMAIN_SIZE), + EC_IOCTL_DEF(EC_IOCTL_DOMAIN_OFFSET), + EC_IOCTL_DEF(EC_IOCTL_DOMAIN_PROCESS), + EC_IOCTL_DEF(EC_IOCTL_DOMAIN_QUEUE), + EC_IOCTL_DEF(EC_IOCTL_DOMAIN_STATE), + EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_INDEX), + EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_TIMEOUT), + EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_STATE), + EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_READ), + EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_WRITE), + EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_DATA), + EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_DATA), + EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_STATE), + EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_WRITE), + EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_READ), + EC_IOCTL_DEF(EC_IOCTL_VOE_SEND_HEADER), + EC_IOCTL_DEF(EC_IOCTL_VOE_REC_HEADER), + EC_IOCTL_DEF(EC_IOCTL_VOE_READ), + EC_IOCTL_DEF(EC_IOCTL_VOE_READ_NOSYNC), + EC_IOCTL_DEF(EC_IOCTL_VOE_WRITE), + EC_IOCTL_DEF(EC_IOCTL_VOE_EXEC), + EC_IOCTL_DEF(EC_IOCTL_VOE_DATA), + EC_IOCTL_DEF(EC_IOCTL_SET_SEND_INTERVAL), + EC_IOCTL_DEF(EC_IOCTL_SC_OVERLAPPING_IO), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_REBOOT), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_REG_READWRITE), + EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_READWRITE), + EC_IOCTL_DEF(EC_IOCTL_SETUP_DOMAIN_MEMORY), + EC_IOCTL_DEF(EC_IOCTL_DEACTIVATE_SLAVES), + EC_IOCTL_DEF(EC_IOCTL_64_REF_CLK_TIME_QUEUE), + EC_IOCTL_DEF(EC_IOCTL_64_REF_CLK_TIME), + EC_IOCTL_DEF(EC_IOCTL_SC_FOE_REQUEST), + EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_FILE), + EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_TIMEOUT), + EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_STATE), + EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_READ), + EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_WRITE), + EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_DATA), + EC_IOCTL_DEF(EC_IOCTL_RT_SLAVE_REQUESTS), + EC_IOCTL_DEF(EC_IOCTL_EXEC_SLAVE_REQUESTS), +}; +#endif + +static int ec_rtdm_ioctl_rt(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; + +#if DEBUG_RTDM + unsigned int nr = _IOC_NR(request); + const struct ec_ioctl_desc *ioctl = &ec_ioctls[nr]; + + EC_MASTER_INFO(rtdm_dev->master, "ioctl_rt(request = %u, ctl = %02x %s)" + " on RTDM device %s.\n", request, _IOC_NR(request),ioctl->name, + dev->name); +#endif + + /* + * FIXME: Execute ioctls from non-rt context except below ioctls to + * avoid any unknown system hanging. + */ + switch (request) { + case EC_IOCTL_SEND: + case EC_IOCTL_RECEIVE: + case EC_IOCTL_MASTER_STATE: + case EC_IOCTL_APP_TIME: + case EC_IOCTL_SYNC_REF: + case EC_IOCTL_SYNC_SLAVES: + case EC_IOCTL_REF_CLOCK_TIME: + case EC_IOCTL_SC_STATE: + case EC_IOCTL_DOMAIN_PROCESS: + case EC_IOCTL_DOMAIN_QUEUE: + case EC_IOCTL_DOMAIN_STATE: + break; + default: + return -ENOSYS; + } + + return ec_ioctl_rtdm(rtdm_dev->master, &ctx->ioctl_ctx, request, arg); +} + +static int ec_rtdm_ioctl(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; + +#if DEBUG_RTDM + unsigned int nr = _IOC_NR(request); + const struct ec_ioctl_desc *ioctl = &ec_ioctls[nr]; + + EC_MASTER_INFO(rtdm_dev->master, "ioctl(request = %u, ctl = %02x %s)" + " on RTDM device %s.\n", request, _IOC_NR(request),ioctl->name, + dev->name); +#endif + + return ec_ioctl_rtdm(rtdm_dev->master, &ctx->ioctl_ctx, request, arg); +} + +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, + .ioctl_nrt = ec_rtdm_ioctl, + }, +}; + +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); +} + +int ec_rtdm_mmap(ec_ioctl_context_t *ioctl_ctx, void **user_address) +{ + struct ec_rtdm_context *ctx = + container_of(ioctl_ctx, struct ec_rtdm_context, ioctl_ctx); + int ret; + + ret = rtdm_mmap_to_user(ctx->fd, + ioctl_ctx->process_data, ioctl_ctx->process_data_size, + PROT_READ | PROT_WRITE, + user_address, + NULL, NULL); + if (ret < 0) + return ret; + + return 0; +} From e76109c854abc0ea3bdfbaf452103cb3771133ff Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Thu, 16 Nov 2023 13:48:31 +0100 Subject: [PATCH 14/36] Use xeno_config for xenomai version detection --- configure.ac | 4 ++-- master/Kbuild.in | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index c222f240..ffd5bc57 100644 --- a/configure.ac +++ b/configure.ac @@ -728,12 +728,12 @@ 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 ${xenomaidir}/bin/xeno-config; then AC_MSG_ERROR([no Xenomai installation found in ${xenomaidir}!]) fi AC_MSG_RESULT([$xenomaidir]) - xenomai_ver=`grep -R "VERSION_STRING" ${xenomaidir}/include/xeno_config.h | awk '{print $3}'` + xenomai_ver=`$xenomaidir/bin/xeno-config --version` xenomai_ver=${xenomai_ver##\"} xenomai_ver=${xenomai_ver%%\"} echo "xenomai version: " $xenomai_ver diff --git a/master/Kbuild.in b/master/Kbuild.in index a0c9be6d..8ec1c573 100644 --- a/master/Kbuild.in +++ b/master/Kbuild.in @@ -80,7 +80,6 @@ ifeq (@ENABLE_RTDM@,1) ifeq (@ENABLE_XENOMAI_V3@, 1) ec_master-objs += rtdm_xenomai_v3.o -CFLAGS_rtdm.o := -I@XENOMAI_DIR@/include else ec_master-objs += rtdm.o endif From 1dae91d8c3e9090760351881d9ab5980b696561e Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Thu, 25 Jan 2024 15:57:17 +0100 Subject: [PATCH 15/36] Use mmap handler in Xenomai3 --- configure.ac | 1 + lib/Makefile.am | 2 +- lib/master.c | 2 +- master/ioctl.c | 2 +- master/ioctl.h | 3 +++ master/rtdm_xenomai_v3.c | 24 +++++++----------------- 6 files changed, 14 insertions(+), 20 deletions(-) diff --git a/configure.ac b/configure.ac index ffd5bc57..05e0c664 100644 --- a/configure.ac +++ b/configure.ac @@ -745,6 +745,7 @@ else xeno_rtdm_ldflags=`$xenomaidir/bin/xeno-config --skin rtdm --auto-init-solib --ldflags` xeno_v3=1 xeno=0 + AC_DEFINE([EC_RTDM_OPS_HAS_MMAP], [1], [RTDM device operations has mmap handler]) else xeno_native_cflags=`$xenomaidir/bin/xeno-config --skin native --cflags` xeno_native_ldflags=`$xenomaidir/bin/xeno-config --skin native --ldflags` diff --git a/lib/Makefile.am b/lib/Makefile.am index af2af89e..f1caaa2d 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -104,7 +104,7 @@ 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 +libethercat_rtdm_la_CFLAGS += -DUSE_RTDM_XENOMAI_V3 -DEC_RTDM_OPS_HAS_MMAP else libethercat_rtdm_la_CFLAGS += -DUSE_RTDM endif diff --git a/lib/master.c b/lib/master.c index 9ea1b457..0b984873 100644 --- a/lib/master.c +++ b/lib/master.c @@ -564,7 +564,7 @@ int ecrt_master_activate(ec_master_t *master) master->process_data_size = io.process_data_size; if (master->process_data_size) { -#if defined(USE_RTDM) || defined(USE_RTDM_XENOMAI_V3) +#if defined(USE_RTDM) || !defined(EC_RTDM_OPS_HAS_MMAP) /* memory-mapping was already done in kernel. The user-space addess is * provided in the ioctl data. */ diff --git a/master/ioctl.c b/master/ioctl.c index 042e9d2a..fe1eb27f 100644 --- a/master/ioctl.c +++ b/master/ioctl.c @@ -1893,7 +1893,7 @@ static ATTRIBUTES int ec_ioctl_activate( offset += ecrt_domain_size(domain); } -#ifdef EC_IOCTL_RTDM +#if defined(EC_IOCTL_RTDM) && !defined(EC_RTDM_OPS_HAS_MMAP) /* RTDM uses a different approach for memory-mapping, which has to be * initiated by the kernel. */ diff --git a/master/ioctl.h b/master/ioctl.h index 61c8354f..6442852c 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -845,7 +845,10 @@ long ec_ioctl(ec_master_t *, ec_ioctl_context_t *, unsigned int, long ec_ioctl_rtdm(ec_master_t *, ec_ioctl_context_t *, unsigned int, void __user *); + +#ifndef EC_RTDM_OPS_HAS_MMAP int ec_rtdm_mmap(ec_ioctl_context_t *, void **); +#endif #endif diff --git a/master/rtdm_xenomai_v3.c b/master/rtdm_xenomai_v3.c index 54ff066a..29db6bc9 100644 --- a/master/rtdm_xenomai_v3.c +++ b/master/rtdm_xenomai_v3.c @@ -273,6 +273,12 @@ static int ec_rtdm_ioctl(struct rtdm_fd *fd, unsigned int request, return ec_ioctl_rtdm(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, @@ -286,6 +292,7 @@ static struct rtdm_driver ec_rtdm_driver = { .close = ec_rtdm_close, .ioctl_rt = ec_rtdm_ioctl_rt, .ioctl_nrt = ec_rtdm_ioctl, + .mmap = ec_rtdm_mmap, }, }; @@ -331,20 +338,3 @@ void ec_rtdm_dev_clear(ec_rtdm_dev_t *rtdm_dev) kfree(rtdm_dev->dev); } - -int ec_rtdm_mmap(ec_ioctl_context_t *ioctl_ctx, void **user_address) -{ - struct ec_rtdm_context *ctx = - container_of(ioctl_ctx, struct ec_rtdm_context, ioctl_ctx); - int ret; - - ret = rtdm_mmap_to_user(ctx->fd, - ioctl_ctx->process_data, ioctl_ctx->process_data_size, - PROT_READ | PROT_WRITE, - user_address, - NULL, NULL); - if (ret < 0) - return ret; - - return 0; -} From 3ba71d5702104caf65be27dd038387978c83166e Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Fri, 26 Jan 2024 18:50:05 +0100 Subject: [PATCH 16/36] use sig_atomic_t for run flag in examples Otherwise the loop may run forever. --- examples/rtai_rtdm/main.c | 2 +- examples/rtai_rtdm_dc/main.c | 2 +- examples/xenomai/main.c | 2 +- examples/xenomai_posix/main.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/rtai_rtdm/main.c b/examples/rtai_rtdm/main.c index 577310f7..d7570efc 100644 --- a/examples/rtai_rtdm/main.c +++ b/examples/rtai_rtdm/main.c @@ -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; /****************************************************************************/ diff --git a/examples/rtai_rtdm_dc/main.c b/examples/rtai_rtdm_dc/main.c index 61fa4ae4..1676cae4 100644 --- a/examples/rtai_rtdm_dc/main.c +++ b/examples/rtai_rtdm_dc/main.c @@ -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; /****************************************************************************/ diff --git a/examples/xenomai/main.c b/examples/xenomai/main.c index ca3d8674..c2cddb16 100644 --- a/examples/xenomai/main.c +++ b/examples/xenomai/main.c @@ -41,7 +41,7 @@ RT_TASK my_task; -static int run = 1; +static volatile sig_atomic_t run = 1; /****************************************************************************/ diff --git a/examples/xenomai_posix/main.c b/examples/xenomai_posix/main.c index 71593b75..b78e7499 100644 --- a/examples/xenomai_posix/main.c +++ b/examples/xenomai_posix/main.c @@ -43,7 +43,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; /****************************************************************************/ From 64adc0ce1679bedec14e5a3e47ae95b0a8e75769 Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Tue, 30 Jan 2024 14:48:33 +0100 Subject: [PATCH 17/36] Port examples to Xenomai3 --- examples/Makefile.am | 5 +++++ examples/xenomai/Makefile.am | 19 ++++++++++++++++--- examples/xenomai/main.c | 8 ++++++++ examples/xenomai_posix/Makefile.am | 5 +++++ examples/xenomai_posix/main.c | 2 ++ 5 files changed, 36 insertions(+), 3 deletions(-) diff --git a/examples/Makefile.am b/examples/Makefile.am index 7ac06ecd..d73d0977 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -40,6 +40,11 @@ SUBDIRS += \ xenomai \ xenomai_posix endif +if ENABLE_XENOMAI_V3 +SUBDIRS += \ + xenomai \ + xenomai_posix +endif if ENABLE_RTAI SUBDIRS += \ diff --git a/examples/xenomai/Makefile.am b/examples/xenomai/Makefile.am index 5792e1ef..ef20fb2d 100644 --- a/examples/xenomai/Makefile.am +++ b/examples/xenomai/Makefile.am @@ -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 #------------------------------------------------------------------------------ diff --git a/examples/xenomai/main.c b/examples/xenomai/main.c index c2cddb16..c322e2ca 100644 --- a/examples/xenomai/main.c +++ b/examples/xenomai/main.c @@ -29,12 +29,18 @@ #include #include #include +#ifdef XENOMAI_API_V3 +#include +#include +enum {T_FPU = 0}; +#else #include #include #include #include #include #include +#endif #include #include "ecrt.h" @@ -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); diff --git a/examples/xenomai_posix/Makefile.am b/examples/xenomai_posix/Makefile.am index 5d3962de..994750ee 100644 --- a/examples/xenomai_posix/Makefile.am +++ b/examples/xenomai_posix/Makefile.am @@ -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) \ diff --git a/examples/xenomai_posix/main.c b/examples/xenomai_posix/main.c index b78e7499..891c3fd3 100644 --- a/examples/xenomai_posix/main.c +++ b/examples/xenomai_posix/main.c @@ -32,8 +32,10 @@ #include #include +#ifndef XENOMAI_API_V3 #include #include +#endif #include "ecrt.h" From db0d120e2e4c70bc2591066b471041adce3dd2fa Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Tue, 30 Jan 2024 15:47:12 +0100 Subject: [PATCH 18/36] Fix Xenomai Posix setschedparam --- examples/xenomai_posix/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/xenomai_posix/main.c b/examples/xenomai_posix/main.c index 891c3fd3..9e18008b 100644 --- a/examples/xenomai_posix/main.c +++ b/examples/xenomai_posix/main.c @@ -273,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, ¶m); + pthread_attr_setschedparam(&thattr, ¶m); ret = pthread_create(&cyclic_thread, &thattr, &my_thread, NULL); if (ret) { From bc1f0e8f411030b75604146e1b79db97adb2efb6 Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Tue, 30 Jan 2024 17:36:06 +0100 Subject: [PATCH 19/36] Add --with-xenomai-config option --- configure.ac | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index 05e0c664..6d480b5e 100644 --- a/configure.ac +++ b/configure.ac @@ -723,38 +723,51 @@ AC_ARG_WITH([xenomai-dir], ] ) +AC_ARG_WITH([xenomai-config], + AC_HELP_STRING( + [--with-xenomai-config=], + [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 \! -x ${xenomaidir}/bin/xeno-config; then + if test \! -x ${xenomaiconfig}; then AC_MSG_ERROR([no Xenomai installation found in ${xenomaidir}!]) fi AC_MSG_RESULT([$xenomaidir]) - xenomai_ver=`$xenomaidir/bin/xeno-config --version` + 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=`$xenomaidir/bin/xeno-config --skin alchemy --cflags` - xeno_alchemy_ldflags=`$xenomaidir/bin/xeno-config --skin alchemy --auto-init-solib --ldflags` - xeno_posix_ldflags=`$xenomaidir/bin/xeno-config --skin posix --auto-init-solib --ldflags` - xeno_rtdm_ldflags=`$xenomaidir/bin/xeno-config --skin rtdm --auto-init-solib --ldflags` + 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_OPS_HAS_MMAP], [1], [RTDM device operations has mmap handler]) else - xeno_native_cflags=`$xenomaidir/bin/xeno-config --skin native --cflags` - xeno_native_ldflags=`$xenomaidir/bin/xeno-config --skin native --ldflags` - xeno_posix_ldflags=`$xenomaidir/bin/xeno-config --skin posix --ldflags` - xeno_rtdm_ldflags=`$xenomaidir/bin/xeno-config --skin rtdm --ldflags` + 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=`$xenomaidir/bin/xeno-config --skin posix --cflags` - xeno_rtdm_cflags=`$xenomaidir/bin/xeno-config --skin rtdm --cflags` + xeno_posix_cflags=`$xenomaiconfig --skin posix --cflags` + xeno_rtdm_cflags=`$xenomaiconfig --skin rtdm --cflags` fi AC_SUBST(XENOMAI_DIR,[$xenomaidir]) From 1c9f9bfe7da10ecf024f1533bc68e565717b3f3c Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Wed, 31 Jan 2024 09:28:35 +0100 Subject: [PATCH 20/36] use RTDM CFLAGS for non-standard include dir --- master/Kbuild.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/master/Kbuild.in b/master/Kbuild.in index 8ec1c573..f03519e3 100644 --- a/master/Kbuild.in +++ b/master/Kbuild.in @@ -85,7 +85,7 @@ ec_master-objs += rtdm.o endif ifeq (@ENABLE_XENOMAI@, 1) -CFLAGS_rtdm.o := -I@XENOMAI_DIR@/include +CFLAGS_rtdm.o := @XENOMAI_RTDM_CFLAGS@ endif ifeq (@ENABLE_RTAI@, 1) From 656526f03c97a6ba414ebfc4257a22c8bcd102fa Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Wed, 31 Jan 2024 09:49:02 +0100 Subject: [PATCH 21/36] remove EC_RTDM_OPS_HAS_MMAP again --- configure.ac | 2 +- lib/Makefile.am | 2 +- lib/master.c | 2 +- master/ioctl.c | 2 +- master/ioctl.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 6d480b5e..576c12eb 100644 --- a/configure.ac +++ b/configure.ac @@ -758,7 +758,7 @@ else xeno_rtdm_ldflags=`$xenomaiconfig --skin rtdm --auto-init-solib --ldflags` xeno_v3=1 xeno=0 - AC_DEFINE([EC_RTDM_OPS_HAS_MMAP], [1], [RTDM device operations has mmap handler]) + 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` diff --git a/lib/Makefile.am b/lib/Makefile.am index f1caaa2d..af2af89e 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -104,7 +104,7 @@ 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 -DEC_RTDM_OPS_HAS_MMAP +libethercat_rtdm_la_CFLAGS += -DUSE_RTDM_XENOMAI_V3 else libethercat_rtdm_la_CFLAGS += -DUSE_RTDM endif diff --git a/lib/master.c b/lib/master.c index 0b984873..f2d846e1 100644 --- a/lib/master.c +++ b/lib/master.c @@ -564,7 +564,7 @@ int ecrt_master_activate(ec_master_t *master) master->process_data_size = io.process_data_size; if (master->process_data_size) { -#if defined(USE_RTDM) || !defined(EC_RTDM_OPS_HAS_MMAP) +#ifdef USE_RTDM /* memory-mapping was already done in kernel. The user-space addess is * provided in the ioctl data. */ diff --git a/master/ioctl.c b/master/ioctl.c index fe1eb27f..f9892cda 100644 --- a/master/ioctl.c +++ b/master/ioctl.c @@ -1893,7 +1893,7 @@ static ATTRIBUTES int ec_ioctl_activate( offset += ecrt_domain_size(domain); } -#if defined(EC_IOCTL_RTDM) && !defined(EC_RTDM_OPS_HAS_MMAP) +#if defined(EC_IOCTL_RTDM) && !defined(EC_RTDM_XENOMAI_V3) /* RTDM uses a different approach for memory-mapping, which has to be * initiated by the kernel. */ diff --git a/master/ioctl.h b/master/ioctl.h index 6442852c..01f75539 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -846,7 +846,7 @@ long ec_ioctl(ec_master_t *, ec_ioctl_context_t *, unsigned int, long ec_ioctl_rtdm(ec_master_t *, ec_ioctl_context_t *, unsigned int, void __user *); -#ifndef EC_RTDM_OPS_HAS_MMAP +#ifndef EC_RTDM_XENOMAI_V3 int ec_rtdm_mmap(ec_ioctl_context_t *, void **); #endif From 0a41222ee656e7d03168ac2fc9027c735b08a1b7 Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Wed, 31 Jan 2024 10:12:24 +0100 Subject: [PATCH 22/36] prepare uniting ec_rtdm_context --- master/rtdm.c | 6 +++--- master/rtdm_xenomai_v3.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/master/rtdm.c b/master/rtdm.c index e28c26de..eac71eea 100644 --- a/master/rtdm.c +++ b/master/rtdm.c @@ -43,7 +43,7 @@ /** Context structure for an open RTDM file handle. */ typedef struct { - rtdm_user_info_t *user_info; /**< RTDM user data. */ + rtdm_user_info_t *user_fd; /**< RTDM user data. */ ec_ioctl_context_t ioctl_ctx; /**< Context structure. */ } ec_rtdm_context_t; @@ -143,7 +143,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; @@ -220,7 +220,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, diff --git a/master/rtdm_xenomai_v3.c b/master/rtdm_xenomai_v3.c index 29db6bc9..0bc90862 100644 --- a/master/rtdm_xenomai_v3.c +++ b/master/rtdm_xenomai_v3.c @@ -43,7 +43,7 @@ #define DEBUG_RTDM 0 struct ec_rtdm_context { - struct rtdm_fd *fd; + struct rtdm_fd *user_fd; ec_ioctl_context_t ioctl_ctx; /**< Context structure. */ }; @@ -55,7 +55,7 @@ static int ec_rtdm_open(struct rtdm_fd *fd, int oflags) ec_rtdm_dev_t *rtdm_dev = dev->device_data; #endif - ctx->fd = fd; + ctx->user_fd = fd; ctx->ioctl_ctx.writable = oflags & O_WRONLY || oflags & O_RDWR; ctx->ioctl_ctx.requested = 0; From 95209d28580987d24b6ebe40a37e8e18395bb057 Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Wed, 31 Jan 2024 10:21:06 +0100 Subject: [PATCH 23/36] Move ec_rtdm_context into common header --- master/Makefile.am | 1 + master/rtdm.c | 10 +------ master/rtdm_details.h | 57 ++++++++++++++++++++++++++++++++++++++++ master/rtdm_xenomai_v3.c | 6 +---- 4 files changed, 60 insertions(+), 14 deletions(-) create mode 100644 master/rtdm_details.h diff --git a/master/Makefile.am b/master/Makefile.am index 65371f72..1a0ef30a 100644 --- a/master/Makefile.am +++ b/master/Makefile.am @@ -60,6 +60,7 @@ 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 \ diff --git a/master/rtdm.c b/master/rtdm.c index eac71eea..e5e73e09 100644 --- a/master/rtdm.c +++ b/master/rtdm.c @@ -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,15 +41,6 @@ /****************************************************************************/ -/** Context structure for an open RTDM file handle. - */ -typedef struct { - rtdm_user_info_t *user_fd; /**< 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 *, diff --git a/master/rtdm_details.h b/master/rtdm_details.h new file mode 100644 index 00000000..8b8c0f3c --- /dev/null +++ b/master/rtdm_details.h @@ -0,0 +1,57 @@ +/***************************************************************************** + * + * Copyright (C) 2024 Bjarne von Horn + * + * 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 . + * + * 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 + +#ifdef EC_RTDM_XENOMAI_V3 + +#include +#define EC_RTDM_USERFD_T struct rtdm_fd + +#else // EC_RTDM_XENOMAI_V3 + +#include + +#define EC_RTDM_USERFD_T rtdm_user_info_t + +#endif + +/****************************************************************************/ + +/** 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; + +/****************************************************************************/ + +#endif // __EC_RTDM_DETAILS_H__ diff --git a/master/rtdm_xenomai_v3.c b/master/rtdm_xenomai_v3.c index 0bc90862..4a58950a 100644 --- a/master/rtdm_xenomai_v3.c +++ b/master/rtdm_xenomai_v3.c @@ -37,16 +37,12 @@ #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 -struct ec_rtdm_context { - struct rtdm_fd *user_fd; - ec_ioctl_context_t ioctl_ctx; /**< Context structure. */ -}; - static int ec_rtdm_open(struct rtdm_fd *fd, int oflags) { struct ec_rtdm_context *ctx = rtdm_fd_to_private(fd); From ca6076999615e46ecae55c93cf9f0e62e8313a8f Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Wed, 31 Jan 2024 11:26:14 +0100 Subject: [PATCH 24/36] introduce ec_copy_{from,to}_user macros with ctx argument in ioctl --- master/ioctl.c | 140 +++++++++++++++++++++++++++---------------------- 1 file changed, 76 insertions(+), 64 deletions(-) diff --git a/master/ioctl.c b/master/ioctl.c index f9892cda..21c32083 100644 --- a/master/ioctl.c +++ b/master/ioctl.c @@ -61,6 +61,9 @@ rt_mutex_lock_interruptible(lock) #endif // EC_IOCTL_RTDM +#define ec_copy_to_user(to, from, n, ctx) copy_to_user(to, from, n) +#define ec_copy_from_user(to, from, n, ctx) copy_from_user(to, from, n) + /****************************************************************************/ /** Copies a string to an ioctl structure. @@ -85,7 +88,8 @@ static void ec_ioctl_strcpy( * \return Zero on success, otherwise a negative error code. */ static ATTRIBUTES int ec_ioctl_module( - void *arg /**< Userspace address to store the results. */ + void *arg, /**< ioctl() argument. */ + ec_ioctl_context_t *ctx /**< Private data structure of file handle. */ ) { ec_ioctl_module_t data; @@ -93,7 +97,7 @@ static ATTRIBUTES int ec_ioctl_module( data.ioctl_version_magic = EC_IOCTL_VERSION_MAGIC; data.master_count = ec_master_count(); - if (copy_to_user((void __user *) arg, &data, sizeof(data))) + if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx)) return -EFAULT; return 0; @@ -2038,7 +2042,7 @@ static ATTRIBUTES int ec_ioctl_master_state( ecrt_master_state(master, &data); - if (copy_to_user((void __user *) arg, &data, sizeof(data))) + if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx)) return -EFAULT; return 0; @@ -2060,7 +2064,7 @@ static ATTRIBUTES int ec_ioctl_master_link_state( ec_master_link_state_t state; int ret; - if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) { + if (ec_copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl), ctx)) { return -EFAULT; } @@ -2069,7 +2073,8 @@ static ATTRIBUTES int ec_ioctl_master_link_state( return ret; } - if (copy_to_user((void __user *) ioctl.state, &state, sizeof(state))) { + if (ec_copy_to_user((void __user *) ioctl.state, + &state, sizeof(state), ctx)) { return -EFAULT; } @@ -2093,7 +2098,7 @@ static ATTRIBUTES int ec_ioctl_app_time( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&time, (void __user *) arg, sizeof(time))) { + if (ec_copy_from_user(&time, (void __user *) arg, sizeof(time), ctx)) { return -EFAULT; } @@ -2141,7 +2146,7 @@ static ATTRIBUTES int ec_ioctl_sync_ref_to( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&time, (void __user *) arg, sizeof(time))) { + if (ec_copy_from_user(&time, (void __user *) arg, sizeof(time), ctx)) { return -EFAULT; } @@ -2199,7 +2204,7 @@ static ATTRIBUTES int ec_ioctl_ref_clock_time( return ret; } - if (copy_to_user((void __user *) arg, &time, sizeof(time))) { + if (ec_copy_to_user((void __user *) arg, &time, sizeof(time), ctx)) { return -EFAULT; } @@ -2248,7 +2253,8 @@ static ATTRIBUTES int ec_ioctl_sync_mon_process( time_diff = ecrt_master_sync_monitor_process(master); - if (copy_to_user((void __user *) arg, &time_diff, sizeof(time_diff))) + if (ec_copy_to_user((void __user *) arg, &time_diff, + sizeof(time_diff), ctx)) return -EFAULT; return 0; @@ -2764,7 +2770,7 @@ static ATTRIBUTES int ec_ioctl_sc_emerg_pop( return -EPERM; } - if (copy_from_user(&io, (void __user *) arg, sizeof(io))) { + if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) { return -EFAULT; } @@ -2780,7 +2786,7 @@ static ATTRIBUTES int ec_ioctl_sc_emerg_pop( return ret; } - if (copy_to_user((void __user *) io.target, msg, sizeof(msg))) { + if (ec_copy_to_user((void __user *) io.target, msg, sizeof(msg), ctx)) { return -EFAULT; } @@ -2806,7 +2812,7 @@ static ATTRIBUTES int ec_ioctl_sc_emerg_clear( return -EPERM; } - if (copy_from_user(&io, (void __user *) arg, sizeof(io))) { + if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) { return -EFAULT; } @@ -2840,7 +2846,7 @@ static ATTRIBUTES int ec_ioctl_sc_emerg_overruns( return -EPERM; } - if (copy_from_user(&io, (void __user *) arg, sizeof(io))) { + if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) { return -EFAULT; } @@ -2858,7 +2864,7 @@ static ATTRIBUTES int ec_ioctl_sc_emerg_overruns( io.overruns = ret; - if (copy_to_user((void __user *) arg, &io, sizeof(io))) { + if (ec_copy_to_user((void __user *) arg, &io, sizeof(io), ctx)) { return -EFAULT; } @@ -3092,7 +3098,7 @@ static ATTRIBUTES int ec_ioctl_sc_state( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) { return -EFAULT; } @@ -3105,7 +3111,8 @@ static ATTRIBUTES int ec_ioctl_sc_state( ecrt_slave_config_state(sc, &state); - if (copy_to_user((void __user *) data.state, &state, sizeof(state))) + if (ec_copy_to_user((void __user *) data.state, + &state, sizeof(state), ctx)) return -EFAULT; return 0; @@ -3368,7 +3375,7 @@ static ATTRIBUTES int ec_ioctl_domain_state( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) { return -EFAULT; } @@ -3381,7 +3388,7 @@ static ATTRIBUTES int ec_ioctl_domain_state( ecrt_domain_state(domain, &state); - if (copy_to_user((void __user *) data.state, &state, sizeof(state))) + if (ec_copy_to_user((void __user *) data.state, &state, sizeof(state), ctx)) return -EFAULT; return 0; @@ -3406,7 +3413,7 @@ static ATTRIBUTES int ec_ioctl_sdo_request_index( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; /* no locking of master_sem needed, because neither sc nor req will not be @@ -3443,7 +3450,7 @@ static ATTRIBUTES int ec_ioctl_sdo_request_timeout( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; /* no locking of master_sem needed, because neither sc nor req will not be @@ -3480,7 +3487,7 @@ static ATTRIBUTES int ec_ioctl_sdo_request_state( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; /* no locking of master_sem needed, because neither sc nor req will not be @@ -3500,7 +3507,7 @@ static ATTRIBUTES int ec_ioctl_sdo_request_state( else data.size = 0; - if (copy_to_user((void __user *) arg, &data, sizeof(data))) + if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx)) return -EFAULT; return 0; @@ -3525,7 +3532,7 @@ static ATTRIBUTES int ec_ioctl_sdo_request_read( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; /* no locking of master_sem needed, because neither sc nor req will not be @@ -3563,7 +3570,7 @@ static ATTRIBUTES int ec_ioctl_sdo_request_write( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; if (!data.size) { @@ -3586,7 +3593,8 @@ static ATTRIBUTES int ec_ioctl_sdo_request_write( if (ret) return ret; - if (copy_from_user(req->data, (void __user *) data.data, data.size)) + if (ec_copy_from_user(req->data, (void __user *) data.data, + data.size, ctx)) return -EFAULT; req->data_size = data.size; @@ -3613,7 +3621,7 @@ static ATTRIBUTES int ec_ioctl_sdo_request_data( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; /* no locking of master_sem needed, because neither sc nor req will not be @@ -3627,8 +3635,8 @@ static ATTRIBUTES int ec_ioctl_sdo_request_data( return -ENOENT; } - if (copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req), - ecrt_sdo_request_data_size(req))) + if (ec_copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req), + ecrt_sdo_request_data_size(req), ctx)) return -EFAULT; return 0; @@ -3653,7 +3661,7 @@ static ATTRIBUTES int ec_ioctl_soe_request_index( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; /* no locking of master_sem needed, because neither sc nor req will not be @@ -3690,7 +3698,7 @@ static ATTRIBUTES int ec_ioctl_soe_request_timeout( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; /* no locking of master_sem needed, because neither sc nor req will not be @@ -3727,7 +3735,7 @@ static ATTRIBUTES int ec_ioctl_soe_request_state( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; /* no locking of master_sem needed, because neither sc nor req will not be @@ -3749,7 +3757,7 @@ static ATTRIBUTES int ec_ioctl_soe_request_state( data.size = 0; } - if (copy_to_user((void __user *) arg, &data, sizeof(data))) + if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx)) return -EFAULT; return 0; @@ -3774,7 +3782,7 @@ static ATTRIBUTES int ec_ioctl_soe_request_read( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; /* no locking of master_sem needed, because neither sc nor req will not be @@ -3812,7 +3820,7 @@ static ATTRIBUTES int ec_ioctl_soe_request_write( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; if (!data.size) { @@ -3835,7 +3843,8 @@ static ATTRIBUTES int ec_ioctl_soe_request_write( if (ret) return ret; - if (copy_from_user(req->data, (void __user *) data.data, data.size)) + if (ec_copy_from_user(req->data, (void __user *) data.data, + data.size, ctx)) return -EFAULT; req->data_size = data.size; @@ -3862,7 +3871,7 @@ static ATTRIBUTES int ec_ioctl_soe_request_data( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; /* no locking of master_sem needed, because neither sc nor req will not be @@ -3876,8 +3885,8 @@ static ATTRIBUTES int ec_ioctl_soe_request_data( return -ENOENT; } - if (copy_to_user((void __user *) data.data, ecrt_soe_request_data(req), - ecrt_soe_request_data_size(req))) + if (ec_copy_to_user((void __user *) data.data, ecrt_soe_request_data(req), + ecrt_soe_request_data_size(req), ctx)) return -EFAULT; return 0; @@ -3903,7 +3912,7 @@ static ATTRIBUTES int ec_ioctl_reg_request_data( return -EPERM; } - if (copy_from_user(&io, (void __user *) arg, sizeof(io))) { + if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) { return -EFAULT; } @@ -3922,8 +3931,8 @@ static ATTRIBUTES int ec_ioctl_reg_request_data( return -ENOENT; } - if (copy_to_user((void __user *) io.data, ecrt_reg_request_data(reg), - min(reg->mem_size, io.mem_size))) { + if (ec_copy_to_user((void __user *) io.data, ecrt_reg_request_data(reg), + min(reg->mem_size, io.mem_size), ctx)) { return -EFAULT; } @@ -3950,7 +3959,7 @@ static ATTRIBUTES int ec_ioctl_reg_request_state( return -EPERM; } - if (copy_from_user(&io, (void __user *) arg, sizeof(io))) { + if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) { return -EFAULT; } @@ -3968,7 +3977,7 @@ static ATTRIBUTES int ec_ioctl_reg_request_state( io.state = ecrt_reg_request_state(reg); io.new_data = io.state == EC_REQUEST_SUCCESS && reg->dir == EC_DIR_INPUT; - if (copy_to_user((void __user *) arg, &io, sizeof(io))) { + if (ec_copy_to_user((void __user *) arg, &io, sizeof(io), ctx)) { return -EFAULT; } @@ -3995,7 +4004,7 @@ static ATTRIBUTES int ec_ioctl_reg_request_write( return -EPERM; } - if (copy_from_user(&io, (void __user *) arg, sizeof(io))) { + if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) { return -EFAULT; } @@ -4014,8 +4023,8 @@ static ATTRIBUTES int ec_ioctl_reg_request_write( return -EOVERFLOW; } - if (copy_from_user(reg->data, (void __user *) io.data, - io.transfer_size)) { + if (ec_copy_from_user(reg->data, (void __user *) io.data, + io.transfer_size, ctx)) { return -EFAULT; } @@ -4043,7 +4052,7 @@ static ATTRIBUTES int ec_ioctl_reg_request_read( return -EPERM; } - if (copy_from_user(&io, (void __user *) arg, sizeof(io))) { + if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) { return -EFAULT; } @@ -4087,13 +4096,14 @@ static ATTRIBUTES int ec_ioctl_voe_send_header( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; - if (get_user(vendor_id, data.vendor_id)) + if (ec_copy_from_user(&vendor_id, data.vendor_id, sizeof(vendor_id), ctx)) return -EFAULT; - if (get_user(vendor_type, data.vendor_type)) + if (ec_copy_from_user(&vendor_type, data.vendor_type, + sizeof(vendor_type), ctx)) return -EFAULT; /* no locking of master_sem needed, because neither sc nor voe will not be @@ -4132,7 +4142,7 @@ static ATTRIBUTES int ec_ioctl_voe_rec_header( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; /* no locking of master_sem needed, because neither sc nor voe will not be @@ -4149,11 +4159,13 @@ static ATTRIBUTES int ec_ioctl_voe_rec_header( ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type); if (likely(data.vendor_id)) - if (put_user(vendor_id, data.vendor_id)) + if (ec_copy_to_user(data.vendor_id, &vendor_id, + sizeof(vendor_id), ctx)) return -EFAULT; if (likely(data.vendor_type)) - if (put_user(vendor_type, data.vendor_type)) + if (ec_copy_to_user(data.vendor_type, &vendor_type, + sizeof(vendor_type), ctx)) return -EFAULT; return 0; @@ -4178,7 +4190,7 @@ static ATTRIBUTES int ec_ioctl_voe_read( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; /* no locking of master_sem needed, because neither sc nor voe will not be @@ -4215,7 +4227,7 @@ static ATTRIBUTES int ec_ioctl_voe_read_nosync( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; /* no locking of master_sem needed, because neither sc nor voe will not be @@ -4252,7 +4264,7 @@ static ATTRIBUTES int ec_ioctl_voe_write( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; /* no locking of master_sem needed, because neither sc nor voe will not be @@ -4270,8 +4282,8 @@ static ATTRIBUTES int ec_ioctl_voe_write( if (data.size > ec_voe_handler_mem_size(voe)) return -EOVERFLOW; - if (copy_from_user(ecrt_voe_handler_data(voe), - (void __user *) data.data, data.size)) + if (ec_copy_from_user(ecrt_voe_handler_data(voe), + (void __user *) data.data, data.size, ctx)) return -EFAULT; } @@ -4298,7 +4310,7 @@ static ATTRIBUTES int ec_ioctl_voe_exec( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; /* no locking of master_sem needed, because neither sc nor voe will not be @@ -4321,7 +4333,7 @@ static ATTRIBUTES int ec_ioctl_voe_exec( else data.size = 0; - if (copy_to_user((void __user *) arg, &data, sizeof(data))) + if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx)) return -EFAULT; return 0; @@ -4346,7 +4358,7 @@ static ATTRIBUTES int ec_ioctl_voe_data( if (unlikely(!ctx->requested)) return -EPERM; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) + if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) return -EFAULT; /* no locking of master_sem needed, because neither sc nor voe will not be @@ -4360,8 +4372,8 @@ static ATTRIBUTES int ec_ioctl_voe_data( return -ENOENT; } - if (copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe), - ecrt_voe_handler_data_size(voe))) + if (ec_copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe), + ecrt_voe_handler_data_size(voe), ctx)) return -EFAULT; return 0; @@ -4675,7 +4687,7 @@ long EC_IOCTL( switch (cmd) { case EC_IOCTL_MODULE: - ret = ec_ioctl_module(arg); + ret = ec_ioctl_module(arg, ctx); break; case EC_IOCTL_MASTER: ret = ec_ioctl_master(master, arg); From 385f2ba64efbeb0dff3afba2439dca85d474b8c7 Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Wed, 31 Jan 2024 11:38:34 +0100 Subject: [PATCH 25/36] Use rtdm_safe_copy_{from,to}_user --- master/Kbuild.in | 4 +++- master/ioctl.c | 10 +++++++--- master/rtdm_details.h | 9 ++++++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/master/Kbuild.in b/master/Kbuild.in index f03519e3..75eff6ff 100644 --- a/master/Kbuild.in +++ b/master/Kbuild.in @@ -86,14 +86,16 @@ endif ifeq (@ENABLE_XENOMAI@, 1) 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 diff --git a/master/ioctl.c b/master/ioctl.c index 21c32083..367442d9 100644 --- a/master/ioctl.c +++ b/master/ioctl.c @@ -49,21 +49,25 @@ #endif #ifdef EC_IOCTL_RTDM +# include "rtdm_details.h" /* RTDM does not support locking yet, * therefore no send/receive callbacks are set too. */ # define ec_ioctl_lock(lock) do {} while(0) # define ec_ioctl_unlock(lock) do {} while(0) # define ec_ioctl_lock_interruptible(lock) (0) +# define ec_copy_to_user(to, from, n, ctx) \ + rtdm_safe_copy_to_user(ec_ioctl_to_rtdm(ctx), to, from, n) +# define ec_copy_from_user(to, from, n, ctx) \ + rtdm_safe_copy_from_user(ec_ioctl_to_rtdm(ctx), to, from, n) #else # define ec_ioctl_lock(lock) rt_mutex_lock(lock) # define ec_ioctl_unlock(lock) rt_mutex_unlock(lock) # define ec_ioctl_lock_interruptible(lock) \ rt_mutex_lock_interruptible(lock) +# define ec_copy_to_user(to, from, n, ctx) copy_to_user(to, from, n) +# define ec_copy_from_user(to, from, n, ctx) copy_from_user(to, from, n) #endif // EC_IOCTL_RTDM -#define ec_copy_to_user(to, from, n, ctx) copy_to_user(to, from, n) -#define ec_copy_from_user(to, from, n, ctx) copy_from_user(to, from, n) - /****************************************************************************/ /** Copies a string to an ioctl structure. diff --git a/master/rtdm_details.h b/master/rtdm_details.h index 8b8c0f3c..9bea0636 100644 --- a/master/rtdm_details.h +++ b/master/rtdm_details.h @@ -27,6 +27,7 @@ #define __EC_RTDM_DETAILS_H__ #include "../config.h" +#include "ioctl.h" #include @@ -41,7 +42,7 @@ #define EC_RTDM_USERFD_T rtdm_user_info_t -#endif +#endif // EC_RTDM_XENOMAI_V3 /****************************************************************************/ @@ -54,4 +55,10 @@ typedef struct ec_rtdm_context { /****************************************************************************/ +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__ From df7145a1c385262196e669572607f1b0ce2f0c9b Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Wed, 31 Jan 2024 11:43:03 +0100 Subject: [PATCH 26/36] Add Xenomai{2,3} and RTAI to CI --- .gitlab-ci.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 47f1478f..e4cc5db1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,6 +11,33 @@ stages: 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 From 1e7b4816c172c37280da0e47852c7c086be241e0 Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Wed, 31 Jan 2024 13:21:50 +0100 Subject: [PATCH 27/36] Add rtai modules to KBUILD_EXTRA_SYMBOLS --- Kbuild.in | 5 +++++ configure.ac | 2 ++ 2 files changed, 7 insertions(+) diff --git a/Kbuild.in b/Kbuild.in index 546430bc..4cc9eb9f 100644 --- a/Kbuild.in +++ b/Kbuild.in @@ -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 + #----------------------------------------------------------------------------- diff --git a/configure.ac b/configure.ac index 576c12eb..7a9d22d1 100644 --- a/configure.ac +++ b/configure.ac @@ -695,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]) @@ -703,6 +704,7 @@ 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) From bf790debb6b2b9c449c2779662da32ba0ab7120a Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Wed, 31 Jan 2024 16:54:20 +0100 Subject: [PATCH 28/36] Split ioctl switch statements into rt, nrt and common --- include/ecrt.h | 6 + master/cdev.c | 7 +- master/ioctl.c | 572 +++++++++++++++++++++------------------ master/ioctl.h | 8 +- master/rtdm.c | 46 +++- master/rtdm_xenomai_v3.c | 178 +----------- 6 files changed, 380 insertions(+), 437 deletions(-) diff --git a/include/ecrt.h b/include/ecrt.h index 1df3afac..b33f5010 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -1158,6 +1158,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( @@ -1169,6 +1172,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( diff --git a/master/cdev.c b/master/cdev.c index eb95bfe9..721209fc 100644 --- a/master/cdev.c +++ b/master/cdev.c @@ -191,6 +191,7 @@ int eccdev_release(struct inode *inode, struct file *filp) */ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { + long result; ec_cdev_priv_t *priv = (ec_cdev_priv_t *) filp->private_data; #if DEBUG @@ -199,7 +200,11 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) filp, cmd, _IOC_NR(cmd), arg); #endif - return ec_ioctl(priv->cdev->master, &priv->ctx, cmd, (void __user *) arg); + result = ec_ioctl_rt(priv->cdev->master, &priv->ctx, cmd, (void __user *) arg); + if (result == -ENOTTY) { + result = ec_ioctl_nrt(priv->cdev->master, &priv->ctx, cmd, (void __user *) arg); + } + return result; } /****************************************************************************/ diff --git a/master/ioctl.c b/master/ioctl.c index 367442d9..bb4d5d8f 100644 --- a/master/ioctl.c +++ b/master/ioctl.c @@ -4667,16 +4667,328 @@ static ATTRIBUTES int ec_ioctl_slave_soe_write( /** ioctl() function to use. */ #ifdef EC_IOCTL_RTDM -#define EC_IOCTL ec_ioctl_rtdm +#define EC_IOCTL(x) ec_ioctl_rtdm_ ## x #else -#define EC_IOCTL ec_ioctl +#define EC_IOCTL(x) ec_ioctl_ ## x #endif /** Called when an ioctl() command is issued. + * Both RT and nRT context. * * \return ioctl() return code. */ -long EC_IOCTL( +static long EC_IOCTL(both)( + ec_master_t *master, /**< EtherCAT master. */ + ec_ioctl_context_t *ctx, /**< Device context. */ + unsigned int cmd, /**< ioctl() command identifier. */ + void *arg /**< ioctl() argument. */ + ) +{ + int ret; + + switch (cmd) { + case EC_IOCTL_MODULE: + ret = ec_ioctl_module(arg, ctx); + break; + case EC_IOCTL_MASTER_DEBUG: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_master_debug(master, arg); + break; + case EC_IOCTL_MASTER_RESCAN: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_master_rescan(master, arg); + break; + case EC_IOCTL_MASTER_STATE: + ret = ec_ioctl_master_state(master, arg, ctx); + break; + case EC_IOCTL_MASTER_LINK_STATE: + ret = ec_ioctl_master_link_state(master, arg, ctx); + break; + case EC_IOCTL_APP_TIME: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_app_time(master, arg, ctx); + break; + case EC_IOCTL_REF_CLOCK_TIME: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_ref_clock_time(master, arg, ctx); + break; + case EC_IOCTL_SC_EMERG_POP: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_sc_emerg_pop(master, arg, ctx); + break; + case EC_IOCTL_SC_EMERG_CLEAR: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_sc_emerg_clear(master, arg, ctx); + break; + case EC_IOCTL_SC_EMERG_OVERRUNS: + ret = ec_ioctl_sc_emerg_overruns(master, arg, ctx); + break; + case EC_IOCTL_SC_STATE: + ret = ec_ioctl_sc_state(master, arg, ctx); + break; + case EC_IOCTL_DOMAIN_STATE: + ret = ec_ioctl_domain_state(master, arg, ctx); + break; + case EC_IOCTL_SDO_REQUEST_INDEX: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_sdo_request_index(master, arg, ctx); + break; + case EC_IOCTL_SDO_REQUEST_TIMEOUT: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_sdo_request_timeout(master, arg, ctx); + break; + case EC_IOCTL_SDO_REQUEST_STATE: + ret = ec_ioctl_sdo_request_state(master, arg, ctx); + break; + case EC_IOCTL_SDO_REQUEST_READ: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_sdo_request_read(master, arg, ctx); + break; + case EC_IOCTL_SDO_REQUEST_WRITE: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_sdo_request_write(master, arg, ctx); + break; + case EC_IOCTL_SDO_REQUEST_DATA: + ret = ec_ioctl_sdo_request_data(master, arg, ctx); + break; + case EC_IOCTL_SOE_REQUEST_IDN: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_soe_request_index(master, arg, ctx); + break; + case EC_IOCTL_SOE_REQUEST_TIMEOUT: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_soe_request_timeout(master, arg, ctx); + break; + case EC_IOCTL_SOE_REQUEST_STATE: + ret = ec_ioctl_soe_request_state(master, arg, ctx); + break; + case EC_IOCTL_SOE_REQUEST_READ: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_soe_request_read(master, arg, ctx); + break; + case EC_IOCTL_SOE_REQUEST_WRITE: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_soe_request_write(master, arg, ctx); + break; + case EC_IOCTL_SOE_REQUEST_DATA: + ret = ec_ioctl_soe_request_data(master, arg, ctx); + break; + case EC_IOCTL_REG_REQUEST_DATA: + ret = ec_ioctl_reg_request_data(master, arg, ctx); + break; + case EC_IOCTL_REG_REQUEST_STATE: + ret = ec_ioctl_reg_request_state(master, arg, ctx); + break; + case EC_IOCTL_REG_REQUEST_WRITE: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_reg_request_write(master, arg, ctx); + break; + case EC_IOCTL_REG_REQUEST_READ: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_reg_request_read(master, arg, ctx); + break; + case EC_IOCTL_VOE_SEND_HEADER: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_voe_send_header(master, arg, ctx); + break; + case EC_IOCTL_VOE_REC_HEADER: + ret = ec_ioctl_voe_rec_header(master, arg, ctx); + break; + case EC_IOCTL_VOE_READ: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_voe_read(master, arg, ctx); + break; + case EC_IOCTL_VOE_READ_NOSYNC: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_voe_read_nosync(master, arg, ctx); + break; + case EC_IOCTL_VOE_WRITE: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_voe_write(master, arg, ctx); + break; + case EC_IOCTL_VOE_DATA: + ret = ec_ioctl_voe_data(master, arg, ctx); + break; + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/** Called when an ioctl() command is issued. + * RT only. + * + * \return ioctl() return code. + */ +long EC_IOCTL(rt)( + ec_master_t *master, /**< EtherCAT master. */ + ec_ioctl_context_t *ctx, /**< Device context. */ + unsigned int cmd, /**< ioctl() command identifier. */ + void *arg /**< ioctl() argument. */ + ) +{ +#if DEBUG_LATENCY + cycles_t a = get_cycles(), b; + unsigned int t; +#endif + long ret; + + switch (cmd) { + case EC_IOCTL_SEND: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_send(master, arg, ctx); + break; + case EC_IOCTL_RECEIVE: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_receive(master, arg, ctx); + break; + case EC_IOCTL_SYNC_REF: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_sync_ref(master, arg, ctx); + break; + case EC_IOCTL_SYNC_REF_TO: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_sync_ref_to(master, arg, ctx); + break; + case EC_IOCTL_SYNC_SLAVES: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_sync_slaves(master, arg, ctx); + break; + case EC_IOCTL_SYNC_MON_QUEUE: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_sync_mon_queue(master, arg, ctx); + break; + case EC_IOCTL_SYNC_MON_PROCESS: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_sync_mon_process(master, arg, ctx); + break; + case EC_IOCTL_DOMAIN_PROCESS: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_domain_process(master, arg, ctx); + break; + case EC_IOCTL_DOMAIN_QUEUE: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_domain_queue(master, arg, ctx); + break; + case EC_IOCTL_VOE_EXEC: + if (!ctx->writable) { + ret = -EPERM; + break; + } + ret = ec_ioctl_voe_exec(master, arg, ctx); + break; + default: + ret = EC_IOCTL(both)(master, ctx, cmd, arg); + break; + } + +#if DEBUG_LATENCY + b = get_cycles(); + t = (unsigned int) ((b - a) * 1000LL) / cpu_khz; + if (t > 50) { + EC_MASTER_WARN(master, "ioctl(0x%02x) took %u us.\n", + _IOC_NR(cmd), t); + } +#endif + + return ret; +} + +/** Called when an ioctl() command is issued. + * nRT context only. + * + * \return ioctl() return code. + */ +long EC_IOCTL(nrt)( ec_master_t *master, /**< EtherCAT master. */ ec_ioctl_context_t *ctx, /**< Device context. */ unsigned int cmd, /**< ioctl() command identifier. */ @@ -4690,9 +5002,6 @@ long EC_IOCTL( int ret; switch (cmd) { - case EC_IOCTL_MODULE: - ret = ec_ioctl_module(arg, ctx); - break; case EC_IOCTL_MASTER: ret = ec_ioctl_master(master, arg); break; @@ -4717,20 +5026,6 @@ long EC_IOCTL( case EC_IOCTL_DOMAIN_DATA: ret = ec_ioctl_domain_data(master, arg); break; - case EC_IOCTL_MASTER_DEBUG: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_master_debug(master, arg); - break; - case EC_IOCTL_MASTER_RESCAN: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_master_rescan(master, arg); - break; case EC_IOCTL_SLAVE_STATE: if (!ctx->writable) { ret = -EPERM; @@ -4868,75 +5163,6 @@ long EC_IOCTL( } ret = ec_ioctl_deactivate(master, arg, ctx); break; - case EC_IOCTL_SEND: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_send(master, arg, ctx); - break; - case EC_IOCTL_RECEIVE: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_receive(master, arg, ctx); - break; - case EC_IOCTL_MASTER_STATE: - ret = ec_ioctl_master_state(master, arg, ctx); - break; - case EC_IOCTL_MASTER_LINK_STATE: - ret = ec_ioctl_master_link_state(master, arg, ctx); - break; - case EC_IOCTL_APP_TIME: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_app_time(master, arg, ctx); - break; - case EC_IOCTL_SYNC_REF: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_sync_ref(master, arg, ctx); - break; - case EC_IOCTL_SYNC_REF_TO: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_sync_ref_to(master, arg, ctx); - break; - case EC_IOCTL_SYNC_SLAVES: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_sync_slaves(master, arg, ctx); - break; - case EC_IOCTL_REF_CLOCK_TIME: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_ref_clock_time(master, arg, ctx); - break; - case EC_IOCTL_SYNC_MON_QUEUE: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_sync_mon_queue(master, arg, ctx); - break; - case EC_IOCTL_SYNC_MON_PROCESS: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_sync_mon_process(master, arg, ctx); - break; case EC_IOCTL_RESET: if (!ctx->writable) { ret = -EPERM; @@ -5021,23 +5247,6 @@ long EC_IOCTL( } ret = ec_ioctl_sc_emerg_size(master, arg, ctx); break; - case EC_IOCTL_SC_EMERG_POP: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_sc_emerg_pop(master, arg, ctx); - break; - case EC_IOCTL_SC_EMERG_CLEAR: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_sc_emerg_clear(master, arg, ctx); - break; - case EC_IOCTL_SC_EMERG_OVERRUNS: - ret = ec_ioctl_sc_emerg_overruns(master, arg, ctx); - break; case EC_IOCTL_SC_SDO_REQUEST: if (!ctx->writable) { ret = -EPERM; @@ -5066,9 +5275,6 @@ long EC_IOCTL( } ret = ec_ioctl_sc_create_voe_handler(master, arg, ctx); break; - case EC_IOCTL_SC_STATE: - ret = ec_ioctl_sc_state(master, arg, ctx); - break; case EC_IOCTL_SC_IDN: if (!ctx->writable) { ret = -EPERM; @@ -5089,152 +5295,6 @@ long EC_IOCTL( case EC_IOCTL_DOMAIN_OFFSET: ret = ec_ioctl_domain_offset(master, arg, ctx); break; - case EC_IOCTL_DOMAIN_PROCESS: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_domain_process(master, arg, ctx); - break; - case EC_IOCTL_DOMAIN_QUEUE: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_domain_queue(master, arg, ctx); - break; - case EC_IOCTL_DOMAIN_STATE: - ret = ec_ioctl_domain_state(master, arg, ctx); - break; - case EC_IOCTL_SDO_REQUEST_INDEX: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_sdo_request_index(master, arg, ctx); - break; - case EC_IOCTL_SDO_REQUEST_TIMEOUT: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_sdo_request_timeout(master, arg, ctx); - break; - case EC_IOCTL_SDO_REQUEST_STATE: - ret = ec_ioctl_sdo_request_state(master, arg, ctx); - break; - case EC_IOCTL_SDO_REQUEST_READ: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_sdo_request_read(master, arg, ctx); - break; - case EC_IOCTL_SDO_REQUEST_WRITE: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_sdo_request_write(master, arg, ctx); - break; - case EC_IOCTL_SDO_REQUEST_DATA: - ret = ec_ioctl_sdo_request_data(master, arg, ctx); - break; - case EC_IOCTL_SOE_REQUEST_IDN: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_soe_request_index(master, arg, ctx); - break; - case EC_IOCTL_SOE_REQUEST_TIMEOUT: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_soe_request_timeout(master, arg, ctx); - break; - case EC_IOCTL_SOE_REQUEST_STATE: - ret = ec_ioctl_soe_request_state(master, arg, ctx); - break; - case EC_IOCTL_SOE_REQUEST_READ: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_soe_request_read(master, arg, ctx); - break; - case EC_IOCTL_SOE_REQUEST_WRITE: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_soe_request_write(master, arg, ctx); - break; - case EC_IOCTL_SOE_REQUEST_DATA: - ret = ec_ioctl_soe_request_data(master, arg, ctx); - break; - case EC_IOCTL_REG_REQUEST_DATA: - ret = ec_ioctl_reg_request_data(master, arg, ctx); - break; - case EC_IOCTL_REG_REQUEST_STATE: - ret = ec_ioctl_reg_request_state(master, arg, ctx); - break; - case EC_IOCTL_REG_REQUEST_WRITE: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_reg_request_write(master, arg, ctx); - break; - case EC_IOCTL_REG_REQUEST_READ: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_reg_request_read(master, arg, ctx); - break; - case EC_IOCTL_VOE_SEND_HEADER: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_voe_send_header(master, arg, ctx); - break; - case EC_IOCTL_VOE_REC_HEADER: - ret = ec_ioctl_voe_rec_header(master, arg, ctx); - break; - case EC_IOCTL_VOE_READ: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_voe_read(master, arg, ctx); - break; - case EC_IOCTL_VOE_READ_NOSYNC: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_voe_read_nosync(master, arg, ctx); - break; - case EC_IOCTL_VOE_WRITE: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_voe_write(master, arg, ctx); - break; - case EC_IOCTL_VOE_EXEC: - if (!ctx->writable) { - ret = -EPERM; - break; - } - ret = ec_ioctl_voe_exec(master, arg, ctx); - break; - case EC_IOCTL_VOE_DATA: - ret = ec_ioctl_voe_data(master, arg, ctx); - break; case EC_IOCTL_SET_SEND_INTERVAL: if (!ctx->writable) { ret = -EPERM; @@ -5243,7 +5303,7 @@ long EC_IOCTL( ret = ec_ioctl_set_send_interval(master, arg, ctx); break; default: - ret = -ENOTTY; + ret = EC_IOCTL(both)(master, ctx, cmd, arg); break; } diff --git a/master/ioctl.h b/master/ioctl.h index 01f75539..9e462d3f 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -838,12 +838,16 @@ typedef struct { size_t process_data_size; /**< Size of the \a process_data. */ } ec_ioctl_context_t; -long ec_ioctl(ec_master_t *, ec_ioctl_context_t *, unsigned int, +long ec_ioctl_rt(ec_master_t *, ec_ioctl_context_t *, unsigned int, + void __user *); +long ec_ioctl_nrt(ec_master_t *, ec_ioctl_context_t *, unsigned int, void __user *); #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 diff --git a/master/rtdm.c b/master/rtdm.c index e5e73e09..f9a15b1c 100644 --- a/master/rtdm.c +++ b/master/rtdm.c @@ -41,11 +41,12 @@ /****************************************************************************/ -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. @@ -74,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"; @@ -124,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. */ @@ -154,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. */ ) @@ -179,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. */ @@ -194,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; } /****************************************************************************/ diff --git a/master/rtdm_xenomai_v3.c b/master/rtdm_xenomai_v3.c index 4a58950a..09a969c1 100644 --- a/master/rtdm_xenomai_v3.c +++ b/master/rtdm_xenomai_v3.c @@ -84,189 +84,31 @@ static void ec_rtdm_close(struct rtdm_fd *fd) #endif } -#if DEBUG_RTDM -struct ec_ioctl_desc { - unsigned int cmd; - const char *name; -}; - -#define EC_IOCTL_DEF(ioctl) \ - [_IOC_NR(ioctl)] = { \ - .cmd = ioctl, \ - .name = #ioctl \ - } - -static const struct ec_ioctl_desc ec_ioctls[] = { - EC_IOCTL_DEF(EC_IOCTL_MODULE), - EC_IOCTL_DEF(EC_IOCTL_MASTER), - EC_IOCTL_DEF(EC_IOCTL_SLAVE), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_SYNC), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_SYNC_PDO), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_SYNC_PDO_ENTRY), - EC_IOCTL_DEF(EC_IOCTL_DOMAIN), - EC_IOCTL_DEF(EC_IOCTL_DOMAIN_FMMU), - EC_IOCTL_DEF(EC_IOCTL_DOMAIN_DATA), - EC_IOCTL_DEF(EC_IOCTL_MASTER_DEBUG), - EC_IOCTL_DEF(EC_IOCTL_MASTER_RESCAN), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_STATE), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_SDO), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_SDO_ENTRY), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_SDO_UPLOAD), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_SDO_DOWNLOAD), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_SII_READ), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_SII_WRITE), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_REG_READ), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_REG_WRITE), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_FOE_READ), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_FOE_WRITE), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_SOE_READ), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_SOE_WRITE), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_EOE_IP_PARAM), - EC_IOCTL_DEF(EC_IOCTL_CONFIG), - EC_IOCTL_DEF(EC_IOCTL_CONFIG_PDO), - EC_IOCTL_DEF(EC_IOCTL_CONFIG_PDO_ENTRY), - EC_IOCTL_DEF(EC_IOCTL_CONFIG_SDO), - EC_IOCTL_DEF(EC_IOCTL_CONFIG_IDN), -#ifdef EC_EOE - EC_IOCTL_DEF(EC_IOCTL_EOE_HANDLER), -#endif - EC_IOCTL_DEF(EC_IOCTL_SLAVE_DICT_UPLOAD), - EC_IOCTL_DEF(EC_IOCTL_REQUEST), - EC_IOCTL_DEF(EC_IOCTL_CREATE_DOMAIN), - EC_IOCTL_DEF(EC_IOCTL_CREATE_SLAVE_CONFIG), - EC_IOCTL_DEF(EC_IOCTL_SELECT_REF_CLOCK), - EC_IOCTL_DEF(EC_IOCTL_ACTIVATE), - EC_IOCTL_DEF(EC_IOCTL_DEACTIVATE), - EC_IOCTL_DEF(EC_IOCTL_SEND), - EC_IOCTL_DEF(EC_IOCTL_RECEIVE), - EC_IOCTL_DEF(EC_IOCTL_MASTER_STATE), - EC_IOCTL_DEF(EC_IOCTL_MASTER_LINK_STATE), - EC_IOCTL_DEF(EC_IOCTL_APP_TIME), - EC_IOCTL_DEF(EC_IOCTL_SYNC_REF), - EC_IOCTL_DEF(EC_IOCTL_SYNC_SLAVES), - EC_IOCTL_DEF(EC_IOCTL_REF_CLOCK_TIME), - EC_IOCTL_DEF(EC_IOCTL_SYNC_MON_QUEUE), - EC_IOCTL_DEF(EC_IOCTL_SYNC_MON_PROCESS), - EC_IOCTL_DEF(EC_IOCTL_RESET), - EC_IOCTL_DEF(EC_IOCTL_SC_SYNC), - EC_IOCTL_DEF(EC_IOCTL_SC_WATCHDOG), - EC_IOCTL_DEF(EC_IOCTL_SC_ADD_PDO), - EC_IOCTL_DEF(EC_IOCTL_SC_CLEAR_PDOS), - EC_IOCTL_DEF(EC_IOCTL_SC_ADD_ENTRY), - EC_IOCTL_DEF(EC_IOCTL_SC_CLEAR_ENTRIES), - EC_IOCTL_DEF(EC_IOCTL_SC_REG_PDO_ENTRY), - EC_IOCTL_DEF(EC_IOCTL_SC_REG_PDO_POS), - EC_IOCTL_DEF(EC_IOCTL_SC_DC), - EC_IOCTL_DEF(EC_IOCTL_SC_SDO), - EC_IOCTL_DEF(EC_IOCTL_SC_EMERG_SIZE), - EC_IOCTL_DEF(EC_IOCTL_SC_EMERG_POP), - EC_IOCTL_DEF(EC_IOCTL_SC_EMERG_CLEAR), - EC_IOCTL_DEF(EC_IOCTL_SC_EMERG_OVERRUNS), - EC_IOCTL_DEF(EC_IOCTL_SC_SDO_REQUEST), - EC_IOCTL_DEF(EC_IOCTL_SC_REG_REQUEST), - EC_IOCTL_DEF(EC_IOCTL_SC_VOE), - EC_IOCTL_DEF(EC_IOCTL_SC_STATE), - EC_IOCTL_DEF(EC_IOCTL_SC_IDN), - EC_IOCTL_DEF(EC_IOCTL_DOMAIN_SIZE), - EC_IOCTL_DEF(EC_IOCTL_DOMAIN_OFFSET), - EC_IOCTL_DEF(EC_IOCTL_DOMAIN_PROCESS), - EC_IOCTL_DEF(EC_IOCTL_DOMAIN_QUEUE), - EC_IOCTL_DEF(EC_IOCTL_DOMAIN_STATE), - EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_INDEX), - EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_TIMEOUT), - EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_STATE), - EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_READ), - EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_WRITE), - EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_DATA), - EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_DATA), - EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_STATE), - EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_WRITE), - EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_READ), - EC_IOCTL_DEF(EC_IOCTL_VOE_SEND_HEADER), - EC_IOCTL_DEF(EC_IOCTL_VOE_REC_HEADER), - EC_IOCTL_DEF(EC_IOCTL_VOE_READ), - EC_IOCTL_DEF(EC_IOCTL_VOE_READ_NOSYNC), - EC_IOCTL_DEF(EC_IOCTL_VOE_WRITE), - EC_IOCTL_DEF(EC_IOCTL_VOE_EXEC), - EC_IOCTL_DEF(EC_IOCTL_VOE_DATA), - EC_IOCTL_DEF(EC_IOCTL_SET_SEND_INTERVAL), - EC_IOCTL_DEF(EC_IOCTL_SC_OVERLAPPING_IO), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_REBOOT), - EC_IOCTL_DEF(EC_IOCTL_SLAVE_REG_READWRITE), - EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_READWRITE), - EC_IOCTL_DEF(EC_IOCTL_SETUP_DOMAIN_MEMORY), - EC_IOCTL_DEF(EC_IOCTL_DEACTIVATE_SLAVES), - EC_IOCTL_DEF(EC_IOCTL_64_REF_CLK_TIME_QUEUE), - EC_IOCTL_DEF(EC_IOCTL_64_REF_CLK_TIME), - EC_IOCTL_DEF(EC_IOCTL_SC_FOE_REQUEST), - EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_FILE), - EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_TIMEOUT), - EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_STATE), - EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_READ), - EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_WRITE), - EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_DATA), - EC_IOCTL_DEF(EC_IOCTL_RT_SLAVE_REQUESTS), - EC_IOCTL_DEF(EC_IOCTL_EXEC_SLAVE_REQUESTS), -}; -#endif - -static int ec_rtdm_ioctl_rt(struct rtdm_fd *fd, unsigned int request, +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; -#if DEBUG_RTDM - unsigned int nr = _IOC_NR(request); - const struct ec_ioctl_desc *ioctl = &ec_ioctls[nr]; + result = ec_ioctl_rtdm_rt(rtdm_dev->master, &ctx->ioctl_ctx, request, arg); - EC_MASTER_INFO(rtdm_dev->master, "ioctl_rt(request = %u, ctl = %02x %s)" - " on RTDM device %s.\n", request, _IOC_NR(request),ioctl->name, - dev->name); -#endif - - /* - * FIXME: Execute ioctls from non-rt context except below ioctls to - * avoid any unknown system hanging. - */ - switch (request) { - case EC_IOCTL_SEND: - case EC_IOCTL_RECEIVE: - case EC_IOCTL_MASTER_STATE: - case EC_IOCTL_APP_TIME: - case EC_IOCTL_SYNC_REF: - case EC_IOCTL_SYNC_SLAVES: - case EC_IOCTL_REF_CLOCK_TIME: - case EC_IOCTL_SC_STATE: - case EC_IOCTL_DOMAIN_PROCESS: - case EC_IOCTL_DOMAIN_QUEUE: - case EC_IOCTL_DOMAIN_STATE: - break; - default: + if (result == -ENOTTY) + /* Try again with nrt ioctl handler below in secondary mode. */ return -ENOSYS; - } - return ec_ioctl_rtdm(rtdm_dev->master, &ctx->ioctl_ctx, request, arg); + return result; } -static int ec_rtdm_ioctl(struct rtdm_fd *fd, unsigned int request, +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; -#if DEBUG_RTDM - unsigned int nr = _IOC_NR(request); - const struct ec_ioctl_desc *ioctl = &ec_ioctls[nr]; - - EC_MASTER_INFO(rtdm_dev->master, "ioctl(request = %u, ctl = %02x %s)" - " on RTDM device %s.\n", request, _IOC_NR(request),ioctl->name, - dev->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_mmap(struct rtdm_fd *fd, struct vm_area_struct *vma) @@ -286,8 +128,8 @@ static struct rtdm_driver ec_rtdm_driver = { .ops = { .open = ec_rtdm_open, .close = ec_rtdm_close, - .ioctl_rt = ec_rtdm_ioctl_rt, - .ioctl_nrt = ec_rtdm_ioctl, + .ioctl_rt = ec_rtdm_ioctl_rt_handler, + .ioctl_nrt = ec_rtdm_ioctl_nrt_handler, .mmap = ec_rtdm_mmap, }, }; From aa89735e557bc83498441b17fd4fed6666ecd9d2 Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Thu, 1 Feb 2024 10:14:28 +0100 Subject: [PATCH 29/36] do ioctl multiplexing in ioctl.c --- master/cdev.c | 7 +------ master/ioctl.c | 48 ++++++++++++++++++++++++++++++++++++------------ master/ioctl.h | 4 +--- 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/master/cdev.c b/master/cdev.c index 721209fc..eb95bfe9 100644 --- a/master/cdev.c +++ b/master/cdev.c @@ -191,7 +191,6 @@ int eccdev_release(struct inode *inode, struct file *filp) */ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - long result; ec_cdev_priv_t *priv = (ec_cdev_priv_t *) filp->private_data; #if DEBUG @@ -200,11 +199,7 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) filp, cmd, _IOC_NR(cmd), arg); #endif - result = ec_ioctl_rt(priv->cdev->master, &priv->ctx, cmd, (void __user *) arg); - if (result == -ENOTTY) { - result = ec_ioctl_nrt(priv->cdev->master, &priv->ctx, cmd, (void __user *) arg); - } - return result; + return ec_ioctl(priv->cdev->master, &priv->ctx, cmd, (void __user *) arg); } /****************************************************************************/ diff --git a/master/ioctl.c b/master/ioctl.c index bb4d5d8f..394dee15 100644 --- a/master/ioctl.c +++ b/master/ioctl.c @@ -4665,11 +4665,16 @@ static ATTRIBUTES int ec_ioctl_slave_soe_write( /****************************************************************************/ /** ioctl() function to use. + * + * For RTDM, there will be ec_ioctl_rtdm_rt and ec_ioctl_rtdm_nrt. + * For "normal" cdev, there will be ec_ioctl_rt only. */ -#ifdef EC_IOCTL_RTDM -#define EC_IOCTL(x) ec_ioctl_rtdm_ ## x -#else -#define EC_IOCTL(x) ec_ioctl_ ## x +#ifndef EC_IOCTL_RTDM +static long ec_ioctl_nrt( + ec_master_t *master, /**< EtherCAT master. */ + ec_ioctl_context_t *ctx, /**< Device context. */ + unsigned int cmd, /**< ioctl() command identifier. */ + void *arg /**< ioctl() argument. */); #endif /** Called when an ioctl() command is issued. @@ -4677,7 +4682,7 @@ static ATTRIBUTES int ec_ioctl_slave_soe_write( * * \return ioctl() return code. */ -static long EC_IOCTL(both)( +static long ec_ioctl_both( ec_master_t *master, /**< EtherCAT master. */ ec_ioctl_context_t *ctx, /**< Device context. */ unsigned int cmd, /**< ioctl() command identifier. */ @@ -4870,7 +4875,12 @@ static long EC_IOCTL(both)( ret = ec_ioctl_voe_data(master, arg, ctx); break; default: +#ifdef EC_IOCTL_RTDM ret = -ENOTTY; +#else + /* chain non-rt commands for normal cdev */ + ret = ec_ioctl_nrt(master, ctx, cmd, arg); +#endif break; } @@ -4878,11 +4888,16 @@ static long EC_IOCTL(both)( } /** Called when an ioctl() command is issued. - * RT only. + * RTDM: RT only. * * \return ioctl() return code. */ -long EC_IOCTL(rt)( +#ifdef EC_IOCTL_RTDM +long ec_ioctl_rtdm_rt +#else +long ec_ioctl +#endif + ( ec_master_t *master, /**< EtherCAT master. */ ec_ioctl_context_t *ctx, /**< Device context. */ unsigned int cmd, /**< ioctl() command identifier. */ @@ -4967,7 +4982,7 @@ long EC_IOCTL(rt)( ret = ec_ioctl_voe_exec(master, arg, ctx); break; default: - ret = EC_IOCTL(both)(master, ctx, cmd, arg); + ret = ec_ioctl_both(master, ctx, cmd, arg); break; } @@ -4988,14 +5003,19 @@ long EC_IOCTL(rt)( * * \return ioctl() return code. */ -long EC_IOCTL(nrt)( +#ifdef EC_IOCTL_RTDM +long ec_ioctl_rtdm_nrt +#else +static long ec_ioctl_nrt +#endif + ( ec_master_t *master, /**< EtherCAT master. */ ec_ioctl_context_t *ctx, /**< Device context. */ unsigned int cmd, /**< ioctl() command identifier. */ void *arg /**< ioctl() argument. */ ) { -#if DEBUG_LATENCY +#if DEBUG_LATENCY && !defined(EC_IOCTL_RTDM) cycles_t a = get_cycles(), b; unsigned int t; #endif @@ -5303,11 +5323,15 @@ long EC_IOCTL(nrt)( ret = ec_ioctl_set_send_interval(master, arg, ctx); break; default: - ret = EC_IOCTL(both)(master, ctx, cmd, arg); +#ifdef EC_IOCTL_RTDM + ret = ec_ioctl_both(master, ctx, cmd, arg); +#else + ret = -ENOTTY; +#endif break; } -#if DEBUG_LATENCY +#if DEBUG_LATENCY && !defined(EC_IOCTL_RTDM) b = get_cycles(); t = (unsigned int) ((b - a) * 1000LL) / cpu_khz; if (t > 50) { diff --git a/master/ioctl.h b/master/ioctl.h index 9e462d3f..afaf62c6 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -838,9 +838,7 @@ typedef struct { size_t process_data_size; /**< Size of the \a process_data. */ } ec_ioctl_context_t; -long ec_ioctl_rt(ec_master_t *, ec_ioctl_context_t *, unsigned int, - void __user *); -long ec_ioctl_nrt(ec_master_t *, ec_ioctl_context_t *, unsigned int, +long ec_ioctl(ec_master_t *, ec_ioctl_context_t *, unsigned int, void __user *); #ifdef EC_RTDM From 0c1e2bc397856a3e717e1303ffcff74c1d8ca33a Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Thu, 1 Feb 2024 15:51:30 +0100 Subject: [PATCH 30/36] fix r8169 modname --- devices/r8169/r8169_main-5.10-ethercat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devices/r8169/r8169_main-5.10-ethercat.c b/devices/r8169/r8169_main-5.10-ethercat.c index 91595421..9508e74d 100644 --- a/devices/r8169/r8169_main-5.10-ethercat.c +++ b/devices/r8169/r8169_main-5.10-ethercat.c @@ -35,7 +35,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" From bdd7d1f8f7086daadb2beefb06e8c50c4cf7951b Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Thu, 1 Feb 2024 16:03:33 +0100 Subject: [PATCH 31/36] Fix r8169 link detection with Xenomai ``` [ 741.073012] IRQ pipeline: some code running in oob context 'Xenomai' [ 741.073013] called an in-band only routine [ 741.073013] CPU: 1 PID: 22419 Comm: my_task Tainted: G O 5.10.179-lp154.3-0510xenomai3 #1 [ 741.073014] Hardware name: ICP / iEi IMBA-9454ISA/IMBA-9454ISA(E168), BIOS 080014 02/20/2009 [ 741.073015] IRQ stage: Xenomai [ 741.073015] Call Trace: [ 741.073015] dump_stack+0x86/0xa6 [ 741.073016] check_inband_stage+0x8c/0xa0 [ 741.073017] inband_irq_save+0xe/0x30 [ 741.073017] try_to_grab_pending+0x1e/0x180 [ 741.073018] mod_delayed_work_on+0x42/0xa0 [ 741.073018] phy_trigger_machine+0x23/0x30 [ 741.073019] phy_mac_interrupt+0xe/0x20 [ 741.073019] ec_poll+0x105/0x110 [ec_r8169] [ 741.073020] ec_device_poll+0x24/0x30 [ec_master] [ 741.073020] ecrt_master_receive+0x21/0x160 [ec_master] [ 741.073021] ec_ioctl_rtdm_rt+0x430/0x4c0 [ec_master] [ 741.073021] ? rtdm_fd_get+0x11d/0x210 [ 741.073022] ec_rtdm_ioctl_rt_handler+0x26/0x40 [ec_master] [ 741.073022] rtdm_fd_ioctl+0xdc/0x240 [ 741.073023] ? xnlock_dbg_release+0x21/0xf0 [ 741.073023] CoBaLt_ioctl+0xe/0x20 [ 741.073024] handle_head_syscall+0x10f/0x4d0 [ 741.073025] ? CoBaLt_fcntl+0x20/0x20 [ 741.073025] ? handle_pipelined_syscall+0x39/0x40 [ 741.073026] handle_oob_syscall+0x13/0x20 [ 741.073026] pipeline_syscall+0x8c/0x130 [ 741.073027] syscall_enter_from_user_mode+0x26/0x90 [ 741.073027] do_syscall_64+0x13/0x60 [ 741.073028] entry_SYSCALL_64_after_hwframe+0x61/0xc6 [ 741.073029] RIP: 0033:0x7fac8da13c8f [ 741.073029] Code: Unable to access opcode bytes at RIP 0x7fac8da13c65. [ 741.073030] RSP: 002b:00007fac8e864c90 EFLAGS: 00000206 ORIG_RAX: 0000000010000050 [ 741.073031] RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007fac8da13c8f [ 741.073032] RDX: 0000000000000000 RSI: 000000000000a426 RDI: 0000000000000003 [ 741.073032] RBP: 000000000000a426 R08: 00007fac8e865700 R09: 0000000000000000 [ 741.073033] R10: 0000000000000113 R11: 0000000000000206 R12: 0000000000000000 [ 741.073033] R13: 0000000000000000 R14: 0000000000000000 R15: 00007fac8e864e80 ``` --- devices/r8169/r8169_main-5.10-ethercat.c | 15 +++++++++++++-- devices/r8169/r8169_main-5.14-ethercat.c | 14 +++++++++++++- devices/r8169/r8169_main-5.15-ethercat.c | 14 +++++++++++++- devices/r8169/r8169_main-6.1-ethercat.c | 14 +++++++++++++- 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/devices/r8169/r8169_main-5.10-ethercat.c b/devices/r8169/r8169_main-5.10-ethercat.c index 9508e74d..b00c04af 100644 --- a/devices/r8169/r8169_main-5.10-ethercat.c +++ b/devices/r8169/r8169_main-5.10-ethercat.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -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); diff --git a/devices/r8169/r8169_main-5.14-ethercat.c b/devices/r8169/r8169_main-5.14-ethercat.c index 58ed3d95..51c54f47 100644 --- a/devices/r8169/r8169_main-5.14-ethercat.c +++ b/devices/r8169/r8169_main-5.14-ethercat.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -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); diff --git a/devices/r8169/r8169_main-5.15-ethercat.c b/devices/r8169/r8169_main-5.15-ethercat.c index f2bc5230..df956257 100644 --- a/devices/r8169/r8169_main-5.15-ethercat.c +++ b/devices/r8169/r8169_main-5.15-ethercat.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -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); diff --git a/devices/r8169/r8169_main-6.1-ethercat.c b/devices/r8169/r8169_main-6.1-ethercat.c index 82405979..06e02bc6 100644 --- a/devices/r8169/r8169_main-6.1-ethercat.c +++ b/devices/r8169/r8169_main-6.1-ethercat.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -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); From 35ff31985618d7445e6df37bbe4b3554aa4abb71 Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Fri, 2 Feb 2024 13:13:54 +0100 Subject: [PATCH 32/36] Fix igb link detection with xenomai --- devices/igb/igb-4.4-ethercat.h | 2 ++ devices/igb/igb-5.10-ethercat.h | 2 ++ devices/igb/igb-5.14-ethercat.h | 2 ++ devices/igb/igb-5.15-ethercat.h | 2 ++ devices/igb/igb-6.1-ethercat.h | 2 ++ devices/igb/igb_main-4.4-ethercat.c | 24 +++++++++++++++++++----- devices/igb/igb_main-5.10-ethercat.c | 24 +++++++++++++++++++----- devices/igb/igb_main-5.14-ethercat.c | 24 +++++++++++++++++++----- devices/igb/igb_main-5.15-ethercat.c | 24 +++++++++++++++++++----- devices/igb/igb_main-6.1-ethercat.c | 24 +++++++++++++++++++----- 10 files changed, 105 insertions(+), 25 deletions(-) diff --git a/devices/igb/igb-4.4-ethercat.h b/devices/igb/igb-4.4-ethercat.h index 05f41ddd..846e2c81 100644 --- a/devices/igb/igb-4.4-ethercat.h +++ b/devices/igb/igb-4.4-ethercat.h @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -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) diff --git a/devices/igb/igb-5.10-ethercat.h b/devices/igb/igb-5.10-ethercat.h index 3fbfcad0..6bfdc364 100644 --- a/devices/igb/igb-5.10-ethercat.h +++ b/devices/igb/igb-5.10-ethercat.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -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 */ diff --git a/devices/igb/igb-5.14-ethercat.h b/devices/igb/igb-5.14-ethercat.h index 8c634215..59392816 100644 --- a/devices/igb/igb-5.14-ethercat.h +++ b/devices/igb/igb-5.14-ethercat.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -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 */ diff --git a/devices/igb/igb-5.15-ethercat.h b/devices/igb/igb-5.15-ethercat.h index 2e82cc6f..02c798fe 100644 --- a/devices/igb/igb-5.15-ethercat.h +++ b/devices/igb/igb-5.15-ethercat.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -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 */ diff --git a/devices/igb/igb-6.1-ethercat.h b/devices/igb/igb-6.1-ethercat.h index 78b9125a..dbdf917d 100644 --- a/devices/igb/igb-6.1-ethercat.h +++ b/devices/igb/igb-6.1-ethercat.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -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 */ diff --git a/devices/igb/igb_main-4.4-ethercat.c b/devices/igb/igb_main-4.4-ethercat.c index 22c22b6f..0d89fde9 100644 --- a/devices/igb/igb_main-4.4-ethercat.c +++ b/devices/igb/igb_main-4.4-ethercat.c @@ -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; diff --git a/devices/igb/igb_main-5.10-ethercat.c b/devices/igb/igb_main-5.10-ethercat.c index 0b5dab47..719a03d4 100644 --- a/devices/igb/igb_main-5.10-ethercat.c +++ b/devices/igb/igb_main-5.10-ethercat.c @@ -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; diff --git a/devices/igb/igb_main-5.14-ethercat.c b/devices/igb/igb_main-5.14-ethercat.c index 29c5656c..483642c6 100644 --- a/devices/igb/igb_main-5.14-ethercat.c +++ b/devices/igb/igb_main-5.14-ethercat.c @@ -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; diff --git a/devices/igb/igb_main-5.15-ethercat.c b/devices/igb/igb_main-5.15-ethercat.c index 2e93f4be..4d3703a5 100644 --- a/devices/igb/igb_main-5.15-ethercat.c +++ b/devices/igb/igb_main-5.15-ethercat.c @@ -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; diff --git a/devices/igb/igb_main-6.1-ethercat.c b/devices/igb/igb_main-6.1-ethercat.c index 13b860ce..8c1c1165 100644 --- a/devices/igb/igb_main-6.1-ethercat.c +++ b/devices/igb/igb_main-6.1-ethercat.c @@ -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; From 34c56eae7d935e723502c041dbe0c8ca50cf3326 Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Fri, 2 Feb 2024 13:24:20 +0100 Subject: [PATCH 33/36] Fix igc link detection with xenomai --- devices/igc/igc-6.4-ethercat.h | 2 ++ devices/igc/igc-6.6-ethercat.h | 2 ++ devices/igc/igc_main-6.4-ethercat.c | 25 +++++++++++++++++++------ devices/igc/igc_main-6.6-ethercat.c | 25 +++++++++++++++++++------ 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/devices/igc/igc-6.4-ethercat.h b/devices/igc/igc-6.4-ethercat.h index 52ad0a95..5f01efdf 100644 --- a/devices/igc/igc-6.4-ethercat.h +++ b/devices/igc/igc-6.4-ethercat.h @@ -5,6 +5,7 @@ #define _IGC_H_ #include "../ecdev.h" +#include #include #include #include @@ -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); diff --git a/devices/igc/igc-6.6-ethercat.h b/devices/igc/igc-6.6-ethercat.h index 18efb14e..dc1b5813 100644 --- a/devices/igc/igc-6.6-ethercat.h +++ b/devices/igc/igc-6.6-ethercat.h @@ -5,6 +5,7 @@ #define _IGC_H_ #include "../ecdev.h" +#include #include #include #include @@ -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); diff --git a/devices/igc/igc_main-6.4-ethercat.c b/devices/igc/igc_main-6.4-ethercat.c index 7c6b5dc8..ef1e34fe 100644 --- a/devices/igc/igc_main-6.4-ethercat.c +++ b/devices/igc/igc_main-6.4-ethercat.c @@ -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); } diff --git a/devices/igc/igc_main-6.6-ethercat.c b/devices/igc/igc_main-6.6-ethercat.c index 7faa0df1..81e911ad 100644 --- a/devices/igc/igc_main-6.6-ethercat.c +++ b/devices/igc/igc_main-6.6-ethercat.c @@ -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); } From a1a0edb9c47b4cf38b9187f2ccbacabaa037b121 Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Fri, 2 Feb 2024 15:04:24 +0100 Subject: [PATCH 34/36] Fix e1000 link detection with xenomai --- devices/e1000/e1000-4.4-ethercat.h | 2 ++ devices/e1000/e1000-5.10-ethercat.h | 2 ++ devices/e1000/e1000-5.14-ethercat.h | 2 ++ devices/e1000/e1000-5.15-ethercat.h | 2 ++ devices/e1000/e1000-6.1-ethercat.h | 2 ++ devices/e1000/e1000_main-4.4-ethercat.c | 12 +++++++++++- devices/e1000/e1000_main-5.10-ethercat.c | 12 +++++++++++- devices/e1000/e1000_main-5.14-ethercat.c | 12 +++++++++++- devices/e1000/e1000_main-5.15-ethercat.c | 12 +++++++++++- devices/e1000/e1000_main-6.1-ethercat.c | 12 +++++++++++- 10 files changed, 65 insertions(+), 5 deletions(-) diff --git a/devices/e1000/e1000-4.4-ethercat.h b/devices/e1000/e1000-4.4-ethercat.h index 8abbe43b..1b047b23 100644 --- a/devices/e1000/e1000-4.4-ethercat.h +++ b/devices/e1000/e1000-4.4-ethercat.h @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -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 { diff --git a/devices/e1000/e1000-5.10-ethercat.h b/devices/e1000/e1000-5.10-ethercat.h index 87301858..e8281f68 100644 --- a/devices/e1000/e1000-5.10-ethercat.h +++ b/devices/e1000/e1000-5.10-ethercat.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -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 { diff --git a/devices/e1000/e1000-5.14-ethercat.h b/devices/e1000/e1000-5.14-ethercat.h index 023fee7b..71aa37ad 100644 --- a/devices/e1000/e1000-5.14-ethercat.h +++ b/devices/e1000/e1000-5.14-ethercat.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -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 { diff --git a/devices/e1000/e1000-5.15-ethercat.h b/devices/e1000/e1000-5.15-ethercat.h index b94866b7..17589120 100644 --- a/devices/e1000/e1000-5.15-ethercat.h +++ b/devices/e1000/e1000-5.15-ethercat.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -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 { diff --git a/devices/e1000/e1000-6.1-ethercat.h b/devices/e1000/e1000-6.1-ethercat.h index 30546b83..0769b47c 100644 --- a/devices/e1000/e1000-6.1-ethercat.h +++ b/devices/e1000/e1000-6.1-ethercat.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -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 { diff --git a/devices/e1000/e1000_main-4.4-ethercat.c b/devices/e1000/e1000_main-4.4-ethercat.c index b3649eb6..18042c1f 100644 --- a/devices/e1000/e1000_main-4.4-ethercat.c +++ b/devices/e1000/e1000_main-4.4-ethercat.c @@ -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); diff --git a/devices/e1000/e1000_main-5.10-ethercat.c b/devices/e1000/e1000_main-5.10-ethercat.c index 03c4bc6a..018f1168 100644 --- a/devices/e1000/e1000_main-5.10-ethercat.c +++ b/devices/e1000/e1000_main-5.10-ethercat.c @@ -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); diff --git a/devices/e1000/e1000_main-5.14-ethercat.c b/devices/e1000/e1000_main-5.14-ethercat.c index 20f154c6..ad3e681b 100644 --- a/devices/e1000/e1000_main-5.14-ethercat.c +++ b/devices/e1000/e1000_main-5.14-ethercat.c @@ -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); diff --git a/devices/e1000/e1000_main-5.15-ethercat.c b/devices/e1000/e1000_main-5.15-ethercat.c index 5f94a2c3..082150e9 100644 --- a/devices/e1000/e1000_main-5.15-ethercat.c +++ b/devices/e1000/e1000_main-5.15-ethercat.c @@ -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); diff --git a/devices/e1000/e1000_main-6.1-ethercat.c b/devices/e1000/e1000_main-6.1-ethercat.c index ce79ffa8..1898e511 100644 --- a/devices/e1000/e1000_main-6.1-ethercat.c +++ b/devices/e1000/e1000_main-6.1-ethercat.c @@ -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); From 76837179988507370dbc0ac589dab68aaf790e34 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Mon, 5 Feb 2024 10:59:25 +0100 Subject: [PATCH 35/36] Added srcdir for mapfile dependencies. --- lib/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Makefile.am b/lib/Makefile.am index af2af89e..60cbd9b5 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -73,7 +73,7 @@ libethercat_la_LDFLAGS = -version-info 3:0:2 \ -Wl,--version-script=$(srcdir)/libethercat.map \ -fvisibility=hidden -libethercat_la_DEPENDENCIES = libethercat.map +libethercat_la_DEPENDENCIES = $(srcdir)/libethercat.map pkgconfig_DATA = libethercat.pc From ec54baeef6387eb8af213f7605a9ebe17ae7680b Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Mon, 5 Feb 2024 11:06:01 +0100 Subject: [PATCH 36/36] Removed nunecessary srcdir again; added libethercat.map to EXTRA_DIST. --- lib/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Makefile.am b/lib/Makefile.am index 60cbd9b5..e64c7c30 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -73,7 +73,7 @@ libethercat_la_LDFLAGS = -version-info 3:0:2 \ -Wl,--version-script=$(srcdir)/libethercat.map \ -fvisibility=hidden -libethercat_la_DEPENDENCIES = $(srcdir)/libethercat.map +libethercat_la_DEPENDENCIES = libethercat.map pkgconfig_DATA = libethercat.pc @@ -81,7 +81,7 @@ 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)