Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for circle barebone environment on Raspberry Pi 3 #289

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "libs/circle-stdlib"]
path = libs/circle-stdlib
url = https://github.com/smuehlst/circle-stdlib.git
20 changes: 16 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 2.8.4)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules")
project(SOEM C)
project(SOEM C CXX)

if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
# Default to installing in SOEM source directory
Expand Down Expand Up @@ -43,13 +43,23 @@ elseif(${CMAKE_SYSTEM_NAME} MATCHES "rtems")
set(OS "rtems")
set(SOEM_LIB_INSTALL_DIR ${LIB_DIR})
set(BUILD_TESTS FALSE)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "circle")
set(OS "circle")
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DAARCH=32 -march=armv8-a -mtune=cortex-a53 -marm -mfpu=neon-fp-armv8 -mfloat-abi=hard")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DAARCH=32 -march=armv8-a -mtune=cortex-a53 -marm -mfpu=neon-fp-armv8 -mfloat-abi=hard")
include_directories(./libs/circle-stdlib/libs/circle/include)
include_directories(./libs/circle-stdlib/libs/circle-newlib/include)
include_directories(./libs/circle-stdlib/libs/circle-newlib/newlib/libc/include)
include_directories(./libs/circle-stdlib/libs/circle-newlib/newlib/libm/include)
endif()

message("OS is ${OS}")

