flexPTP 1.0
An IEEE 1588 PTP implementation designed for microcontrollers
Loading...
Searching...
No Matches
Porting and configuration

In the Porting section a guide is presented to help porting flexPTP to a new platform. In the Configuration part basic and initial settings are listed.

Porting

We have included numerous examples into the basic flexPTP package with the intent to clarify purpose and structure of each porting file. The flexPTP accesses the target system using the following modules:

  • a flexptp_options.h configuration file, that defines settings for hardware clock operation, provides handles to the servo, connects flexPTP to the standard output and passes common includes to all flexPTP modules.
  • Network Stack Driver that outsources the message transmission and reception to and from the network. It acts like a glue code between the flexPTP and the network stack.
  • a (simple) hardware clock driver, through which flexPTP can set or tune the hardware clock and query time.

In the sections below you'll see samples for all three configuration module types.

Port option file

Each project that includes flexPTP must provide a flexptp_options.h header file. This file has the purpose to tell flexPTP the basic hardware features (e.g. oscillator frequency), and to define bindings to hardware clock and servo management routines.

Our experience with embedded development shows that a newcomer might run into difficulties on creating a port to a software to be learned. We recommend you to open an example flexptp_options_XXX.h file from the port/example_options location before reading the following. Taking a quick look into a pre-made configuration file might make the interpretation of the section below much easier.

The assembling of a configuration file can be broken down into the following major steps:

  1. Choose an OS interface:

    • define the FLEXPTP_CMSIS_OS2 macro to use the CMSIS OS2 bindings OR
    • define the FLEXPTP_FREERTOS macro to let the library call the FreeRTOS API directly OR
    • define the FLEXPTP_LINUX macro to use the standard Linux API (experimental)
    • define the FLEXPTP_OSLESS macro to enable the no-OS operation mode
      • In OS-less mode, a method to enter and leave critical sections must be provided through the FLEXPTP_OSLESS_LOCK macro with the type FifoLockFn. The simplest locking is to globally disable/enable interrupts.
      • Usually hidden-from-the-user, core method task_ptp() and ptp_heartbeat_tmr_cb() are exposed in this mode. They should be invoked periodically to run the library. Learn more at the functions' documentations.

    OS headers must be available to the library (e.g. cmsis_os2.h, FreeRTOS.h, etc.).

  2. Define printing routines or macros:
    • MSG(...): a basic formatted printing function that mimics printf() functionality (called with printf()-fashioned parameters). flexPTP uses the following formatting marks: %d, %i, %u, %lu, %f, %x, %X, %s, %c, %%.
    • CLILOG(en,...): a maskable printing function: if en is true, it behaves like MSG(...)
    • SPRINTF(str,n,...): a basic snprintf() implementation, that supports at least the same set of formatting marks as MSG(...) does
  3. Define hardware clock management functions: Two different clock management interface are supported, the ADDEND-based and the HLT interface. More on this in Hardware Clock Driver.
    • ADDEND interface
      • define the PTP_ADDEND_INTERFACE macro to select this interface
      • PTP_HW_INIT(increment, addend): a method that initializes the hardware clock. increment: clock increment, addend: initial frequency tuning
      • PTP_SET_CLOCK(s, ns): a method that sets the hardware clock. s: seconds part of the UNIX time, ns: nanoseconds of the UNIX time
      • PTP_SET_ADDEND(addend): a method that sets the hardware clock frequency tuning word. addend: 32-bit tuning value (0x00000000..0xFFFFFFFF)
      • PTP_HW_GET_TIME(pt): a method that fetches the time right from the hardware clock. pt: time of type TimestampI *; time is stored to *pt
      • PTP_MAIN_OSCILLATOR_FREQ_HZ: clock frequency that drives the hardware clock in Hz
      • PTP_INCREMENT_NSEC: amount of time the clock gets incremented each tick expressed in nanoseconds
    • HLT interface
      • define the PTP_HLT_INTERFACE macro to select this interface
      • PTP_HW_INIT(): a method that initializes the hardware clock.
      • PTP_SET_CLOCK(s, ns): a method that sets the hardware clock. s: seconds part of the UNIX time, ns: nanoseconds of the UNIX time
      • PTP_SET_TUNING(tuning): a method that sets the hardware clock tuning. tuning: tuning in PPB
      • PTP_HW_GET_TIME(pt): a method that fetches the time right from the hardware clock. pt: time of type TimestampI *; time is stored to *pt
  4. Define servo management functions:
  5. Optionally define a function that registers CLI commands:
  6. Optionally define a function for loading retained options:
  7. Optionally define a function for handling flexPTP's user events (this can be done during runtime as well):
    • PTP_USER_EVENT_CALLBACK: a function pointer of the PtpUserEventCallback type
  8. Optionally enable Master operation mode:
    • set PTP_ENABLE_MASTER_OPERATION to 1
    • Optionally set (initial) PTP master capabilities, see Master configuration

