diff options
author | Levi Pearson <levipearson@gmail.com> | 2018-06-19 14:52:52 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-19 14:52:52 -0600 |
commit | 5b95644093b857b2dc886e29871519edd7d66b67 (patch) | |
tree | 0e593f3b76dcffe86e73d54b7c39dd831e5915a5 | |
parent | 247413605cc4cda855ea89cc6b5c4168a247a91a (diff) | |
parent | b66379611283f1daae1008f9fb8f084bf115a531 (diff) | |
download | Open-AVB-5b95644093b857b2dc886e29871519edd7d66b67.tar.gz |
Merge pull request #795 from christopher-s-hall/open-avb-next
gptp: Add monotonic raw clock option
-rw-r--r-- | daemons/gptp/common/common_tstamper.hpp | 9 | ||||
-rw-r--r-- | daemons/gptp/common/gptp_cfg.cpp | 11 | ||||
-rw-r--r-- | daemons/gptp/common/gptp_cfg.hpp | 41 | ||||
-rw-r--r-- | daemons/gptp/gptp_cfg.ini | 8 | ||||
-rw-r--r-- | daemons/gptp/linux/build/Makefile | 4 | ||||
-rw-r--r-- | daemons/gptp/linux/src/daemon_cl.cpp | 14 | ||||
-rw-r--r-- | daemons/gptp/linux/src/linux_hal_generic.cpp | 103 | ||||
-rw-r--r-- | daemons/gptp/linux/src/linux_hal_generic.hpp | 14 |
8 files changed, 182 insertions, 22 deletions
diff --git a/daemons/gptp/common/common_tstamper.hpp b/daemons/gptp/common/common_tstamper.hpp index cfaf3abd..557ac184 100644 --- a/daemons/gptp/common/common_tstamper.hpp +++ b/daemons/gptp/common/common_tstamper.hpp @@ -73,6 +73,15 @@ public: } /** + * @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 * @return false diff --git a/daemons/gptp/common/gptp_cfg.cpp b/daemons/gptp/common/gptp_cfg.cpp index 8b9db0dc..943c639a 100644 --- a/daemons/gptp/common/gptp_cfg.cpp +++ b/daemons/gptp/common/gptp_cfg.cpp @@ -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); } @@ -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") ) diff --git a/daemons/gptp/common/gptp_cfg.hpp b/daemons/gptp/common/gptp_cfg.hpp index f283a4db..4b172b4c 100644 --- a/daemons/gptp/common/gptp_cfg.hpp +++ b/daemons/gptp/common/gptp_cfg.hpp @@ -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 @@ -65,20 +66,23 @@ class GptpIniParser */ typedef struct { - /*ptp data set*/ - unsigned char priority1; - - /*port data set*/ - unsigned int announceReceiptTimeout; - unsigned int syncReceiptTimeout; - unsigned int syncReceiptThresh; //!< Number of wrong sync messages that will trigger a switch to master - int64_t neighborPropDelayThresh; - unsigned int seqIdAsCapableThresh; - uint16_t lostPdelayRespThresh; - PortState port_state; - - /*ethernet adapter data set*/ - std::string ifname; + /*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; + unsigned int syncReceiptThresh; //!< Number of wrong sync messages that will trigger a switch to master + int64_t neighborPropDelayThresh; + unsigned int seqIdAsCapableThresh; + uint16_t lostPdelayRespThresh; + PortState port_state; + + /*ethernet adapter data set*/ + std::string ifname; phy_delay_map_t phy_delay; } gptp_cfg_t; @@ -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 diff --git a/daemons/gptp/gptp_cfg.ini b/daemons/gptp/gptp_cfg.ini index ee593e9e..83387606 100644 --- a/daemons/gptp/gptp_cfg.ini +++ b/daemons/gptp/gptp_cfg.ini @@ -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 diff --git a/daemons/gptp/linux/build/Makefile b/daemons/gptp/linux/build/Makefile index 1e00b1a5..fa9441d7 100644 --- a/daemons/gptp/linux/build/Makefile +++ b/daemons/gptp/linux/build/Makefile @@ -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 diff --git a/daemons/gptp/linux/src/daemon_cl.cpp b/daemons/gptp/linux/src/daemon_cl.cpp index 3a6d95e5..53a8f9a4 100644 --- a/daemons/gptp/linux/src/daemon_cl.cpp +++ b/daemons/gptp/linux/src/daemon_cl.cpp @@ -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; @@ -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) { @@ -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()) { diff --git a/daemons/gptp/linux/src/linux_hal_generic.cpp b/daemons/gptp/linux/src/linux_hal_generic.cpp index 9eeba46f..2a462696 100644 --- a/daemons/gptp/linux/src/linux_hal_generic.cpp +++ b/daemons/gptp/linux/src/linux_hal_generic.cpp @@ -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> @@ -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 @@ -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 { @@ -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 ×tamp, unsigned &clock_value, bool last ) @@ -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 @@ -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 ) { @@ -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; diff --git a/daemons/gptp/linux/src/linux_hal_generic.hpp b/daemons/gptp/linux/src/linux_hal_generic.hpp index 943294f4..76b09015 100644 --- a/daemons/gptp/linux/src/linux_hal_generic.hpp +++ b/daemons/gptp/linux/src/linux_hal_generic.hpp @@ -67,11 +67,22 @@ private: #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 @@ -108,6 +119,9 @@ public: */ 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. |