ICARUS OS (Intelligent Cooperative Architecture for Real-time Unified Systems) 0.1.0
Preemptive Real-Time Operating System for ARM Cortex-M7
Loading...
Searching...
No Matches
sb.c
Go to the documentation of this file.
1
28#include "icarus/icarus.h"
29#include "icarus/svc.h"
30#include <string.h>
31
32/* ============================================================================
33 * ROUTE TABLE (DTCM)
34 * ========================================================================= */
35
39typedef struct {
41 uint8_t pipes[SB_MAX_SUBS_PER_MSG];
42 uint8_t count;
43 bool used;
45
48
51
52/* ============================================================================
53 * INTERNAL HELPERS (ITCM, privileged)
54 * ========================================================================= */
55
62 for (uint8_t i = 0u; i < route_used; i++) {
63 if (routes[i].used && (routes[i].msg_id == msg_id)) {
64 return &routes[i];
65 }
66 }
67 return NULL;
68}
69
76 if (route_used >= (uint8_t)SB_MAX_ROUTES) {
77 return NULL;
78 }
80 (void)memset(r, 0, sizeof(*r));
81 r->used = true;
82 return r;
83}
84
85/* ============================================================================
86 * PRIVILEGED IMPLEMENTATIONS
87 * ========================================================================= */
88
93ITCM_FUNC void __sb_init(void) {
94 (void)memset(routes, 0, sizeof(routes));
95 route_used = 0;
96}
97
110ITCM_FUNC bool __sb_subscribe(sb_msg_id_t msg_id, uint8_t pipe_idx) {
111 sb_route_t *r = find_route(msg_id);
112 if (r == NULL) {
113 r = alloc_route();
114 if (r == NULL) {
115 return false;
116 }
117 r->msg_id = msg_id;
118 }
119
120 /* Subscriber limit */
121 if (r->count >= (uint8_t)SB_MAX_SUBS_PER_MSG) {
122 return false;
123 }
124
125 /* Reject duplicate */
126 for (uint8_t i = 0u; i < r->count; i++) {
127 if (r->pipes[i] == pipe_idx) {
128 return false;
129 }
130 }
131
132 r->pipes[r->count++] = pipe_idx;
133 return true;
134}
135
144ITCM_FUNC bool __sb_unsubscribe(sb_msg_id_t msg_id, uint8_t pipe_idx) {
145 sb_route_t *r = find_route(msg_id);
146 if (r == NULL) {
147 return false;
148 }
149
150 for (uint8_t i = 0u; i < r->count; i++) {
151 if (r->pipes[i] == pipe_idx) {
152 /* Compact: move last into this slot */
153 r->pipes[i] = r->pipes[(uint8_t)(r->count - 1u)];
154 r->count--;
155 return true;
156 }
157 }
158 return false;
159}
160
173ITCM_FUNC uint8_t __sb_publish(sb_msg_id_t msg_id, const uint8_t *data,
174 uint8_t len) {
175 if ((data == NULL) || (len == 0u)) {
176 return 0u;
177 }
178
179 sb_route_t *r = find_route(msg_id);
180 if (r == NULL) {
181 return 0u;
182 }
183
184 uint8_t delivered = 0u;
185 for (uint8_t i = 0u; i < r->count; i++) {
186 uint8_t pidx = r->pipes[i];
187 if (__pipe_can_enqueue(pidx, len)) {
188 __pipe_write_bytes(pidx, (uint8_t *)(uintptr_t)data, len);
189 delivered++;
190 }
191 }
192 return delivered;
193}
194
201 sb_route_t *r = find_route(msg_id);
202 return (r != NULL) ? r->count : 0u;
203}
204
210 return route_used;
211}
212
213/* ============================================================================
214 * PUBLIC API (SVC call gates — privileged access to DTCM_PRIV data)
215 * ========================================================================= */
216
221void sb_init(void) {
222#ifndef HOST_TEST
223 __asm__ volatile ("svc %0\n" : : "I" (SVC_SB_INIT));
224#else
225 __sb_init();
226#endif
227}
228
236bool sb_subscribe(sb_msg_id_t msg_id, uint8_t pipe_idx) {
237#ifndef HOST_TEST
238 uint32_t result;
239 __asm__ volatile (
240 "mov r0, %1\n"
241 "mov r1, %2\n"
242 "svc %3\n"
243 "mov %0, r0\n"
244 : "=r" (result)
245 : "r" ((uint32_t)msg_id), "r" ((uint32_t)pipe_idx),
246 "I" (SVC_SB_SUBSCRIBE)
247 : "r0", "r1"
248 );
249 return (bool)result;
250#else
251 return __sb_subscribe(msg_id, pipe_idx);
252#endif
253}
254
262bool sb_unsubscribe(sb_msg_id_t msg_id, uint8_t pipe_idx) {
263#ifndef HOST_TEST
264 uint32_t result;
265 __asm__ volatile (
266 "mov r0, %1\n"
267 "mov r1, %2\n"
268 "svc %3\n"
269 "mov %0, r0\n"
270 : "=r" (result)
271 : "r" ((uint32_t)msg_id), "r" ((uint32_t)pipe_idx),
273 : "r0", "r1"
274 );
275 return (bool)result;
276#else
277 return __sb_unsubscribe(msg_id, pipe_idx);
278#endif
279}
280
288uint8_t sb_publish(sb_msg_id_t msg_id, const uint8_t *data, uint8_t len) {
289#ifndef HOST_TEST
290 uint32_t result;
291 __asm__ volatile (
292 "mov r0, %1\n"
293 "mov r1, %2\n"
294 "mov r2, %3\n"
295 "svc %4\n"
296 "mov %0, r0\n"
297 : "=r" (result)
298 : "r" ((uint32_t)msg_id), "r" ((uint32_t)(uintptr_t)data),
299 "r" ((uint32_t)len), "I" (SVC_SB_PUBLISH)
300 : "r0", "r1", "r2"
301 );
302 return (uint8_t)result;
303#else
304 return __sb_publish(msg_id, data, len);
305#endif
306}
307
314#ifndef HOST_TEST
315 uint32_t result;
316 __asm__ volatile (
317 "mov r0, %1\n"
318 "svc %2\n"
319 "mov %0, r0\n"
320 : "=r" (result)
321 : "r" ((uint32_t)msg_id), "I" (SVC_SB_SUBSCRIBER_COUNT)
322 : "r0"
323 );
324 return (uint8_t)result;
325#else
326 return __sb_subscriber_count(msg_id);
327#endif
328}
329
334uint8_t sb_route_count(void) {
335#ifndef HOST_TEST
336 uint32_t result;
337 __asm__ volatile (
338 "svc %1\n"
339 "mov %0, r0\n"
340 : "=r" (result)
341 : "I" (SVC_SB_ROUTE_COUNT)
342 : "r0"
343 );
344 return (uint8_t)result;
345#else
346 return __sb_route_count();
347#endif
348}
#define SB_MAX_ROUTES
Maximum number of distinct message IDs that can have subscriptions.
Definition sb.h:62
#define SB_MAX_SUBS_PER_MSG
Maximum subscribers per message ID.
Definition sb.h:70
#define DTCM_DATA_PRIV
Definition config.h:156
#define ITCM_FUNC
Definition config.h:155
ICARUS OS - Main API Header.
void __pipe_write_bytes(uint8_t pipe_idx, uint8_t *message, uint8_t message_bytes)
Privileged write gate: write bytes to pipe buffer.
Definition pipe.c:176
bool __pipe_can_enqueue(uint8_t pipe_idx, uint8_t message_bytes)
Privileged call gate: can pipe accept message_bytes bytes?
Definition pipe.c:149
static uint8_t route_used
Number of route slots in use.
Definition sb.c:50
static sb_route_t routes[32]
Route table — privileged DTCM, zero wait-state.
Definition sb.c:47
bool sb_subscribe(sb_msg_id_t msg_id, uint8_t pipe_idx)
Subscribe a pipe to a message ID via SVC gate.
Definition sb.c:236
void sb_init(void)
Initialize the software bus via SVC gate.
Definition sb.c:221
bool sb_unsubscribe(sb_msg_id_t msg_id, uint8_t pipe_idx)
Remove a subscription via SVC gate.
Definition sb.c:262
uint8_t __sb_subscriber_count(sb_msg_id_t msg_id)
Privileged implementation of sb_subscriber_count().
Definition sb.c:200
static sb_route_t * alloc_route(void)
Allocate a fresh route slot.
Definition sb.c:75
uint8_t sb_route_count(void)
Return the total route count via SVC gate.
Definition sb.c:334
bool __sb_subscribe(sb_msg_id_t msg_id, uint8_t pipe_idx)
Privileged implementation of sb_subscribe().
Definition sb.c:110
void __sb_init(void)
Privileged implementation of sb_init().
Definition sb.c:93
uint8_t __sb_route_count(void)
Privileged implementation of sb_route_count().
Definition sb.c:209
uint8_t sb_publish(sb_msg_id_t msg_id, const uint8_t *data, uint8_t len)
Publish a message to all subscribers via SVC gate.
Definition sb.c:288
uint8_t __sb_publish(sb_msg_id_t msg_id, const uint8_t *data, uint8_t len)
Privileged implementation of sb_publish().
Definition sb.c:173
bool __sb_unsubscribe(sb_msg_id_t msg_id, uint8_t pipe_idx)
Privileged implementation of sb_unsubscribe().
Definition sb.c:144
static sb_route_t * find_route(sb_msg_id_t msg_id)
Find the route entry for msg_id.
Definition sb.c:61
uint8_t sb_subscriber_count(sb_msg_id_t msg_id)
Return the subscriber count for a message ID via SVC gate.
Definition sb.c:313
uint16_t sb_msg_id_t
Software Bus message identifier.
Definition sb.h:86
Single route entry: one msg_id → up to SB_MAX_SUBS_PER_MSG pipes.
Definition sb.c:39
bool used
Slot is occupied
Definition sb.c:43
uint8_t pipes[4]
Subscriber pipe indices
Definition sb.c:41
sb_msg_id_t msg_id
Subscribed message ID
Definition sb.c:40
uint8_t count
Active subscriber count
Definition sb.c:42
ICARUS Supervisor Call (SVC) Definitions.
#define SVC_SB_PUBLISH
Definition svc.h:139
#define SVC_SB_ROUTE_COUNT
Definition svc.h:141
#define SVC_SB_UNSUBSCRIBE
Definition svc.h:138
#define SVC_SB_SUBSCRIBE
Definition svc.h:137
#define SVC_SB_INIT
Definition svc.h:136
#define SVC_SB_SUBSCRIBER_COUNT
Definition svc.h:140