file(GLOB SOEM_SOURCES soem/*.c)
file(GLOB OSAL_SOURCES osal/${OS}/*.c)
file(GLOB OSHW_SOURCES oshw/${OS}/*.c)
file(GLOB OSAL_SOURCES osal/${OS}/*.c osal/${OS}/*.cpp)
file(GLOB OSHW_SOURCES oshw/${OS}/*.c oshw/${OS}/*.cpp)

file(GLOB SOEM_HEADERS soem/*.h)
file(GLOB OSAL_HEADERS osal/osal.h osal/${OS}/*.h)
Expand All @@ -76,7 +86,9 @@ install(FILES
${OSHW_HEADERS}
DESTINATION ${SOEM_INCLUDE_INSTALL_DIR})

if(BUILD_TESTS)
if(${OS} MATCHES "circle")

elseif(BUILD_TESTS)
add_subdirectory(test/linux/slaveinfo)
add_subdirectory(test/linux/eepromtool)
add_subdirectory(test/linux/simple_test)
Expand Down
26 changes: 26 additions & 0 deletions build_rpi_3.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

#execute in a MSYS2-MINGW32 shell, with arm-none-eabi-gcc already in path.
#export PATH=$PATH:/h/Qt/gcc-arm-none-eabi-8-2018-q4-major-win32/bin

if [ "$1" == "" ]; then
#/h/Qt/gcc-arm-none-eabi-8-2018-q4-major-win32/lib/gcc/arm-none-eabi/8.2.1/include
echo "Usage: build_rpi_3.sh <path to stddef.h>"
exit
fi

export HOMEDIR=$PWD

cd $HOMEDIR/libs/circle-stdlib
./configure -r 3 -s $1
make

cd $HOMEDIR
mkdir build
cd build
cmake -D CMAKE_SYSTEM_NAME=circle ../
make





1 change: 1 addition & 0 deletions libs/circle-stdlib
Submodule circle-stdlib added at dda161
137 changes: 137 additions & 0 deletions osal/circle/cethercatmaster.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#include "cethercatmaster.h"
#include <circle/sched/scheduler.h>
#include <circle/synchronize.h>
#include <circle/timer.h>
#include <circle/types.h>
#include <circle/alloc.h>
#include <assert.h>
#include <osal.h>
#include <time.h>

CEtherCATMaster *_instance = 0L;

CEtherCATMaster::CEtherCATMaster(bool use_scheduler)
: _use_scheduler(use_scheduler)
{
// Cannot create more than one instance
assert(_instance == 0L);

_instance = this;
}

bool CEtherCATMaster::IsSchedulerFriendly() const
{
return _use_scheduler;
}

bool CEtherCATMaster::IsActive()
{
return (_instance != 0L);
}

CEtherCATMaster *CEtherCATMaster::Get()
{
assert(_instance != 0L);

return _instance;
}

int osal_usleep(uint32 usec)
{
if (!CScheduler::IsActive()) {
// Busy-waiting sleep
CTimer::SimpleusDelay(usec);
} else if (!CEtherCATMaster::IsActive()) {
// Busy-waiting sleep
CTimer::SimpleusDelay(usec);
} else if (!CEtherCATMaster::Get()->IsSchedulerFriendly()) {
// Busy-waiting sleep
CTimer::SimpleusDelay(usec);
} else {
// Scheduler-friendly sleep
CScheduler::Get()->usSleep(usec);
}
return 0;
}

static long long get_monotonic_clock()
{
// Copied from circle's timer, using both words to get 64bit monotonic clock
InstructionSyncBarrier();

u32 nCNTPCTLow, nCNTPCTHigh;
asm volatile ("mrrc p15, 0, %0, %1, c14" : "=r" (nCNTPCTLow), "=r" (nCNTPCTHigh));

return (((long long)nCNTPCTHigh) << 32) | nCNTPCTLow;
}

int osal_gettimeofday(struct timeval *tv, struct timezone *tz)
{
long long usec = get_monotonic_clock();

tv->tv_sec = usec / 1000000LL;
tv->tv_usec = usec % 1000000LL;
return 0;
}

ec_timet osal_current_time(void)
{
struct timeval current_time;
ec_timet return_value;

osal_gettimeofday(&current_time, 0);
return_value.sec = current_time.tv_sec;
return_value.usec = current_time.tv_usec;
return return_value;
}

void osal_time_diff(ec_timet *start, ec_timet *end, ec_timet *diff)
{
if (end->usec < start->usec) {
diff->sec = end->sec - start->sec - 1;
diff->usec = end->usec + 1000000 - start->usec;
} else {
diff->sec = end->sec - start->sec;
diff->usec = end->usec - start->usec;
}
}

void osal_timer_start(osal_timert * self, uint32 timeout_usec)
{
long long stop_time_usec = get_monotonic_clock() + (long long)timeout_usec;

self->stop_time.sec = stop_time_usec / 1000000LL;
self->stop_time.usec = stop_time_usec % 1000000LL;
}

boolean osal_timer_is_expired(osal_timert * self)
{
long long now_usec = get_monotonic_clock();
long long stop_time_usec = self->stop_time.sec * 1000000LL + self->stop_time.usec;

return (now_usec >= stop_time_usec);
}

void *osal_malloc(size_t size)
{
// Use circle's malloc
return malloc(size);
}

void osal_free(void *ptr)
{
// Use circle's free
free(ptr);
}

int osal_thread_create(void *thandle, int stacksize, void *func, void *param)
{
// Not supported
return 0;
}

int osal_thread_create_rt(void *thandle, int stacksize, void *func, void *param)
{
// Not supported
return 0;
}
19 changes: 19 additions & 0 deletions osal/circle/cethercatmaster.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef CETHERCATMASTER_H
#define CETHERCATMASTER_H

class CEtherCATMaster
{
public:
CEtherCATMaster(bool use_scheduler);

bool IsSchedulerFriendly() const;

static bool IsActive();
static CEtherCATMaster* Get();

private:

bool _use_scheduler;
};

#endif // CETHERCATMASTER_H
102 changes: 102 additions & 0 deletions osal/circle/osal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include <circle/sched/scheduler.h>
#include <circle/synchronize.h>
#include <circle/timer.h>
#include <circle/types.h>
#include <circle/alloc.h>
#include <assert.h>
#include <osal.h>
#include <time.h>

int osal_usleep(uint32 usec)
{
if (CScheduler::IsActive()) {
// Scheduler-friendly sleep
CScheduler::Get()->usSleep(usec);
} else {
// Busy-waiting sleep
CTimer::SimpleusDelay(usec);
}
return 0;
}

static long long get_monotonic_clock()
{
// Copied from circle's timer, using both words to get 64bit monotonic clock
InstructionSyncBarrier();

u32 nCNTPCTLow, nCNTPCTHigh;
asm volatile ("mrrc p15, 0, %0, %1, c14" : "=r" (nCNTPCTLow), "=r" (nCNTPCTHigh));

return (((long long)nCNTPCTHigh) << 32) | nCNTPCTLow;
}

int osal_gettimeofday(struct timeval *tv, struct timezone *tz)
{
long long usec = get_monotonic_clock();

tv->tv_sec = usec / 1000000LL;
tv->tv_usec = usec % 1000000LL;
return 0;
}

ec_timet osal_current_time(void)
{
struct timeval current_time;
ec_timet return_value;

osal_gettimeofday(&current_time, 0);
return_value.sec = current_time.tv_sec;
return_value.usec = current_time.tv_usec;
return return_value;
}

void osal_time_diff(ec_timet *start, ec_timet *end, ec_timet *diff)
{
if (end->usec < start->usec) {
diff->sec = end->sec - start->sec - 1;
diff->usec = end->usec + 1000000 - start->usec;
} else {
diff->sec = end->sec - start->sec;
diff->usec = end->usec - start->usec;
}
}

void osal_timer_start(osal_timert * self, uint32 timeout_usec)
{
long long stop_time_usec = get_monotonic_clock() + (long long)timeout_usec;

self->stop_time.sec = stop_time_usec / 1000000LL;
self->stop_time.usec = stop_time_usec % 1000000LL;
}

boolean osal_timer_is_expired(osal_timert * self)
{
long long now_usec = get_monotonic_clock();
long long stop_time_usec = self->stop_time.sec * 1000000LL + self->stop_time.usec;

return (now_usec >= stop_time_usec);
}

void *osal_malloc(size_t size)
{
// Use circle's malloc
return malloc(size);
}

void osal_free(void *ptr)
{
// Use circle's free
free(ptr);
}

int osal_thread_create(void *thandle, int stacksize, void *func, void *param)
{
// Not supported
return 0;
}

int osal_thread_create_rt(void *thandle, int stacksize, void *func, void *param)
{
// Not supported
return 0;
}
44 changes: 44 additions & 0 deletions osal/circle/osal_defs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/

#ifndef _osal_defs_
#define _osal_defs_

#include <circle/types.h>
#include <circle/macros.h>

#define _osal_defs_circle_

#ifdef __cplusplus
extern "C"
{
#endif

// define if debug printf is needed
//#define EC_DEBUG

#ifdef EC_DEBUG
#define EC_PRINT printf
#else
#define EC_PRINT(...) do {} while (0)
#endif

#ifndef PACKED_BEGIN
#define PACKED_BEGIN
#endif

#ifndef PACKED_END
#define PACKED_END
#endif

#define OSAL_THREAD_HANDLE void *
#define OSAL_THREAD_FUNC void
#define OSAL_THREAD_FUNC_RT void

#ifdef __cplusplus
}
#endif

#endif
3 changes: 3 additions & 0 deletions osal/osal.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ extern "C"
#include <stdint.h>

/* General types */
#ifndef _osal_defs_circle_
typedef uint8_t boolean;
#define TRUE 1
#define FALSE 0
#endif // _osal_defs_circle_

typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
Expand Down
Loading