mirror of
https://github.com/OpenEtherCATsociety/SOEM.git
synced 2026-03-25 09:23:02 +08:00
This commit adds osal_get_monotonic_time() and osal_monotonic_sleep(). These functions are designed to facilitate synchronization with DC time, which can achieve nanosecond precision. To support this functionality, the ec_timet structure has been refactored to hold time values in nanoseconds, eliminating the need to maintain separate time representations. Change-Id: I039a006ccdb21ba35c437ab76e44e5153c711998
155 lines
3.5 KiB
C
155 lines
3.5 KiB
C
/*
|
|
* This software is dual-licensed under GPLv3 and a commercial
|
|
* license. See the file LICENSE.md distributed with this software for
|
|
* full license information.
|
|
*/
|
|
#include <osal.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
/* Returns time from some unspecified moment in past,
|
|
* strictly increasing, used for time intervals measurement. */
|
|
void osal_get_monotonic_time(ec_timet *ts)
|
|
{
|
|
/* Use clock_gettime to prevent possible live-lock.
|
|
* Gettimeofday uses CLOCK_REALTIME that can get NTP timeadjust.
|
|
* If this function preempts timeadjust and it uses vpage it live-locks.
|
|
* Also when using XENOMAI, only clock_gettime is RT safe */
|
|
clock_gettime(CLOCK_MONOTONIC, ts);
|
|
}
|
|
|
|
ec_timet osal_current_time(void)
|
|
{
|
|
struct timespec ts;
|
|
|
|
clock_gettime(CLOCK_REALTIME, &ts);
|
|
return ts;
|
|
}
|
|
|
|
void osal_time_diff(ec_timet *start, ec_timet *end, ec_timet *diff)
|
|
{
|
|
osal_timespecsub(end, start, diff);
|
|
}
|
|
|
|
void osal_timer_start(osal_timert *self, uint32 timeout_usec)
|
|
{
|
|
struct timespec start_time;
|
|
struct timespec timeout;
|
|
|
|
osal_get_monotonic_time(&start_time);
|
|
osal_timespec_from_usec(timeout_usec, &timeout);
|
|
osal_timespecadd(&start_time, &timeout, &self->stop_time);
|
|
}
|
|
|
|
boolean osal_timer_is_expired(osal_timert *self)
|
|
{
|
|
struct timespec current_time;
|
|
int is_not_yet_expired;
|
|
|
|
osal_get_monotonic_time(¤t_time);
|
|
is_not_yet_expired = osal_timespeccmp(¤t_time, &self->stop_time, <);
|
|
|
|
return is_not_yet_expired == FALSE;
|
|
}
|
|
|
|
int osal_usleep(uint32 usec)
|
|
{
|
|
struct timespec ts;
|
|
int result;
|
|
|
|
osal_timespec_from_usec(usec, &ts);
|
|
result = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
|
|
return result == 0 ? 0 : -1;
|
|
}
|
|
|
|
int osal_monotonic_sleep(ec_timet *ts)
|
|
{
|
|
int result;
|
|
result = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ts, NULL);
|
|
return result == 0 ? 0 : -1;
|
|
}
|
|
|
|
void *osal_malloc(size_t size)
|
|
{
|
|
return malloc(size);
|
|
}
|
|
|
|
void osal_free(void *ptr)
|
|
{
|
|
free(ptr);
|
|
}
|
|
|
|
int osal_thread_create(void *thandle, int stacksize, void *func, void *param)
|
|
{
|
|
int ret;
|
|
pthread_attr_t attr;
|
|
pthread_t *threadp;
|
|
|
|
threadp = thandle;
|
|
pthread_attr_init(&attr);
|
|
pthread_attr_setstacksize(&attr, stacksize);
|
|
ret = pthread_create(threadp, &attr, func, param);
|
|
if (ret < 0)
|
|
{
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int osal_thread_create_rt(void *thandle, int stacksize, void *func, void *param)
|
|
{
|
|
int ret;
|
|
pthread_attr_t attr;
|
|
struct sched_param schparam;
|
|
pthread_t *threadp;
|
|
|
|
threadp = thandle;
|
|
pthread_attr_init(&attr);
|
|
pthread_attr_setstacksize(&attr, stacksize);
|
|
ret = pthread_create(threadp, &attr, func, param);
|
|
pthread_attr_destroy(&attr);
|
|
if (ret < 0)
|
|
{
|
|
return 0;
|
|
}
|
|
memset(&schparam, 0, sizeof(schparam));
|
|
schparam.sched_priority = 40;
|
|
ret = pthread_setschedparam(*threadp, SCHED_FIFO, &schparam);
|
|
if (ret < 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void *osal_mutex_create(void)
|
|
{
|
|
pthread_mutexattr_t mutexattr;
|
|
osal_mutext *mutex;
|
|
mutex = (osal_mutext *)osal_malloc(sizeof(osal_mutext));
|
|
if (mutex)
|
|
{
|
|
pthread_mutexattr_init(&mutexattr);
|
|
pthread_mutexattr_setprotocol(&mutexattr, PTHREAD_PRIO_INHERIT);
|
|
pthread_mutex_init(mutex, &mutexattr);
|
|
}
|
|
return (void *)mutex;
|
|
}
|
|
|
|
void osal_mutex_destroy(void *mutex)
|
|
{
|
|
pthread_mutex_destroy((osal_mutext *)mutex);
|
|
osal_free(mutex);
|
|
}
|
|
|
|
void osal_mutex_lock(void *mutex)
|
|
{
|
|
pthread_mutex_lock((osal_mutext *)mutex);
|
|
}
|
|
|
|
void osal_mutex_unlock(void *mutex)
|
|
{
|
|
pthread_mutex_unlock((osal_mutext *)mutex);
|
|
}
|