We emphasize, that many examples can be found on configuration files in the port/example_options directory.

Throughout the assembling of a new the options file you might find that the Ethernet driver, that came along the target platform lacks routines handling PTP functionality. In that case you it's your duty to extend the driver with the proper features. Many examples on such extensions can be found in the port/example_ports directory.

Example option files

flexptp_options_stm32f407_etherlib.h, flexptp_options_stm32h743_etherlib.h, flexptp_options_stm32h743.h, flexptp_options_tm4c1294.h, flexptp_options_mk64f.h

Network Stack Driver (NSD)

The flexPTP library expects (only!) the below message transception related functions defined. These are the functions, that are declared in network_stack_driver.h. During the porting work, these functions must be implemented.

  • void ptp_nsd_init(PtpTransportType tp, PtpDelayMechanism dm): This function initializes (opens and closes) the network connections based on the profile settings passed in the tp and dm parameters. tp and dm can take on any value from PtpTransportType and PtpDelayMechanism, respectively. Passing -1 in either parameter signals that the flexPTP wants the network layer to close all connections. In other words, by passing -1 the flexPTP does not defined a valid profile. It is expected that this function gets called multiple times. On subsequent calls, the function first informs the network that we are leaving the IGMP-group of the profile we abandon and closes connection associated with the profile we are leaving. Then, it takes on the new profile, opens the new connection and joins the new IGMP-groups. Joining and leaving of the IGMP-groups is performed by invoking the ptp_nsd_igmp_join_leave() method.
  • void ptp_nsd_transmit_msg(RawPtpMessage *pMsg, uint32_t uid)1: The flexPTP engine calls this function to dispatch a PTP message. The NSD can safely anticipate that fields of the message passed from the PTP engine carry fields reflecting the profile that was set by the latest ptp_nsd_init() call. The function must only fetch the PTP message class from the message passed to determine through which connection it has to be sent. The outbound messages are identified by unique IDs (UIDs). The message UID must be used to identify messages upon feeding back transmit timestamps using the ptp_transmit_timestamp_cb() function. The former function is 'thread safe', it can be called from an interrupt context as well.
  • void ptp_nsd_igmp_join_leave(bool join): The flexPTP engine might intend to inform the network about the joining or leaving of the IGMP-group associated with the operating profile (for example upon link recovery). Besides, ptp_nsd_init() references this function as well.
  • void ptp_nsd_get_interface_address(uint8_t * hwa): This function returns with the hardware address of the associated Ethernet interface. Parameter hwa is expected to be able to hold (at least) 6-bytes (the size of an Ethernet Hardware Address).

Finally, it's also the job of the NSD module to make the received messages available to the flexPTP core. This is done by calling the ptp_receive_enqueue() function with the proper parameters: data, size and ingress timestamp split into seconds and nanoseconds field.

Inherently, the fetching and exchanging of the ingress and egress timestamps with the flexPTP core fall also in the scope of the NSD module.

1 This function signature has changed.

NSD examples

nsd_lwip.c, nsd_etherlib.c : Sample NSD implementations for lwIP and EtherLib network stacks.

Hardware Clock Driver

The library supports two different, mutually exclusive clock management interfaces: the old-style ADDEND-based tuning interface and the newly introduced High-Level Tuning (HLT) interface. The user should implement the one better matched to the underlying hardware.

ADDEND-interface

General structure of a PTP hardware clock with distinguished high precision frequency divider and counter

This interface assumes the above hardware clock model. In the majority of the microcontrollers with PTP support the structure of the PTP hardware clock follows this scheme.

Such hardware clocks can be tuned by altering a so called frequency tuning code word. The actual tuning value, a code word is an addend of a high-precision frequency divider in the clock's core. The code word is directly proportional with the output frequency. That's why we decided to represent 0 frequency with a zero and the maximum frequency with a 0xFFFFFFFF ( \(2^{32}-1\)) 32 bits code word. The former phrase in the form of a function:

\[ f_\text{clock} = f_\text{osc} \frac{\texttt{CODE WORD}}{2^{32}} \]

