- HAL: added thread/semaphore support for MacOS

pull/246/head
Michael Zillgith 5 years ago
parent 02f03aea2f
commit cf7dbcc612

@ -1,183 +1,192 @@
cmake_minimum_required(VERSION 2.8) cmake_minimum_required(VERSION 2.8)
# automagically detect if we should cross-compile # automagically detect if we should cross-compile
if(DEFINED ENV{TOOLCHAIN}) if(DEFINED ENV{TOOLCHAIN})
set(CMAKE_C_COMPILER $ENV{TOOLCHAIN}gcc) set(CMAKE_C_COMPILER $ENV{TOOLCHAIN}gcc)
set(CMAKE_CXX_COMPILER $ENV{TOOLCHAIN}g++) set(CMAKE_CXX_COMPILER $ENV{TOOLCHAIN}g++)
set(CMAKE_AR "$ENV{TOOLCHAIN}ar" CACHE FILEPATH "CW archiver" FORCE) set(CMAKE_AR "$ENV{TOOLCHAIN}ar" CACHE FILEPATH "CW archiver" FORCE)
endif() endif()
project(hal) project(hal)
set(LIBHAL_VERSION_MAJOR "2") set(LIBHAL_VERSION_MAJOR "2")
set(LIBHAL_VERSION_MINOR "0") set(LIBHAL_VERSION_MINOR "0")
set(LIBHAL_VERSION_PATCH "0") set(LIBHAL_VERSION_PATCH "0")
# feature checks # feature checks
include(CheckLibraryExists) include(CheckLibraryExists)
check_library_exists(rt clock_gettime "time.h" CONFIG_SYSTEM_HAS_CLOCK_GETTIME) check_library_exists(rt clock_gettime "time.h" CONFIG_SYSTEM_HAS_CLOCK_GETTIME)
# check if we are on a little or a big endian # check if we are on a little or a big endian
include (TestBigEndian) include (TestBigEndian)
test_big_endian(PLATFORM_IS_BIGENDIAN) test_big_endian(PLATFORM_IS_BIGENDIAN)
if(WIN32) if(WIN32)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/wpcap.lib") if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/wpcap.lib")
message("Found winpcap -> compile ethernet HAL layer (required for GOOSE/SV support)") message("Found winpcap -> compile ethernet HAL layer (required for GOOSE/SV support)")
set(WITH_WPCAP 1) set(WITH_WPCAP 1)
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Include") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Include")
else() else()
message("winpcap not found -> skip ethernet HAL layer (no GOOSE/SV support)") message("winpcap not found -> skip ethernet HAL layer (no GOOSE/SV support)")
endif() endif()
endif(WIN32) endif(WIN32)
include_directories( include_directories(
${CMAKE_CURRENT_LIST_DIR}/inc ${CMAKE_CURRENT_LIST_DIR}/inc
) )
set (libhal_linux_SRCS set (libhal_linux_SRCS
${CMAKE_CURRENT_LIST_DIR}/socket/linux/socket_linux.c ${CMAKE_CURRENT_LIST_DIR}/socket/linux/socket_linux.c
${CMAKE_CURRENT_LIST_DIR}/ethernet/linux/ethernet_linux.c ${CMAKE_CURRENT_LIST_DIR}/ethernet/linux/ethernet_linux.c
${CMAKE_CURRENT_LIST_DIR}/thread/linux/thread_linux.c ${CMAKE_CURRENT_LIST_DIR}/thread/linux/thread_linux.c
${CMAKE_CURRENT_LIST_DIR}/filesystem/linux/file_provider_linux.c ${CMAKE_CURRENT_LIST_DIR}/filesystem/linux/file_provider_linux.c
${CMAKE_CURRENT_LIST_DIR}/time/unix/time.c ${CMAKE_CURRENT_LIST_DIR}/time/unix/time.c
${CMAKE_CURRENT_LIST_DIR}/serial/linux/serial_port_linux.c ${CMAKE_CURRENT_LIST_DIR}/serial/linux/serial_port_linux.c
${CMAKE_CURRENT_LIST_DIR}/memory/lib_memory.c ${CMAKE_CURRENT_LIST_DIR}/memory/lib_memory.c
) )
set (libhal_windows_SRCS set (libhal_windows_SRCS
${CMAKE_CURRENT_LIST_DIR}/socket/win32/socket_win32.c ${CMAKE_CURRENT_LIST_DIR}/socket/win32/socket_win32.c
${CMAKE_CURRENT_LIST_DIR}/thread/win32/thread_win32.c ${CMAKE_CURRENT_LIST_DIR}/thread/win32/thread_win32.c
${CMAKE_CURRENT_LIST_DIR}/filesystem/win32/file_provider_win32.c ${CMAKE_CURRENT_LIST_DIR}/filesystem/win32/file_provider_win32.c
${CMAKE_CURRENT_LIST_DIR}/time/win32/time.c ${CMAKE_CURRENT_LIST_DIR}/time/win32/time.c
${CMAKE_CURRENT_LIST_DIR}/serial/win32/serial_port_win32.c ${CMAKE_CURRENT_LIST_DIR}/serial/win32/serial_port_win32.c
${CMAKE_CURRENT_LIST_DIR}/memory/lib_memory.c ${CMAKE_CURRENT_LIST_DIR}/memory/lib_memory.c
) )
if(WITH_WPCAP) if(WITH_WPCAP)
set (libhal_windows_SRCS ${libhal_windows_SRCS} set (libhal_windows_SRCS ${libhal_windows_SRCS}
${CMAKE_CURRENT_LIST_DIR}/ethernet/win32/ethernet_win32.c ${CMAKE_CURRENT_LIST_DIR}/ethernet/win32/ethernet_win32.c
) )
endif(WITH_WPCAP) endif(WITH_WPCAP)
set (libhal_bsd_SRCS set (libhal_bsd_SRCS
${CMAKE_CURRENT_LIST_DIR}/socket/bsd/socket_bsd.c ${CMAKE_CURRENT_LIST_DIR}/socket/bsd/socket_bsd.c
${CMAKE_CURRENT_LIST_DIR}/ethernet/bsd/ethernet_bsd.c ${CMAKE_CURRENT_LIST_DIR}/ethernet/bsd/ethernet_bsd.c
${CMAKE_CURRENT_LIST_DIR}/thread/bsd/thread_bsd.c ${CMAKE_CURRENT_LIST_DIR}/thread/bsd/thread_macos.c
${CMAKE_CURRENT_LIST_DIR}/filesystem/linux/file_provider_linux.c ${CMAKE_CURRENT_LIST_DIR}/filesystem/linux/file_provider_linux.c
${CMAKE_CURRENT_LIST_DIR}/time/unix/time.c ${CMAKE_CURRENT_LIST_DIR}/time/unix/time.c
${CMAKE_CURRENT_LIST_DIR}/memory/lib_memory.c ${CMAKE_CURRENT_LIST_DIR}/memory/lib_memory.c
) )
IF(WIN32) set (libhal_macos_SRCS
${CMAKE_CURRENT_LIST_DIR}/socket/bsd/socket_bsd.c
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/wpcap.lib") ${CMAKE_CURRENT_LIST_DIR}/ethernet/bsd/ethernet_bsd.c
message("Found winpcap -> can compile with GOOSE support") ${CMAKE_CURRENT_LIST_DIR}/thread/macos/thread_macos.c
set(WITH_WPCAP 1) ${CMAKE_CURRENT_LIST_DIR}/filesystem/linux/file_provider_linux.c
endif() ${CMAKE_CURRENT_LIST_DIR}/time/unix/time.c
${CMAKE_CURRENT_LIST_DIR}/memory/lib_memory.c
set (libhal_SRCS )
${libhal_windows_SRCS}
) IF(WIN32)
IF(MSVC) if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/wpcap.lib")
set_source_files_properties(${libhal_SRCS} message("Found winpcap -> can compile with GOOSE support")
PROPERTIES LANGUAGE CXX) set(WITH_WPCAP 1)
ENDIF() endif()
ELSEIF(UNIX) set (libhal_SRCS
IF(APPLE) ${libhal_windows_SRCS}
set (libhal_SRCS )
${libhal_bsd_SRCS}
) IF(MSVC)
ELSEIF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") set_source_files_properties(${libhal_SRCS}
set (libhal_SRCS PROPERTIES LANGUAGE CXX)
${libhal_bsd_SRCS} ENDIF()
)
ELSE() ELSEIF(UNIX)
set (libhal_SRCS IF(APPLE)
${libhal_linux_SRCS} set (libhal_SRCS
) ${libhal_macos_SRCS}
ENDIF(APPLE) )
ENDIF(WIN32) ELSEIF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
set (libhal_SRCS
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" ) ${libhal_bsd_SRCS}
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC" ) )
ELSE()
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.16) set (libhal_SRCS
message("Found mbedtls -> can compile with TLS support") ${libhal_linux_SRCS}
set(WITH_MBEDTLS 1) )
endif(EXISTS ${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.16) ENDIF(APPLE)
ENDIF(WIN32)
if(WITH_MBEDTLS)
include_directories( #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" )
${CMAKE_CURRENT_LIST_DIR}/tls/mbedtls #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC" )
${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.16/include
) if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.16)
message("Found mbedtls -> can compile with TLS support")
file(GLOB tls_SRCS ${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.16/library/*.c) set(WITH_MBEDTLS 1)
endif(EXISTS ${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.16)
add_definitions(-DMBEDTLS_CONFIG_FILE="mbedtls_config.h")
if(WITH_MBEDTLS)
set (libhal_SRCS ${libhal_SRCS} include_directories(
${CMAKE_CURRENT_LIST_DIR}/tls/mbedtls/tls_mbedtls.c ${CMAKE_CURRENT_LIST_DIR}/tls/mbedtls
) ${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.16/include
)
IF(MSVC)
set_source_files_properties(${libhal_SRCS} file(GLOB tls_SRCS ${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.16/library/*.c)
PROPERTIES LANGUAGE CXX)
ENDIF() add_definitions(-DMBEDTLS_CONFIG_FILE="mbedtls_config.h")
list (APPEND libhal_SRCS ${tls_SRCS}) set (libhal_SRCS ${libhal_SRCS}
${CMAKE_CURRENT_LIST_DIR}/tls/mbedtls/tls_mbedtls.c
endif(WITH_MBEDTLS) )
add_library (hal STATIC ${libhal_SRCS}) IF(MSVC)
set_source_files_properties(${libhal_SRCS}
add_library (hal-shared STATIC ${libhal_SRCS}) PROPERTIES LANGUAGE CXX)
ENDIF()
target_compile_definitions(hal-shared PRIVATE EXPORT_FUNCTIONS_FOR_DLL)
list (APPEND libhal_SRCS ${tls_SRCS})
SET_TARGET_PROPERTIES(hal-shared PROPERTIES
COMPILE_FLAGS "-fPIC" endif(WITH_MBEDTLS)
)
add_library (hal STATIC ${libhal_SRCS})
IF(UNIX)
IF (CONFIG_SYSTEM_HAS_CLOCK_GETTIME) add_library (hal-shared STATIC ${libhal_SRCS})
target_link_libraries (hal
-lpthread target_compile_definitions(hal-shared PRIVATE EXPORT_FUNCTIONS_FOR_DLL)
-lrt
) SET_TARGET_PROPERTIES(hal-shared PROPERTIES
ELSE () COMPILE_FLAGS "-fPIC"
target_link_libraries (hal )
-lpthread
) IF(UNIX)
ENDIF (CONFIG_SYSTEM_HAS_CLOCK_GETTIME) IF (CONFIG_SYSTEM_HAS_CLOCK_GETTIME)
ENDIF(UNIX) target_link_libraries (hal
IF(MINGW) -lpthread
target_link_libraries(hal ws2_32 iphlpapi) -lrt
ENDIF(MINGW) )
ELSE ()
iF(WITH_WPCAP) target_link_libraries (hal
target_link_libraries(hal -lpthread
${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/wpcap.lib )
${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/packet.lib ENDIF (CONFIG_SYSTEM_HAS_CLOCK_GETTIME)
) ENDIF(UNIX)
ENDIF(WITH_WPCAP) IF(MINGW)
target_link_libraries(hal ws2_32 iphlpapi)
set(BINDIR "bin") ENDIF(MINGW)
set(LIBDIR "lib")
if(UNIX) iF(WITH_WPCAP)
# GNUInstallDirs is required for Debian multiarch target_link_libraries(hal
include(GNUInstallDirs) ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/wpcap.lib
set(LIBDIR ${CMAKE_INSTALL_LIBDIR}) ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/packet.lib
set(BINDIR ${CMAKE_INSTALL_BINDIR}) )
endif() ENDIF(WITH_WPCAP)
install (TARGETS hal hal-shared set(BINDIR "bin")
RUNTIME DESTINATION ${BINDIR} COMPONENT Applications set(LIBDIR "lib")
ARCHIVE DESTINATION ${LIBDIR} COMPONENT Libraries if(UNIX)
LIBRARY DESTINATION ${LIBDIR} COMPONENT Libraries # GNUInstallDirs is required for Debian multiarch
) include(GNUInstallDirs)
set(LIBDIR ${CMAKE_INSTALL_LIBDIR})
set(BINDIR ${CMAKE_INSTALL_BINDIR})
endif()
install (TARGETS hal hal-shared
RUNTIME DESTINATION ${BINDIR} COMPONENT Applications
ARCHIVE DESTINATION ${LIBDIR} COMPONENT Libraries
LIBRARY DESTINATION ${LIBDIR} COMPONENT Libraries
)

@ -34,6 +34,7 @@
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h>
#include "lib_memory.h" #include "lib_memory.h"
#include "hal_ethernet.h" #include "hal_ethernet.h"
@ -390,7 +391,7 @@ Ethernet_receivePacket(EthernetSocket self, uint8_t* buffer, int bufferSize)
/* Check if the target buffer is big enough to hold the received ethernet frame. */ /* Check if the target buffer is big enough to hold the received ethernet frame. */
if ((unsigned int) bufferSize >= header->bh_caplen) if ((unsigned int) bufferSize >= header->bh_caplen)
{ {
/* Copy the frame to the target buffer. /* Copy the frame to the target buffer. */
memcpy(buffer, self->bpfPositon + header->bh_hdrlen, header->bh_caplen); memcpy(buffer, self->bpfPositon + header->bh_hdrlen, header->bh_caplen);
/* Move the read pointer to the next ethernet frame header WORD ALIGNED (Took me a while to find that out). */ /* Move the read pointer to the next ethernet frame header WORD ALIGNED (Took me a while to find that out). */

@ -0,0 +1,124 @@
/**
* thread_macos.c
*
* Copyright 2013-2019 MZ Automation GmbH
*
* This file is part of Platform Abstraction Layer (libpal)
* for libiec61850, libmms, and lib60870.
*/
/*
* NOTE: MacOS needs own thread layer because it doesn't support unnamed semaphores!
*/
#include <pthread.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include "hal_thread.h"
#include "lib_memory.h"
struct sThread {
ThreadExecutionFunction function;
void* parameter;
pthread_t pthread;
int state;
bool autodestroy;
};
Semaphore
Semaphore_create(int initialValue)
{
char tmpname[] = {"/tmp/libiec61850.XXXXXX"};
mktemp(tmpname);
Semaphore self = (Semaphore) sem_open(tmpname, O_CREAT, 0666, initialValue);
if (self == SEM_FAILED) {
printf("ERROR: Failed to create semaphore (errno = %i)\n", errno);
}
int ret = sem_unlink(tmpname);
if (ret == -1)
printf("ERROR: Failed to unlink semaphore %s\n", tmpname);
return self;
}
/* Wait until semaphore value is more than zero. Then decrease the semaphore value. */
void
Semaphore_wait(Semaphore self)
{
sem_wait((sem_t*) self);
}
void
Semaphore_post(Semaphore self)
{
sem_post((sem_t*) self);
}
void
Semaphore_destroy(Semaphore self)
{
sem_close(self);
}
Thread
Thread_create(ThreadExecutionFunction function, void* parameter, bool autodestroy)
{
Thread thread = (Thread) GLOBAL_MALLOC(sizeof(struct sThread));
if (thread != NULL) {
thread->parameter = parameter;
thread->function = function;
thread->state = 0;
thread->autodestroy = autodestroy;
}
return thread;
}
static void*
destroyAutomaticThread(void* parameter)
{
Thread thread = (Thread) parameter;
thread->function(thread->parameter);
GLOBAL_FREEMEM(thread);
pthread_exit(NULL);
}
void
Thread_start(Thread thread)
{
if (thread->autodestroy == true) {
pthread_create(&thread->pthread, NULL, destroyAutomaticThread, thread);
pthread_detach(thread->pthread);
}
else
pthread_create(&thread->pthread, NULL, thread->function, thread->parameter);
thread->state = 1;
}
void
Thread_destroy(Thread thread)
{
if (thread->state == 1) {
pthread_join(thread->pthread, NULL);
}
GLOBAL_FREEMEM(thread);
}
void
Thread_sleep(int millies)
{
usleep(millies * 1000);
}
Loading…
Cancel
Save