DeterministicESPAsyncWebServer v6.28.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
powerlink.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file powerlink.h
6 * @brief Ethernet POWERLINK (EPSG) basic frame codec (DETWS_ENABLE_POWERLINK).
7 *
8 * Ethernet POWERLINK is the EPSG real-time managed-node bus over raw L2 (ethertype 0x88AB, on the
9 * shipped services/rawl2). The Managing Node (MN) runs an isochronous cycle: it multicasts a **SoC**
10 * (Start of Cycle), unicasts a **PReq** (Poll Request) to each Controlled Node (CN), each CN answers with
11 * a **PRes** (Poll Response) carrying its process data, then an **SoA** (Start of Async) opens the async
12 * phase. Every EPL basic frame is:
13 *
14 * [messageType : 1][destination node : 1][source node : 1][payload...]
15 *
16 * This builds and parses those frames (the four cyclic message types + the node addressing), so the MN
17 * schedules the cycle and a CN answers with its PRes process image. Pure, zero heap, no stdlib,
18 * host-testable; the raw-L2 transmit + the isochronous timing (the preempting-task model) are the device
19 * step.
20 */
21
22#ifndef DETERMINISTICESPASYNCWEBSERVER_POWERLINK_H
23#define DETERMINISTICESPASYNCWEBSERVER_POWERLINK_H
24
25#include "ServerConfig.h"
26#include <stddef.h>
27#include <stdint.h>
28
29#if DETWS_ENABLE_POWERLINK
30
31/** @brief EPL message types (EPSG DS 301). */
32// POWERLINK message types + node ids: wire bytes, so integer constants in a namespacing struct.
33struct Epl
34{
35 static constexpr uint8_t EPL_MSG_SOC = 0x01; ///< Start of Cycle (MN -> all, multicast).
36 static constexpr uint8_t EPL_MSG_PREQ = 0x03; ///< Poll Request (MN -> CN, unicast).
37 static constexpr uint8_t EPL_MSG_PRES = 0x04; ///< Poll Response (CN -> all, multicast, carries process data).
38 static constexpr uint8_t EPL_MSG_SOA = 0x05; ///< Start of Async (MN -> all).
39 static constexpr uint8_t EPL_MSG_ASND = 0x06; ///< Async Send.
40 static constexpr uint8_t EPL_NODE_BROADCAST = 0xFF; ///< broadcast node id (SoC/SoA destination).
41 static constexpr uint8_t EPL_NODE_MN = 0xF0; ///< the Managing Node id (240).
42};
43
44/**
45 * @brief Build an EPL basic frame: [messageType][dest][source][payload...].
46 * @return the frame length (3 + payload_len), or 0 on overflow / bad args.
47 */
48size_t detws_epl_build(uint8_t msg_type, uint8_t dest, uint8_t source, const uint8_t *payload, size_t payload_len,
49 uint8_t *out, size_t cap);
50
51/** @brief Convenience: build an SoC (MN -> broadcast, no payload). */
52size_t detws_epl_soc(uint8_t source, uint8_t *out, size_t cap);
53
54/** @brief Convenience: build a PReq to a CN carrying its output process image. */
55size_t detws_epl_preq(uint8_t dest_cn, uint8_t source, const uint8_t *pdo, size_t pdo_len, uint8_t *out, size_t cap);
56
57/** @brief Convenience: build a PRes from a CN carrying its input process image (multicast). */
58size_t detws_epl_pres(uint8_t source_cn, const uint8_t *pdo, size_t pdo_len, uint8_t *out, size_t cap);
59
60/** @brief A parsed EPL basic frame (payload points into the input). */
61struct EplFrame
62{
63 uint8_t msg_type;
64 uint8_t dest;
65 uint8_t source;
66 const uint8_t *payload;
67 size_t payload_len;
68};
69
70/** @brief Parse an EPL basic frame. @return true if @p len >= 3 and the message type is known. */
71bool detws_epl_parse(const uint8_t *frame, size_t len, EplFrame *out);
72
73#endif // DETWS_ENABLE_POWERLINK
74#endif // DETERMINISTICESPASYNCWEBSERVER_POWERLINK_H
User-facing configuration for DeterministicESPAsyncWebServer.