flexPTP 1.0
An IEEE 1588 PTP implementation designed for microcontrollers
Loading...
Searching...
No Matches
task_ptp.c
Go to the documentation of this file.
1#include "task_ptp.h"
2
3#include <string.h>
4
5#include "config.h"
6#include "event.h"
8#include "portmacro.h"
9#include "profiles.h"
10#include "projdefs.h"
11#include "ptp_core.h"
12#include "ptp_raw_msg_circbuf.h"
13#include "settings_interface.h"
14
15#include "FreeRTOS.h"
16#include "queue.h"
17#include "task.h"
18
19#include <flexptp_options.h>
20
21// provide own MIN implementation
22#ifdef MIN
23#undef MIN
24#endif
25
26#define MIN(a, b) (((a) < (b)) ? (a) : (b))
27
29// ----- TASK PROPERTIES -----
30static TaskHandle_t sTH; // task handle
31static uint8_t sPrio = FLEXPTP_TASK_PRIORITY; // priority
32static uint16_t sStkSize = 2048; // stack size
33static void task_ptp(void *pParam); // task routine function
34// ---------------------------
35
36static bool sPTP_operating = false; // does the PTP subsystem operate?
37
38// ---------------------------
39
41
42// FIFO for incoming packets
43#define RX_PACKET_FIFO_LENGTH (32)
44#define TX_PACKET_FIFO_LENGTH (16)
45#define EVENT_FIFO_LENGTH (32)
46
48// queues for message reception and transmission
49static QueueHandle_t sRxPacketFIFO, sEventFIFO;
50QueueHandle_t gTxPacketFIFO;
51static QueueSetHandle_t sRxTxEvFIFOSet;
52
53// "ring" buffer for PTP-messages
55static RawPtpMessage sRawRxMsgBufPool[RX_PACKET_FIFO_LENGTH];
56static RawPtpMessage sRawTxMsgBufPool[TX_PACKET_FIFO_LENGTH];
58
59// create message queues
61 // create packet FIFO
62 sRxPacketFIFO = xQueueCreate(RX_PACKET_FIFO_LENGTH, sizeof(uint8_t));
63 gTxPacketFIFO = xQueueCreate(TX_PACKET_FIFO_LENGTH, sizeof(uint8_t));
64 sEventFIFO = xQueueCreate(EVENT_FIFO_LENGTH, sizeof(PtpCoreEvent));
65 sRxTxEvFIFOSet = xQueueCreateSet(RX_PACKET_FIFO_LENGTH + TX_PACKET_FIFO_LENGTH);
66 xQueueAddToSet(sRxPacketFIFO, sRxTxEvFIFOSet);
67 xQueueAddToSet(gTxPacketFIFO, sRxTxEvFIFOSet);
68 xQueueAddToSet(sEventFIFO, sRxTxEvFIFOSet);
69
70 // initalize packet buffers
73}
74
75// destroy message queues
77 // destroy packet FIFO
78 xQueueRemoveFromSet(sRxPacketFIFO, sRxTxEvFIFOSet);
79 xQueueRemoveFromSet(gTxPacketFIFO, sRxTxEvFIFOSet);
80 xQueueRemoveFromSet(sEventFIFO, sRxTxEvFIFOSet);
81 vQueueDelete(sRxPacketFIFO);
82 vQueueDelete(gTxPacketFIFO);
83 vQueueDelete(sEventFIFO);
84 vQueueDelete(sRxTxEvFIFOSet);
85
86 // packet buffers cannot be released since nothing has been allocated for them
87}
88
89// register PTP task and initialize
91 // initialize message queues and buffers
93
94#ifdef PTP_USER_EVENT_CALLBACK
95 ptp_set_user_event_callback(PTP_USER_EVENT_CALLBACK);
96#endif
97
98 // initialize PTP subsystem
99 uint8_t hwa[6];
101 ptp_init(hwa);
102
103#ifdef PTP_CONFIG_PTR // load config if provided
104 MSG("Loading PTP-config!\n");
106
107 // print profile summary
108 MSG("\n\n----\n");
110 MSG("----\n\n");
111#endif
112
113 // initialize network stack driver
115
116 // create task
117 BaseType_t result = xTaskCreate(task_ptp, "ptp", sStkSize / 4, NULL, sPrio, &sTH);
118 if (result != pdPASS) {
119 MSG("Failed to create PTP task! (errcode: %d)\n", result);
121 return;
122 }
123
124 sPTP_operating = true; // the PTP subsystem is operating
125}
126
127// unregister PTP task
129 ptp_nsd_init(-1, -1); // de-initialize the network stack driver
130 vTaskDelete(sTH); // delete task
131 ptp_deinit(); // ptp subsystem de-initialization
132 ptp_destroy_message_queues(); // destroy message queues and buffers
133 sPTP_operating = false; // the PTP subsystem is NOT operating anymore
134}
135
136bool ptp_event_enqueue(const PtpCoreEvent * event) {
137 return xQueueSend(sEventFIFO, event, portMAX_DELAY) == pdPASS;
138}
139
140// put ptp message onto processing queue
141void ptp_receive_enqueue(const void *pPayload, uint32_t len, uint32_t ts_sec, uint32_t ts_ns, int tp) {
142 // only consider messages received on the matching transport layer
143 if (tp != ptp_get_transport_type()) {
144 return;
145 }
146
147 // enqueue message
149 if (pMsg) {
150 // copy payload and timestamp
151 uint32_t copyLen = MIN(len, MAX_PTP_MSG_SIZE);
152 memcpy(pMsg->data, pPayload, copyLen);
153 pMsg->size = copyLen;
154 pMsg->ts.sec = ts_sec;
155 pMsg->ts.nanosec = ts_ns;
156 pMsg->pTs = NULL;
157 pMsg->pTxCb = NULL; // not meaningful...
158
159 uint8_t idx = ptp_circ_buf_commit(&gRawRxMsgBuf);
160
161 xQueueSend(sRxPacketFIFO, &idx, portMAX_DELAY); // send index
162 } else {
163 MSG("PTP-packet buffer full, a packet has been dropped!\n");
164 }
165
166 // MSG("TS: %u.%09u\n", (uint32_t)ts_sec, (uint32_t)ts_ns);
167
168 // if the transport layer matches...
169}
170
173 extern QueueHandle_t gTxPacketFIFO;
175 if (pMsgAlloc) {
176 *pMsgAlloc = *pMsg;
177 uint8_t idx = ptp_circ_buf_commit(&gRawTxMsgBuf);
178 BaseType_t hptWoken = false;
179 if (xPortIsInsideInterrupt()) {
180 xQueueSendFromISR(gTxPacketFIFO, &idx, (BaseType_t *)&hptWoken);
181 } else {
182 xQueueSend(gTxPacketFIFO, &idx, portMAX_DELAY);
183 }
184 return true;
185 } else {
186 MSG("PTP TX Enqueue failed!\n");
187 PTP_IUEV(PTP_UEV_QUEUE_ERROR); // dispatch QUEUE_ERROR event
188 return false;
189 }
190}
191
192// task routine
193static void task_ptp(void *pParam) {
194 while (1) {
195 // wait for received packet or packet to transfer
196 QueueHandle_t activeQueue = xQueueSelectFromSet(sRxTxEvFIFOSet, pdMS_TO_TICKS(200));
197
198 // if packet is on the RX queue
199 if (activeQueue == sRxPacketFIFO) {
200 // pop packet from FIFO
201 uint8_t bufIdx;
202 xQueueReceive(sRxPacketFIFO, &bufIdx, portMAX_DELAY);
203
204 // fetch buffer
205 RawPtpMessage *pRawMsg = ptp_circ_buf_get(&gRawRxMsgBuf, bufIdx);
206 pRawMsg->pTs = &pRawMsg->ts;
207
208 // process packet
209 ptp_process_packet(pRawMsg);
210
211 // free buffer
213 } else if (activeQueue == gTxPacketFIFO) {
214 // pop packet from FIFO
215 uint8_t bufIdx;
216 xQueueReceive(gTxPacketFIFO, &bufIdx, portMAX_DELAY);
217
218 // fetch buffer
219 RawPtpMessage *pRawMsg = ptp_circ_buf_get(&gRawTxMsgBuf, bufIdx);
220 ptp_nsd_transmit_msg(pRawMsg);
221 } else if (activeQueue == sEventFIFO) {
222 // pop event from the FIFO
223 PtpCoreEvent event;
224 xQueueReceive(sEventFIFO, &event, portMAX_DELAY);
225
226 // process event
227 ptp_process_event(&event);
228 } else {
229 // ....
230 }
231 }
232}
233
234// --------------------------
235
236// function to query PTP operation state
238 return sPTP_operating;
239}
240
241// --------------------------
242
void ptp_load_config_from_dump(const void *pDump)
Definition: config.c:78
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.
Definition: event.h:67
#define PTP_IUEV(uev)
Definition: event.h:77
#define PTP_CONFIG_PTR()
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)
Definition: nsd_etherlib.c:135
void ptp_nsd_init(PtpTransportType tp, PtpDelayMechanism dm)
Definition: nsd_etherlib.c:50
PtpCircBuf gRawTxMsgBuf
Output circular buffers.
void ptp_nsd_get_interface_address(uint8_t *hwa)
Definition: nsd_etherlib.c:150
PtpCircBuf gRawRxMsgBuf
Input circular buffer.
void ptp_print_profile()
Definition: profiles.c:13
This module implements defines a single method that prints a verbose summary of the operating PTP pro...
void ptp_deinit()
Definition: ptp_core.c:140
void ptp_process_event(const PtpCoreEvent *event)
Definition: ptp_core.c:250
void ptp_init(const uint8_t *hwa)
Definition: ptp_core.c:113
void ptp_process_packet(RawPtpMessage *pRawMsg)
Definition: ptp_core.c:209
void ptp_set_user_event_callback(PtpUserEventCallback userEventCb)
Definition: ptp_core.c:282
Core of the PTP implementation. Defines functions for message processing, clock tuning,...
RawPtpMessage * ptp_circ_buf_alloc(PtpCircBuf *pCircBuf)
void ptp_circ_buf_free(PtpCircBuf *pCircBuf)
int ptp_circ_buf_commit(PtpCircBuf *pCircBuf)
RawPtpMessage * ptp_circ_buf_get(PtpCircBuf *pCircBuf, uint8_t idx)
void ptp_circ_buf_init(PtpCircBuf *pCircBuf, RawPtpMessage *pMsgPool, uint8_t n)
This module implements a circular buffer that is used for accepting and omitting received and to be t...
#define MAX_PTP_MSG_SIZE
Maximum PTP message size.
Definition: ptp_types.h:157
PtpDelayMechanism ptp_get_delay_mechanism()
PtpTransportType ptp_get_transport_type()
This module features functions to tweak around the PTP engine's almost every property.
"Ring" buffer for PTP-messages.
Raw PTP message structure.
Definition: ptp_types.h:162
TimestampI ts
Timestamp.
Definition: ptp_types.h:163
void(* pTxCb)(const struct RawPtpMessage_ *pMsg)
transmit callback function
Definition: ptp_types.h:168
uint32_t size
Packet size.
Definition: ptp_types.h:164
TimestampI * pTs
pointer to timestamp
Definition: ptp_types.h:167
uint8_t data[(128)]
raw packet data
Definition: ptp_types.h:173
int32_t nanosec
nanoseconds
Definition: timeutils.h:31
int64_t sec
seconds
Definition: timeutils.h:30
void ptp_receive_enqueue(const void *pPayload, uint32_t len, uint32_t ts_sec, uint32_t ts_ns, int tp)
Definition: task_ptp.c:141
static void task_ptp(void *pParam)
Definition: task_ptp.c:193
bool ptp_transmit_enqueue(const RawPtpMessage *pMsg)
Definition: task_ptp.c:171
void reg_task_ptp()
Definition: task_ptp.c:90
#define MIN(a, b)
Definition: task_ptp.c:26
static void ptp_create_message_queues()
Definition: task_ptp.c:60
static void ptp_destroy_message_queues()
Definition: task_ptp.c:76
void unreg_task_ptp()
Definition: task_ptp.c:128
#define EVENT_FIFO_LENGTH
Event FIFO length.
Definition: task_ptp.c:45
bool ptp_event_enqueue(const PtpCoreEvent *event)
Definition: task_ptp.c:136
bool task_ptp_is_operating()
Definition: task_ptp.c:237
#define RX_PACKET_FIFO_LENGTH
Receive packet FIFO length.
Definition: task_ptp.c:43
#define TX_PACKET_FIFO_LENGTH
Transmit packet FIFO length.
Definition: task_ptp.c:44
The entry point of the whole PTP-implementation. Calling reg_task_ptp() initializes the PTP-engine,...