16#include <flexptp_options.h>
23#ifdef FLEXPTP_NON_LINUX_OS
24#ifdef FLEXPTP_FREERTOS
25static TaskHandle_t
sTH;
26#elif defined(FLEXPTP_CMSIS_OS2)
27static osThreadId_t
sTH;
30#elif defined(FLEXPTP_LINUX)
33#elif defined(FLEXPTP_OSLESS)
44#define S (gPtpCoreState)
49#define RX_PACKET_FIFO_LENGTH (16)
50#define TX_PACKET_FIFO_LENGTH (16)
53#if defined(FLEXPTP_NON_LINUX_OS) || defined(FLEXPTP_OSLESS)
54#define EVENT_FIFO_LENGTH (16)
55#define NOTIFICATION_FIFO_LENGTH (16)
56#define TX_CALLBACK_FIFO_LENGTH (10)
59#define TX_TTL_MS (2000)
60#define RX_TTL_MS (2000)
89#ifdef FLEXPTP_FREERTOS
90static TimerHandle_t sHeartBeatTmr;
91#elif defined(FLEXPTP_CMSIS_OS2)
92static osTimerId_t sHeartBeatTmr;
93#elif defined(FLEXPTP_LINUX)
94static timer_t sHeartBeatTmr;
98#ifdef FLEXPTP_FREERTOS
99static QueueHandle_t sEventFIFO;
100static QueueHandle_t sRxPacketFIFO;
101static QueueHandle_t sTxPacketFIFO;
102static QueueHandle_t sNotificationFIFO;
103static QueueHandle_t sTxCbFIFO;
104#elif defined(FLEXPTP_CMSIS_OS2)
105static osMessageQueueId_t sEventFIFO;
106static osMessageQueueId_t sRxPacketFIFO;
107static osMessageQueueId_t sTxPacketFIFO;
108static osMessageQueueId_t sNotificationFIFO;
109static osMessageQueueId_t sTxCbFIFO;
110#elif defined(FLEXPTP_LINUX)
111static int sRxPacketFIFO[2];
112static int sTxPacketFIFO[2];
113static int sEventFIFO[2];
114static int sTxCbFIFO[2];
115static sem_t sTxCbSem;
116#elif defined(FLEXPTP_OSLESS)
117static Fifo sEventFIFO;
118static Fifo sRxPacketFIFO;
119static Fifo sTxPacketFIFO;
120static Fifo sNotificationFIFO;
121static Fifo sTxCbFIFO;
130static PtpMsgBuf sRawRxMsgBuf, sRawTxMsgBuf;
144#ifndef FLEXPTP_OSLESS
151#elif defined(FLEXPTP_CMSIS_OS2)
153#elif defined(FLEXPTP_LINUX)
166#ifndef FLEXPTP_OSLESS
167 sHeartBeatTmr = NULL;
168#ifdef FLEXPTP_FREERTOS
173#elif defined(FLEXPTP_CMSIS_OS2)
175#elif defined(FLEXPTP_LINUX)
176 struct sigevent sev = {
177 .sigev_notify = SIGEV_THREAD,
179 .sigev_value = {.sival_ptr = NULL}};
180 if (timer_create(CLOCK_REALTIME, &sev, &sHeartBeatTmr) < 0) {
181 sHeartBeatTmr = NULL;
184 if (sHeartBeatTmr == NULL) {
185 MSG(
"Failed to create the PTP heartbeat timer!\n");
197#ifndef FLEXPTP_OSLESS
199#ifdef FLEXPTP_FREERTOS
200 xTimerDelete(sHeartBeatTmr, 0);
201#elif defined(FLEXPTP_CMSIS_OS2)
202 osTimerDelete(sHeartBeatTmr);
203#elif defined(FLEXPTP_LINUX)
204 timer_delete(sHeartBeatTmr);
206 sHeartBeatTmr = NULL;
211#ifdef FLEXPTP_FREERTOS
212 xTimerStart(sHeartBeatTmr, 0);
213#elif defined(FLEXPTP_CMSIS_OS2)
215#elif defined(FLEXPTP_LINUX)
216 struct itimerspec its = {
219 .it_value = {.tv_sec = 1, .tv_nsec = 0}
221 timer_settime(sHeartBeatTmr, 0, &its, NULL);
226#ifdef FLEXPTP_FREERTOS
227 xTimerStop(sHeartBeatTmr, 0);
228#elif defined(FLEXPTP_CMSIS_OS2)
229 osTimerStop(sHeartBeatTmr);
230#elif defined(FLEXPTP_LINUX)
231 struct itimerspec its;
232 memset(&its, 0,
sizeof(its));
233 timer_settime(sHeartBeatTmr, 0, &its, NULL);
243#ifdef FLEXPTP_FREERTOS
249 ok = (sRxPacketFIFO != NULL) && (sTxPacketFIFO != NULL) && (sEventFIFO != NULL) && (sNotificationFIFO != NULL) && (sTxCbFIFO != NULL);
250#elif defined(FLEXPTP_CMSIS_OS2)
256 ok = (sRxPacketFIFO != NULL) && (sTxPacketFIFO != NULL) && (sEventFIFO != NULL) && (sNotificationFIFO != NULL) && (sTxCbFIFO != NULL);
257#elif defined(FLEXPTP_LINUX)
265 ok &= pipe(sRxPacketFIFO) == 0;
267 ok &= pipe(sTxPacketFIFO) == 0;
269 ok &= pipe(sEventFIFO) == 0;
271 ok &= pipe(sTxCbFIFO) == 0;
272 ok &= sem_init(&sTxCbSem, 0, 0) == 0;
273#elif defined(FLEXPTP_OSLESS)
282 MSG(
"Failed to create the PTP message queues!\n");
294#define CLOSE_PIPE(pipefd) \
302#ifdef FLEXPTP_FREERTOS
303 vQueueDelete(sRxPacketFIFO);
304 vQueueDelete(sTxPacketFIFO);
305 vQueueDelete(sEventFIFO);
306 vQueueDelete(sNotificationFIFO);
307 vQueueDelete(sTxCbFIFO);
308#elif defined(FLEXPTP_CMSIS_OS2)
309 osMessageQueueDelete(sRxPacketFIFO);
310 osMessageQueueDelete(sTxPacketFIFO);
311 osMessageQueueDelete(sEventFIFO);
312 osMessageQueueDelete(sNotificationFIFO);
313 osMessageQueueDelete(sTxCbFIFO);
314#elif defined(FLEXPTP_LINUX)
315 CLOSE_PIPE(sRxPacketFIFO);
316 CLOSE_PIPE(sTxPacketFIFO);
317 CLOSE_PIPE(sEventFIFO);
318 CLOSE_PIPE(sTxCbFIFO);
319 sem_destroy(&sTxCbSem);
334#ifdef PTP_USER_EVENT_CALLBACK
349 MSG(
"Loading the PTP-configuration!\n");
362#ifdef FLEXPTP_FREERTOS
365 if (result != pdPASS) {
366 MSG(
"Failed to create the PTP task! (errcode: %d)\n", result);
370#elif defined(FLEXPTP_CMSIS_OS2)
373 memset(&attr, 0,
sizeof(osThreadAttr_t));
379 MSG(
"Failed to create the PTP task!\n");
383#elif defined(FLEXPTP_LINUX)
385 if (pthread_create(&
sTH, NULL,
task_ptp, NULL) != 0) {
386 MSG(
"Failed to create the PTP thread!\n");
407#if defined(FLEXPTP_NON_LINUX_OS)
409#ifdef FLEXPTP_FREERTOS
411#elif defined(FLEXPTP_CMSIS_OS2)
412 osThreadTerminate(
sTH);
416#elif defined(FLEXPTP_LINUX)
420 pthread_join(
sTH, NULL);
434#ifdef FLEXPTP_FREERTOS
435 ok = xQueueSend(sEventFIFO, event, portMAX_DELAY) == pdPASS;
437 xQueueSend(sNotificationFIFO, ¬if, portMAX_DELAY);
439#elif defined(FLEXPTP_CMSIS_OS2)
440 ok = osMessageQueuePut(sEventFIFO, event, 0, osWaitForever) == osOK;
442 osMessageQueuePut(sNotificationFIFO, ¬if, 0, osWaitForever);
444#elif defined(FLEXPTP_LINUX)
446 ok = write(sEventFIFO[1], event, len) == len;
447#elif defined(FLEXPTP_OSLESS)
468 memcpy(pMsgAlloc->
data, pPayload, copyLen);
469 pMsgAlloc->
size = copyLen;
470 pMsgAlloc->
ts.
sec = ts_sec;
473 pMsgAlloc->
pTxCb = NULL;
483#ifdef FLEXPTP_FREERTOS
484 xQueueSend(sRxPacketFIFO, &uid, portMAX_DELAY);
485 xQueueSend(sNotificationFIFO, ¬if, portMAX_DELAY);
486#elif defined(FLEXPTP_CMSIS_OS2)
487 osMessageQueuePut(sRxPacketFIFO, &uid, 0, osWaitForever);
488 osMessageQueuePut(sNotificationFIFO, ¬if, 0, osWaitForever);
489#elif defined(FLEXPTP_LINUX)
490 write(sRxPacketFIFO[1], &uid,
sizeof(uint32_t));
491#elif defined(FLEXPTP_OSLESS)
497 CLILOG(S.logging.info,
"The PTP receive packet buffer is full, a packet was lost!\n");
509#ifdef FLEXPTP_FREERTOS
510 BaseType_t hptWoken =
false;
511 if (xPortIsInsideInterrupt()) {
512 xQueueSendFromISR(sTxPacketFIFO, &uid, &hptWoken);
513 xQueueSendFromISR(sNotificationFIFO, ¬if, &hptWoken);
515 xQueueSend(sTxPacketFIFO, &uid, portMAX_DELAY);
516 xQueueSend(sNotificationFIFO, ¬if, portMAX_DELAY);
518#elif defined(FLEXPTP_CMSIS_OS2)
519 osMessageQueuePut(sTxPacketFIFO, &uid, 0, osWaitForever);
520 osMessageQueuePut(sNotificationFIFO, ¬if, 0, osWaitForever);
521#elif defined(FLEXPTP_LINUX)
522 write(sTxPacketFIFO[1], &uid,
sizeof(uint32_t));
523#elif defined(FLEXPTP_OSLESS)
530 CLILOG(S.logging.info,
"PTP TX Enqueue failed, buffer is full! (%u)\n", pMsg->
tag);
539 TxTs ts = {.
uid = uid, .seconds = seconds, .nanoseconds = nanoseconds};
543#ifdef FLEXPTP_FREERTOS
544 BaseType_t hptWoken =
false;
545 if (xPortIsInsideInterrupt()) {
546 xQueueSendFromISR(sTxCbFIFO, &ts, &hptWoken);
547 xQueueSendFromISR(sNotificationFIFO, ¬if, &hptWoken);
549 xQueueSend(sTxCbFIFO, &ts, portMAX_DELAY);
550 xQueueSend(sNotificationFIFO, ¬if, portMAX_DELAY);
552#elif defined(FLEXPTP_CMSIS_OS2)
553 osMessageQueuePut(sTxCbFIFO, &ts, 0, osWaitForever);
554 osMessageQueuePut(sNotificationFIFO, ¬if, 0, osWaitForever);
555#elif defined(FLEXPTP_LINUX)
556 write(sTxCbFIFO[1], &ts,
sizeof(
TxTs));
558#elif defined(FLEXPTP_OSLESS)
567 if (pRawMsg == NULL) {
587#ifdef FLEXPTP_NON_LINUX_OS
589#elif defined(FLEXPTP_LINUX)
590static void *
task_ptp(
void *pParam) {
591#elif defined(FLEXPTP_OSLESS)
595#ifndef FLEXPTP_OSLESS
603#ifdef FLEXPTP_FREERTOS
604 xQueueReceive(sNotificationFIFO, ¬ification, portMAX_DELAY);
605#elif defined(FLEXPTP_CMSIS_OS2)
606 osMessageQueueGet(sNotificationFIFO, ¬ification, NULL, osWaitForever);
607#elif defined(FLEXPTP_LINUX)
611 struct pollfd pfd[POLL_N_FD] = {
612 {.fd = sRxPacketFIFO[0], .events = POLLIN, .revents = 0},
613 {.fd = sTxPacketFIFO[0], .events = POLLIN, .revents = 0},
614 {.fd = sTxCbFIFO[0], .events = POLLIN, .revents = 0},
615 {.fd = sEventFIFO[0], .events = POLLIN, .revents = 0},
624 int pret = poll(pfd, POLL_N_FD, -1);
627 for (uint32_t i = 0; i < POLL_N_FD; i++) {
628 if (pfd[i].revents & POLLIN) {
629 notification |= notif_mapping[i];
634 CLILOG(S.logging.info,
"A polling error occurred!\n");
637#elif defined(FLEXPTP_OSLESS)
638 fifo_pop(&sNotificationFIFO, ¬ification);
647#ifdef FLEXPTP_FREERTOS
648 xQueueReceive(sTxCbFIFO, &ts, portMAX_DELAY);
649#elif defined(FLEXPTP_CMSIS_OS2)
650 osMessageQueueGet(sTxCbFIFO, &ts, NULL, osWaitForever);
651#elif defined(FLEXPTP_LINUX)
652 read(sTxCbFIFO[0], &ts,
sizeof(
TxTs));
653#elif defined(FLEXPTP_OSLESS)
659 CLILOG(S.logging.transmission,
"[% 8u]---> %u\n", S.ticks, ts.
uid);
661 if (pRawMsg != NULL) {
670 if (pRawMsg->
pTxCb != NULL) {
671 pRawMsg->
pTxCb(pRawMsg);
677 CLILOG(S.logging.transmission,
"[% 8u] %u AUTOFREE\n", S.ticks, ts.
uid);
691#ifdef FLEXPTP_FREERTOS
692 xQueueReceive(sTxPacketFIFO, &uid, portMAX_DELAY);
693#elif defined(FLEXPTP_CMSIS_OS2)
694 osMessageQueueGet(sTxPacketFIFO, &uid, NULL, osWaitForever);
695#elif defined(FLEXPTP_LINUX)
696 read(sTxPacketFIFO[0], &uid,
sizeof(uint32_t));
697#elif defined(FLEXPTP_OSLESS)
704 if (pRawMsg != NULL) {
720#ifdef FLEXPTP_FREERTOS
721 xQueueReceive(sRxPacketFIFO, &uid, portMAX_DELAY);
722#elif defined(FLEXPTP_CMSIS_OS2)
723 osMessageQueueGet(sRxPacketFIFO, &uid, NULL, osWaitForever);
724#elif defined(FLEXPTP_LINUX)
725 read(sRxPacketFIFO[0], &uid,
sizeof(uint32_t));
726#elif defined(FLEXPTP_OSLESS)
733 if (pRawMsg != NULL) {
749#ifdef FLEXPTP_FREERTOS
750 xQueueReceive(sEventFIFO, &event, portMAX_DELAY);
751#elif defined(FLEXPTP_CMSIS_OS2)
752 osMessageQueueGet(sEventFIFO, &event, NULL, osWaitForever);
753#elif defined(FLEXPTP_LINUX)
755#elif defined(FLEXPTP_OSLESS)
void ptp_load_config_from_dump(const void *pDump)
This module defines functions for storing and loading flexPTP configurations.
In this module are the core and user events defined.
@ PTP_UEV_QUEUE_ERROR
This event signals that the flexPTP's internal transmission output queue is full and blocked.
@ PTP_CEV_TERMINATE
A shutdown is requested.
@ PTP_CEV_HEARTBEAT
Heartbeat event (tick)
bool fifo_pop(Fifo *f, void *item)
uint32_t fifo_get_level(const Fifo *f)
bool fifo_push(Fifo *f, void const *item)
void fifo_init(Fifo *f, uint32_t len, uint32_t esize, uint8_t *data, FifoLockFn lockFn)
#define FIFO_POOL(name, len, esize)
#define FLEXPTP_TASK_PRIORITY
void msgb_set_sent(PtpMsgBuf *buf, RawPtpMessage *msg)
RawPtpMessage * msgb_get_by_uid(PtpMsgBuf *buf, uint32_t uid)
void msgb_init(PtpMsgBuf *buf, PtpMsgBufBlock *pool, uint32_t n)
void msgb_commit(PtpMsgBuf *buf, RawPtpMessage *msg)
RawPtpMessage * msgb_get_sent_by_tag(PtpMsgBuf *buf, uint32_t tag)
uint32_t msgb_get_uid(const PtpMsgBuf *buf, const RawPtpMessage *msg)
RawPtpMessage * msgb_alloc(PtpMsgBuf *buf, uint32_t tag, uint32_t ttl)
void msgb_free(PtpMsgBuf *buf, RawPtpMessage *msg)
void msgb_tick(PtpMsgBuf *buf)
uint32_t msgb_get_error(PtpMsgBuf *buf)
#define MSGBUF_TAG_OVERWRITE
Overwrite if a message exists with the same tag.
@ MSGB_ERR_FULL
The buffer is full, cannot allocate a slot.
This file is a header for the employed Network Stack Driver (NSD). A NSD must define ALL four functio...
void ptp_nsd_transmit_msg(RawPtpMessage *pMsg, uint32_t uid)
void ptp_nsd_init(PtpTransportType tp, PtpDelayMechanism dm)
This module implements defines a single method that prints a verbose summary of the operating PTP pro...
void ptp_process_event(const PtpCoreEvent *event)
void ptp_process_packet(RawPtpMessage *pRawMsg)
void ptp_set_user_event_callback(PtpUserEventCallback userEventCb)
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_HEARTBEAT_TICKRATE_MS
Heartbeat ticking period.
#define FLEXPTP_TASK_STACK_SIZE
flexPTP task stack size
#define FLEXPTP_MS_TO_TICKS(ms)
Interval conversion between milliseconds and ticks.
This module defines the fundamental PTP message and state machine type, flags, bitfields and the PTP ...
@ RPMT_RANDOM
Create a random, unique tag.
#define MAX_PTP_MSG_SIZE
Maximum PTP message size.
PtpDelayMechanism ptp_get_delay_mechanism()
PtpTransportType ptp_get_transport_type()
This module features functions to tweak around the PTP engine's almost every property.
PTP message buffer entry.
uint32_t tag
unique transmit tag
uint32_t ttl
transmit Time-to-Live in ticks
uint32_t size
Packet size.
uint8_t data[(128)]
raw packet data
TxCb * pTxCb
transmit callback function
int32_t nanosec
nanoseconds
Structure for communicating transmit timestamp writeback.
uint32_t seconds
Timestamp seconds.
uint32_t nanoseconds
Timestamp nanoseconds.
#define TX_CALLBACK_FIFO_LENGTH
Transmit callback FIFO length.
void ptp_receive_enqueue(const void *pPayload, uint32_t len, uint32_t ts_sec, uint32_t ts_ns, int tp)
static void task_ptp(void *pParam)
bool ptp_transmit_enqueue(const RawPtpMessage *pMsg)
void ptp_start_heartbeat_tmr()
static bool ptp_create_message_queues()
static void ptp_destroy_message_queues()
ProcThreadNotification
Notifications for the processing thread.
@ PTN_EVENT
An event has occurred.
@ PTN_TRANSMIT
A message awaits transmission.
@ PTN_NONE
Empty notification.
@ PTN_RECEIVE
A message has been received.
@ PTN_TRANSMIT_DONE
A transmit timestamp awaits delegation.
void ptp_transmit_timestamp_cb(uint32_t uid, uint32_t seconds, uint32_t nanoseconds)
#define EVENT_FIFO_LENGTH
Event FIFO length.
bool ptp_event_enqueue(const PtpCoreEvent *event)
#define NOTIFICATION_FIFO_LENGTH
Notification FIFO length.
static bool sPTP_operating
#define RX_TTL_MS
TTL for inbound packets.
void ptp_stop_heartbeat_tmr()
bool is_flexPTP_operating()
bool ptp_read_and_clear_transmit_timestamp(uint32_t tag, TimestampI *pTs)
#define RX_PACKET_FIFO_LENGTH
Receive packet FIFO length.
static bool ptp_create_heartbeat_tmr()
#define TX_PACKET_FIFO_LENGTH
Transmit packet FIFO length.
static void ptp_heartbeat_tmr_cb(TimerHandle_t timer)
static void ptp_remove_heartbeat_tmr()
The entry point of the whole PTP-implementation. Calling reg_task_ptp() initializes the PTP-engine,...