flexPTP 1.0
An IEEE 1588 PTP implementation designed for microcontrollers
Loading...
Searching...
No Matches
ptp_core.c
Go to the documentation of this file.
1/* (C) AndrĂ¡s Wiesner, 2020-2022 */
2
3#include "ptp_core.h"
4
5#include <math.h>
6#include <stdint.h>
7#include <string.h>
8
9#include "common.h"
10#include "event.h"
11#include "logging.h"
12#include "master.h"
13#include "slave.h"
14
15#include "bmca.h"
16#include "cli_cmds.h"
17#include "clock_utils.h"
18#include "format_utils.h"
19#include "msg_utils.h"
21#include "ptp_defs.h"
22#include "ptp_types.h"
23#include "settings_interface.h"
24#include "stats.h"
25#include "task_ptp.h"
26#include "timeutils.h"
27
28#include <flexptp_options.h>
29
30#include "minmax.h"
31
32#include <stdlib.h>
33
35// global state
36PtpCoreState gPtpCoreState;
37#define S (gPtpCoreState)
38
39const TimestampI zeroTs = {0, 0}; // a zero timestamp
41
42// --------------------------------------
43
44static void ptp_common_init(void) {
45
46 // seed the randomizer
47 srand(S.hwoptions.clockIdentity);
48
49 // reset options
50 nsToTsI(&S.hwoptions.offset, PTP_DEFAULT_SERVO_OFFSET);
51
52 // initialize hardware
53#ifdef PTP_ADDEND_INTERFACE
55#elif defined(PTP_HLT_INTERFACE)
57#endif
58
59 // get the hardware address
60 uint8_t hwa[6];
62
63 // create clock identity
65
66 // initialize controller
68}
69
70// initialize PTP module
71void ptp_init(void) {
72#ifdef CLI_REG_CMD
73 // register cli commands
75#endif // CLI_REG_CMD
76
77 // clear the timer
78 S.ticks = 0;
79
80 /* ---- COMMON ----- */
82
83 /* ----- SBMC ------ */
85
86 /* ----- SLAVE ----- */
88
89 /* ---- MASTER --- */
91
92 // ---------------------
93
94 ptp_reset(); // reset all PTP systems
95
96 // dispatch INIT_DONE event
98}
99
100// deinit PTP module
102 /* ---- COMMON ----- */
103#ifdef CLI_REG_CMD
104 // remove cli commands
106#endif // CLI_REG_CMD
107
108 // deinitialize controller
110
111 /* ----- SBMC ------ */
113
114 /* ----- SLAVE ----- */
116
117 /* ---- MASTER --- */
119}
120
121// reset PTP subsystem
122static void ptp_core_reset() {
123 // pause the heartbeat timer
125
126 /* ---- COMMON ---- */
127 memset(&S.network, 0, sizeof(PtpNetworkState)); // network state
128
129 // reinitialize the Network Stack Driver
130 NsdInitSettings nsdInit = {
133 {}, {}
134 };
135 memcpy(nsdInit.primary_p2p_8023_dest, S.profile.primary_p2p_8023_destination, 6);
136 memcpy(nsdInit.pdelay_p2p_8023_dest, S.profile.pdelay_p2p_8023_destination, 6);
137
138 ptp_nsd_init(&nsdInit);
139
140 // reset statistics
142
143 // reset common functionality
145
146 /* ---- SBMC ----- */
148
149 /* ---- SLAVE ---- */
151
152 /* ---- MASTER --- */
154
155 // ------------------------
156
157 // resume the heartbeat timer
159
160 // dispatch RESET event
162}
163
164// packet processing
166 PtpHeader header;
167
168 // header readout
169 ptp_extract_header(&header, pRawMsg->data);
170
171 // consider only messages in our domain
172 if (header.domainNumber != S.profile.domainNumber ||
173 header.transportSpecific != S.profile.transportSpecific) {
174 return;
175 }
176
177 // process Announce messages and halt further processing
178 PtpMessageType mt = header.messageType;
179 if (mt == PTP_MT_Announce) {
180 PtpMasterProperties newMstProp;
181 ptp_extract_announce_message(&newMstProp, pRawMsg->data);
182 ptp_handle_announce_msg(&newMstProp, &header);
183 PTP_IUEV(PTP_UEV_ANNOUNCE_RECVED); // dispatch ANNOUNCE_RECVED event
184 return;
185 }
186
187 // PDelay_Req messages should always be processed
188 if ((header.messageType == PTP_MT_PDelay_Req) && (S.profile.delayMechanism == PTP_DM_P2P)) {
189 PTP_IUEV(PTP_UEV_PDELAY_REQ_RECVED); // dispatch PDELAY_REQ_RECVED event
190 ptp_send_pdelay_resp(pRawMsg); // sent the PDelay_Resp message
191 PTP_IUEV(PTP_UEV_PDELAY_RESP_SENT); // dispatch PDELAY_RESP_SENT event
192 return;
193 }
194
195 // if operating in slave mode
196 PtpBmcaFsmState bmcaState = S.bmca.state;
197 if (bmcaState == PTP_BMCA_SLAVE) {
198 ptp_slave_process_message(pRawMsg, &header);
199 return;
200 } else if (bmcaState == PTP_BMCA_MASTER) { // if operating in Master mode
201 ptp_master_process_message(pRawMsg, &header);
202 return;
203 }
204}
205
206void ptp_process_event(const PtpCoreEvent *event) {
207 switch (event->code) {
208 case PTP_CEV_HEARTBEAT: { // heartbeat event
209 S.ticks++;
213 } break;
215 PtpBmcaFsmState bmcaState = event->w.w;
216 if (bmcaState == PTP_BMCA_SLAVE) {
218 } else if (bmcaState == PTP_BMCA_MASTER) {
220 } else {
223 }
224
225 // dispatch BMCA_STATE_CHANGED event
227 } break;
228 case PTP_CEV_RESET: {
230 } break;
231 default:
232 break;
233 }
234}
235
236// -----------------------------------------------
237
238uint32_t ptp_get_tick() {
239 return S.ticks;
240}
241
242void ptp_reset() {
243 PtpCoreEvent event = { .code = PTP_CEV_RESET, .w = 0, .dw = 0 };
244 ptp_event_enqueue(&event);
245}
246
247// -----------------------------------------------
248
250 S.slave.syncCb = syncCb;
251}
252
254 S.userEventCb = userEventCb;
255}
void ptp_bmca_destroy()
Definition: bmca.c:207
void ptp_bmca_tick()
Definition: bmca.c:74
void ptp_bmca_init()
Definition: bmca.c:193
void ptp_bmca_reset()
Definition: bmca.c:211
void ptp_handle_announce_msg(PtpAnnounceBody *pAnn, PtpHeader *pHeader)
Definition: bmca.c:137
This module implements the Best Master Clock Algorithm.
void ptp_register_cli_commands()
Definition: cli_cmds.c:360
void ptp_remove_cli_commands()
Definition: cli_cmds.c:387
This module handles and registers CLI commands. Commands:
void ptp_create_clock_identity(const uint8_t *hwa)
Definition: clock_utils.c:25
This module defines clock identity related operations.
void ptp_common_reset()
Definition: common.c:170
void ptp_send_pdelay_resp(const RawPtpMessage *pMsg)
Definition: common.c:103
This module defines messaging functions for both the slave and master modules.
In this module are the core and user events defined.
@ PTP_UEV_RESET_DONE
The flexPTP module has been reset.
Definition: event.h:48
@ PTP_UEV_PDELAY_RESP_SENT
A PDelay_Resp had been sent (master/slave)
Definition: event.h:61
@ PTP_UEV_INIT_DONE
The flexPTP core has been initialized.
Definition: event.h:47
@ PTP_UEV_BMCA_STATE_CHANGED
The BMCA state has changed.
Definition: event.h:70
@ PTP_UEV_ANNOUNCE_RECVED
An Announce message has been received (master/slave)
Definition: event.h:65
@ PTP_UEV_PDELAY_REQ_RECVED
A PDelay_Req had been received (master/slave)
Definition: event.h:58
#define PTP_IUEV(uev)
Definition: event.h:83
@ PTP_CEV_HEARTBEAT
Heartbeat event (tick)
Definition: event.h:19
@ PTP_CEV_RESET
A reset has been issued.
Definition: event.h:21
@ PTP_CEV_BMCA_STATE_CHANGED
The BMCA state has changed.
Definition: event.h:20
#define PTP_HW_INIT(increment, addend)
#define PTP_SERVO_DEINIT()
#define PTP_SERVO_INIT()
#define PTP_INCREMENT_NSEC
This module defines format conversion functions between network and host byte order and conversion fu...
This module handles various logging capabilities.
void ptp_master_disable()
Definition: master.c:437
void ptp_master_enable()
Definition: master.c:413
void ptp_master_tick()
Definition: master.c:441
void ptp_master_reset()
Definition: master.c:390
void ptp_master_init()
Definition: master.c:381
void ptp_master_destroy()
Definition: master.c:386
void ptp_master_process_message(RawPtpMessage *pRawMsg, PtpHeader *pHeader)
Definition: master.c:308
This module implements the master clock functionality.
void ptp_extract_header(PtpHeader *pHeader, const void *pPayload)
Definition: msg_utils.c:55
void ptp_extract_announce_message(PtpAnnounceBody *pAnnounce, void *pPayload)
Definition: msg_utils.c:122
This module defines functions that deal with actual PTP messages; they can extract or insert headers,...
This file is a header for the employed Network Stack Driver (NSD). A NSD must define ALL four functio...
void ptp_nsd_init(const NsdInitSettings *init)
Definition: nsd_etherlib.c:63
void ptp_nsd_get_interface_address(uint8_t *hwa)
Definition: nsd_etherlib.c:178
void ptp_deinit()
Definition: ptp_core.c:101
void ptp_process_event(const PtpCoreEvent *event)
Definition: ptp_core.c:206
void ptp_process_packet(RawPtpMessage *pRawMsg)
Definition: ptp_core.c:165
void ptp_set_sync_callback(PtpSyncCallback syncCb)
Definition: ptp_core.c:249
uint32_t ptp_get_tick()
Definition: ptp_core.c:238
void ptp_reset()
Definition: ptp_core.c:242
static void ptp_core_reset()
Definition: ptp_core.c:122
void ptp_set_user_event_callback(PtpUserEventCallback userEventCb)
Definition: ptp_core.c:253
static void ptp_common_init(void)
Definition: ptp_core.c:44
void ptp_init(void)
Definition: ptp_core.c:71
Core of the PTP implementation. Defines functions for message processing, clock tuning,...
In here reside a multitude of fundamental PTP-related constants and definitions.
#define PTP_DEFAULT_SERVO_OFFSET
Default servo offset in nanoseconds.
Definition: ptp_defs.h:140
#define PTP_ADDEND_INIT
Initial addend value.
Definition: ptp_defs.h:77
This module defines the fundamental PTP message and state machine type, flags, bitfields and the PTP ...
void(* PtpUserEventCallback)(PtpUserEventCode uev)
Definition: ptp_types.h:495
void(* PtpSyncCallback)(int64_t time_error, const PtpSyncCycleData *pSCD, uint32_t freqCodeWord)
Definition: ptp_types.h:484
PtpBmcaFsmState
Definition: ptp_types.h:310
@ PTP_BMCA_MASTER
Definition: ptp_types.h:314
@ PTP_BMCA_SLAVE
Definition: ptp_types.h:315
PtpMessageType
PTP packet type enumeration.
Definition: ptp_types.h:37
@ PTP_MT_PDelay_Req
Peer Delay Request.
Definition: ptp_types.h:40
@ PTP_MT_Announce
Announce.
Definition: ptp_types.h:45
@ PTP_DM_P2P
Peer-to-Peer Delay Mechanism.
Definition: ptp_types.h:146
PtpDelayMechanism ptp_get_delay_mechanism()
PtpTransportType ptp_get_transport_type()
This module features functions to tweak around the PTP engine's almost every property.
void ptp_slave_destroy()
Definition: slave.c:513
void ptp_slave_init()
Definition: slave.c:505
void ptp_slave_process_message(RawPtpMessage *pRawMsg, PtpHeader *pHeader)
Definition: slave.c:325
void ptp_slave_enable()
Definition: slave.c:577
void ptp_slave_tick()
Definition: slave.c:549
void ptp_slave_reset()
Definition: slave.c:517
void ptp_slave_disable()
Definition: slave.c:585
This module implements the slave clock functionality.
void ptp_clear_stats()
Definition: stats.c:17
This is the statistics module that gathers data of the operating PTP-engine.
Network Stack Driver initialization object.
uint8_t primary_p2p_8023_dest[6]
Destination address for primary P2P messages over Ethernet.
uint8_t pdelay_p2p_8023_dest[6]
Destination address for PDel* P2P messages over Ethernet.
Contents of a PTP Announce message without the common PTP header.
Definition: ptp_types.h:262
uint16_t code
Event code.
Definition: event.h:27
Giant PTP core state object.
Definition: ptp_types.h:509
PTP message header structure.
Definition: ptp_types.h:81
uint8_t messageType
ID.
Definition: ptp_types.h:83
uint8_t domainNumber
Domain.
Definition: ptp_types.h:94
uint8_t transportSpecific
Transport Specific.
Definition: ptp_types.h:84
Network state.
Definition: ptp_types.h:464
uint8_t data[(128)]
raw packet data
Definition: ptp_types.h:199
Timestamp (signed)
Definition: timeutils.h:33
void ptp_start_heartbeat_tmr()
Definition: task_ptp.c:216
bool ptp_event_enqueue(const PtpCoreEvent *event)
Definition: task_ptp.c:445
void ptp_stop_heartbeat_tmr()
Definition: task_ptp.c:231
The entry point of the whole PTP-implementation. Calling reg_task_ptp() initializes the PTP-engine,...
TimestampI * nsToTsI(TimestampI *r, int64_t ns)
Definition: timeutils.c:69
This module defines storage classes for timestamps and operations on time values.