From b7648f0f0848894529f7e339ace3519544b4121a Mon Sep 17 00:00:00 2001 From: Jiacheng Shi Date: Sat, 26 Mar 2022 13:51:38 +0800 Subject: [PATCH] powerlink: build liboplkmn.a and liboplkcn.a --- .../connection/industrial_ethernet/Makefile | 21 + .../toolchain-xiuos-arm-none-eabi-gnu.cmake | 53 ++ .../openPOWERLINK/stack/CMakeLists.txt | 3 + .../stack/build/xiuos/.gitignore | 3 + .../stack/cmake/options-xiuos.cmake | 121 ++++ .../stack/cmake/stackfiles.cmake | 28 + .../stack/include/oplk/targetsystem.h | 5 +- .../stack/proj/xiuos/liboplkcn/CMakeLists.txt | 96 +++ .../stack/proj/xiuos/liboplkcn/oplkcfg.h | 134 ++++ .../stack/proj/xiuos/liboplkmn/CMakeLists.txt | 95 +++ .../stack/proj/xiuos/liboplkmn/oplkcfg.h | 141 ++++ .../stack/src/arch/xiuos/netif-xiuos.c | 122 ++++ .../stack/src/arch/xiuos/target-mutex.c | 196 ++++++ .../stack/src/arch/xiuos/target-xiuos.c | 381 +++++++++++ .../stack/src/kernel/edrv/edrv-xiuos.c | 634 ++++++++++++++++++ .../stack/src/kernel/event/eventkcal-xiuos.c | 377 +++++++++++ .../stack/src/kernel/timer/hrestimer-xiuos.c | 617 +++++++++++++++++ .../openPOWERLINK/stack/src/user/cfmu.c | 2 + .../stack/src/user/event/eventucal-xiuos.c | 379 +++++++++++ .../user_api/posix_support/include/pthread.h | 5 + .../XiZi/board/aiit-arm32-board/Kconfig | 2 +- .../XiZi/board/aiit-riscv64-board/Kconfig | 2 +- .../XiZi/board/cortex-m4-emulator/Kconfig | 2 +- Ubiquitous/XiZi/board/gapuino/Kconfig | 2 +- Ubiquitous/XiZi/board/k210-emulator/Kconfig | 2 +- Ubiquitous/XiZi/board/kd233/Kconfig | 2 +- .../XiZi/board/stm32f407-st-discovery/Kconfig | 2 +- Ubiquitous/XiZi/board/stm32f407zgt6/Kconfig | 2 +- Ubiquitous/XiZi/compiler.mk | 13 +- devtools.sh | 8 +- 30 files changed, 3436 insertions(+), 14 deletions(-) create mode 100644 APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/cmake/toolchain-xiuos-arm-none-eabi-gnu.cmake create mode 100644 APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/build/xiuos/.gitignore create mode 100644 APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/cmake/options-xiuos.cmake create mode 100644 APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/proj/xiuos/liboplkcn/CMakeLists.txt create mode 100644 APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/proj/xiuos/liboplkcn/oplkcfg.h create mode 100644 APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/proj/xiuos/liboplkmn/CMakeLists.txt create mode 100644 APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/proj/xiuos/liboplkmn/oplkcfg.h create mode 100644 APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/arch/xiuos/netif-xiuos.c create mode 100644 APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/arch/xiuos/target-mutex.c create mode 100644 APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/arch/xiuos/target-xiuos.c create mode 100644 APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/kernel/edrv/edrv-xiuos.c create mode 100644 APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/kernel/event/eventkcal-xiuos.c create mode 100644 APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/kernel/timer/hrestimer-xiuos.c create mode 100644 APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/user/event/eventucal-xiuos.c diff --git a/APP_Framework/Framework/connection/industrial_ethernet/Makefile b/APP_Framework/Framework/connection/industrial_ethernet/Makefile index e9ec8be90..2bdec6d77 100644 --- a/APP_Framework/Framework/connection/industrial_ethernet/Makefile +++ b/APP_Framework/Framework/connection/industrial_ethernet/Makefile @@ -1,3 +1,24 @@ +all: COMPILER + +CUR_DIR := $(shell pwd) +OPLK_ROOT := $(CUR_DIR)/openPOWERLINK +LIBOPLKMN := $(OPLK_ROOT)/stack/lib/xiuos/arm/liboplkmn.a +LIBOPLKCN := $(OPLK_ROOT)/stack/lib/xiuos/arm/liboplkcn.a +LIBOPLK_BUILD_DIR := $(OPLK_ROOT)/stack/build/xiuos +OPLK_TOOLCHAIN := $(OPLK_ROOT)/cmake/toolchain-xiuos-arm-none-eabi-gnu.cmake + +.PHONY: $(LIBOPLKMN) $(LIBOPLKCN) +$(LIBOPLKMN) $(LIBOPLKCN)&: + cd $(LIBOPLK_BUILD_DIR) && \ + rm -rf CMakeFiles proj cmake_install.cmake CMakeCache.txt Makefile && \ + cmake -DCMAKE_TOOLCHAIN_FILE=$(OPLK_TOOLCHAIN) ../.. && \ + cmake --build . --target install + +LIBOPLKMN := $(LIBOPLKMN:$(CUR_DIR)/%=%) +LIBOPLKCN := $(LIBOPLKCN:$(CUR_DIR)/%=%) + +SRC_FILES := $(LIBOPLKMN) $(LIBOPLKCN) + ifeq ($(CONFIG_CONNECTION_ADAPTER_ETHERCAT),y) SRC_DIR += ethercat endif diff --git a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/cmake/toolchain-xiuos-arm-none-eabi-gnu.cmake b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/cmake/toolchain-xiuos-arm-none-eabi-gnu.cmake new file mode 100644 index 000000000..17a8c10b7 --- /dev/null +++ b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/cmake/toolchain-xiuos-arm-none-eabi-gnu.cmake @@ -0,0 +1,53 @@ +################################################################################ +# +# CMake target configuration file for ARM XiUOS +# +# Copyright (c) 2016, Kalycito Infotech Pvt. Ltd. +# Copyright (c) 2020, AIIT XUOS Lab +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the copyright holders nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +################################################################################ + +################################################################################ +# Name of the target platform +SET(CMAKE_SYSTEM ARM-XiUOS) +SET(CMAKE_SYSTEM_NAME XiUOS) +SET(CMAKE_SYSTEM_PROCESSOR arm) + +# specify the cross compiler +SET(CMAKE_C_COMPILER arm-none-eabi-gcc) +SET(CMAKE_CXX_COMPILER arm-none-eabi-g++) +SET(CMAKE_ASM-ATT_COMPILER arm-none-eabi-as) + +# skip CMake compiler check +SET(CMAKE_C_COMPILER_WORKS TRUE) +SET(CMAKE_CXX_COMPILER_WORKS TRUE) +SET(CMAKE_ASM-ATT_COMPILER_WORKS TRUE) + +# search for programs in the build host directories +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +# for libraries in the target directories +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER) +# for headers in the target directories +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER) diff --git a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/CMakeLists.txt b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/CMakeLists.txt index 8058b609c..7415fbed6 100644 --- a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/CMakeLists.txt +++ b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/CMakeLists.txt @@ -4,6 +4,7 @@ # # Copyright (c) 2014, B&R Industrial Automation GmbH # Copyright (c) 2016, Kalycito Infotech Private Limited +# Copyright (c) 2020, AIIT XUOS Lab # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -101,6 +102,8 @@ IF(CMAKE_SYSTEM_NAME STREQUAL "Linux") INCLUDE(cmake/options-linux.cmake) ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "Windows") INCLUDE(cmake/options-windows.cmake) +ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "XiUOS") + INCLUDE(cmake/options-xiuos.cmake) ELSEIF((CMAKE_SYSTEM_NAME STREQUAL "Generic") AND (CMAKE_SYSTEM_PROCESSOR STREQUAL "Microblazeise")) INCLUDE(cmake/options-microblazeise.cmake) ELSEIF((CMAKE_SYSTEM_NAME STREQUAL "Generic") AND (CMAKE_SYSTEM_PROCESSOR STREQUAL "Microblaze")) diff --git a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/build/xiuos/.gitignore b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/build/xiuos/.gitignore new file mode 100644 index 000000000..7d0e838f5 --- /dev/null +++ b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/build/xiuos/.gitignore @@ -0,0 +1,3 @@ +* +.* +!.gitignore \ No newline at end of file diff --git a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/cmake/options-xiuos.cmake b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/cmake/options-xiuos.cmake new file mode 100644 index 000000000..c8111d029 --- /dev/null +++ b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/cmake/options-xiuos.cmake @@ -0,0 +1,121 @@ +################################################################################ +# +# CMake options for openPOWERLINK stack on XiUOS +# +# Copyright (c) 2016, B&R Industrial Automation GmbH +# Copyright (c) 2016, Franz Profelt (franz.profelt@gmail.com) +# Copyright (c) 2018, Kalycito Infotech Private Limited +# Copyright (c) 2020, AIIT XUOS Lab +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the copyright holders nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +################################################################################ + +MESSAGE(STATUS "Adding CMAKE configuration options for XiUOS") + +################################################################################ +# Options for MN libraries + +OPTION (CFG_COMPILE_LIB_MN "Compile openPOWERLINK MN library" ON) +OPTION (CFG_COMPILE_LIB_MNAPP_USERINTF "Compile openPOWERLINK MN application library for userspace" OFF) +OPTION (CFG_COMPILE_LIB_MNAPP_KERNELINTF "Compile openPOWERLINK MN application library for kernel interface" OFF) +OPTION (CFG_COMPILE_LIB_MNAPP_PCIEINTF "Compile openPOWERLINK MN application library for PCIe interface" OFF) +OPTION (CFG_COMPILE_LIB_MNAPP_ZYNQINTF "Compile openPOWERLINK MN application library for zynq/FPGA interface" OFF) +OPTION (CFG_COMPILE_LIB_MNDRV_PCAP "Compile openPOWERLINK MN driver library for linux userspace (pcap)" OFF) +OPTION (CFG_COMPILE_LIB_MN_SIM "Compile openPOWERLINK MN library with simulation interface" OFF) + +################################################################################ +# Options for CN libraries + +OPTION (CFG_COMPILE_LIB_CN "Compile openPOWERLINK CN library" ON) +OPTION (CFG_COMPILE_LIB_CNAPP_USERINTF "Compile openPOWERLINK CN application library for userspace" OFF) +OPTION (CFG_COMPILE_LIB_CNAPP_KERNELINTF "Compile openPOWERLINK CN application library for kernel interface" OFF) +OPTION (CFG_COMPILE_LIB_CNAPP_ZYNQINTF "Compile openPOWERLINK CN application library for zynq/FPGA interface" OFF) +OPTION (CFG_COMPILE_LIB_CNDRV_PCAP "Compile openPOWERLINK CN driver library for linux userspace (pcap)" OFF) +OPTION (CFG_COMPILE_LIB_CN_SIM "Compile openPOWERLINK CN library with simulation interface" OFF) + +################################################################################ +# Options for shared libraries + +OPTION (CFG_COMPILE_SHARED_LIBRARY "Build openPOWERLINK library as shared library" OFF) + +################################################################################ +# Options for library features + +OPTION (CFG_USE_PCAP_EDRV "Compile openPOWERLINK library with pcap edrv" OFF) +OPTION (CFG_INCLUDE_MN_REDUNDANCY "Compile MN redundancy functions into MN libraries" OFF) +CMAKE_DEPENDENT_OPTION (CFG_STORE_RESTORE "Support storing of OD in non-volatile memory (file system)" OFF + "CFG_COMPILE_LIB_CN OR CFG_COMPILE_LIB_CNAPP_USERINTF OR CFG_COMPILE_LIB_CNAPP_KERNELINTF" OFF) + +################################################################################ +# Add library subdirectories + +# Add MN libraries +IF(CFG_COMPILE_LIB_MN) + ADD_SUBDIRECTORY(proj/xiuos/liboplkmn) +ENDIF() + +IF(CFG_COMPILE_LIB_MNAPP_USERINTF) + ADD_SUBDIRECTORY(proj/linux/liboplkmnapp-userintf) +ENDIF() + +IF(CFG_COMPILE_LIB_MNAPP_KERNELINTF) + ADD_SUBDIRECTORY(proj/linux/liboplkmnapp-kernelintf) +ENDIF() + +IF((CFG_COMPILE_LIB_MNAPP_PCIEINTF) OR (CFG_COMPILE_LIB_MNAPP_ZYNQINTF)) + ADD_SUBDIRECTORY(proj/linux/liboplkmnapp-kernelpcp) +ENDIF() + +IF(CFG_COMPILE_LIB_MNDRV_PCAP) + ADD_SUBDIRECTORY(proj/linux/liboplkmndrv-pcap) +ENDIF() + +IF(CFG_COMPILE_LIB_MN_SIM) + ADD_SUBDIRECTORY(proj/linux/liboplkmn-sim) +ENDIF() + +# Add CN libraries +IF(CFG_COMPILE_LIB_CN) + ADD_SUBDIRECTORY(proj/xiuos/liboplkcn) +ENDIF() + +IF(CFG_COMPILE_LIB_CNAPP_USERINTF) + ADD_SUBDIRECTORY(proj/linux/liboplkcnapp-userintf) +ENDIF() + +IF(CFG_COMPILE_LIB_CNAPP_KERNELINTF) + ADD_SUBDIRECTORY(proj/linux/liboplkcnapp-kernelintf) +ENDIF() + +IF(CFG_COMPILE_LIB_CNAPP_ZYNQINTF) + ADD_SUBDIRECTORY(proj/linux/liboplkcnapp-kernelpcp) +ENDIF() + +IF(CFG_COMPILE_LIB_CNDRV_PCAP) + ADD_SUBDIRECTORY(proj/linux/liboplkcndrv-pcap) +ENDIF() + +IF(CFG_COMPILE_LIB_CN_SIM) + ADD_SUBDIRECTORY(proj/linux/liboplkcn-sim) +ENDIF() diff --git a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/cmake/stackfiles.cmake b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/cmake/stackfiles.cmake index fb5384673..c850e3b5c 100644 --- a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/cmake/stackfiles.cmake +++ b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/cmake/stackfiles.cmake @@ -5,6 +5,7 @@ # Copyright (c) 2017, B&R Industrial Automation GmbH # Copyright (c) 2016, Franz Profelt (franz.profelt@gmail.com) # Copyright (c) 2018, Kalycito Infotech Private Limited +# Copyright (c) 2020, AIIT XUOS Lab # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -220,6 +221,11 @@ SET(EVENT_UCAL_LINUXUSER_SOURCES ${USER_SOURCE_DIR}/event/eventucalintf-circbuf.c ) +SET(EVENT_UCAL_XIUOS_SOURCES + ${USER_SOURCE_DIR}/event/eventucal-xiuos.c + ${USER_SOURCE_DIR}/event/eventucalintf-circbuf.c + ) + SET(EVENT_UCAL_LINUXIOCTL_SOURCES ${USER_SOURCE_DIR}/event/eventucal-linuxioctl.c ) @@ -396,6 +402,11 @@ SET(EVENT_KCAL_WINDOWS_SOURCES ${KERNEL_SOURCE_DIR}/event/eventkcalintf-circbuf.c ) +SET(EVENT_KCAL_XIUOS_SOURCES + ${KERNEL_SOURCE_DIR}/event/eventkcal-xiuos.c + ${KERNEL_SOURCE_DIR}/event/eventkcalintf-circbuf.c + ) + SET(EVENT_KCAL_LINUXKERNEL_SOURCES ${KERNEL_SOURCE_DIR}/event/eventkcal-linuxkernel.c ${KERNEL_SOURCE_DIR}/event/eventkcalintf-circbuf.c @@ -476,6 +487,13 @@ SET(HARDWARE_DRIVER_LINUXUSERRAWSOCKET_SOURCES ${EDRV_SOURCE_DIR}/edrv-rawsock_linux.c ) +SET(HARDWARE_DRIVER_XIUOS_SOURCES + ${KERNEL_SOURCE_DIR}/veth/veth-generic.c + ${KERNEL_SOURCE_DIR}/timer/hrestimer-xiuos.c + ${EDRV_SOURCE_DIR}/edrvcyclic.c + ${EDRV_SOURCE_DIR}/edrv-xiuos.c + ) + SET(HARDWARE_DRIVER_WINDOWS_SOURCES ${EDRV_SOURCE_DIR}/edrvcyclic.c ${EDRV_SOURCE_DIR}/edrv-pcap_win.c @@ -533,6 +551,10 @@ SET(USER_TIMER_WINDOWS_SOURCES ${USER_SOURCE_DIR}/timer/timer-generic.c ) +SET(USER_TIMER_XIUOS_SOURCES + ${USER_SOURCE_DIR}/timer/timer-generic.c + ) + SET(USER_TIMER_GENERIC_SOURCES ${USER_SOURCE_DIR}/timer/timer-generic.c ) @@ -643,6 +665,12 @@ ELSE () ) ENDIF () +SET(TARGET_XIUOS_SOURCES + ${ARCH_SOURCE_DIR}/xiuos/target-xiuos.c + ${ARCH_SOURCE_DIR}/xiuos/target-mutex.c + ${ARCH_SOURCE_DIR}/xiuos/netif-xiuos.c + ) + SET(TARGET_MICROBLAZE_SOURCES ${ARCH_SOURCE_DIR}/xilinx-microblaze/systemtimer.c ${ARCH_SOURCE_DIR}/xilinx-microblaze/usleep.c diff --git a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/include/oplk/targetsystem.h b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/include/oplk/targetsystem.h index c6288381a..b3f9c2c00 100644 --- a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/include/oplk/targetsystem.h +++ b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/include/oplk/targetsystem.h @@ -136,6 +136,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #elif (defined (_WIN32) || defined (__MINGW32__)) #define TARGET_SYSTEM _WIN32_ // WIN32 definition #define DEV_SYSTEM _DEV_WIN32_MINGW_ +#elif (defined(__XIUOS__)) // ARM / XiUOS +#define TARGET_SYSTEM _XIUOS_ +#define DEV_SYSTEM _DEV_LINUX_ #else /* (defined (_WIN32) || defined (__MINGW32__)) */ // unsupported #error 'ERROR: TARGET_SYSTEM / DEV_SYSTEM not found!' #endif @@ -171,7 +174,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //------------------------------------------------------------------------------ // TARGET_SYSTEM specific definitions //------------------------------------------------------------------------------ -#if (TARGET_SYSTEM == _LINUX_) +#if (TARGET_SYSTEM == _LINUX_ || TARGET_SYSTEM == _XIUOS_) #include diff --git a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/proj/xiuos/liboplkcn/CMakeLists.txt b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/proj/xiuos/liboplkcn/CMakeLists.txt new file mode 100644 index 000000000..1358d603a --- /dev/null +++ b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/proj/xiuos/liboplkcn/CMakeLists.txt @@ -0,0 +1,96 @@ +################################################################################ +# +# CMake file for openPOWERLINK CN library on Linux userspace +# +# Copyright (c) 2017, B&R Industrial Automation GmbH +# Copyright (c) 2020, AIIT XUOS Lab +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the copyright holders nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +################################################################################ + +# Set library name +SET(LIB_NAME "oplkcn") +MESSAGE(STATUS "Configuring ${LIB_NAME}") + +# Set type of library +IF(CFG_COMPILE_SHARED_LIBRARY) + SET(LIB_TYPE "SHARED") +ELSE() + SET(LIB_TYPE "STATIC") +ENDIF() + +# set sources of POWERLINK library +SET (LIB_SOURCES + ${USER_SOURCES} + ${CTRL_UCAL_DIRECT_SOURCES} + ${DLL_UCAL_CIRCBUF_SOURCES} + ${ERRHND_UCAL_LOCAL_SOURCES} + ${EVENT_UCAL_XIUOS_SOURCES} + ${PDO_UCAL_LOCAL_SOURCES} + ${USER_TIMER_XIUOS_SOURCES} + ${KERNEL_SOURCES} + ${CTRL_KCAL_DIRECT_SOURCES} + ${DLL_KCAL_CIRCBUF_SOURCES} + ${ERRHND_KCAL_LOCAL_SOURCES} + ${EVENT_KCAL_XIUOS_SOURCES} + ${PDO_KCAL_LOCAL_SOURCES} + ${COMMON_SOURCES} + ${COMMON_LINUXUSER_SOURCES} + ${TARGET_XIUOS_SOURCES} + ${OBD_CONF_LINUXUSER_SOURCES} + ${CIRCBUF_NOOS_SOURCES} + ${MEMMAP_NULL_SOURCES} + ${HARDWARE_DRIVER_XIUOS_SOURCES} + ) + +# Configure compile definitions +IF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(i.86|x86(_64)?)$") + SET(LIB_SOURCES ${LIB_SOURCES} ${ARCH_X86_SOURCES}) +ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES arm*) + SET(LIB_SOURCES ${LIB_SOURCES} ${ARCH_LE_SOURCES}) +ELSE() + MESSAGE(FATAL_ERROR "Unsupported CMAKE_SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR}") +ENDIF() + +# Configure compile definitions +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -pedantic -std=c99 -fno-strict-aliasing") +ADD_DEFINITIONS(-D__XIUOS__) +ADD_DEFINITIONS(-D_GNU_SOURCE -D_POSIX_C_SOURCE=200112L) +ADD_DEFINITIONS(-DCONFIG_FIND_LOCAL_INTERFACES) + +IF(CFG_STORE_RESTORE) + ADD_DEFINITIONS(-DCONFIG_INCLUDE_STORE_RESTORE) +ENDIF() + +# Additional include directories +INCLUDE_DIRECTORIES( + . + ) + +# Define library and installation rules +ADD_LIBRARY(${LIB_NAME} ${LIB_TYPE} ${LIB_SOURCES}) +TARGET_LINK_LIBRARIES(${LIB_NAME} ${ARCH_LIBRARIES}) +SET_PROPERTY(TARGET ${LIB_NAME} PROPERTY COMPILE_DEFINITIONS_DEBUG DEBUG;DEF_DEBUG_LVL=${CFG_DEBUG_LVL}) +SET_PROPERTY(TARGET ${LIB_NAME} PROPERTY DEBUG_POSTFIX "_d") +INSTALL(TARGETS ${LIB_NAME} ARCHIVE DESTINATION . LIBRARY DESTINATION .) diff --git a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/proj/xiuos/liboplkcn/oplkcfg.h b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/proj/xiuos/liboplkcn/oplkcfg.h new file mode 100644 index 000000000..297c77429 --- /dev/null +++ b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/proj/xiuos/liboplkcn/oplkcfg.h @@ -0,0 +1,134 @@ +/** +******************************************************************************** +\file oplkcfg.h + +\brief Configuration options for openPOWERLINK CN library + +This file contains the configuration options for the openPOWERLINK CN libary +on Linux. + +*******************************************************************************/ + +/*------------------------------------------------------------------------------ +Copyright (c) 2012, SYSTEC electronik GmbH +Copyright (c) 2018, B&R Industrial Automation GmbH +Copyright (c) 2017, Kalycito Infotech Private Limited. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +------------------------------------------------------------------------------*/ + +#ifndef _INC_oplkcfg_H_ +#define _INC_oplkcfg_H_ + +//============================================================================== +// generic defines which for whole openPOWERLINK stack +//============================================================================== + +#ifndef BENCHMARK_MODULES +#define BENCHMARK_MODULES 0 //0xEE800042L +#endif + +// Default debug level: +// Only debug traces of these modules will be compiled which flags are set in define DEF_DEBUG_LVL. +#ifndef DEF_DEBUG_LVL +#define DEF_DEBUG_LVL 0xC0000000L +#endif + +#undef FTRACE_DEBUG + +/* assure that system priorities of hrtimer and net-rx kernel threads are set appropriate */ +#define CONFIG_THREAD_PRIORITY_HIGH 75 +#define CONFIG_THREAD_PRIORITY_MEDIUM 50 +#define CONFIG_THREAD_PRIORITY_LOW 49 + +// These macros define all modules which are included +#define CONFIG_INCLUDE_PDO +#define CONFIG_INCLUDE_SDOS +#define CONFIG_INCLUDE_SDOC +#define CONFIG_INCLUDE_SDO_ASND + +#define CONFIG_DLLCAL_QUEUE CIRCBUF_QUEUE + +#define CONFIG_VETH_SET_DEFAULT_GATEWAY FALSE + +#define CONFIG_CHECK_HEARTBEAT_PERIOD 1000 // 1000 ms + +//============================================================================== +// Ethernet driver (Edrv) specific defines +//============================================================================== + +// switch this define to TRUE if Edrv supports auto delay responses +#define CONFIG_EDRV_AUTO_RESPONSE_DELAY FALSE + +// switch this define to TRUE to include Edrv diagnostic functions +#define CONFIG_EDRV_USE_DIAGNOSTICS FALSE + +//============================================================================== +// Data Link Layer (DLL) specific defines +//============================================================================== + +// CN supports PRes Chaining +#define CONFIG_DLL_PRES_CHAINING_CN FALSE + +// negative time shift of isochronous task in relation to SoC +#define CONFIG_DLL_SOC_SYNC_SHIFT_US 150 + +// time when CN processing the isochronous task (sync callback of application and cycle preparation) +#define CONFIG_DLL_PROCESS_SYNC DLL_PROCESS_SYNC_ON_SOC + +// Disable deferred release of rx-buffers until EdrvPcap supports it +#define CONFIG_DLL_DEFERRED_RXFRAME_RELEASE_SYNC FALSE +#define CONFIG_DLL_DEFERRED_RXFRAME_RELEASE_ASYNC FALSE + +//============================================================================== +// OBD specific defines +//============================================================================== + +// Switch this define to TRUE if the stack should check the object ranges +#define CONFIG_OBD_CHECK_OBJECT_RANGE TRUE + +// set this define to TRUE if there are strings or domains in OD, which +// may be changed in object size and/or object data pointer by its object +// callback function (called event kObdEvWrStringDomain) +#define CONFIG_OBD_USE_STRING_DOMAIN_IN_RAM TRUE + +// Set this string to true if OD configuration save and load feature is +// supported by the device +#ifdef CONFIG_INCLUDE_STORE_RESTORE +#define CONFIG_OBD_USE_STORE_RESTORE TRUE +#define CONFIG_OBD_CALC_OD_SIGNATURE TRUE +#endif + +//============================================================================== +// Timer module specific defines +//============================================================================== + +// if TRUE the high resolution timer module will be used (must always be TRUE!) +#define CONFIG_TIMER_USE_HIGHRES TRUE + +//============================================================================== +// SDO module specific defines +//============================================================================== + +#endif // _INC_oplkcfg_H_ diff --git a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/proj/xiuos/liboplkmn/CMakeLists.txt b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/proj/xiuos/liboplkmn/CMakeLists.txt new file mode 100644 index 000000000..7a513cedb --- /dev/null +++ b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/proj/xiuos/liboplkmn/CMakeLists.txt @@ -0,0 +1,95 @@ +################################################################################ +# +# CMake file for openPOWERLINK MN library +# +# Copyright (c) 2017, B&R Industrial Automation GmbH +# Copyright (c) 2020, AIIT XUOS Lab +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the copyright holders nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +################################################################################ + +# Set library name +SET(LIB_NAME "oplkmn") +MESSAGE(STATUS "Configuring ${LIB_NAME}") + +# Set type of library +IF(CFG_COMPILE_SHARED_LIBRARY) + SET(LIB_TYPE "SHARED") +ELSE() + SET(LIB_TYPE "STATIC") +ENDIF() + +# set general sources of POWERLINK library +SET (LIB_SOURCES + ${USER_SOURCES} + ${USER_MN_SOURCES} + ${CTRL_UCAL_DIRECT_SOURCES} + ${DLL_UCAL_CIRCBUF_SOURCES} + ${ERRHND_UCAL_LOCAL_SOURCES} + ${EVENT_UCAL_XIUOS_SOURCES} + ${PDO_UCAL_LOCAL_SOURCES} + ${USER_TIMER_XIUOS_SOURCES} + ${KERNEL_SOURCES} + ${CTRL_KCAL_DIRECT_SOURCES} + ${DLL_KCAL_CIRCBUF_SOURCES} + ${ERRHND_KCAL_LOCAL_SOURCES} + ${EVENT_KCAL_XIUOS_SOURCES} + ${PDO_KCAL_LOCAL_SOURCES} + ${COMMON_SOURCES} + ${COMMON_LINUXUSER_SOURCES} + ${TARGET_XIUOS_SOURCES} + ${CIRCBUF_NOOS_SOURCES} + ${MEMMAP_NULL_SOURCES} + ${HARDWARE_DRIVER_XIUOS_SOURCES} + ) + +# Configure compile definitions +IF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(i.86|x86(_64)?)$") + SET(LIB_SOURCES ${LIB_SOURCES} ${ARCH_X86_SOURCES}) +ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES arm*) + SET(LIB_SOURCES ${LIB_SOURCES} ${ARCH_LE_SOURCES}) +ELSE() + MESSAGE(FATAL_ERROR "Unsupported CMAKE_SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR}") +ENDIF() + +# Configure compile definitions +IF(CFG_INCLUDE_MN_REDUNDANCY) + ADD_DEFINITIONS(-DCONFIG_INCLUDE_NMT_RMN) +ENDIF() +ADD_DEFINITIONS(-D__XIUOS__) +ADD_DEFINITIONS(-DCONFIG_FIND_LOCAL_INTERFACES) +ADD_DEFINITIONS(-DCONFIG_MN -D_GNU_SOURCE -D_POSIX_C_SOURCE=200112L) +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -pedantic -std=c99 -fno-strict-aliasing") + +# Additional include directories +INCLUDE_DIRECTORIES( + . + ) + +# Define library and installation rules +ADD_LIBRARY(${LIB_NAME} ${LIB_TYPE} ${LIB_SOURCES}) +TARGET_LINK_LIBRARIES(${LIB_NAME} ${ARCH_LIBRARIES}) +SET_PROPERTY(TARGET ${LIB_NAME} PROPERTY COMPILE_DEFINITIONS_DEBUG DEBUG;DEF_DEBUG_LVL=${CFG_DEBUG_LVL}) +SET_PROPERTY(TARGET ${LIB_NAME} PROPERTY DEBUG_POSTFIX "_d") +INSTALL(TARGETS ${LIB_NAME} ARCHIVE DESTINATION . LIBRARY DESTINATION .) diff --git a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/proj/xiuos/liboplkmn/oplkcfg.h b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/proj/xiuos/liboplkmn/oplkcfg.h new file mode 100644 index 000000000..70f458a3e --- /dev/null +++ b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/proj/xiuos/liboplkmn/oplkcfg.h @@ -0,0 +1,141 @@ +/** +******************************************************************************** +\file oplkcfg.h + +\brief Configuration options for openPOWERLINK MN library + +This file contains the configuration options for the openPOWERLINK MN libary +on Linux. + +*******************************************************************************/ + +/*------------------------------------------------------------------------------ +Copyright (c) 2012, SYSTEC electronik GmbH +Copyright (c) 2018, B&R Industrial Automation GmbH +Copyright (c) 2017, Kalycito Infotech Private Limited. +Copyright (c) 2020, AIIT XUOS Lab +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +------------------------------------------------------------------------------*/ + +#ifndef _INC_oplkcfg_H_ +#define _INC_oplkcfg_H_ + +//============================================================================== +// generic defines which for whole openPOWERLINK stack +//============================================================================== + +#ifndef BENCHMARK_MODULES +#define BENCHMARK_MODULES 0 //0xEE800042L +#endif + +// Default debug level: +// Only debug traces of these modules will be compiled which flags are set in define DEF_DEBUG_LVL. +#ifndef DEF_DEBUG_LVL +#define DEF_DEBUG_LVL 0xC0000000L +#endif + +#undef FTRACE_DEBUG + +/* assure that system priorities of hrtimer and net-rx kernel threads are set appropriate */ +#define CONFIG_THREAD_PRIORITY_HIGH 75 +#define CONFIG_THREAD_PRIORITY_MEDIUM 50 +#define CONFIG_THREAD_PRIORITY_LOW 49 + +// These macros define all modules which are included +#define CONFIG_INCLUDE_NMT_MN +#define CONFIG_INCLUDE_PDO +#define CONFIG_INCLUDE_SDOS +#define CONFIG_INCLUDE_SDOC +#define CONFIG_INCLUDE_SDO_ASND + +#define CONFIG_DLLCAL_QUEUE CIRCBUF_QUEUE + +#define CONFIG_VETH_SET_DEFAULT_GATEWAY FALSE + +#define CONFIG_CHECK_HEARTBEAT_PERIOD 1000 // 1000 ms + +//============================================================================== +// Ethernet driver (Edrv) specific defines +//============================================================================== + +// switch this define to TRUE if Edrv supports auto delay responses +#define CONFIG_EDRV_AUTO_RESPONSE_DELAY FALSE + +// switch this define to TRUE to include Edrv diagnostic functions +#define CONFIG_EDRV_USE_DIAGNOSTICS FALSE + +//============================================================================== +// Data Link Layer (DLL) specific defines +//============================================================================== + +// CN supports PRes Chaining +#define CONFIG_DLL_PRES_CHAINING_CN FALSE + +// time when CN processing the isochronous task (sync callback of application and cycle preparation) +#define CONFIG_DLL_PROCESS_SYNC DLL_PROCESS_SYNC_ON_SOC + +// Disable deferred release of rx-buffers until EdrvPcap supports it +#define CONFIG_DLL_DEFERRED_RXFRAME_RELEASE_SYNC FALSE +#define CONFIG_DLL_DEFERRED_RXFRAME_RELEASE_ASYNC FALSE + +//============================================================================== +// OBD specific defines +//============================================================================== + +// Switch this define to TRUE if the stack should check the object ranges +#define CONFIG_OBD_CHECK_OBJECT_RANGE TRUE + +// set this define to TRUE if there are strings or domains in OD, which +// may be changed in object size and/or object data pointer by its object +// callback function (called event kObdEvWrStringDomain) +#define CONFIG_OBD_USE_STRING_DOMAIN_IN_RAM TRUE + +#if defined(CONFIG_INCLUDE_CFM) +#define CONFIG_OBD_DEF_CONCISEDCF_FILENAME "mnobd.cdc" +#define CONFIG_CFM_CONFIGURE_CYCLE_LENGTH TRUE +#endif + +// Configure if the range from 0xA000 is used for mapping client objects. +// openCONFIGURATOR uses this range for mapping objects. +#define CONFIG_OBD_INCLUDE_A000_TO_DEVICE_PART TRUE + +//============================================================================== +// Timer module specific defines +//============================================================================== + +// if TRUE the high resolution timer module will be used (must always be TRUE!) +#define CONFIG_TIMER_USE_HIGHRES TRUE + +//============================================================================== +// SDO module specific defines +//============================================================================== + +// increase the number of SDO channels, because we are master +#define CONFIG_SDO_MAX_CONNECTION_ASND 100 +#define CONFIG_SDO_MAX_CONNECTION_SEQ 100 +#define CONFIG_SDO_MAX_CONNECTION_COM 100 +#define CONFIG_SDO_MAX_CONNECTION_UDP 50 + +#endif // _INC_oplkcfg_H_ diff --git a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/arch/xiuos/netif-xiuos.c b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/arch/xiuos/netif-xiuos.c new file mode 100644 index 000000000..bab688641 --- /dev/null +++ b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/arch/xiuos/netif-xiuos.c @@ -0,0 +1,122 @@ +/** +******************************************************************************** +\file netif-linux.c + +\brief Implementation of network interface enumeration functions for Linux + +This file contains the implementation of helper functions for enumerating the +network interfaces in Linux. + +\ingroup module_target +*******************************************************************************/ + +/*------------------------------------------------------------------------------ +Copyright (c) 2017, B&R Industrial Automation GmbH +Copyright (c) 2020, AIIT XUOS Lab +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +------------------------------------------------------------------------------*/ + +//------------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------------ +#include +#include + +#include +#include + +//============================================================================// +// G L O B A L D E F I N I T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +// const defines +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// module global vars +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// global function prototypes +//------------------------------------------------------------------------------ + + +//============================================================================// +// P R I V A T E D E F I N I T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +// const defines +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// local types +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// local vars +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// local function prototypes +//------------------------------------------------------------------------------ + +//============================================================================// +// P U B L I C F U N C T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +/** +\brief Enumerate network interfaces + +This function enumerates all available network interfaces to be used by +openPOWERLINK. + +\param[out] pInterfaces_p Pointer to store the list of + found interfaces. +\param[in,out] pNoInterfaces_p Pointer to the number of interfaces. + The maximum number of interfaces to be + stored is passed to the function. + The number of interfaces found is returned. + +\return The function returns a \ref tOplkError error code. +*/ +//------------------------------------------------------------------------------ +tOplkError target_enumerateNetworkInterfaces(tNetIfId* pInterfaces_p, + size_t* pNoInterfaces_p) +{ + UNUSED_PARAMETER(pInterfaces_p); + UNUSED_PARAMETER(pNoInterfaces_p); + return kErrorApiNotSupported; +} + +//============================================================================// +// P R I V A T E F U N C T I O N S // +//============================================================================// +/// \name Private Functions +/// \{ + +/// \} diff --git a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/arch/xiuos/target-mutex.c b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/arch/xiuos/target-mutex.c new file mode 100644 index 000000000..dd4698d90 --- /dev/null +++ b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/arch/xiuos/target-mutex.c @@ -0,0 +1,196 @@ +/** +******************************************************************************** +\file linux/target-mutex.c + +\brief Architecture specific mutex implementation + +This file contains the mutex implementation for Linux userspace. It uses +BSD semaphores for the implementation and can therefore synchronize different +threads or processes. + +\ingroup module_target +*******************************************************************************/ + +/*------------------------------------------------------------------------------ +Copyright (c) 2016, B&R Industrial Automation GmbH +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +------------------------------------------------------------------------------*/ + +//------------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------------ +#include +#include + +#include /* For O_* constants */ +#include /* For mode constants */ +#include + +//============================================================================// +// G L O B A L D E F I N I T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +// const defines +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// module global vars +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// global function prototypes +//------------------------------------------------------------------------------ + +//============================================================================// +// P R I V A T E D E F I N I T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +// const defines +//------------------------------------------------------------------------------ +#define SEM_SHARED 0 // Mutex shared between threads of a process +#define SEM_VALUE 1 +//------------------------------------------------------------------------------ +// local types +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// local vars +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// local function prototypes +//------------------------------------------------------------------------------ + +//============================================================================// +// P U B L I C F U N C T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +/** +\brief Create Mutex + +The function creates a mutex. + +\param[in] mutexName_p The name of the mutex to create. +\param[out] pMutex_p Pointer to store the created mutex. + +\return The function returns a tOplkError error code. +\retval kErrorOk Mutex was successfully created. +\retval kErrorNoFreeInstance An error occurred while creating the mutex. + +\ingroup module_target +*/ +//------------------------------------------------------------------------------ +tOplkError target_createMutex(const char* mutexName_p, + OPLK_MUTEX_T* pMutex_p) +{ + sem_t* pLockSem; + + // WARNING: target_createMutex() will create a new independent mutex on each + // call, even if the very same name is specified. + UNUSED_PARAMETER(mutexName_p); + + pLockSem = malloc(sizeof(sem_t)); + if (pLockSem != NULL) + { + if (sem_init(pLockSem, SEM_SHARED, SEM_VALUE) == 0) + { + *pMutex_p = pLockSem; + return kErrorOk; + } + free(pLockSem); + } + return kErrorNoFreeInstance; +} + +//------------------------------------------------------------------------------ +/** +\brief Destroy Mutex + +The function destroys a mutex. + +\param[in] mutexId_p The ID of the mutex to destroy. + +\ingroup module_target +*/ +//------------------------------------------------------------------------------ +void target_destroyMutex(OPLK_MUTEX_T mutexId_p) +{ + sem_t* pLockSem = (sem_t*)mutexId_p; + if (pLockSem != NULL) + { + sem_destroy(pLockSem); + free(mutexId_p); + } +} + +//------------------------------------------------------------------------------ +/** +\brief Lock Mutex + +The function locks a mutex. + +\param[in] mutexId_p The ID of the mutex to lock. + +\return The function returns a tOplkError error code. +\retval kErrorOk Mutex was successfully locked. +\retval kErrorNoFreeInstance An error occurred while locking the mutex. + +\ingroup module_target +*/ +//------------------------------------------------------------------------------ +tOplkError target_lockMutex(OPLK_MUTEX_T mutexId_p) +{ + if (sem_wait(mutexId_p) < 0) + return kErrorIllegalInstance; + + return kErrorOk; +} + +//------------------------------------------------------------------------------ +/** +\brief Unlock Mutex + +The function unlocks a mutex. + +\param[in] mutexId_p The ID of the mutex to unlock. + +\ingroup module_target +*/ +//------------------------------------------------------------------------------ +void target_unlockMutex(OPLK_MUTEX_T mutexId_p) +{ + sem_post(mutexId_p); +} + +//============================================================================// +// P R I V A T E F U N C T I O N S // +//============================================================================// +/// \name Private Functions +/// \{ + +/// \} diff --git a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/arch/xiuos/target-xiuos.c b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/arch/xiuos/target-xiuos.c new file mode 100644 index 000000000..e7f2a9c69 --- /dev/null +++ b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/arch/xiuos/target-xiuos.c @@ -0,0 +1,381 @@ +/** +******************************************************************************** +\file linux/target-linux.c + +\brief Target specific functions for Linux + +The file implements target specific functions used in the openPOWERLINK stack. + +\ingroup module_target +*******************************************************************************/ + +/*------------------------------------------------------------------------------ +Copyright (c) 2016, B&R Industrial Automation GmbH +Copyright (c) 2018, Kalycito Infotech Private Limited +Copyright (c) 2020, AIIT XUOS Lab +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +------------------------------------------------------------------------------*/ + +//------------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------------ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +//============================================================================// +// G L O B A L D E F I N I T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +// const defines +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// module global vars +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// global function prototypes +//------------------------------------------------------------------------------ + +//============================================================================// +// P R I V A T E D E F I N I T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +// const defines +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// local types +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// local vars +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// local function prototypes +//------------------------------------------------------------------------------ + +//============================================================================// +// P U B L I C F U N C T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +/** +\brief Initialize target specific stuff + +The function initialize target specific stuff which is needed to run the +openPOWERLINK stack. + +\return The function returns a tOplkError error code. +*/ +//------------------------------------------------------------------------------ +tOplkError target_init(void) +{ + return kErrorOk; +} + +//------------------------------------------------------------------------------ +/** +\brief Clean up target specific stuff + +The function cleans up target specific stuff. + +\return The function returns a tOplkError error code. +*/ +//------------------------------------------------------------------------------ +tOplkError target_cleanup(void) +{ + return kErrorOk; +} + +//------------------------------------------------------------------------------ +/** +\brief Sleep for the specified number of milliseconds + +The function makes the calling thread sleep until the number of specified +milliseconds has elapsed. + +\param[in] milliSeconds_p Number of milliseconds to sleep + +\ingroup module_target +*/ +//------------------------------------------------------------------------------ +void target_msleep(UINT32 milliSeconds_p) +{ + struct timeval timeout; + fd_set readFds; + int maxFd; + int selectRetVal; + unsigned int seconds; + unsigned int microSeconds; + + // initialize file descriptor set + maxFd = 0 + 1; + FD_ZERO(&readFds); + + // Calculate timeout values + seconds = milliSeconds_p / 1000; + microSeconds = (milliSeconds_p - (seconds * 1000)) * 1000; + + // initialize timeout value + timeout.tv_sec = seconds; + timeout.tv_usec = microSeconds; + + selectRetVal = select(maxFd, &readFds, NULL, NULL, &timeout); + switch (selectRetVal) + { + case 0: // select timeout occurred, no packet received + break; + + case -1: // select error occurred + break; + + default: // packet available for receive + break; + } +} + +//------------------------------------------------------------------------------ +/** +\brief Set IP address of specified Ethernet interface + +The function sets the IP address, subnetMask and MTU of an Ethernet +interface. + +\param[in] ifName_p Name of Ethernet interface. +\param[in] ipAddress_p IP address to set for interface. +\param[in] subnetMask_p Subnet mask to set for interface. +\param[in] mtu_p MTU to set for interface. + +\return The function returns a tOplkError error code. + +\ingroup module_target +*/ +//------------------------------------------------------------------------------ +tOplkError target_setIpAdrs(const char* ifName_p, + UINT32 ipAddress_p, + UINT32 subnetMask_p, + UINT16 mtu_p) +{ + UNUSED_PARAMETER(ifName_p); + UNUSED_PARAMETER(ipAddress_p); + UNUSED_PARAMETER(subnetMask_p); + UNUSED_PARAMETER(mtu_p); + return kErrorApiNotSupported; +} + +//------------------------------------------------------------------------------ +/** +\brief Set default gateway for Ethernet interface + +The function sets the default gateway of an Ethernet interface. + +\param[in] defaultGateway_p Default gateway to set. + +\return The function returns a tOplkError error code. + +\ingroup module_target +*/ +//------------------------------------------------------------------------------ +tOplkError target_setDefaultGateway(UINT32 defaultGateway_p) +{ + UNUSED_PARAMETER(defaultGateway_p); + return kErrorApiNotSupported; +} + +//------------------------------------------------------------------------------ +/** +\brief Enables global interrupt + +This function enables/disables global interrupts. + +\param[in] fEnable_p TRUE = enable interrupts + FALSE = disable interrupts + +\note This function is implemented empty for the sim target +\ingroup module_target +*/ +//------------------------------------------------------------------------------ +void target_enableGlobalInterrupt(BOOL fEnable_p) +{ + UNUSED_PARAMETER(fEnable_p); +} + + +//------------------------------------------------------------------------------ +/** +\brief Set interrupt context flag + +This function enables/disables the interrupt context flag. The flag has to be +set when the CPU enters the interrupt context. The flag has to be cleared when +the interrupt context is left. + +\param[in] fEnable_p TRUE = enable interrupt context flag + FALSE = disable interrupt context flag + +\ingroup module_target +*/ +//------------------------------------------------------------------------------ +void target_setInterruptContextFlag(BOOL fEnable_p) +{ + UNUSED_PARAMETER(fEnable_p); +} + +//------------------------------------------------------------------------------ +/** +\brief Get interrupt context flag + +This function returns the interrupt context flag. + +\return The function returns the state of the interrupt context flag. + +\ingroup module_target +*/ +//------------------------------------------------------------------------------ +BOOL target_getInterruptContextFlag(void) +{ + return FALSE; +} + +//------------------------------------------------------------------------------ +/** +\brief Get current system tick + +This function returns the current system tick determined by the system timer. + +\return Returns the system tick in milliseconds + +\ingroup module_target +*/ +//------------------------------------------------------------------------------ +UINT32 target_getTickCount(void) +{ + return PrivGetTickTime(); +} + +//------------------------------------------------------------------------------ +/** +\brief Get current timestamp + +The function returns the current timestamp in nanoseconds. + +\return The function returns the timestamp in nanoseconds +*/ +//------------------------------------------------------------------------------ +ULONGLONG target_getCurrentTimestamp(void) +{ + // Not implemented for this target + return 0ULL; +} + +//------------------------------------------------------------------------------ +/** +\brief Set POWERLINK status/error LED + +The function sets the POWERLINK status/error LED. + +\param[in] ledType_p Determines which LED shall be set/reset. +\param[in] fLedOn_p Set the addressed LED on (TRUE) or off (FALSE). + +\return The function returns a tOplkError error code. + +\ingroup module_target +*/ +//------------------------------------------------------------------------------ +tOplkError target_setLed(tLedType ledType_p, BOOL fLedOn_p) +{ + UNUSED_PARAMETER(ledType_p); + UNUSED_PARAMETER(fLedOn_p); + + return kErrorOk; +} + +#if (defined(CONFIG_INCLUDE_SOC_TIME_FORWARD) && defined(CONFIG_INCLUDE_NMT_MN)) +//------------------------------------------------------------------------------ +/** +\brief Get system time + +The function returns the current system timestamp. + +\param[out] pNetTime_p Pointer to current system timestamp. +\param[out] pValidSystemTime_p Pointer to flag which is set to indicate the + system time is valid or not. + +\return The function returns a tOplkError code. + +\ingroup module_target +*/ +//------------------------------------------------------------------------------ +tOplkError target_getSystemTime(tNetTime* pNetTime_p, BOOL* pValidSystemTime_p) +{ + struct timespec currentTime; + + if ((pNetTime_p == NULL) || (pValidSystemTime_p == NULL)) + return kErrorNoResource; + + // Note: clock_gettime() returns 0 for success + if (clock_gettime(CLOCK_REALTIME, ¤tTime) != 0) + { + *pValidSystemTime_p = FALSE; + return kErrorGeneralError; + } + + if (currentTime.tv_sec < 0) + { + *pValidSystemTime_p = FALSE; + DEBUG_LVL_ERROR_TRACE("%s(): Failed! Invalid time stamp.\n", + __func__); + return kErrorInvalidOperation; + } + + pNetTime_p->sec = currentTime.tv_sec; + pNetTime_p->nsec = currentTime.tv_nsec; + + // Set the flag to indicate the system time is valid + *pValidSystemTime_p = TRUE; + + return kErrorOk; +} +#endif + +//============================================================================// +// P R I V A T E F U N C T I O N S // +//============================================================================// +/// \name Private Functions +/// \{ + +/// \} diff --git a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/kernel/edrv/edrv-xiuos.c b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/kernel/edrv/edrv-xiuos.c new file mode 100644 index 000000000..748a21407 --- /dev/null +++ b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/kernel/edrv/edrv-xiuos.c @@ -0,0 +1,634 @@ +/** +******************************************************************************** +\file edrv-xiuos.c + +\brief Implementation of XiUOS Ethernet driver + +This file contains the implementation of the XiUOS Ethernet driver. + +\ingroup module_edrv +*******************************************************************************/ + +/*------------------------------------------------------------------------------ +Copyright (c) 2017, BE.services GmbH +Copyright (c) 2017, B&R Industrial Automation GmbH +Copyright (c) 2020, AIIT XUOS Lab +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +------------------------------------------------------------------------------*/ + +//------------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------------ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +//============================================================================// +// G L O B A L D E F I N I T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +// const defines +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// module global vars +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// global function prototypes +//------------------------------------------------------------------------------ + +//============================================================================// +// P R I V A T E D E F I N I T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +// const defines +//------------------------------------------------------------------------------ +#define EDRV_MAX_FRAME_SIZE 0x0600 +#define PROTO_PLK 0x88AB +#ifndef PACKET_QDISC_BYPASS +#define PACKET_QDISC_BYPASS 20 +#endif +//------------------------------------------------------------------------------ +// local types +//------------------------------------------------------------------------------ +/** +\brief Structure describing an instance of the Edrv + +This structure describes an instance of the Ethernet driver. +*/ +typedef struct +{ + tEdrvInitParam initParam; ///< Init parameters + tEdrvTxBuffer* pTransmittedTxBufferLastEntry; ///< Pointer to the last entry of the transmitted TX buffer + tEdrvTxBuffer* pTransmittedTxBufferFirstEntry; ///< Pointer to the first entry of the transmitted Tx buffer + pthread_mutex_t mutex; ///< Mutex for locking of critical sections + sem_t syncSem; ///< Semaphore for signaling the start of the worker thread + int sock; ///< Raw socket handle + pthread_t hThread; ///< Handle of the worker thread + BOOL fStartCommunication; ///< Flag to indicate, that communication is started. Set to false on exit + BOOL fThreadIsExited; ///< Set by thread if already exited +} tEdrvInstance; + +//------------------------------------------------------------------------------ +// local vars +//------------------------------------------------------------------------------ +static tEdrvInstance edrvInstance_l; + +//------------------------------------------------------------------------------ +// local function prototypes +//------------------------------------------------------------------------------ +static void packetHandler(void* pParam_p, + const int frameSize_p, + void* pPktData_p); +static void* workerThread(void* pArgument_p); +static void getMacAdrs(const char* pIfName_p, UINT8* pMacAddr_p); +static BOOL getLinkStatus(const char* pIfName_p); + +//------------------------------------------------------------------------------ +// XiUOS implementaion of raw socket +//------------------------------------------------------------------------------ + +//============================================================================// +// P U B L I C F U N C T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +/** +\brief Ethernet driver initialization + +This function initializes the Ethernet driver. + +\param[in] pEdrvInitParam_p Edrv initialization parameters + +\return The function returns a tOplkError error code. + +\ingroup module_edrv +*/ +//------------------------------------------------------------------------------ +tOplkError edrv_init(const tEdrvInitParam* pEdrvInitParam_p) +{ + struct sched_param schedParam; + + // Check parameter validity + ASSERT(pEdrvInitParam_p != NULL); + + // Clear instance structure + OPLK_MEMSET(&edrvInstance_l, 0, sizeof(edrvInstance_l)); + + if (pEdrvInitParam_p->pDevName == NULL) + return kErrorEdrvInit; + + // Save the init data + edrvInstance_l.initParam = *pEdrvInitParam_p; + + edrvInstance_l.fStartCommunication = TRUE; + edrvInstance_l.fThreadIsExited = FALSE; + + // If no MAC address was specified read MAC address of used + // Ethernet interface + if ((edrvInstance_l.initParam.aMacAddr[0] == 0) && + (edrvInstance_l.initParam.aMacAddr[1] == 0) && + (edrvInstance_l.initParam.aMacAddr[2] == 0) && + (edrvInstance_l.initParam.aMacAddr[3] == 0) && + (edrvInstance_l.initParam.aMacAddr[4] == 0) && + (edrvInstance_l.initParam.aMacAddr[5] == 0)) + { // read MAC address from controller + getMacAdrs(edrvInstance_l.initParam.pDevName, + edrvInstance_l.initParam.aMacAddr); + } + if (pthread_mutex_init(&edrvInstance_l.mutex, NULL) != 0) + { + DEBUG_LVL_ERROR_TRACE("%s() couldn't init mutex\n", __func__); + return kErrorEdrvInit; + } + + edrvInstance_l.sock = open(ETHERNET_UART_NAME, O_RDWR); + if (edrvInstance_l.sock < 0) + { + DEBUG_LVL_ERROR_TRACE("%s() cannot open socket. Error = %s\n", __func__, strerror(errno)); + return kErrorEdrvInit; + } + + if (sem_init(&edrvInstance_l.syncSem, 0, 0) != 0) + { + DEBUG_LVL_ERROR_TRACE("%s() couldn't init semaphore\n", __func__); + return kErrorEdrvInit; + } + + if (pthread_create(&edrvInstance_l.hThread, NULL, + workerThread, &edrvInstance_l) != 0) + { + DEBUG_LVL_ERROR_TRACE("%s() Couldn't create worker thread!\n", __func__); + return kErrorEdrvInit; + } + + schedParam.sched_priority = CONFIG_THREAD_PRIORITY_MEDIUM; + if (pthread_setschedparam(edrvInstance_l.hThread, SCHED_FIFO, &schedParam) != 0) + { + DEBUG_LVL_ERROR_TRACE("%s() couldn't set thread scheduling parameters!\n", __func__); + } + +#if (defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 12)) + pthread_setname_np(edrvInstance_l.hThread, "oplk-edrvrawsock"); +#endif + + // wait until thread is started + sem_wait(&edrvInstance_l.syncSem); + + return kErrorOk; +} + +//------------------------------------------------------------------------------ +/** +\brief Shut down Ethernet driver + +This function shuts down the Ethernet driver. + +\return The function returns a tOplkError error code. + +\ingroup module_edrv +*/ +//------------------------------------------------------------------------------ +tOplkError edrv_exit(void) +{ + edrvInstance_l.fStartCommunication = FALSE; + + // Wait to terminate thread safely + usleep(100000); + + if (edrvInstance_l.fThreadIsExited) + pthread_cancel(edrvInstance_l.hThread); + + pthread_mutex_destroy(&edrvInstance_l.mutex); + + // Close the socket + close(edrvInstance_l.sock); + + // Clear instance structure + OPLK_MEMSET(&edrvInstance_l, 0, sizeof(edrvInstance_l)); + + return kErrorOk; +} + +//------------------------------------------------------------------------------ +/** +\brief Get MAC address + +This function returns the MAC address of the Ethernet controller + +\return The function returns a pointer to the MAC address. + +\ingroup module_edrv +*/ +//------------------------------------------------------------------------------ +const UINT8* edrv_getMacAddr(void) +{ + return edrvInstance_l.initParam.aMacAddr; +} + +//------------------------------------------------------------------------------ +/** +\brief Send Tx buffer + +This function sends the Tx buffer. + +\param[in,out] pBuffer_p Tx buffer descriptor + +\return The function returns a tOplkError error code. + +\ingroup module_edrv +*/ +//------------------------------------------------------------------------------ +tOplkError edrv_sendTxBuffer(tEdrvTxBuffer* pBuffer_p) +{ + int sockRet; + + // Check parameter validity + ASSERT(pBuffer_p != NULL); + + FTRACE_MARKER("%s", __func__); + + if (pBuffer_p->txBufferNumber.pArg != NULL) + return kErrorInvalidOperation; + + if (getLinkStatus(edrvInstance_l.initParam.pDevName) == FALSE) + { + /* If there is no link, we pretend that the packet is sent and immediately call + * tx handler. Otherwise the stack would hang! */ + if (pBuffer_p->pfnTxHandler != NULL) + { + pBuffer_p->pfnTxHandler(pBuffer_p); + } + } + else + { + pthread_mutex_lock(&edrvInstance_l.mutex); + if (edrvInstance_l.pTransmittedTxBufferLastEntry == NULL) + { + edrvInstance_l.pTransmittedTxBufferLastEntry = pBuffer_p; + edrvInstance_l.pTransmittedTxBufferFirstEntry = pBuffer_p; + } + else + { + edrvInstance_l.pTransmittedTxBufferLastEntry->txBufferNumber.pArg = pBuffer_p; + edrvInstance_l.pTransmittedTxBufferLastEntry = pBuffer_p; + } + pthread_mutex_unlock(&edrvInstance_l.mutex); + + sockRet = write(edrvInstance_l.sock, (u_char*)pBuffer_p->pBuffer, (int)pBuffer_p->txFrameSize); + if (sockRet < 0) + { + DEBUG_LVL_EDRV_TRACE("%s() send() returned %d\n", __func__, sockRet); + return kErrorInvalidOperation; + } + else + { + packetHandler((u_char*)&edrvInstance_l, sockRet, pBuffer_p->pBuffer); + } + } + + return kErrorOk; +} + +//------------------------------------------------------------------------------ +/** +\brief Allocate Tx buffer + +This function allocates a Tx buffer. + +\param[in,out] pBuffer_p Tx buffer descriptor + +\return The function returns a tOplkError error code. + +\ingroup module_edrv +*/ +//------------------------------------------------------------------------------ +tOplkError edrv_allocTxBuffer(tEdrvTxBuffer* pBuffer_p) +{ + // Check parameter validity + ASSERT(pBuffer_p != NULL); + + if (pBuffer_p->maxBufferSize > EDRV_MAX_FRAME_SIZE) + return kErrorEdrvNoFreeBufEntry; + + // allocate buffer with malloc + pBuffer_p->pBuffer = OPLK_MALLOC(pBuffer_p->maxBufferSize); + if (pBuffer_p->pBuffer == NULL) + return kErrorEdrvNoFreeBufEntry; + + pBuffer_p->txBufferNumber.pArg = NULL; + + return kErrorOk; +} + +//------------------------------------------------------------------------------ +/** +\brief Free Tx buffer + +This function releases the Tx buffer. + +\param[in,out] pBuffer_p Tx buffer descriptor + +\return The function returns a tOplkError error code. + +\ingroup module_edrv +*/ +//------------------------------------------------------------------------------ +tOplkError edrv_freeTxBuffer(tEdrvTxBuffer* pBuffer_p) +{ + void* pBuffer; + + // Check parameter validity + ASSERT(pBuffer_p != NULL); + + pBuffer = pBuffer_p->pBuffer; + + // mark buffer as free, before actually freeing it + pBuffer_p->pBuffer = NULL; + + OPLK_FREE(pBuffer); + + return kErrorOk; +} + +//------------------------------------------------------------------------------ +/** +\brief Change Rx filter setup + +This function changes the Rx filter setup. The parameter entryChanged_p +selects the Rx filter entry that shall be changed and \p changeFlags_p determines +the property. +If \p entryChanged_p is equal or larger count_p all Rx filters shall be changed. + +\note Rx filters are not supported by this driver! + +\param[in,out] pFilter_p Base pointer of Rx filter array +\param[in] count_p Number of Rx filter array entries +\param[in] entryChanged_p Index of Rx filter entry that shall be changed +\param[in] changeFlags_p Bit mask that selects the changing Rx filter property + +\return The function returns a tOplkError error code. + +\ingroup module_edrv +*/ +//------------------------------------------------------------------------------ +tOplkError edrv_changeRxFilter(tEdrvFilter* pFilter_p, + UINT count_p, + UINT entryChanged_p, + UINT changeFlags_p) +{ + UNUSED_PARAMETER(pFilter_p); + UNUSED_PARAMETER(count_p); + UNUSED_PARAMETER(entryChanged_p); + UNUSED_PARAMETER(changeFlags_p); + + return kErrorOk; +} + +//------------------------------------------------------------------------------ +/** +\brief Clear multicast address entry + +This function removes the multicast entry from the Ethernet controller. + +\note The multicast filters are not supported by this driver. + +\param[in] pMacAddr_p Multicast address + +\return The function returns a tOplkError error code. + +\ingroup module_edrv +*/ +//------------------------------------------------------------------------------ +tOplkError edrv_clearRxMulticastMacAddr(const UINT8* pMacAddr_p) +{ + UNUSED_PARAMETER(pMacAddr_p); + + return kErrorOk; +} + +//------------------------------------------------------------------------------ +/** +\brief Set multicast address entry + +This function sets a multicast entry into the Ethernet controller. + +\note The multicast filters are not supported by this driver. + +\param[in] pMacAddr_p Multicast address. + +\return The function returns a tOplkError error code. + +\ingroup module_edrv +*/ +//------------------------------------------------------------------------------ +tOplkError edrv_setRxMulticastMacAddr(const UINT8* pMacAddr_p) +{ + UNUSED_PARAMETER(pMacAddr_p); + + return kErrorOk; +} + +//============================================================================// +// P R I V A T E F U N C T I O N S // +//============================================================================// +/// \name Private Functions +/// \{ + +//------------------------------------------------------------------------------ +/** +\brief Edrv packet handler + +This function is the packet handler forwarding the frames to the dllk. + +\param[in,out] pParam_p User specific pointer pointing to the instance structure +\param[in] frameSize_p Framesize information +\param[in] pPktData_p Packet buffer +*/ +//------------------------------------------------------------------------------ +static void packetHandler(void* pParam_p, + const int frameSize_p, + void* pPktData_p) +{ + tEdrvInstance* pInstance = (tEdrvInstance*)pParam_p; + tEdrvRxBuffer rxBuffer; + + if (OPLK_MEMCMP((UINT8*)pPktData_p + 6, pInstance->initParam.aMacAddr, 6) != 0) + { // filter out self generated traffic + rxBuffer.bufferInFrame = kEdrvBufferLastInFrame; + rxBuffer.rxFrameSize = frameSize_p; + rxBuffer.pBuffer = pPktData_p; + + FTRACE_MARKER("%s RX", __func__); + pInstance->initParam.pfnRxHandler(&rxBuffer); + } + else + { // self generated traffic + FTRACE_MARKER("%s TX-receive", __func__); + + if (pInstance->pTransmittedTxBufferFirstEntry != NULL) + { + tEdrvTxBuffer* pTxBuffer = pInstance->pTransmittedTxBufferFirstEntry; + + if (pTxBuffer->pBuffer != NULL) + { + if (OPLK_MEMCMP(pPktData_p, pTxBuffer->pBuffer, 6) == 0) + { // compare with packet buffer with destination MAC + pthread_mutex_lock(&pInstance->mutex); + pInstance->pTransmittedTxBufferFirstEntry = (tEdrvTxBuffer*)pInstance->pTransmittedTxBufferFirstEntry->txBufferNumber.pArg; + if (pInstance->pTransmittedTxBufferFirstEntry == NULL) + { + pInstance->pTransmittedTxBufferLastEntry = NULL; + } + pthread_mutex_unlock(&pInstance->mutex); + + pTxBuffer->txBufferNumber.pArg = NULL; + + if (pTxBuffer->pfnTxHandler != NULL) + { + pTxBuffer->pfnTxHandler(pTxBuffer); + } + } + else + { + TRACE("%s: no matching TxB: DstMAC=%02X%02X%02X%02X%02X%02X\n", + __func__, + (UINT)((UINT8*)pPktData_p)[0], + (UINT)((UINT8*)pPktData_p)[1], + (UINT)((UINT8*)pPktData_p)[2], + (UINT)((UINT8*)pPktData_p)[3], + (UINT)((UINT8*)pPktData_p)[4], + (UINT)((UINT8*)pPktData_p)[5]); + TRACE(" current TxB %p: DstMAC=%02X%02X%02X%02X%02X%02X\n", + (void*)pTxBuffer, + (UINT)((UINT8*)(pTxBuffer->pBuffer))[0], + (UINT)((UINT8*)(pTxBuffer->pBuffer))[1], + (UINT)((UINT8*)(pTxBuffer->pBuffer))[2], + (UINT)((UINT8*)(pTxBuffer->pBuffer))[3], + (UINT)((UINT8*)(pTxBuffer->pBuffer))[4], + (UINT)((UINT8*)(pTxBuffer->pBuffer))[5]); + } + } + } + else + { + TRACE("%s: no TxB: DstMAC=%02X%02X%02X%02X%02X%02X\n", __func__, + ((UINT8*)pPktData_p)[0], + ((UINT8*)pPktData_p)[1], + ((UINT8*)pPktData_p)[2], + ((UINT8*)pPktData_p)[3], + ((UINT8*)pPktData_p)[4], + ((UINT8*)pPktData_p)[5]); + } + } +} + +//------------------------------------------------------------------------------ +/** +\brief Edrv worker thread + +This function implements the edrv worker thread. It is responsible to receive frames + +\param[in,out] pArgument_p User specific pointer pointing to the instance structure + +\return The function returns a thread error code. +*/ +//------------------------------------------------------------------------------ +static void* workerThread(void* pArgument_p) +{ + tEdrvInstance* pInstance = (tEdrvInstance*)pArgument_p; + int rawSockRet; + u_char aBuffer[EDRV_MAX_FRAME_SIZE]; + + // signal that thread is successfully started + sem_post(&pInstance->syncSem); + + while (edrvInstance_l.fStartCommunication) + { + rawSockRet = read(edrvInstance_l.sock, aBuffer, EDRV_MAX_FRAME_SIZE); + if (rawSockRet > 0) + { + packetHandler(pInstance, rawSockRet, aBuffer); + } + } + edrvInstance_l.fThreadIsExited = TRUE; + + return NULL; +} + +//------------------------------------------------------------------------------ +/** +\brief Get Edrv MAC address + +This function gets the interface's MAC address. + +\param[in] pIfName_p Ethernet interface device name +\param[out] pMacAddr_p Pointer to store MAC address +*/ +//------------------------------------------------------------------------------ +static void getMacAdrs(const char* pIfName_p, UINT8* pMacAddr_p) +{ + UNUSED_PARAMETER(pIfName_p); + + /* Generate a MAC address randomly */ + pMacAddr_p[0] = 0x52; + pMacAddr_p[1] = 0x54; + pMacAddr_p[2] = 0x98; + pMacAddr_p[3] = 0x76; + pMacAddr_p[4] = 0x54; + pMacAddr_p[5] = target_getTickCount(); +} + +//------------------------------------------------------------------------------ +/** +\brief Get link status + +This function returns the interface link status. + +\param[in] pIfName_p Ethernet interface device name + +\return The function returns the link status. +\retval TRUE The link is up. +\retval FALSE The link is down. +*/ +//------------------------------------------------------------------------------ +static BOOL getLinkStatus(const char* pIfName_p) +{ + UNUSED_PARAMETER(pIfName_p); + return TRUE; +} diff --git a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/kernel/event/eventkcal-xiuos.c b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/kernel/event/eventkcal-xiuos.c new file mode 100644 index 000000000..b010b758c --- /dev/null +++ b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/kernel/event/eventkcal-xiuos.c @@ -0,0 +1,377 @@ +/** +******************************************************************************** +\file eventkcal-linux.c + +\brief Kernel event CAL module for Linux userspace + +This file implements the kernel event handler CAL module for the Linux +userspace platform. It uses the circular buffer interface for all event queues. + +\see eventkcalintf-circbuf.c + +\ingroup module_eventkcal +*******************************************************************************/ + +/*------------------------------------------------------------------------------ +Copyright (c) 2016, B&R Industrial Automation GmbH +Copyright (c) 2020, AIIT XUOS Lab +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +------------------------------------------------------------------------------*/ + +//------------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------------ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +//============================================================================// +// G L O B A L D E F I N I T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +// const defines +//------------------------------------------------------------------------------ +#define KERNEL_EVENT_THREAD_PRIORITY 55 + +//------------------------------------------------------------------------------ +// module global vars +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// global function prototypes +//------------------------------------------------------------------------------ + +//============================================================================// +// P R I V A T E D E F I N I T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +// const defines +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// local types +//------------------------------------------------------------------------------ + +/** +\brief Kernel event CAL instance type + +The structure contains all necessary information needed by the kernel event +CAL module. +*/ +typedef struct +{ + pthread_t threadId; + BOOL fStopThread; + sem_t semUserData; + sem_t semKernelData; + BOOL fInitialized; +} tEventkCalInstance; + +//------------------------------------------------------------------------------ +// local vars +//------------------------------------------------------------------------------ +static tEventkCalInstance instance_l; ///< Instance variable of kernel event CAL module + +//------------------------------------------------------------------------------ +// local function prototypes +//------------------------------------------------------------------------------ +static void* eventThread(void* arg); +static void signalKernelEvent(void); +static void signalUserEvent(void); + +//============================================================================// +// P U B L I C F U N C T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +/** +\brief Initialize kernel event CAL module + +The function initializes the kernel event CAL module on Linux. + +\return The function returns a tOplkError error code. +\retval kErrorOk Function executes correctly +\retval other error codes An error occurred + +\ingroup module_eventkcal +*/ +//------------------------------------------------------------------------------ +tOplkError eventkcal_init(void) +{ + struct sched_param schedParam; + + OPLK_MEMSET(&instance_l, 0, sizeof(tEventkCalInstance)); + + if (sem_init(&instance_l.semUserData, 0, 0) < 0) + goto Exit; + + if (sem_init(&instance_l.semKernelData, 0, 0) < 0) + goto Exit; + + if (eventkcal_initQueueCircbuf(kEventQueueK2U) != kErrorOk) + goto Exit; + + if (eventkcal_initQueueCircbuf(kEventQueueU2K) != kErrorOk) + goto Exit; + + if (eventkcal_initQueueCircbuf(kEventQueueKInt) != kErrorOk) + goto Exit; + + eventkcal_setSignalingCircbuf(kEventQueueK2U, signalUserEvent); + + eventkcal_setSignalingCircbuf(kEventQueueKInt, signalKernelEvent); + + instance_l.fStopThread = FALSE; + if (pthread_create(&instance_l.threadId, NULL, eventThread, (void*)&instance_l) != 0) + goto Exit; + + schedParam.sched_priority = KERNEL_EVENT_THREAD_PRIORITY; + if (pthread_setschedparam(instance_l.threadId, SCHED_FIFO, &schedParam) != 0) + { + DEBUG_LVL_ERROR_TRACE("%s(): couldn't set thread scheduling parameters! %d\n", + __func__, + schedParam.sched_priority); + } + +#if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 12) + pthread_setname_np(instance_l.threadId, "oplk-eventk"); +#endif + + instance_l.fInitialized = TRUE; + return kErrorOk; + +Exit: + if (instance_l.semUserData >= 0) + sem_destroy(&instance_l.semUserData); + + if (instance_l.semKernelData >= 0) + sem_destroy(&instance_l.semKernelData); + + eventkcal_exitQueueCircbuf(kEventQueueK2U); + eventkcal_exitQueueCircbuf(kEventQueueU2K); + eventkcal_exitQueueCircbuf(kEventQueueKInt); + + return kErrorNoResource; +} + + +//------------------------------------------------------------------------------ +/** +\brief Clean up kernel event CAL module + +The function cleans up the kernel event CAL module. For cleanup it calls the exit +functions of the queue implementations for each used queue. + +\return The function returns a tOplkError error code. +\retval kErrorOk Function executes correctly +\retval other error codes An error occurred + +\ingroup module_eventkcal +*/ +//------------------------------------------------------------------------------ +tOplkError eventkcal_exit(void) +{ + UINT i = 0; + + if (instance_l.fInitialized != FALSE) + { + instance_l.fStopThread = TRUE; + while (instance_l.fStopThread != FALSE) + { + target_msleep(10); + if (i++ > 100) + { + DEBUG_LVL_EVENTK_TRACE("Event thread is not terminating, continue shutdown...!\n"); + break; + } + } + + eventkcal_exitQueueCircbuf(kEventQueueK2U); + eventkcal_exitQueueCircbuf(kEventQueueU2K); + eventkcal_exitQueueCircbuf(kEventQueueKInt); + + sem_destroy(&instance_l.semUserData); + sem_destroy(&instance_l.semKernelData); + + sem_unlink("/semUserEvent"); + sem_unlink("/semKernelEvent"); + + } + instance_l.fInitialized = FALSE; + + return kErrorOk; +} + +//------------------------------------------------------------------------------ +/** +\brief Post kernel event + +This function posts a event to the kernel queue. + +\param[in] pEvent_p Event to be posted. + +\return The function returns a tOplkError error code. +\retval kErrorOk Function executes correctly +\retval other error codes An error occurred + +\ingroup module_eventkcal +*/ +//------------------------------------------------------------------------------ +tOplkError eventkcal_postKernelEvent(const tEvent* pEvent_p) +{ + tOplkError ret; + + ret = eventkcal_postEventCircbuf(kEventQueueKInt, pEvent_p); + + return ret; +} + +//------------------------------------------------------------------------------ +/** +\brief Post user event + +This function posts a event to the user queue. + +\param[in] pEvent_p Event to be posted. + +\return The function returns a tOplkError error code. +\retval kErrorOk Function executes correctly +\retval other error codes An error occurred + +\ingroup module_eventkcal +*/ +//------------------------------------------------------------------------------ +tOplkError eventkcal_postUserEvent(const tEvent* pEvent_p) +{ + tOplkError ret; + + ret = eventkcal_postEventCircbuf(kEventQueueK2U, pEvent_p); + + return ret; +} + +//------------------------------------------------------------------------------ +/** +\brief Process function of kernel CAL module + +This function will be called by the systems process function. + +\ingroup module_eventkcal +*/ +//------------------------------------------------------------------------------ +void eventkcal_process(void) +{ + // Nothing to do, because we use threads +} + +//============================================================================// +// P R I V A T E F U N C T I O N S // +//============================================================================// +/// \name Private Functions +/// \{ + +//------------------------------------------------------------------------------ +/** +\brief Event handler thread function + +This function contains the main function for the event handler thread. + +\param[in,out] arg Thread parameter. Not used! + +\return The function returns the thread exit code. +*/ +//------------------------------------------------------------------------------ +static void* eventThread(void* arg) +{ + UINT32 tickCount; + struct timespec curTime, timeout; + tEventkCalInstance* pInstance = (tEventkCalInstance*)arg; + + while (!pInstance->fStopThread) + { + tickCount = target_getTickCount(); + curTime.tv_sec = tickCount / 1000; + curTime.tv_nsec = (tickCount % 1000) * 1000000; + timeout.tv_sec = 0; + timeout.tv_nsec = 50000 * 1000; + TIMESPECADD(&timeout, &curTime); + + if (sem_timedwait(&pInstance->semKernelData, &timeout) == 0) + { + /* first handle kernel internal events --> higher priority! */ + if (eventkcal_getEventCountCircbuf(kEventQueueKInt) > 0) + { + eventkcal_processEventCircbuf(kEventQueueKInt); + } + else + { + if (eventkcal_getEventCountCircbuf(kEventQueueU2K) > 0) + { + eventkcal_processEventCircbuf(kEventQueueU2K); + } + } + } + } + + pInstance->fStopThread = FALSE; + return 0; +} + +//------------------------------------------------------------------------------ +/** +\brief Signal a user event + +This function signals that a user event was posted. It will be registered in +the circular buffer library as signal callback function +*/ +//------------------------------------------------------------------------------ +static void signalUserEvent(void) +{ + sem_post(&instance_l.semUserData); +} + +//------------------------------------------------------------------------------ +/** +\brief Signal a kernel event + +This function signals that a kernel event was posted. It will be registered in +the circular buffer library as signal callback function +*/ +//------------------------------------------------------------------------------ +static void signalKernelEvent(void) +{ + sem_post(&instance_l.semKernelData); +} + +/// \} diff --git a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/kernel/timer/hrestimer-xiuos.c b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/kernel/timer/hrestimer-xiuos.c new file mode 100644 index 000000000..1b692554a --- /dev/null +++ b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/kernel/timer/hrestimer-xiuos.c @@ -0,0 +1,617 @@ +/** +******************************************************************************** +\file hrestimer-xiuos.c + +\brief High-resolution timer module for XiUOS + +This module is the target specific implementation of the high-resolution +timer module for XiUOS. + +\ingroup module_hrestimer +*******************************************************************************/ + +/*------------------------------------------------------------------------------ +Copyright (c) 2012, SYSTEC electronic GmbH +Copyright (c) 2016, B&R Industrial Automation GmbH +Copyright (c) 2020, AIIT XUOS Lab +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +------------------------------------------------------------------------------*/ + +//------------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------------ +#include +#include +#include +#include + +#include +#include +#include +#include + +//============================================================================// +// G L O B A L D E F I N I T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +// const defines +//------------------------------------------------------------------------------ +#undef HIGH_RESK_TIMER_LATENCY_DEBUG ///< enable/disable latency debugging + +#define TIMER_COUNT 2 ///< number of high-resolution timers +#define TIMER_MIN_VAL_SINGLE 20000 ///< minimum timer interval for single timeouts +#define TIMER_MIN_VAL_CYCLE 100000 ///< minimum timer interval for continuous timeouts + +/* macros for timer handles */ +#define TIMERHDL_MASK 0x0FFFFFFF +#define TIMERHDL_SHIFT 28 +#define HDL_TO_IDX(hdl) ((hdl >> TIMERHDL_SHIFT) - 1) +#define HDL_INIT(idx) ((idx + 1) << TIMERHDL_SHIFT) +#define HDL_INC(hdl) (((hdl + 1) & TIMERHDL_MASK) | (hdl & ~TIMERHDL_MASK)) + +//------------------------------------------------------------------------------ +// module global vars +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// global function prototypes +//------------------------------------------------------------------------------ + +//============================================================================// +// P R I V A T E D E F I N I T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +// const defines +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// local types +//------------------------------------------------------------------------------ + +/** +\brief High-resolution timer information structure + +The structure contains all necessary information for a high-resolution timer. +*/ +typedef struct +{ + tTimerEventArg eventArg; ///< Event argument + tTimerkCallback pfnCallback; ///< Pointer to timer callback function + struct timespec startTime; ///< Timestamp of timer start + ULONGLONG time; ///< Timer period in nanoseconds + pthread_t timerThreadId; ///< Handle of timer thread + sem_t syncSem; ///< Thread synchronization semaphore + BOOL fTerminate; ///< Thread termination flag + BOOL fContinue; ///< Flag determines if timer will be restarted continuously +#ifdef HIGH_RESK_TIMER_LATENCY_DEBUG + /* additional variables for latency debugging */ + LONG maxLatency; ///< Minimum measured timer latency + LONG minLatency; ///< Maximum measured timer latency +#endif +} tHresTimerInfo; + +/** +\brief High-resolution timer instance + +The structure defines a high-resolution timer module instance. +*/ +typedef struct +{ + tHresTimerInfo aTimerInfo[TIMER_COUNT]; ///< Array with timer information for a set of timers +} tHresTimerInstance; + +//------------------------------------------------------------------------------ +// module local vars +//------------------------------------------------------------------------------ +static tHresTimerInstance hresTimerInstance_l; + +//------------------------------------------------------------------------------ +// local function prototypes +//------------------------------------------------------------------------------ +static void* timerThread(void* pArgument_p); +static inline void timespec_add(const struct timespec* time1_p, + ULONGLONG offset_p, + struct timespec* result_p); + +#ifdef HIGH_RESK_TIMER_LATENCY_DEBUG +static inline void timespec_sub(const struct timespec* time1_p, + const struct timespec* time2_p, + struct timespec* result_p); +#endif + + +//============================================================================// +// P U B L I C F U N C T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +/** +\brief Initialize high-resolution timer module + +The function initializes the high-resolution timer module + +\return Returns a tOplkError error code. + +\ingroup module_hrestimer +*/ +//------------------------------------------------------------------------------ +tOplkError hrestimer_init(void) +{ + tOplkError ret = kErrorOk; + UINT index; + struct sched_param schedParam; + tHresTimerInfo* pTimerInfo; + + OPLK_MEMSET(&hresTimerInstance_l, 0, sizeof(hresTimerInstance_l)); + + /* Initialize timer threads for all usable timers. */ + for (index = 0; index < TIMER_COUNT; index++) + { + pTimerInfo = &hresTimerInstance_l.aTimerInfo[index]; + pTimerInfo->fTerminate = FALSE; + +#ifdef HIGH_RESK_TIMER_LATENCY_DEBUG + pTimerInfo->maxLatency = 0; + pTimerInfo->minLatency = 999999999; +#endif + + if (sem_init(&pTimerInfo->syncSem, 0, 0) != 0) + { + DEBUG_LVL_ERROR_TRACE("%s() Couldn't init semaphore!\n", __func__); + return kErrorNoResource; + } + + if (pthread_create(&pTimerInfo->timerThreadId, NULL, timerThread, pTimerInfo) != 0) + { + sem_destroy(&pTimerInfo->syncSem); + return kErrorNoResource; + } + + schedParam.sched_priority = CONFIG_THREAD_PRIORITY_HIGH; + if (pthread_setschedparam(pTimerInfo->timerThreadId, SCHED_FIFO, &schedParam) != 0) + { + DEBUG_LVL_ERROR_TRACE("%s() Couldn't set thread scheduling parameters!\n", __func__); + sem_destroy(&pTimerInfo->syncSem); + pthread_cancel(pTimerInfo->timerThreadId); + return kErrorNoResource; + } + +#if (defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 12)) + pthread_setname_np(pTimerInfo->timerThreadId, "oplk-hrtimer"); +#endif + } + + return ret; +} + +//------------------------------------------------------------------------------ +/** +\brief Shut down high-resolution timer module + +The function shuts down the high-resolution timer module. + +\return Returns a tOplkError error code. + +\ingroup module_hrestimer +*/ +//------------------------------------------------------------------------------ +tOplkError hrestimer_exit(void) +{ + tHresTimerInfo* pTimerInfo; + tOplkError ret = kErrorOk; + UINT index; + + for (index = 0; index < TIMER_COUNT; index++) + { + pTimerInfo = &hresTimerInstance_l.aTimerInfo[index]; + + pTimerInfo->eventArg.timerHdl.handle = 0; + + /* send exit signal to thread */ + pTimerInfo->fContinue = 0; + pTimerInfo->fTerminate = TRUE; + sem_post(&pTimerInfo->syncSem); + + /* wait until thread terminates */ + pthread_join(pTimerInfo->timerThreadId, NULL); + + /* clean up */ + pTimerInfo->pfnCallback = NULL; + sem_destroy(&pTimerInfo->syncSem); + } + + return ret; +} + +//------------------------------------------------------------------------------ +/** +\brief Modify a high-resolution timer + +The function modifies the timeout of the timer with the specified handle. +If the handle to which the pointer points to is zero, the timer must be created +first. If it is not possible to stop the old timer, this function always assures +that the old timer does not trigger the callback function with the same handle +as the new timer. That means the callback function must check the passed handle +with the one returned by this function. If these are unequal, the call can be +discarded. + +\param[in,out] pTimerHdl_p Pointer to timer handle. +\param[in] time_p Relative timeout in [ns]. +\param[in] pfnCallback_p Callback function, which is called when timer expires. + (The function is called mutually exclusive with + the Edrv callback functions (Rx and Tx)). +\param[in] argument_p User-specific argument. +\param[in] fContinue_p If TRUE, the callback function will be called continuously. + Otherwise, it is a one-shot timer. + +\return Returns a tOplkError error code. + +\ingroup module_hrestimer +*/ +//------------------------------------------------------------------------------ +tOplkError hrestimer_modifyTimer(tTimerHdl* pTimerHdl_p, + ULONGLONG time_p, + tTimerkCallback pfnCallback_p, + ULONG argument_p, + BOOL fContinue_p) +{ + tOplkError ret = kErrorOk; + UINT index; + UINT32 tickCount; + tHresTimerInfo* pTimerInfo; + + DEBUG_LVL_TIMERH_TRACE("%s() pTimerHdl_p=%08x/%08x\n", + __func__, (unsigned int)pTimerHdl_p, (unsigned int)*pTimerHdl_p); + + if (pTimerHdl_p == NULL) + return kErrorTimerInvalidHandle; + + if (*pTimerHdl_p == 0) + { // no timer created yet + // search free timer info structure + pTimerInfo = &hresTimerInstance_l.aTimerInfo[0]; + for (index = 0; index < TIMER_COUNT; index++, pTimerInfo++) + { + if (pTimerInfo->eventArg.timerHdl.handle == 0) + { // free structure found + break; + } + } + if (index >= TIMER_COUNT) + { // no free structure found + return kErrorTimerNoTimerCreated; + } + + pTimerInfo->eventArg.timerHdl.handle = HDL_INIT(index); + } + else + { + index = HDL_TO_IDX(*pTimerHdl_p); + if (index >= TIMER_COUNT) + { // invalid handle + return kErrorTimerInvalidHandle; + } + + pTimerInfo = &hresTimerInstance_l.aTimerInfo[index]; + } + + // increase too small time values + if (fContinue_p != FALSE) + { + if (time_p < TIMER_MIN_VAL_CYCLE) + time_p = TIMER_MIN_VAL_CYCLE; + } + else + { + if (time_p < TIMER_MIN_VAL_SINGLE) + time_p = TIMER_MIN_VAL_SINGLE; + } + + /* increment timer handle + * (if timer expires right after this statement, the user + * would detect an unknown timer handle and discard it) */ + pTimerInfo->eventArg.timerHdl.handle = HDL_INC(pTimerInfo->eventArg.timerHdl.handle); + *pTimerHdl_p = pTimerInfo->eventArg.timerHdl.handle; + + /* initialize timer info */ + pTimerInfo->eventArg.argument.value = argument_p; + pTimerInfo->pfnCallback = pfnCallback_p; + pTimerInfo->fContinue = fContinue_p; + pTimerInfo->time = time_p; + + tickCount = target_getTickCount(); + pTimerInfo->startTime.tv_sec = tickCount / 1000; + pTimerInfo->startTime.tv_nsec = (tickCount % 1000) * 1000000; + sem_post(&pTimerInfo->syncSem); /* signal timer start to thread */ + + return ret; +} + +//------------------------------------------------------------------------------ +/** +\brief Delete a high-resolution timer + +The function deletes a created high-resolution timer. The timer is specified +by its timer handle. After deleting, the handle is reset to zero. + +\param[in,out] pTimerHdl_p Pointer to timer handle. + +\return Returns a tOplkError error code. + +\ingroup module_hrestimer +*/ +//------------------------------------------------------------------------------ +tOplkError hrestimer_deleteTimer(tTimerHdl* pTimerHdl_p) +{ + tOplkError ret = kErrorOk; + UINT index; + tHresTimerInfo* pTimerInfo; + + // check pointer to handle + if (pTimerHdl_p == NULL) + return kErrorTimerInvalidHandle; + + if (*pTimerHdl_p == 0) + { // no timer created yet + return ret; + } + else + { + index = HDL_TO_IDX(*pTimerHdl_p); + if (index >= TIMER_COUNT) + { // invalid handle + return kErrorTimerInvalidHandle; + } + pTimerInfo = &hresTimerInstance_l.aTimerInfo[index]; + if (pTimerInfo->eventArg.timerHdl.handle != *pTimerHdl_p) + { // invalid handle + return ret; + } + } + + pTimerInfo->fContinue = FALSE; + *pTimerHdl_p = 0; + pTimerInfo->eventArg.timerHdl.handle = 0; + pTimerInfo->pfnCallback = NULL; + + return ret; +} + +//------------------------------------------------------------------------------ +/** +\brief Control external synchronization interrupt + +This function enables/disables the external synchronization interrupt. If the +external synchronization interrupt is not supported, the call is ignored. + +\param[in] fEnable_p Flag determines if sync should be enabled or disabled. + +\ingroup module_hrestimer +*/ +//------------------------------------------------------------------------------ +void hrestimer_controlExtSyncIrq(BOOL fEnable_p) +{ + UNUSED_PARAMETER(fEnable_p); +} + +//------------------------------------------------------------------------------ +/** +\brief Set external synchronization interrupt time + +This function sets the time when the external synchronization interrupt shall +be triggered to synchronize the host processor. If the external synchronization +interrupt is not supported, the call is ignored. + +\param[in] time_p Time when the sync shall be triggered + +\ingroup module_hrestimer +*/ +//------------------------------------------------------------------------------ +void hrestimer_setExtSyncIrqTime(tTimestamp time_p) +{ + UNUSED_PARAMETER(time_p); +} + +//============================================================================// +// P R I V A T E F U N C T I O N S // +//============================================================================// +/// \name Private Functions +/// \{ + +//------------------------------------------------------------------------------ +/** +\brief Timer thread function + +The function provides the main function of the timer thread. It waits for a +timer start signal. When it is received it reads the high-resolution timer +information structure and calculates the timeout value. It sleeps by calling +clock_nanosleep() until the timeout is reached. When the timeout is reached +the callback function registered in the timer info structure is called. If the +flag m_fContinue is set the thread loops until the timer is deleted. + +\param[in,out] pArgument_p Thread parameter. It contains the pointer to + the timer info structure. + +\return Returns a void* as specified by the pthread interface but it is not used! +*/ +//------------------------------------------------------------------------------ +static void* timerThread(void* pArgument_p) +{ + int iRet; + tHresTimerInfo* pTimerInfo; + struct timespec startTime, timeout; + ULONGLONG period; + tTimerHdl timerHdl; +#ifdef HIGH_RESK_TIMER_LATENCY_DEBUG + struct timespec debugtime, curTime; +#endif + + DEBUG_LVL_TIMERH_TRACE("%s(): ThreadId:%ld\n", __func__, syscall(SYS_gettid)); + DEBUG_LVL_TIMERH_TRACE("%s(): timer:%lx\n", __func__, (unsigned long)pArgument_p); + + /* thread parameter contains the address of the timer information structure */ + pTimerInfo = (tHresTimerInfo*)pArgument_p; + + /* loop forever until thread will be canceled */ + while (1) + { + /* wait for semaphore which signals a timer start */ + sem_wait(&pTimerInfo->syncSem); + + /* check if thread should terminate */ + if (pTimerInfo->fTerminate) + { + DEBUG_LVL_TIMERH_TRACE("%s() Exiting signal received!\n", __func__); + break; + } + else + { + /* save timer information into local variables */ + startTime = pTimerInfo->startTime; + timerHdl = pTimerInfo->eventArg.timerHdl.handle; + period = pTimerInfo->time; + + /* calculate the timeout value for the timer cycle */ + timespec_add(&startTime, period, &timeout); + +#ifdef HIGH_RESK_TIMER_LATENCY_DEBUG + clock_gettime(CLOCK_REALTIME, &curTime); +#endif + do + { + /* sleep until timeout */ + iRet = usleep(period / 1000); + if (iRet < 0) + { + DEBUG_LVL_ERROR_TRACE("%s(): Error in clock_nanosleep!\n", + __func__); + /* todo how to signal that timeout wasn't correct? */ + } + FTRACE_MARKER("HighReskTimer(%d) expired (%d ns)", + (int)pArgument_p, period); + +#ifdef HIGH_RESK_TIMER_LATENCY_DEBUG + clock_gettime(CLOCK_REALTIME, &curTime); + timespec_sub(&timeout, &curTime, &debugtime); + FTRACE_MARKER("%s latency=%ld:%ld", __func__, debugtime.tv_sec, + debugtime.tv_nsec); + if (debugtime.tv_nsec > pTimerInfo->maxLatency) + { + DEBUG_LVL_TIMERH_TRACE("%s() Timer elapsed: max latency=%ld ns\n", + __func__, debugtime.tv_nsec); + pTimerInfo->maxLatency = debugtime.tv_nsec; + } + if (timeout.tv_nsec < pTimerInfo->minLatency) + { + DEBUG_LVL_TIMERH_TRACE("%s() Timer elapsed: min latency=%ld ns\n", + __func__, debugtime.tv_nsec); + pTimerInfo->minLatency = debugtime.tv_nsec; + } +#endif + + /* check if timer handle is valid */ + if (timerHdl == pTimerInfo->eventArg.timerHdl.handle) + { + /* call callback function */ + if (pTimerInfo->pfnCallback != NULL) + { + pTimerInfo->pfnCallback(&pTimerInfo->eventArg); + } + } + + /* check if timer handle is still valid. Could be modified in callback! */ + if (timerHdl == pTimerInfo->eventArg.timerHdl.handle) + { + if (pTimerInfo->fContinue) + { + /* calculate timeout value for next timer cycle */ + timespec_add(&timeout, period, &timeout); + } + } + } while ((pTimerInfo->fContinue) && + (timerHdl == pTimerInfo->eventArg.timerHdl.handle)); + } + } + return NULL; +} + +//------------------------------------------------------------------------------ +/** +\brief Add offset to timespec value + +The function adds a time offset in nanoseconds to a timespec value. + +\param[in] time1_p Pointer to timespec to which the offset should be added. +\param[in] offset_p Offset in nanoseconds to add. +\param[out] result_p Pointer to store the result of the calculation. +*/ +//------------------------------------------------------------------------------ +static inline void timespec_add(const struct timespec* time1_p, + ULONGLONG offset_p, + struct timespec* result_p) +{ + result_p->tv_sec = time1_p->tv_sec + offset_p / 1000000000L; + result_p->tv_nsec = time1_p->tv_nsec + offset_p % 1000000000L; + if (result_p->tv_nsec >= 1000000000L) + { + result_p->tv_sec++; + result_p->tv_nsec -= 1000000000L; + } +} + +#ifdef HIGH_RESK_TIMER_LATENCY_DEBUG +//------------------------------------------------------------------------------ +/** +\brief Subtract two timespec values + +The function subtracts two timespec values. + +\param[in] time1_p Pointer to first timespec value from which + to substract the second one. +\param[in] time2_p Pointer to second timespec value which will + be substracted. +\param[out] result_p Pointer to store the result of the calculation. +*/ +//------------------------------------------------------------------------------ +static inline void timespec_sub(const struct timespec* time1_p, + const struct timespec* time2_p, + struct timespec* result_p) +{ + if (time2_p->tv_nsec > time1_p->tv_nsec) + { + result_p->tv_nsec = time2_p->tv_nsec - time1_p->tv_nsec; + result_p->tv_sec = time2_p->tv_sec - time1_p->tv_sec; + } + else + { + result_p->tv_nsec = 1000000000L + time2_p->tv_nsec - time1_p->tv_nsec; + result_p->tv_sec = time2_p->tv_sec - time1_p->tv_sec - 1; + } +} +#endif + +/// \} diff --git a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/user/cfmu.c b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/user/cfmu.c index 0b13abc94..a5f067209 100644 --- a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/user/cfmu.c +++ b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/user/cfmu.c @@ -846,6 +846,8 @@ static tOplkError downloadCycleLength(tCfmNodeInfo* pNodeInfo_p) pNodeInfo_p->eventCnProgress.nodeId, ret); } +#else + UNUSED_PARAMETER(pNodeInfo_p); #endif return ret; diff --git a/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/user/event/eventucal-xiuos.c b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/user/event/eventucal-xiuos.c new file mode 100644 index 000000000..418e8b782 --- /dev/null +++ b/APP_Framework/Framework/connection/industrial_ethernet/openPOWERLINK/stack/src/user/event/eventucal-xiuos.c @@ -0,0 +1,379 @@ +/** +******************************************************************************** +\file eventucal-linux.c + +\brief User event CAL module for XiUOS + +This file implements the user event handler CAL module for the Linux +userspace platform. It uses the circular buffer interface for all event queues. + +\see eventucalintf-circbuf.c + +\ingroup module_eventucal +*******************************************************************************/ + +/*------------------------------------------------------------------------------ +Copyright (c) 2016, B&R Industrial Automation GmbH +Copyright (c) 2020, AIIT XUOS Lab +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +------------------------------------------------------------------------------*/ + +//------------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------------ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +//============================================================================// +// G L O B A L D E F I N I T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +// const defines +//------------------------------------------------------------------------------ +#define USER_EVENT_THREAD_PRIORITY 45 + +//------------------------------------------------------------------------------ +// module global vars +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// global function prototypes +//------------------------------------------------------------------------------ + +//============================================================================// +// P R I V A T E D E F I N I T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +// const defines +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// local types +//------------------------------------------------------------------------------ +/** +\brief User event CAL instance type + +The structure contains all necessary information needed by the user event +CAL module. +*/ +typedef struct +{ + pthread_t threadId; + BOOL fStopThread; + sem_t semUserData; + sem_t semKernelData; + BOOL fInitialized; +} tEventuCalInstance; + +//------------------------------------------------------------------------------ +// local vars +//------------------------------------------------------------------------------ +static tEventuCalInstance instance_l; ///< Instance variable of user event CAL module + +//------------------------------------------------------------------------------ +// local function prototypes +//------------------------------------------------------------------------------ +static void* eventThread(void* arg); +static void signalUserEvent(void); +static void signalKernelEvent(void); + +//============================================================================// +// P U B L I C F U N C T I O N S // +//============================================================================// + +//------------------------------------------------------------------------------ +/** +\brief Initialize architecture specific stuff of user event CAL module + +The function initializes the architecture specific stuff of the user event +CAL module. + +\return The function returns a tOplkError error code. +\retval kErrorOk Function executes correctly +\retval other error codes An error occurred + +\ingroup module_eventucal +*/ +//------------------------------------------------------------------------------ +tOplkError eventucal_init(void) +{ + struct sched_param schedParam; + + OPLK_MEMSET(&instance_l, 0, sizeof(tEventuCalInstance)); + + if (sem_init(&instance_l.semUserData, 0, 0) < 0) + goto Exit; + + if (sem_init(&instance_l.semKernelData, 0, 0) < 0) + goto Exit; + + if (eventucal_initQueueCircbuf(kEventQueueK2U) != kErrorOk) + goto Exit; + + if (eventucal_initQueueCircbuf(kEventQueueU2K) != kErrorOk) + goto Exit; + + eventucal_setSignalingCircbuf(kEventQueueU2K, signalKernelEvent); + + if (eventucal_initQueueCircbuf(kEventQueueUInt) != kErrorOk) + goto Exit; + + eventucal_setSignalingCircbuf(kEventQueueUInt, signalUserEvent); + + instance_l.fStopThread = FALSE; + if (pthread_create(&instance_l.threadId, NULL, eventThread, (void*)&instance_l) != 0) + goto Exit; + + schedParam.sched_priority = USER_EVENT_THREAD_PRIORITY; + if (pthread_setschedparam(instance_l.threadId, SCHED_FIFO, &schedParam) != 0) + { + DEBUG_LVL_ERROR_TRACE("%s(): couldn't set thread scheduling parameters! %d\n", + __func__, + schedParam.sched_priority); + } + +#if (defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 12)) + pthread_setname_np(instance_l.threadId, "oplk-eventu"); +#endif + + instance_l.fInitialized = TRUE; + return kErrorOk; + +Exit: + if (instance_l.semUserData >= 0) + sem_destroy(&instance_l.semUserData); + + if (instance_l.semKernelData >= 0) + sem_destroy(&instance_l.semKernelData); + + eventucal_exitQueueCircbuf(kEventQueueK2U); + eventucal_exitQueueCircbuf(kEventQueueU2K); + eventucal_exitQueueCircbuf(kEventQueueUInt); + + return kErrorNoResource; +} + +//------------------------------------------------------------------------------ +/** +\brief Clean up kernel event CAL module + +The function cleans up the kernel event CAL module. For cleanup it calls the exit +functions of the queue implementations for each used queue. + +\return The function returns a tOplkError error code. +\retval kErrorOk Function executes correctly +\retval other error codes An error occurred + +\ingroup module_eventucal +*/ +//------------------------------------------------------------------------------ +tOplkError eventucal_exit(void) +{ + UINT i = 0; + + if (instance_l.fInitialized != FALSE) + { + instance_l.fStopThread = TRUE; + while (instance_l.fStopThread != FALSE) + { + target_msleep(10); + if (i++ > 100) + { + DEBUG_LVL_EVENTU_TRACE("%s(): Event thread is not terminating, continue shutdown...!\n", + __func__); + break; + } + } + + eventucal_exitQueueCircbuf(kEventQueueK2U); + eventucal_exitQueueCircbuf(kEventQueueU2K); + eventucal_exitQueueCircbuf(kEventQueueUInt); + + sem_destroy(&instance_l.semUserData); + sem_destroy(&instance_l.semKernelData); + } + instance_l.fInitialized = FALSE; + + return kErrorOk; +} + +//------------------------------------------------------------------------------ +/** +\brief Post kernel event + +This function posts an event to a queue. It is called from the generic kernel +event post function in the event handler. Depending on the sink the appropriate +queue post function is called. + +\param[in] pEvent_p Event to be posted. + +\return The function returns a tOplkError error code. +\retval kErrorOk Function executes correctly +\retval other error codes An error occurred + +\ingroup module_eventucal +*/ +//------------------------------------------------------------------------------ +tOplkError eventucal_postKernelEvent(const tEvent* pEvent_p) +{ + tOplkError ret; + + // Check parameter validity + ASSERT(pEvent_p != NULL); + + ret = eventucal_postEventCircbuf(kEventQueueU2K, pEvent_p); + + return ret; +} + +//------------------------------------------------------------------------------ +/** +\brief Post user event + +This function posts an event to a queue. It is called from the generic kernel +event post function in the event handler. Depending on the sink the appropriate +queue post function is called. + +\param[in] pEvent_p Event to be posted. + +\return The function returns a tOplkError error code. +\retval kErrorOk Function executes correctly +\retval other error codes An error occurred + +\ingroup module_eventucal +*/ +//------------------------------------------------------------------------------ +tOplkError eventucal_postUserEvent(const tEvent* pEvent_p) +{ + tOplkError ret; + + // Check parameter validity + ASSERT(pEvent_p != NULL); + + ret = eventucal_postEventCircbuf(kEventQueueUInt, pEvent_p); + + return ret; +} + +//------------------------------------------------------------------------------ +/** +\brief Process function of user CAL module + +This function will be called by the system process function. + +\ingroup module_eventucal +*/ +//------------------------------------------------------------------------------ +void eventucal_process(void) +{ + // Nothing to do, because we use threads +} + +//============================================================================// +// P R I V A T E F U N C T I O N S // +//============================================================================// +/// \name Private Functions +/// \{ + +//------------------------------------------------------------------------------ +/** +\brief Event handler thread function + +This function contains the main function for the event handler thread. + +\param[in,out] arg Thread parameter. Used to access the module instance. + +\return The function returns the thread exit code. +*/ +//------------------------------------------------------------------------------ +static void* eventThread(void* arg) +{ + UINT32 tickCount; + struct timespec curTime, timeout; + tEventuCalInstance* pInstance = (tEventuCalInstance*)arg; + + while (!pInstance->fStopThread) + { + tickCount = target_getTickCount(); + curTime.tv_sec = tickCount / 1000; + curTime.tv_nsec = (tickCount % 1000) * 1000000; + timeout.tv_sec = 0; + timeout.tv_nsec = 50000 * 1000; + TIMESPECADD(&timeout, &curTime); + + if (sem_timedwait(&pInstance->semUserData, &timeout) == 0) + { + /* first handle all user to kernel events --> higher priority! */ + if (eventucal_getEventCountCircbuf(kEventQueueK2U) > 0) + eventucal_processEventCircbuf(kEventQueueK2U); + else + { + if (eventucal_getEventCountCircbuf(kEventQueueUInt) > 0) + eventucal_processEventCircbuf(kEventQueueUInt); + } + } + } + pInstance->fStopThread = FALSE; + + return 0; +} + +//------------------------------------------------------------------------------ +/** +\brief Signal a user event + +This function signals that a user event has been posted. It will be registered +in the circular buffer library as signal callback function. +*/ +//------------------------------------------------------------------------------ +static void signalUserEvent(void) +{ + sem_post(&instance_l.semUserData); +} + +//------------------------------------------------------------------------------ +/** +\brief Signal a kernel event + +This function signals that a kernel event has been posted. It will be registered +in the circular buffer library as signal callback function. +*/ +//------------------------------------------------------------------------------ +static void signalKernelEvent(void) +{ + sem_post(&instance_l.semKernelData); +} + +/// \} diff --git a/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/include/pthread.h b/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/include/pthread.h index 9f65a971d..19ea1de46 100644 --- a/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/include/pthread.h +++ b/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/include/pthread.h @@ -63,6 +63,11 @@ extern "C" { typedef int pid_t; // typedef int pthread_mutex_t ; +/* scheduling algorithms */ +#define SCHED_OTHER 0 +#define SCHED_FIFO 1 +#define SCHED_RR 2 + /* function in pthread.c */ int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void)); int pthread_create(pthread_t *thread, const pthread_attr_t *attr, diff --git a/Ubiquitous/XiZi/board/aiit-arm32-board/Kconfig b/Ubiquitous/XiZi/board/aiit-arm32-board/Kconfig index 5016abc5f..17a48f191 100644 --- a/Ubiquitous/XiZi/board/aiit-arm32-board/Kconfig +++ b/Ubiquitous/XiZi/board/aiit-arm32-board/Kconfig @@ -34,7 +34,7 @@ menu "aiit-arm32-board feature" endmenu menu "config hardware resources for connection" - if CONNECTION_COMMUNICATION_ETHERNET + if CONNECTION_INDUSTRIAL_ETHERNET config ETHERNET_UART_NAME string "ethernet uart name" default "/dev/usart3_dev3" diff --git a/Ubiquitous/XiZi/board/aiit-riscv64-board/Kconfig b/Ubiquitous/XiZi/board/aiit-riscv64-board/Kconfig index babb6de52..a7eb40013 100644 --- a/Ubiquitous/XiZi/board/aiit-riscv64-board/Kconfig +++ b/Ubiquitous/XiZi/board/aiit-riscv64-board/Kconfig @@ -36,7 +36,7 @@ menu "aiit-riscv64-board feature" endmenu menu "config hardware resources for connection" - if CONNECTION_COMMUNICATION_ETHERNET + if CONNECTION_INDUSTRIAL_ETHERNET config ETHERNET_UART_NAME string "ethernet uart name" default "/dev/uart3_dev3" diff --git a/Ubiquitous/XiZi/board/cortex-m4-emulator/Kconfig b/Ubiquitous/XiZi/board/cortex-m4-emulator/Kconfig index 10bdcc0b4..b5a34397e 100644 --- a/Ubiquitous/XiZi/board/cortex-m4-emulator/Kconfig +++ b/Ubiquitous/XiZi/board/cortex-m4-emulator/Kconfig @@ -34,7 +34,7 @@ menu "cortex-m4-emulator feature" endmenu menu "config hardware resources for connection" - if CONNECTION_COMMUNICATION_ETHERNET + if CONNECTION_INDUSTRIAL_ETHERNET config ETHERNET_UART_NAME string "ethernet uart name" default "/dev/usart3_dev3" diff --git a/Ubiquitous/XiZi/board/gapuino/Kconfig b/Ubiquitous/XiZi/board/gapuino/Kconfig index 72449440a..2eeedd69f 100755 --- a/Ubiquitous/XiZi/board/gapuino/Kconfig +++ b/Ubiquitous/XiZi/board/gapuino/Kconfig @@ -35,7 +35,7 @@ menu "gapuino feature" endmenu menu "config hardware resources for connection" - if CONNECTION_COMMUNICATION_ETHERNET + if CONNECTION_INDUSTRIAL_ETHERNET config ETHERNET_UART_NAME string "ethernet uart name" default "/dev/uart3_dev3" diff --git a/Ubiquitous/XiZi/board/k210-emulator/Kconfig b/Ubiquitous/XiZi/board/k210-emulator/Kconfig index 62a4af941..a910bebf4 100644 --- a/Ubiquitous/XiZi/board/k210-emulator/Kconfig +++ b/Ubiquitous/XiZi/board/k210-emulator/Kconfig @@ -45,7 +45,7 @@ menu "kd233 feature" endmenu menu "config hardware resources for connection" - if CONNECTION_COMMUNICATION_ETHERNET + if CONNECTION_INDUSTRIAL_ETHERNET config ETHERNET_UART_NAME string "ethernet uart name" default "/dev/uart3_dev3" diff --git a/Ubiquitous/XiZi/board/kd233/Kconfig b/Ubiquitous/XiZi/board/kd233/Kconfig index 67ebe8ef0..dd6d262be 100644 --- a/Ubiquitous/XiZi/board/kd233/Kconfig +++ b/Ubiquitous/XiZi/board/kd233/Kconfig @@ -45,7 +45,7 @@ menu "kd233 feature" endmenu menu "config hardware resources for connection" - if CONNECTION_COMMUNICATION_ETHERNET + if CONNECTION_INDUSTRIAL_ETHERNET config ETHERNET_UART_NAME string "ethernet uart name" default "/dev/uart3_dev3" diff --git a/Ubiquitous/XiZi/board/stm32f407-st-discovery/Kconfig b/Ubiquitous/XiZi/board/stm32f407-st-discovery/Kconfig index 3ce31dd03..84261b3e1 100644 --- a/Ubiquitous/XiZi/board/stm32f407-st-discovery/Kconfig +++ b/Ubiquitous/XiZi/board/stm32f407-st-discovery/Kconfig @@ -34,7 +34,7 @@ menu "stm32f407-st-discovery feature" endmenu menu "config hardware resources for connection" - if CONNECTION_COMMUNICATION_ETHERNET + if CONNECTION_INDUSTRIAL_ETHERNET config ETHERNET_UART_NAME string "ethernet uart name" default "/dev/usart3_dev3" diff --git a/Ubiquitous/XiZi/board/stm32f407zgt6/Kconfig b/Ubiquitous/XiZi/board/stm32f407zgt6/Kconfig index 340dec6a0..2c6824e85 100644 --- a/Ubiquitous/XiZi/board/stm32f407zgt6/Kconfig +++ b/Ubiquitous/XiZi/board/stm32f407zgt6/Kconfig @@ -33,7 +33,7 @@ menu "stm32f407zgt6 feature" endmenu menu "config hardware resources for connection" - if CONNECTION_COMMUNICATION_ETHERNET + if CONNECTION_INDUSTRIAL_ETHERNET config ETHERNET_UART_NAME string "ethernet uart name" default "/dev/usart3_dev3" diff --git a/Ubiquitous/XiZi/compiler.mk b/Ubiquitous/XiZi/compiler.mk index 4efb0448a..bbc3aa46e 100644 --- a/Ubiquitous/XiZi/compiler.mk +++ b/Ubiquitous/XiZi/compiler.mk @@ -77,6 +77,16 @@ $(if $(strip $(LOCALS)),$(eval $(LOCALS): $(1) @$(CROSS_COMPILE)gcc $$(AFLAGS) -c $$< -o $$@)) endef +define add_a_file +$(eval SOBJ := $(1:%.a=%.a)) \ +$(eval SOBJ := $(subst $(subst $(APP_DIR),,$(KERNEL_ROOT)),,$(SOBJ))) \ +$(eval LOCALA := $(addprefix $(BUILD_DIR)/,$(SOBJ))) \ +$(eval OBJS += $(LOCALA)) \ +$(if $(strip $(LOCALA)),$(eval $(LOCALA): $(1) + @if [ ! -d $$(@D) ]; then mkdir -p $$(@D); fi + @echo cp $$< + @cp $$< $$@)) +endef @@ -92,7 +102,8 @@ $(if $(SRCS),$(foreach f,$(SRCS),$(call add_cc_file,$(addprefix $(CUR_DIR)/,$(f) SRCS := $(strip $(filter %.S,$(SRC_FILES))) $(if $(SRCS),$(foreach f,$(SRCS),$(call add_S_file,$(addprefix $(CUR_DIR)/,$(f))))) - +SRCS := $(strip $(filter %.a,$(SRC_FILES))) +$(if $(SRCS),$(foreach f,$(SRCS),$(call add_a_file,$(addprefix $(CUR_DIR)/,$(f))))) COMPILER:$(OBJS) diff --git a/devtools.sh b/devtools.sh index 4cbde2330..529914def 100755 --- a/devtools.sh +++ b/devtools.sh @@ -2,8 +2,8 @@ current_path=$(pwd) xizi_path=Ubiquitous/XiZi -board=cortex-m3-emulator -qemu_machine=lm3s6965evb +board=cortex-m4-emulator +qemu_machine=netduinoplus2 run_in_docker() { docker run \ @@ -31,11 +31,11 @@ distclean() { } simulate() { - [ "$1" = "debug" ] && debug_param="-s -S" qemu-system-arm $debug_param \ -machine $qemu_machine \ -nographic \ - -kernel $xizi_path/build/XiZi_$board.elf + -kernel $xizi_path/build/XiZi_$board.elf \ + $@ } gdb() {