Skip to content

Commit

Permalink
gptp: Add monotonic raw clock option
Browse files Browse the repository at this point in the history
Timestamp clocks that implement the PTP_SYS_OFFSET_PRECISE ioctl return
 cross-timestamps with respect to monotonic raw and realtime
Add configuration file option allowing clock selection for system/local
 clock relation

The default clock type is Realtime which is equivalent to the
 CLOCK_REALTIME option to clock_gettime
Optionally, MonotonicRaw (equivalent to CLOCK_MONOTONIC_RAW) can be
 specified in the gPTP daemon configuration file:

[clock]

SystemClock = MonotonicRaw

Fixed Makefile issue where some shell configurations use built-in 'echo'
 and others don't
Forces all to use /bin/echo
  • Loading branch information
christopher-s-hall committed Jun 12, 2018
1 parent 2474136 commit 87acb2c
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 8 deletions.
9 changes: 9 additions & 0 deletions daemons/gptp/common/common_tstamper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ class CommonTimestamper {
virtual void HWTimestamper_final(void) {
}

/**
* @brief Sets system clock descriptor
* @param system_clock_desc name of local clock
* @return false if unimplemented
*/
virtual bool HWTimestamper_setsystemclock
( const char *system_clock_desc )
{ return false; }

/**
* @brief Adjusts the hardware clock frequency
* @param frequency_offset Frequency offset
Expand Down
11 changes: 11 additions & 0 deletions daemons/gptp/common/gptp_cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ uint32_t findSpeedByName( const char *name, const char **end );

GptpIniParser::GptpIniParser(std::string filename)
{
_config.systemClockDesc[0] = '\0';
_error = ini_parse(filename.c_str(), iniCallBack, this);
}

Expand Down Expand Up @@ -86,6 +87,16 @@ int GptpIniParser::iniCallBack(void *user, const char *section, const char *name
}
}
}
else if( parseMatch(section, "clock") )
{
if( parseMatch(name, "SystemClock") )
{
valOK = true;
strncpy( parser->_config.systemClockDesc, value,
MAX_CLOCK_DESC_LEN );
parser->_config.systemClockDesc[MAX_CLOCK_DESC_LEN] = '\0';
}
}
else if( parseMatch(section, "port") )
{
if( parseMatch(name, "announceReceiptTimeout") )
Expand Down
13 changes: 13 additions & 0 deletions daemons/gptp/common/gptp_cfg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const uint32_t LINKSPEED_2_5G = 2500000;
const uint32_t LINKSPEED_1G = 1000000;
const uint32_t LINKSPEED_100MB = 100000;
const uint32_t INVALID_LINKSPEED = UINT_MAX;
const uint8_t MAX_CLOCK_DESC_LEN = 64;

/**
* @brief Returns name given numeric link speed
Expand All @@ -68,6 +69,9 @@ class GptpIniParser
/*ptp data set*/
unsigned char priority1;

/* Clock data set */
char systemClockDesc[MAX_CLOCK_DESC_LEN+1];

/*port data set*/
unsigned int announceReceiptTimeout;
unsigned int syncReceiptTimeout;
Expand All @@ -93,6 +97,15 @@ class GptpIniParser
*/
int parserError(void);

/**
* @brief Read SystemClock description
* @return pointer to c-string representing system clock
*/
const char *getSystemClockDesc(void)
{
return _config.systemClockDesc;
}

/**
* @brief Reads priority1 config value
* @param void
Expand Down
8 changes: 8 additions & 0 deletions daemons/gptp/gptp_cfg.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
# The lower the number, the higher the priority for the BMCA.
priority1 = 248

# Clock option to specify system clock type
# Currently, Linux only. Options are MonotonicRaw and Realtime.
# Realtime works on all network interfaces. MonotonicRaw is available on
# interfaces that support it.

#[clock]
#SystemClock = MonotonicRaw

[port]

# TODO
Expand Down
4 changes: 2 additions & 2 deletions daemons/gptp/linux/build/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ CFLAGS_G = -Wall -g -I. -I../../common -I../src \
PRECISE_TIME_TEST = "\#include <linux/ptp_clock.h>\\n\
\#ifdef PTP_SYS_OFFSET_PRECISE\\nint main(){return 0;}\\n\#endif"

HAS_PRECISE_TIME = $(shell echo $(PRECISE_TIME_TEST) | $(CC) -xc - \
-I$(ALTERNATE_LINUX_INCPATH) -o /dev/null > /dev/null 2>&1 ; echo $$?)
HAS_PRECISE_TIME = $(shell /bin/echo -e $(PRECISE_TIME_TEST) | $(CC) -xc - \
-I$(ALTERNATE_LINUX_INCPATH); echo $$?)

ifeq ($(HAS_PRECISE_TIME),0)
CFLAGS_G += -DPTP_HW_CROSSTSTAMP
Expand Down
14 changes: 14 additions & 0 deletions daemons/gptp/linux/src/daemon_cl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ int main(int argc, char **argv)
LinuxIPCArg *ipc_arg = NULL;
bool use_config_file = false;
char config_file_path[512];
const char *systemClockDesc = NULL;
memset(config_file_path, 0, 512);

GPTPPersist *pGPTPPersist = NULL;
Expand Down Expand Up @@ -424,6 +425,11 @@ int main(int argc, char **argv)
portInit.syncReceiptThreshold =
iniParser.getSyncReceiptThresh();

if( strnlen( iniParser.getSystemClockDesc(),
MAX_CLOCK_DESC_LEN ) != 0 )
systemClockDesc =
iniParser.getSystemClockDesc();

/*Only overwrites phy_delay default values if not input_delay switch enabled*/
if(!input_delay)
{
Expand All @@ -433,6 +439,14 @@ int main(int argc, char **argv)

}

if( systemClockDesc != NULL )
{
if( timestamper->HWTimestamper_setsystemclock
( systemClockDesc ))
GPTP_LOG_INFO
( "Using system Clock: %s", systemClockDesc );
}

pPort = new EtherPort(&portInit);

if (!pPort->init_port()) {
Expand Down
103 changes: 97 additions & 6 deletions daemons/gptp/linux/src/linux_hal_generic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#include <linux_hal_generic_tsprivate.hpp>
#include <platform.hpp>
#include <avbts_message.hpp>
#include <gptp_cfg.hpp>

#include <sys/select.h>
#include <sys/socket.h>
#include <netpacket/packet.h>
Expand Down Expand Up @@ -194,6 +196,13 @@ int findPhcIndex( InterfaceLabel *iface_label ) {
return info.phc_index;
}

LinuxTimestamperGeneric::clock_map_t
LinuxTimestamperGeneric::system_clock_map[] =
{
{ CLOCK_REALTIME, "Realtime" },
{ CLOCK_MONOTONIC_RAW, "MonotonicRaw" }
};

LinuxTimestamperGeneric::~LinuxTimestamperGeneric() {
if( _private != NULL ) delete _private;
#ifdef WITH_IGBLIB
Expand All @@ -207,6 +216,22 @@ LinuxTimestamperGeneric::LinuxTimestamperGeneric() {
igb_private = NULL;
#endif
sd = -1;
system_clockid = CLOCK_REALTIME;
}

const char *LinuxTimestamperGeneric::getClockNameFromId( clockid_t clockid )
const
{
unsigned i;

for( i = 0; i < sizeof(system_clock_map)/sizeof(system_clock_map[0]);
++i )
{
if( system_clock_map[i].clockid == clockid )
return system_clock_map[i].clock_name;
}

return NULL;
}

bool LinuxTimestamperGeneric::Adjust( void *tmx ) const {
Expand Down Expand Up @@ -276,6 +301,32 @@ void LinuxTimestamperGeneric::HWTimestamper_reset()
}
}

bool LinuxTimestamperGeneric::HWTimestamper_setsystemclock
( const char *system_clock_desc )
{
unsigned i;

if( system_clock_desc == NULL )
return false;

for( i = 0; i < sizeof(system_clock_map)/sizeof(system_clock_map[0]);
++i )
{
if( strncmp( system_clock_desc, system_clock_map[i].clock_name,
MAX_CLOCK_DESC_LEN ) == 0 )
{
system_clockid = system_clock_map[i].clockid;

return true;
}
}

GPTP_LOG_ERROR
( "Requested clock type: '%s' not found", system_clock_desc );

return false;
}

int LinuxTimestamperGeneric::HWTimestamper_txtimestamp
( PortIdentity *identity, PTPMessageId messageId, Timestamp &timestamp,
unsigned &clock_value, bool last )
Expand Down Expand Up @@ -454,13 +505,33 @@ bool LinuxTimestamperGeneric::HWTimestamper_gettime
{
struct ptp_sys_offset_precise offset;
memset( &offset, 0, sizeof(offset));
if( ioctl( phc_fd, PTP_SYS_OFFSET_PRECISE, &offset ) == 0 )
if( ioctl( phc_fd, PTP_SYS_OFFSET_PRECISE, &offset ) != 0 )
{
*device_time = pctTimestamp( &offset.device );
GPTP_LOG_ERROR( "Read PHC Crosstime IOCTL failed" );

return false;
}

*device_time = pctTimestamp( &offset.device );

if( system_clockid == CLOCK_REALTIME )
*system_time = pctTimestamp( &offset.sys_realtime );
else if( system_clockid == CLOCK_MONOTONIC_RAW )
*system_time = pctTimestamp( &offset.sys_monoraw );

return true;
else
{
const char * clock_name =
getClockNameFromId( system_clockid );
GPTP_LOG_ERROR(
"Requested clock type: '%s' not supported",
clock_name != NULL ? clock_name : "Unknown"
);

return false;
}

return true;
}
#endif

Expand All @@ -474,7 +545,11 @@ bool LinuxTimestamperGeneric::HWTimestamper_gettime
memset( &offset, 0, sizeof(offset));
offset.n_samples = PTP_MAX_SAMPLES;
if( ioctl( phc_fd, PTP_SYS_OFFSET, &offset ) == -1 )
{
GPTP_LOG_ERROR( "Read PHC Crosstime IOCTL failed" );

return false;
}

pct = &offset.ts[0];
for( i = 0; i < offset.n_samples; ++i ) {
Expand All @@ -487,10 +562,26 @@ bool LinuxTimestamperGeneric::HWTimestamper_gettime
}
}

if (device_time_l)
*device_time = pctTimestamp( device_time_l );
if (system_time_l)
if( !device_time_l || !system_time_l )
{
GPTP_LOG_ERROR( "PHC Crosstime result is empty" );

return false;
}

*device_time = pctTimestamp( device_time_l );

if( system_clockid == CLOCK_REALTIME )
*system_time = pctTimestamp( system_time_l );
else
{
const char *clock_name =
getClockNameFromId( system_clockid );
GPTP_LOG_ERROR(
"Requested clock type: '%s' not supported",
clock_name != NULL ? clock_name : "Unknown"
);
}
}

return true;
Expand Down
14 changes: 14 additions & 0 deletions daemons/gptp/linux/src/linux_hal_generic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,22 @@ class LinuxTimestamperGeneric : public LinuxTimestamper {
#endif

TicketingLock *net_lock;
clockid_t system_clockid;

#ifdef WITH_IGBLIB
LinuxTimestamperIGBPrivate_t igb_private;
#endif

struct clock_map_t
{
clockid_t clockid;
const char *clock_name;
};

static clock_map_t system_clock_map[];

const char *getClockNameFromId( clockid_t clockid ) const;

public:
/**
* @brief Default constructor. Initializes internal variables
Expand Down Expand Up @@ -108,6 +119,9 @@ class LinuxTimestamperGeneric : public LinuxTimestamper {
*/
virtual void HWTimestamper_reset();

virtual bool HWTimestamper_setsystemclock
( const char *system_clock_desc );

/**
* @brief Inserts a new timestamp to the beginning of the
* RX timestamp list.
Expand Down

0 comments on commit 87acb2c

Please sign in to comment.