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
131
132 // reset statistics
134
135 // reset common functionality
137
138 /* ---- SBMC ----- */
140
141 /* ---- SLAVE ---- */
143
144 /* ---- MASTER --- */
146
147 // ------------------------
148
149 // resume the heartbeat timer
151
152 // dispatch RESET event
154}
155
156// packet processing
158 PtpHeader header;
159
160 // header readout
161 ptp_extract_header(&header, pRawMsg->data);
162
163 // consider only messages in our domain
164 if (header.domainNumber != S.profile.domainNumber ||
165 header.transportSpecific != S.profile.transportSpecific) {
166 return;
167 }
168
169 // process Announce messages and halt further processing
170 PtpMessageType mt = header.messageType;
171 if (mt == PTP_MT_Announce) {
172 PtpMasterProperties newMstProp;
173 ptp_extract_announce_message(&newMstProp, pRawMsg->data);
174 ptp_handle_announce_msg(&newMstProp, &header);
175 PTP_IUEV(PTP_UEV_ANNOUNCE_RECVED); // dispatch ANNOUNCE_RECVED event
176 return;
177 }
178
179 // PDelay_Req messages should always be processed
180 if ((header.messageType == PTP_MT_PDelay_Req) && (S.profile.delayMechanism == PTP_DM_P2P)) {
181 PTP_IUEV(PTP_UEV_PDELAY_REQ_RECVED); // dispatch PDELAY_REQ_RECVED event
182 ptp_send_pdelay_resp(pRawMsg); // sent the PDelay_Resp message
183 PTP_IUEV(PTP_UEV_PDELAY_RESP_SENT); // dispatch PDELAY_RESP_SENT event
184 return;
185 }
186
187 // if operating in slave mode
188 PtpBmcaFsmState bmcaState = S.bmca.state;
189 if (bmcaState == PTP_BMCA_SLAVE) {
190 ptp_slave_process_message(pRawMsg, &header);
191 return;
192 } else if (bmcaState == PTP_BMCA_MASTER) { // if operating in Master mode
193 ptp_master_process_message(pRawMsg, &header);
194 return;
195 }
196}
197
198void ptp_process_event(const PtpCoreEvent *event) {
199 switch (event->code) {
200 case PTP_CEV_HEARTBEAT: { // heartbeat event
201 S.ticks++;
205 } break;
207 PtpBmcaFsmState bmcaState = event->w.w;
208 if (bmcaState == PTP_BMCA_SLAVE) {
210 } else if (bmcaState == PTP_BMCA_MASTER) {
212 } else {
215 }
216
217 // dispatch BMCA_STATE_CHANGED event
219 } break;
220 case PTP_CEV_RESET: {
222 } break;
223 default:
224 break;
225 }
226}
227
228// -----------------------------------------------
229
230uint32_t ptp_get_tick() {
231 return S.ticks;
232}
233
234void ptp_reset() {
235 PtpCoreEvent event = { .code = PTP_CEV_RESET, .w = 0, .dw = 0 };
236 ptp_event_enqueue(&event);
237}
238
239// -----------------------------------------------
240
242 S.slave.syncCb = syncCb;
243}
244
246 S.userEventCb = userEventCb;
247}
void ptp_bmca_destroy()
Definition: bmca.c:205
void ptp_bmca_tick()
Definition: bmca.c:72
void ptp_bmca_init()
Definition: bmca.c:191
void ptp_bmca_reset()
Definition: bmca.c:209
void ptp_handle_announce_msg(PtpAnnounceBody *pAnn, PtpHeader *pHeader)
Definition: bmca.c:135
This module implements the Best Master Clock Algorithm.
void ptp_register_cli_commands()
Definition: cli_cmds.c:358
void ptp_remove_cli_commands()
Definition: cli_cmds.c:385
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:167
void ptp_send_pdelay_resp(const RawPtpMessage *pMsg)
Definition: common.c:101
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:428
void ptp_master_enable()
Definition: master.c:404
void ptp_master_tick()
Definition: master.c:432
void ptp_master_reset()
Definition: master.c:381
void ptp_master_init()
Definition: master.c:372
void ptp_master_destroy()
Definition: master.c:377
void ptp_master_process_message(RawPtpMessage *pRawMsg, PtpHeader *pHeader)
Definition: master.c:299
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(PtpTransportType tp, PtpDelayMechanism dm)
Definition: nsd_etherlib.c:50
void ptp_nsd_get_interface_address(uint8_t *hwa)
Definition: nsd_etherlib.c:138
void ptp_deinit()
Definition: ptp_core.c:101
void ptp_process_event(const PtpCoreEvent *event)
Definition: ptp_core.c:198
void ptp_process_packet(RawPtpMessage *pRawMsg)
Definition: ptp_core.c:157
void ptp_set_sync_callback(PtpSyncCallback syncCb)
Definition: ptp_core.c:241
uint32_t ptp_get_tick()
Definition: ptp_core.c:230
void ptp_reset()
Definition: ptp_core.c:234
static void ptp_core_reset()
Definition: ptp_core.c:122
void ptp_set_user_event_callback(PtpUserEventCallback userEventCb)
Definition: ptp_core.c:245
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:487
void(* PtpSyncCallback)(int64_t time_error, const PtpSyncCycleData *pSCD, uint32_t freqCodeWord)
Definition: ptp_types.h:476
PtpBmcaFsmState
Definition: ptp_types.h:309
@ PTP_BMCA_MASTER
Definition: ptp_types.h:313
@ PTP_BMCA_SLAVE
Definition: ptp_types.h:314
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:484
void ptp_slave_init()
Definition: slave.c:476
void ptp_slave_process_message(RawPtpMessage *pRawMsg, PtpHeader *pHeader)
Definition: slave.c:300
void ptp_slave_enable()
Definition: slave.c:547
void ptp_slave_tick()
Definition: slave.c:520
void ptp_slave_reset()
Definition: slave.c:488
void ptp_slave_disable()
Definition: slave.c:555
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.
Contents of a PTP Announce message without the common PTP header.
Definition: ptp_types.h:261
uint16_t code
Event code.
Definition: event.h:27
Giant PTP core state object.
Definition: ptp_types.h:501
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:461
uint8_t data[(128)]
raw packet data
Definition: ptp_types.h:198
Timestamp (signed)
Definition: timeutils.h:33
void ptp_start_heartbeat_tmr()
Definition: task_ptp.c:210
bool ptp_event_enqueue(const PtpCoreEvent *event)
Definition: task_ptp.c:430
void ptp_stop_heartbeat_tmr()
Definition: task_ptp.c:225
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.