MMgr v1.0.0
Zero-heap memory manager in C11. One borrowed buffer, carved by asserted offset.
Loading...
Searching...
No Matches
memoriam_praetereo.h
Go to the documentation of this file.
1/* MMgr - Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2 * SPDX-License-Identifier: AGPL-3.0-or-later OR LicenseRef-Commercial OR LicenseRef-Educational
3 *
4 * Every use falls under AGPL-3.0-or-later unless you hold explicit permission, which is either a
5 * negotiated commercial licensing contract or an educator's license issued to you personally.
6 */
7/**
8 * @file memoriam_praetereo.h
9 * @brief DMA channels: the completion event, the port hooks, the praet dispatch table, and the
10 * schedule and descriptors under them.
11 * @author dstroy0 (Douglas Quigg) <dquigg123@gmail.com>
12 * @date 2026-08-29
13 *
14 * @note The one header a caller includes. praet_ordo.h and praet_descriptor.h come in at the end,
15 * and the knobs they read are set on the build line, before this is reached.
16 * @warning Everything below is declared only when MMGR_ENABLE_DMA is set.
17 */
18#ifndef MMGR_MEMORIAM_PRAETEREO_H
19#define MMGR_MEMORIAM_PRAETEREO_H
20
21#include "mmgr.h"
22
23#if MMGR_ENABLE_DMA
24
25EMBED_BEGIN_DECLS
26
27/**
28 * @brief What the port layer reports when a transfer finishes.
29 *
30 * @warning data points at the port layer's buffer. It is valid only for the callback's duration [BORROWS].
31 */
32typedef struct
33{
34 const uint8_t *data; /**< Bytes the transfer moved [BORROWS]. */
35 uint32_t completion_ms; /**< Completion time, whole milliseconds. */
36 uint32_t completion_us; /**< Completion time, microseconds within that millisecond. */
37 uint16_t bytes; /**< Bytes in data. */
38 uint16_t sequence; /**< Sequence number the port layer assigns. */
39 uint8_t channel; /**< Channel the transfer ran on. */
40 uint8_t peripheral; /**< Peripheral the channel is wired to. */
41 uint8_t direction; /**< Direction of the transfer. */
43
44/**
45 * @brief Reports a finished transfer to whatever registered this callback.
46 *
47 * @param[in] event The completion event [BORROWS].
48 * @param[in] user The pointer registered alongside this callback [BORROWS].
49 * @note Runs in whatever context the port layer finishes a transfer in. No mmgr_praet_ entry point
50 * calls it.
51 * @warning event and event->data belong to the port layer and last only until this returns. Copy
52 * anything kept [BORROWS].
53 */
54typedef void (*mmgr_praet_callback)(const mmgr_praet_event *event, void *user);
55
56/**
57 * @brief A completion callback and the pointer handed back to it.
58 *
59 * @warning mmgr_praet_open forwards the pointer to this struct unchanged and keeps no copy, and so it
60 * must stay valid for as long as the channel is open [BORROWS].
61 */
62typedef struct
63{
64 const mmgr_praet_callback callback; /**< Function to call [BORROWS]. */
65 void *const user; /**< Passed back to callback unexamined [BORROWS]. */
67
68/**
69 * @brief Arguments for opening a channel, and for polling one.
70 *
71 * @note mmgr_praet_open reads all four members. mmgr_praet_poll passes the whole struct to the port
72 * layer.
73 */
74typedef struct
75{
76 const uint8_t channel; /**< Channel to act on. */
77 const uint8_t peripheral; /**< Peripheral the channel is wired to. */
78 const embed_bool loopback; /**< Open the channel looped back on itself. */
79 const PraetCallbackCfg *const on_complete; /**< Called when a transfer finishes [BORROWS]. */
80} PraetCfg;
81
82/**
83 * @brief Arguments for submitting a transfer, and for closing a channel.
84 *
85 * @note mmgr_praet_tx_submit reads all three. mmgr_praet_close reads channel alone.
86 */
87typedef struct
88{
89 const uint8_t channel; /**< Channel to act on. */
90 const uint8_t *const buf; /**< Bytes to send [BORROWS]. */
91 const uint16_t bytes; /**< Bytes in buf. */
93
94/**
95 * @brief Type of the praet dispatch table.
96 *
97 * @note EMBED_TABLE_LAYOUT asserts the four members sit at consecutive EMBED_FUNCTION_POINTER_BYTES offsets, with
98 * nothing else.
99 */
100typedef struct
101{
102 embed_bool (*open)(const PraetCfg *args); /**< Opens a channel. */
103 embed_bool (*tx_submit)(const PraetTransferCfg *args); /**< Submits a transfer. */
104 void (*close)(const PraetTransferCfg *args); /**< Closes a channel. */
105 void (*poll)(const PraetCfg *args); /**< Drives the port layer's poll hook. */
107EMBED_TABLE_LAYOUT(MemoriamPraetereoNs, open, tx_submit, close, poll);
108
109/**
110 * @brief Opens args->channel and registers args->on_complete against it.
111 *
112 * @param[in] args Channel, peripheral, loopback flag and completion callback [BORROWS].
113 * @return EMBED_TRUE when the port layer accepted the request.
114 * @note The default mmgr_praet_hw_open refuses, and so this returns EMBED_FALSE until a port replaces it.
115 * @warning args->channel must be below PRAET_CHANNELS, and args->on_complete must not be NULL.
116 */
117embed_bool mmgr_praet_open(const PraetCfg *args);
118
119/**
120 * @brief Submits args->bytes of args->buf on args->channel.
121 *
122 * @param[in] args Channel, buffer and byte count [BORROWS].
123 * @return EMBED_TRUE when the port layer accepted the transfer.
124 * @note The default mmgr_praet_hw_tx_submit refuses, and so this returns EMBED_FALSE until a port replaces it.
125 * @warning args->buf must stay valid until the completion callback runs [BORROWS].
126 * @warning args->channel must be below PRAET_CHANNELS.
127 */
129
130/**
131 * @brief Closes args->channel.
132 *
133 * @param[in] args Channel to close [BORROWS].
134 * @note Only args->channel is read. buf and bytes take no part.
135 * @warning args->channel must be below PRAET_CHANNELS.
136 */
138
139/**
140 * @brief Drives the port layer's poll hook.
141 *
142 * @param[in] args Channel to poll [BORROWS].
143 * @note Passes args straight to mmgr_praet_hw_poll, unlike the other three entries, which assert first.
144 * @warning No assertion runs here. args and args->channel reach the port layer exactly as the caller gave them.
145 */
146void mmgr_praet_poll(const PraetCfg *args);
147
148/**
149 * @brief Opens a DMA channel on real hardware.
150 *
151 * @param[in] args Channel, peripheral, loopback flag and completion callback, as mmgr_praet_open
152 * forwards them [BORROWS].
153 * @return EMBED_TRUE when the hardware accepted the request.
154 * @note The default in memoriam_praetereo.c refuses every request. A build links without a port.
155 * @note An application definition of this name replaces that default where EMBED_HAS_ATTRIBUTE(weak)
156 * is non-zero.
157 * @warning Reached through mmgr_praet_open, which asserts the channel and the callback first.
158 */
159embed_bool mmgr_praet_hw_open(const PraetCfg *args);
160
161/**
162 * @brief Submits a transfer on real hardware.
163 *
164 * @param[in] args Channel, buffer and byte count, as mmgr_praet_tx_submit forwards them [BORROWS].
165 * @return EMBED_TRUE when the hardware accepted the transfer.
166 * @note The default in memoriam_praetereo.c refuses every transfer. A build links without a port.
167 * @note An application definition of this name replaces that default where EMBED_HAS_ATTRIBUTE(weak)
168 * is non-zero.
169 * @warning Reached through mmgr_praet_tx_submit, which asserts the channel first.
170 * @warning args->buf must stay valid until this reports completion through the registered callback [BORROWS].
171 */
173
174/**
175 * @brief Closes a DMA channel on real hardware.
176 *
177 * @param[in] args Channel to close, as mmgr_praet_close forwards it [BORROWS].
178 * @note The default in memoriam_praetereo.c does nothing. A build links without a port.
179 * @note An application definition of this name replaces that default where EMBED_HAS_ATTRIBUTE(weak)
180 * is non-zero.
181 * @note Only args->channel is forwarded. buf and bytes take no part.
182 * @warning Reached through mmgr_praet_close, which asserts the channel first.
183 */
185
186/**
187 * @brief Advances whatever polling the port layer needs.
188 *
189 * @param[in] args Channel to poll, exactly as the caller gave it [BORROWS].
190 * @note The default in memoriam_praetereo.c does nothing. A build links without a port.
191 * @note An application definition of this name replaces that default where EMBED_HAS_ATTRIBUTE(weak)
192 * is non-zero.
193 * @warning mmgr_praet_poll calls this directly, with no checking call in between. args and
194 * args->channel arrive exactly as the caller wrote them, unasserted.
195 */
196void mmgr_praet_hw_poll(const PraetCfg *args);
197
198/**
199 * @brief Dispatch table instance named praet.
200 *
201 * @note Each member calls the matching mmgr_praet_ function, one to one. No member is pointed at
202 * another's function, which is where this differs from the memor table.
203 */
204EMBED_TABLE_STORAGE MemoriamPraetereoNs praet EMBED_UNUSED = {
205 .open = mmgr_praet_open,
206 .tx_submit = mmgr_praet_tx_submit,
207 .close = mmgr_praet_close,
208 .poll = mmgr_praet_poll,
209};
210
211EMBED_END_DECLS
212
213// The descriptors, and the schedule they ride on with its knobs and its flag word. Both need the
214// knobs this build set, and neither is reached where MMGR_ENABLE_DMA is off
217
218#endif
219
220#endif
static const MemoriamPraetereoNs praet
Dispatch table instance named praet.
void mmgr_praet_poll(const PraetCfg *args)
Drives the port layer's poll hook.
void mmgr_praet_hw_close(const PraetTransferCfg *args)
Closes a DMA channel on real hardware.
embed_bool mmgr_praet_tx_submit(const PraetTransferCfg *args)
Submits args->bytes of args->buf on args->channel.
embed_bool mmgr_praet_hw_open(const PraetCfg *args)
Opens a DMA channel on real hardware.
void mmgr_praet_hw_poll(const PraetCfg *args)
Advances whatever polling the port layer needs.
embed_bool mmgr_praet_hw_tx_submit(const PraetTransferCfg *args)
Submits a transfer on real hardware.
embed_bool mmgr_praet_open(const PraetCfg *args)
Opens args->channel and registers args->on_complete against it.
void mmgr_praet_close(const PraetTransferCfg *args)
Closes args->channel.
void(*) mmgr_praet_callback(const mmgr_praet_event *event, void *user)
Reports a finished transfer to whatever registered this callback.
The embedded_types headers every module builds on.
A transfer written down: where from, where to, how many bytes, how each address moves,...
The schedule context: one flag word per channel, the two volatiles that coordinate the interrupt,...
Type of the praet dispatch table.
embed_bool(*) tx_submit(const PraetTransferCfg *args)
void(*) poll(const PraetCfg *args)
void(*) close(const PraetTransferCfg *args)
embed_bool(*) open(const PraetCfg *args)
A completion callback and the pointer handed back to it.
const mmgr_praet_callback callback
Arguments for opening a channel, and for polling one.
const embed_bool loopback
const uint8_t channel
const uint8_t peripheral
const PraetCallbackCfg *const on_complete
Arguments for submitting a transfer, and for closing a channel.
const uint8_t channel
const uint8_t *const buf
const uint16_t bytes
What the port layer reports when a transfer finishes.
const uint8_t * data