forked from xuos/xiuos
powerlink: build liboplkmn.a and liboplkcn.a
This commit is contained in:
parent
7e1307a3bb
commit
b7648f0f08
|
@ -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)
|
ifeq ($(CONFIG_CONNECTION_ADAPTER_ETHERCAT),y)
|
||||||
SRC_DIR += ethercat
|
SRC_DIR += ethercat
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -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)
|
|
@ -4,6 +4,7 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2014, B&R Industrial Automation GmbH
|
# Copyright (c) 2014, B&R Industrial Automation GmbH
|
||||||
# Copyright (c) 2016, Kalycito Infotech Private Limited
|
# Copyright (c) 2016, Kalycito Infotech Private Limited
|
||||||
|
# Copyright (c) 2020, AIIT XUOS Lab
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# 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)
|
INCLUDE(cmake/options-linux.cmake)
|
||||||
ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
INCLUDE(cmake/options-windows.cmake)
|
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"))
|
ELSEIF((CMAKE_SYSTEM_NAME STREQUAL "Generic") AND (CMAKE_SYSTEM_PROCESSOR STREQUAL "Microblazeise"))
|
||||||
INCLUDE(cmake/options-microblazeise.cmake)
|
INCLUDE(cmake/options-microblazeise.cmake)
|
||||||
ELSEIF((CMAKE_SYSTEM_NAME STREQUAL "Generic") AND (CMAKE_SYSTEM_PROCESSOR STREQUAL "Microblaze"))
|
ELSEIF((CMAKE_SYSTEM_NAME STREQUAL "Generic") AND (CMAKE_SYSTEM_PROCESSOR STREQUAL "Microblaze"))
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
*
|
||||||
|
.*
|
||||||
|
!.gitignore
|
|
@ -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()
|
|
@ -5,6 +5,7 @@
|
||||||
# Copyright (c) 2017, B&R Industrial Automation GmbH
|
# Copyright (c) 2017, B&R Industrial Automation GmbH
|
||||||
# Copyright (c) 2016, Franz Profelt (franz.profelt@gmail.com)
|
# Copyright (c) 2016, Franz Profelt (franz.profelt@gmail.com)
|
||||||
# Copyright (c) 2018, Kalycito Infotech Private Limited
|
# Copyright (c) 2018, Kalycito Infotech Private Limited
|
||||||
|
# Copyright (c) 2020, AIIT XUOS Lab
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# 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
|
${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
|
SET(EVENT_UCAL_LINUXIOCTL_SOURCES
|
||||||
${USER_SOURCE_DIR}/event/eventucal-linuxioctl.c
|
${USER_SOURCE_DIR}/event/eventucal-linuxioctl.c
|
||||||
)
|
)
|
||||||
|
@ -396,6 +402,11 @@ SET(EVENT_KCAL_WINDOWS_SOURCES
|
||||||
${KERNEL_SOURCE_DIR}/event/eventkcalintf-circbuf.c
|
${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
|
SET(EVENT_KCAL_LINUXKERNEL_SOURCES
|
||||||
${KERNEL_SOURCE_DIR}/event/eventkcal-linuxkernel.c
|
${KERNEL_SOURCE_DIR}/event/eventkcal-linuxkernel.c
|
||||||
${KERNEL_SOURCE_DIR}/event/eventkcalintf-circbuf.c
|
${KERNEL_SOURCE_DIR}/event/eventkcalintf-circbuf.c
|
||||||
|
@ -476,6 +487,13 @@ SET(HARDWARE_DRIVER_LINUXUSERRAWSOCKET_SOURCES
|
||||||
${EDRV_SOURCE_DIR}/edrv-rawsock_linux.c
|
${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
|
SET(HARDWARE_DRIVER_WINDOWS_SOURCES
|
||||||
${EDRV_SOURCE_DIR}/edrvcyclic.c
|
${EDRV_SOURCE_DIR}/edrvcyclic.c
|
||||||
${EDRV_SOURCE_DIR}/edrv-pcap_win.c
|
${EDRV_SOURCE_DIR}/edrv-pcap_win.c
|
||||||
|
@ -533,6 +551,10 @@ SET(USER_TIMER_WINDOWS_SOURCES
|
||||||
${USER_SOURCE_DIR}/timer/timer-generic.c
|
${USER_SOURCE_DIR}/timer/timer-generic.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
SET(USER_TIMER_XIUOS_SOURCES
|
||||||
|
${USER_SOURCE_DIR}/timer/timer-generic.c
|
||||||
|
)
|
||||||
|
|
||||||
SET(USER_TIMER_GENERIC_SOURCES
|
SET(USER_TIMER_GENERIC_SOURCES
|
||||||
${USER_SOURCE_DIR}/timer/timer-generic.c
|
${USER_SOURCE_DIR}/timer/timer-generic.c
|
||||||
)
|
)
|
||||||
|
@ -643,6 +665,12 @@ ELSE ()
|
||||||
)
|
)
|
||||||
ENDIF ()
|
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
|
SET(TARGET_MICROBLAZE_SOURCES
|
||||||
${ARCH_SOURCE_DIR}/xilinx-microblaze/systemtimer.c
|
${ARCH_SOURCE_DIR}/xilinx-microblaze/systemtimer.c
|
||||||
${ARCH_SOURCE_DIR}/xilinx-microblaze/usleep.c
|
${ARCH_SOURCE_DIR}/xilinx-microblaze/usleep.c
|
||||||
|
|
|
@ -136,6 +136,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#elif (defined (_WIN32) || defined (__MINGW32__))
|
#elif (defined (_WIN32) || defined (__MINGW32__))
|
||||||
#define TARGET_SYSTEM _WIN32_ // WIN32 definition
|
#define TARGET_SYSTEM _WIN32_ // WIN32 definition
|
||||||
#define DEV_SYSTEM _DEV_WIN32_MINGW_
|
#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
|
#else /* (defined (_WIN32) || defined (__MINGW32__)) */ // unsupported
|
||||||
#error 'ERROR: TARGET_SYSTEM / DEV_SYSTEM not found!'
|
#error 'ERROR: TARGET_SYSTEM / DEV_SYSTEM not found!'
|
||||||
#endif
|
#endif
|
||||||
|
@ -171,7 +174,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// TARGET_SYSTEM specific definitions
|
// TARGET_SYSTEM specific definitions
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
#if (TARGET_SYSTEM == _LINUX_)
|
#if (TARGET_SYSTEM == _LINUX_ || TARGET_SYSTEM == _XIUOS_)
|
||||||
|
|
||||||
#include <oplk/targetdefs/linux.h>
|
#include <oplk/targetdefs/linux.h>
|
||||||
|
|
||||||
|
|
|
@ -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 .)
|
|
@ -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_
|
|
@ -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 .)
|
|
@ -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_
|
|
@ -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 <common/oplkinc.h>
|
||||||
|
#include <common/target.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
//============================================================================//
|
||||||
|
// 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
|
||||||
|
/// \{
|
||||||
|
|
||||||
|
/// \}
|
|
@ -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 <common/oplkinc.h>
|
||||||
|
#include <common/target.h>
|
||||||
|
|
||||||
|
#include <fcntl.h> /* For O_* constants */
|
||||||
|
#include <sys/stat.h> /* For mode constants */
|
||||||
|
#include <semaphore.h>
|
||||||
|
|
||||||
|
//============================================================================//
|
||||||
|
// 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
|
||||||
|
/// \{
|
||||||
|
|
||||||
|
/// \}
|
|
@ -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 <common/oplkinc.h>
|
||||||
|
#include <common/target.h>
|
||||||
|
#include <common/ftracedebug.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include <transform.h>
|
||||||
|
|
||||||
|
//============================================================================//
|
||||||
|
// 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
|
||||||
|
/// \{
|
||||||
|
|
||||||
|
/// \}
|
|
@ -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 <common/oplkinc.h>
|
||||||
|
#include <common/ftracedebug.h>
|
||||||
|
#include <kernel/edrv.h>
|
||||||
|
#include <common/target.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <xsconfig.h>
|
||||||
|
|
||||||
|
//============================================================================//
|
||||||
|
// 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;
|
||||||
|
}
|
|
@ -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 <common/oplkinc.h>
|
||||||
|
#include <kernel/eventkcal.h>
|
||||||
|
#include <kernel/eventkcalintf.h>
|
||||||
|
#include <common/target.h>
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
#include <common/target.h>
|
||||||
|
|
||||||
|
//============================================================================//
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \}
|
|
@ -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 <common/oplkinc.h>
|
||||||
|
#include <common/ftracedebug.h>
|
||||||
|
#include <common/target.h>
|
||||||
|
#include <kernel/hrestimer.h>
|
||||||
|
|
||||||
|
#include <semaphore.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
//============================================================================//
|
||||||
|
// 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
|
||||||
|
|
||||||
|
/// \}
|
|
@ -846,6 +846,8 @@ static tOplkError downloadCycleLength(tCfmNodeInfo* pNodeInfo_p)
|
||||||
pNodeInfo_p->eventCnProgress.nodeId,
|
pNodeInfo_p->eventCnProgress.nodeId,
|
||||||
ret);
|
ret);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
UNUSED_PARAMETER(pNodeInfo_p);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -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 <common/oplkinc.h>
|
||||||
|
#include <user/eventucal.h>
|
||||||
|
#include <user/eventucalintf.h>
|
||||||
|
#include <common/target.h>
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
#include <common/target.h>
|
||||||
|
|
||||||
|
//============================================================================//
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \}
|
|
@ -63,6 +63,11 @@ extern "C" {
|
||||||
typedef int pid_t;
|
typedef int pid_t;
|
||||||
// typedef int pthread_mutex_t ;
|
// typedef int pthread_mutex_t ;
|
||||||
|
|
||||||
|
/* scheduling algorithms */
|
||||||
|
#define SCHED_OTHER 0
|
||||||
|
#define SCHED_FIFO 1
|
||||||
|
#define SCHED_RR 2
|
||||||
|
|
||||||
/* function in pthread.c */
|
/* function in pthread.c */
|
||||||
int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));
|
int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));
|
||||||
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||||
|
|
|
@ -34,7 +34,7 @@ menu "aiit-arm32-board feature"
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "config hardware resources for connection"
|
menu "config hardware resources for connection"
|
||||||
if CONNECTION_COMMUNICATION_ETHERNET
|
if CONNECTION_INDUSTRIAL_ETHERNET
|
||||||
config ETHERNET_UART_NAME
|
config ETHERNET_UART_NAME
|
||||||
string "ethernet uart name"
|
string "ethernet uart name"
|
||||||
default "/dev/usart3_dev3"
|
default "/dev/usart3_dev3"
|
||||||
|
|
|
@ -36,7 +36,7 @@ menu "aiit-riscv64-board feature"
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "config hardware resources for connection"
|
menu "config hardware resources for connection"
|
||||||
if CONNECTION_COMMUNICATION_ETHERNET
|
if CONNECTION_INDUSTRIAL_ETHERNET
|
||||||
config ETHERNET_UART_NAME
|
config ETHERNET_UART_NAME
|
||||||
string "ethernet uart name"
|
string "ethernet uart name"
|
||||||
default "/dev/uart3_dev3"
|
default "/dev/uart3_dev3"
|
||||||
|
|
|
@ -34,7 +34,7 @@ menu "cortex-m4-emulator feature"
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "config hardware resources for connection"
|
menu "config hardware resources for connection"
|
||||||
if CONNECTION_COMMUNICATION_ETHERNET
|
if CONNECTION_INDUSTRIAL_ETHERNET
|
||||||
config ETHERNET_UART_NAME
|
config ETHERNET_UART_NAME
|
||||||
string "ethernet uart name"
|
string "ethernet uart name"
|
||||||
default "/dev/usart3_dev3"
|
default "/dev/usart3_dev3"
|
||||||
|
|
|
@ -35,7 +35,7 @@ menu "gapuino feature"
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "config hardware resources for connection"
|
menu "config hardware resources for connection"
|
||||||
if CONNECTION_COMMUNICATION_ETHERNET
|
if CONNECTION_INDUSTRIAL_ETHERNET
|
||||||
config ETHERNET_UART_NAME
|
config ETHERNET_UART_NAME
|
||||||
string "ethernet uart name"
|
string "ethernet uart name"
|
||||||
default "/dev/uart3_dev3"
|
default "/dev/uart3_dev3"
|
||||||
|
|
|
@ -45,7 +45,7 @@ menu "kd233 feature"
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "config hardware resources for connection"
|
menu "config hardware resources for connection"
|
||||||
if CONNECTION_COMMUNICATION_ETHERNET
|
if CONNECTION_INDUSTRIAL_ETHERNET
|
||||||
config ETHERNET_UART_NAME
|
config ETHERNET_UART_NAME
|
||||||
string "ethernet uart name"
|
string "ethernet uart name"
|
||||||
default "/dev/uart3_dev3"
|
default "/dev/uart3_dev3"
|
||||||
|
|
|
@ -45,7 +45,7 @@ menu "kd233 feature"
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "config hardware resources for connection"
|
menu "config hardware resources for connection"
|
||||||
if CONNECTION_COMMUNICATION_ETHERNET
|
if CONNECTION_INDUSTRIAL_ETHERNET
|
||||||
config ETHERNET_UART_NAME
|
config ETHERNET_UART_NAME
|
||||||
string "ethernet uart name"
|
string "ethernet uart name"
|
||||||
default "/dev/uart3_dev3"
|
default "/dev/uart3_dev3"
|
||||||
|
|
|
@ -34,7 +34,7 @@ menu "stm32f407-st-discovery feature"
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "config hardware resources for connection"
|
menu "config hardware resources for connection"
|
||||||
if CONNECTION_COMMUNICATION_ETHERNET
|
if CONNECTION_INDUSTRIAL_ETHERNET
|
||||||
config ETHERNET_UART_NAME
|
config ETHERNET_UART_NAME
|
||||||
string "ethernet uart name"
|
string "ethernet uart name"
|
||||||
default "/dev/usart3_dev3"
|
default "/dev/usart3_dev3"
|
||||||
|
|
|
@ -33,7 +33,7 @@ menu "stm32f407zgt6 feature"
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "config hardware resources for connection"
|
menu "config hardware resources for connection"
|
||||||
if CONNECTION_COMMUNICATION_ETHERNET
|
if CONNECTION_INDUSTRIAL_ETHERNET
|
||||||
config ETHERNET_UART_NAME
|
config ETHERNET_UART_NAME
|
||||||
string "ethernet uart name"
|
string "ethernet uart name"
|
||||||
default "/dev/usart3_dev3"
|
default "/dev/usart3_dev3"
|
||||||
|
|
|
@ -77,6 +77,16 @@ $(if $(strip $(LOCALS)),$(eval $(LOCALS): $(1)
|
||||||
@$(CROSS_COMPILE)gcc $$(AFLAGS) -c $$< -o $$@))
|
@$(CROSS_COMPILE)gcc $$(AFLAGS) -c $$< -o $$@))
|
||||||
endef
|
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)))
|
SRCS := $(strip $(filter %.S,$(SRC_FILES)))
|
||||||
$(if $(SRCS),$(foreach f,$(SRCS),$(call add_S_file,$(addprefix $(CUR_DIR)/,$(f)))))
|
$(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)
|
COMPILER:$(OBJS)
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
current_path=$(pwd)
|
current_path=$(pwd)
|
||||||
xizi_path=Ubiquitous/XiZi
|
xizi_path=Ubiquitous/XiZi
|
||||||
board=cortex-m3-emulator
|
board=cortex-m4-emulator
|
||||||
qemu_machine=lm3s6965evb
|
qemu_machine=netduinoplus2
|
||||||
|
|
||||||
run_in_docker() {
|
run_in_docker() {
|
||||||
docker run \
|
docker run \
|
||||||
|
@ -31,11 +31,11 @@ distclean() {
|
||||||
}
|
}
|
||||||
|
|
||||||
simulate() {
|
simulate() {
|
||||||
[ "$1" = "debug" ] && debug_param="-s -S"
|
|
||||||
qemu-system-arm $debug_param \
|
qemu-system-arm $debug_param \
|
||||||
-machine $qemu_machine \
|
-machine $qemu_machine \
|
||||||
-nographic \
|
-nographic \
|
||||||
-kernel $xizi_path/build/XiZi_$board.elf
|
-kernel $xizi_path/build/XiZi_$board.elf \
|
||||||
|
$@
|
||||||
}
|
}
|
||||||
|
|
||||||
gdb() {
|
gdb() {
|
||||||
|
|
Loading…
Reference in New Issue