Hardware clocks keep time by increasing their stored time value with an increment in every clock cycle (i.e. clock cycle of the divided clock). The increment is usually constant and is set during the initialization. (It is usually expressed in nanoseconds.)

Addend and increment are the two basic idea that are supported by all such hardware clocks. The hardware clock driver must be able to control at least these two fields. By nature, clock drivers implementing the ADDEND-interface are low-level drivers.

More general, the hardware clock driver must provide solutions for:

To maintain backward-compatibility this interface is auto-selected if no interface selection macro was defined. The best practice is to define the PTP_ADDEND_INTERFACE macro to explicitly select this interface.

Additionally, the frequency of the PTP clock input and the increment must also be defined: PTP_MAIN_OSCILLATOR_FREQ_HZ, PTP_INCREMENT_NSEC

Usually the hardware clock driver also implements further miscellaneous functionality, like the controlling of the PPS output signal.

Example option files

flexptp_options_stm32f407_etherlib.h, flexptp_options_stm32h743_etherlib.h, flexptp_options_stm32h743.h, flexptp_options_tm4c1294.h

Example Hardware Clock Driver files

ptp_port_stm32f407_etherlib.c, ptp_port_stm32f407_lwip.c, ptp_port_stm32h743_etherlib.c, ptp_port_stm32h743_lwip.c, ptp_port_tiva_tm4c1294.c

High-Level Tuning (HLT) interface

This interface enables flexPTP to operate hardware clocks regardless of the clock's inner structure considering the clock as a black-box device. This interface is provided to extend flexPTP support to devices with hardware clocks differing from the formerly introduced one.

The interface consists of the following few methods:

To select this interface, defined the PTP_HLT_INTERFACE macro.

Usually the hardware clock driver also implements further miscellaneous functionality, like the controlling of the PPS output signal.

Example option files

flexptp_options_mk64f.h

Example Hardware Clock Driver files

ptp_port_mk64f_lwip.c

Configuration

Initial configuration

List of definitions, part of the initial configuration, with default values. Default values are used if macros are not defined in flexptp_options.h.

Operation mode parameters

Macros controlling basic internal operation.

Macro Default value Description
PTP_HEARTBEAT_TICKRATE_MS 62 Internal core scheduler period (ms). It should be less than the half of the shortest messaging period.
PTP_ACCURACY_LIMIT_NS 100 Threshold of the LOCKED state (ns)
PTP_DEFAULT_SERVO_OFFSET_NS 0 Initial servo offset (ns) (can be changed in runtime)
PTP_DEFAULT_COARSE_TRIGGER_NS 20000000 Coarse correction kick-in threshold (ns) (can be changed in runtime)

PTP definitions

Common

Macro Default value Description
PTP_PORT_ID 1 ID of the Ethernet interface assigned to flexPTP

BMCA

Macro Default value Description
PTP_BMCA_LISTENING_TIMEOUT_MS 3000 Timeout of the LISTENING BMCA-state (ms)
PTP_MASTER_QUALIFICATION_TIMEOUT 4 Timeout of PRE_MASTER state (Announce-intervals)
PTP_ANNOUNCE_RECEIPT_TIMEOUT 3 Number of tolerated consecutive lost Announce messages

Master

Macro Default value Description
PTP_ENABLE_MASTER_OPERATION 0 (disabled) Enable/disable master operation (once disabled here CANNOT be enabled in runtime)
PTP_FALLBACK_UTC_OFFSET 37 Initial UTC offset caused by the accumulated leap seconds (s)
PTP_PDELAY_SLAVE_QUALIFICATION 3 Number of consecutive PDelReq-PDelResp iterations after the SLAVE is considered stable
PTP_PDELAY_DROPOUT PTP_PDELAY_SLAVE_QUALIFICATION Maximum number of failed PDelReq-PDelResp cycles before the MASTER drops the SLAVE

Clock dataset

Macro Default value Description
PTP_CLOCK_PRIORITY1 128 Priority 1 field
PTP_CLOCK_PRIORITY2 128 Priority 2 field
PTP_BEST_CLOCK_CLASS PTP_CC_DEFAULT Best clock class (PtpClockClass)
PTP_WORST_ACCURACY PTP_CA_PTP_CA_UNKNOWN Worst clock accuracy (PtpClockAccuracy)
PTP_TIME_SOURCE PTP_TSRC_INTERNAL_OSCILLATOR Time source of this device (PtpTimeSource)

Runtime configuration

Runtime configuration is done through the Settings interface (settings_interface.h).

Also, the same configuration options are available through the CLI interface.