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
svc.c
Go to the documentation of this file.
1
21#include "icarus/svc.h"
22#include "icarus/kernel.h"
23#include "icarus/task.h"
24#include "icarus/scheduler.h"
25#include "icarus/pipe.h"
26#include "icarus/semaphore.h"
27#include "icarus/cdc_rx.h"
28#include "icarus/event.h"
29#include "icarus/tables.h"
30#include "icarus/cs.h"
31#include "icarus/sb.h"
32#include "icarus/fs.h"
33#include "bsp/mpu.h"
34#include <stddef.h>
35#include <string.h>
36
37/* ============================================================================
38 * SVC HANDLER (target only)
39 * ========================================================================= */
40
41#ifndef HOST_TEST
42
50void SVC_Handler_C(uint32_t *stack_frame) {
51 uint8_t svc_number = ((uint8_t *)(uintptr_t)stack_frame[6])[-2];
52 uint32_t arg0 = stack_frame[0];
53 uint32_t arg1 = stack_frame[1];
54
55 switch (svc_number) {
56
57 /* Critical section */
60 break;
63 break;
64
65 /* Scheduler */
66 case SVC_OS_YIELD:
67 __os_yield();
68 break;
70 stack_frame[0] = __task_active_sleep(arg0);
71 break;
73 stack_frame[0] = __os_get_tick_count();
74 break;
76 const char *name = __os_get_current_task_name();
77 stack_frame[0] = (uint32_t)(uintptr_t)name;
78 break;
79 }
81 stack_frame[0] = __os_get_running_task_count();
82 break;
84 stack_frame[0] = __os_get_task_ticks_remaining();
85 break;
86
87 /* Task lifecycle */
89 __os_register_task((void (*)(void))(uintptr_t)arg0,
90 (const char *)(uintptr_t)arg1);
91 break;
94 break;
96 __os_kill_process((uint8_t)arg0);
97 break;
100 break;
101
102 /* Kernel data */
104 uint32_t *ptr = __kernel_get_stack((uint8_t)arg0);
105 stack_frame[0] = (uint32_t)(uintptr_t)ptr;
106 break;
107 }
108 case SVC_KERNEL_GET_DATA: {
109 uint32_t *ptr = __kernel_get_data((uint8_t)arg0);
110 stack_frame[0] = (uint32_t)(uintptr_t)ptr;
111 break;
112 }
114 void *ptr = __kernel_protected_data((uint16_t)arg0);
115 stack_frame[0] = (uint32_t)(uintptr_t)ptr;
116 break;
117 }
118
119 /* Semaphore (non-spinning) */
120 case SVC_SEMAPHORE_INIT: {
121 bool ret = __semaphore_init((uint8_t)arg0, arg1);
122 stack_frame[0] = (uint32_t)ret;
123 break;
124 }
126 stack_frame[0] = __semaphore_get_count((uint8_t)arg0);
127 break;
129 stack_frame[0] = __semaphore_get_max_count((uint8_t)arg0);
130 break;
131
132 /* Pipe (non-spinning) */
133 case SVC_PIPE_INIT: {
134 bool ret = __pipe_init((uint8_t)arg0, (uint8_t)arg1);
135 stack_frame[0] = (uint32_t)ret;
136 break;
137 }
139 stack_frame[0] = (uint32_t)__pipe_get_count((uint8_t)arg0);
140 break;
142 stack_frame[0] = (uint32_t)__pipe_get_max_count((uint8_t)arg0);
143 break;
144
145 /* Spinning functions — not dispatched via SVC, run in thread mode */
148 case SVC_PIPE_ENQUEUE:
149 case SVC_PIPE_DEQUEUE:
152 break;
153
154 /* Call gates for spinning functions — read kernel state atomically */
155 case SVC_SEM_CAN_FEED: {
156 bool r = __sem_can_feed((uint8_t)arg0);
157 stack_frame[0] = r ? 1u : 0u;
158 break;
159 }
160 case SVC_SEM_CAN_CONSUME: {
161 bool r = __sem_can_consume((uint8_t)arg0);
162 stack_frame[0] = r ? 1u : 0u;
163 break;
164 }
166 bool r = __pipe_can_enqueue((uint8_t)arg0, (uint8_t)arg1);
167 stack_frame[0] = r ? 1u : 0u;
168 break;
169 }
171 bool r = __pipe_can_dequeue((uint8_t)arg0, (uint8_t)arg1);
172 stack_frame[0] = r ? 1u : 0u;
173 break;
174 }
175
176 /* Write gates for spinning functions — modify kernel state atomically */
178 __sem_increment((uint8_t)arg0);
179 break;
181 __sem_decrement((uint8_t)arg0);
182 break;
184 __pipe_write_bytes((uint8_t)arg0, (uint8_t *)(uintptr_t)arg1,
185 (uint8_t)stack_frame[2]);
186 break;
188 __pipe_read_bytes((uint8_t)arg0, (uint8_t *)(uintptr_t)arg1,
189 (uint8_t)stack_frame[2]);
190 break;
191
192 /* Task metadata read gates — for display/diagnostics from unprivileged mode */
193 case SVC_GET_TASK_NAME: {
194 const char *name = __os_get_task_name((uint8_t)arg0);
195 stack_frame[0] = (uint32_t)(uintptr_t)name;
196 break;
197 }
199 stack_frame[0] = (uint32_t)__os_get_num_created_tasks();
200 break;
202 stack_frame[0] = (uint32_t)__os_is_running();
203 break;
204
205 /* CDC RX ring buffer */
206 case SVC_CDC_RX_INIT:
208 break;
210 bool ok = __cdc_rx_read_byte((uint8_t *)(uintptr_t)arg0);
211 stack_frame[0] = (uint32_t)ok;
212 break;
213 }
215 stack_frame[0] = __cdc_rx_available();
216 break;
217
218 /* Event ring + squelch */
219 case SVC_EVENT_INIT:
220 __event_init();
221 break;
222 case SVC_OS_EVENT: {
223 /* arg0 packs (event_id << 16) | (severity << 8) | module_id
224 * arg1 = payload pointer
225 * stack_frame[2] = payload_len
226 * Packing keeps the SVC wrapper inside the AAPCS R0-R3 budget. */
227 uint8_t module_id = (uint8_t)(arg0 & 0xFF);
228 uint8_t severity = (uint8_t)((arg0 >> 8) & 0xFF);
229 uint16_t event_id = (uint16_t)((arg0 >> 16) & 0xFFFF);
230 const void *payload = (const void *)(uintptr_t)arg1;
231 uint8_t payload_len = (uint8_t)stack_frame[2];
232 __os_event(module_id, (event_severity_t)severity, event_id,
233 payload, payload_len);
234 break;
235 }
237 __event_set_squelch((uint8_t)arg0, (event_severity_t)arg1);
238 break;
240 event_severity_t sq = __event_get_squelch((uint8_t)arg0);
241 stack_frame[0] = (uint32_t)sq;
242 break;
243 }
244 case SVC_EVENT_DRAIN: {
245 bool ok = __event_drain(
246 (event_entry_t *)(uintptr_t)arg0,
247 (uint8_t)arg1,
248 (uint8_t *)(uintptr_t)stack_frame[2]);
249 stack_frame[0] = (uint32_t)ok;
250 break;
251 }
253 stack_frame[0] = __event_get_count();
254 break;
255
256 /* Ground-loadable table engine */
257 case SVC_TBL_INIT:
258 __tbl_init();
259 break;
260 case SVC_TBL_REGISTER: {
261 bool ok = __tbl_register(
262 (const tbl_descriptor_t *)(uintptr_t)arg0);
263 stack_frame[0] = (uint32_t)ok;
264 break;
265 }
266 case SVC_TBL_LOAD: {
267 bool ok = __tbl_load(
268 (tbl_id_t)arg0,
269 (const uint8_t *)(uintptr_t)arg1,
270 (uint16_t)stack_frame[2],
271 (uint16_t)stack_frame[3]);
272 stack_frame[0] = (uint32_t)ok;
273 break;
274 }
276 bool ok = __tbl_activate_prepare(
277 (tbl_id_t)arg0,
278 (uint8_t *)(uintptr_t)arg1,
279 (uint16_t *)(uintptr_t)stack_frame[2],
280 (tbl_activate_fn *)(uintptr_t)stack_frame[3]);
281 stack_frame[0] = (uint32_t)ok;
282 break;
283 }
285 bool ok = __tbl_activate_commit(
286 (tbl_id_t)arg0,
287 (const uint8_t *)(uintptr_t)arg1,
288 (uint16_t)stack_frame[2]);
289 stack_frame[0] = (uint32_t)ok;
290 break;
291 }
292 case SVC_TBL_DUMP: {
293 int16_t n = __tbl_dump(
294 (tbl_id_t)arg0,
295 (uint8_t *)(uintptr_t)arg1,
296 (uint16_t)stack_frame[2]);
297 stack_frame[0] = (uint32_t)(int32_t)n;
298 break;
299 }
302 stack_frame[0] = (uint32_t)(uintptr_t)d;
303 break;
304 }
305 case SVC_TBL_COUNT:
306 stack_frame[0] = (uint32_t)__tbl_count();
307 break;
308
309 /* ---- Task lifecycle extensions ---- */
311 __os_restart_task((uint8_t)arg0);
312 break;
313
314 /* ---- Timed semaphore ---- */
316 bool ok = __semaphore_consume_timeout((uint8_t)arg0, arg1);
317 stack_frame[0] = ok ? 1u : 0u;
318 break;
319 }
320
321 /* ---- Task diagnostics ---- */
322 case SVC_GET_TASK_STATE: {
323 icarus_task_state_t st = __os_get_task_state((uint8_t)arg0);
324 stack_frame[0] = (uint32_t)st;
325 break;
326 }
328 stack_frame[0] = __os_get_task_dispatch_count((uint8_t)arg0);
329 break;
331 stack_frame[0] = __os_get_stack_watermark((uint8_t)arg0);
332 break;
334 __os_update_stack_watermark((uint8_t)arg0);
335 break;
336
337 /* ---- Checksum integrity monitor ---- */
338 case SVC_CS_INIT:
339 __cs_init();
340 break;
342 __cs_set_callback((cs_mismatch_fn)(uintptr_t)arg0);
343 break;
344 case SVC_CS_ADD_REGION: {
345 bool ok = __cs_add_region((uint8_t)arg0,
346 (const uint8_t *)(uintptr_t)arg1,
347 stack_frame[2]);
348 stack_frame[0] = (uint32_t)ok;
349 break;
350 }
351 case SVC_CS_ENABLE: {
352 bool ok = __cs_enable((uint8_t)arg0, (bool)arg1);
353 stack_frame[0] = (uint32_t)ok;
354 break;
355 }
356 case SVC_CS_REBASELINE: {
357 bool ok = __cs_rebaseline((uint8_t)arg0);
358 stack_frame[0] = (uint32_t)ok;
359 break;
360 }
361 case SVC_CS_CHECK_ALL:
362 stack_frame[0] = (uint32_t)__cs_check_all();
363 break;
364 case SVC_CS_GET_REGION: {
365 bool ok = __cs_get_region((uint8_t)arg0,
366 (cs_region_t *)(uintptr_t)arg1);
367 stack_frame[0] = (uint32_t)ok;
368 break;
369 }
371 stack_frame[0] = (uint32_t)__cs_region_count();
372 break;
373
374 /* ---- BKPRAM write gate ---- */
375 case SVC_BKPRAM_WRITE: {
376 const void *src = (const void *)(uintptr_t)arg0;
377 uint32_t offset = arg1;
378 uint32_t len = stack_frame[2];
379 bool ok = false;
380 if (len > 0 && (offset + len) <= BSP_RAM_D3_SIZE &&
381 (offset + len) >= offset) {
382 memcpy((void *)(BSP_RAM_D3_BASE + offset), src, len);
383 ok = true;
384 }
385 stack_frame[0] = (uint32_t)ok;
386 break;
387 }
388
389 /* ---- Software Bus ---- */
390 case SVC_SB_INIT:
391 __sb_init();
392 break;
393 case SVC_SB_SUBSCRIBE: {
394 bool ok = __sb_subscribe((sb_msg_id_t)arg0, (uint8_t)arg1);
395 stack_frame[0] = (uint32_t)ok;
396 break;
397 }
398 case SVC_SB_UNSUBSCRIBE: {
399 bool ok = __sb_unsubscribe((sb_msg_id_t)arg0, (uint8_t)arg1);
400 stack_frame[0] = (uint32_t)ok;
401 break;
402 }
403 case SVC_SB_PUBLISH: {
404 uint8_t n = __sb_publish((sb_msg_id_t)arg0,
405 (const uint8_t *)(uintptr_t)arg1,
406 (uint8_t)stack_frame[2]);
407 stack_frame[0] = (uint32_t)n;
408 break;
409 }
411 stack_frame[0] = (uint32_t)__sb_subscriber_count(
412 (sb_msg_id_t)arg0);
413 break;
415 stack_frame[0] = (uint32_t)__sb_route_count();
416 break;
417
418 /* ---- Filesystem ---- */
419 case SVC_FS_INIT:
420 __fs_init();
421 break;
422 case SVC_FS_CREATE: {
423 bool ok = __fs_create((const char *)(uintptr_t)arg0,
424 (fs_file_t *)(uintptr_t)arg1);
425 stack_frame[0] = (uint32_t)ok;
426 break;
427 }
428 case SVC_FS_OPEN: {
429 bool ok = __fs_open((const char *)(uintptr_t)arg0,
430 (fs_file_t *)(uintptr_t)arg1);
431 stack_frame[0] = (uint32_t)ok;
432 break;
433 }
434 case SVC_FS_WRITE: {
435 bool ok = __fs_write((fs_file_t *)(uintptr_t)arg0,
436 (const uint8_t *)(uintptr_t)arg1,
437 (uint16_t)stack_frame[2]);
438 stack_frame[0] = (uint32_t)ok;
439 break;
440 }
441 case SVC_FS_READ: {
442 uint16_t n = __fs_read((fs_file_t *)(uintptr_t)arg0,
443 (uint8_t *)(uintptr_t)arg1,
444 (uint16_t)stack_frame[2],
445 (uint16_t)stack_frame[3]);
446 stack_frame[0] = (uint32_t)n;
447 break;
448 }
449 case SVC_FS_DELETE: {
450 bool ok = __fs_delete((const char *)(uintptr_t)arg0);
451 stack_frame[0] = (uint32_t)ok;
452 break;
453 }
454 case SVC_FS_LIST: {
455 uint8_t n = __fs_list((fs_file_info_t *)(uintptr_t)arg0,
456 (uint8_t)arg1);
457 stack_frame[0] = (uint32_t)n;
458 break;
459 }
460 case SVC_FS_STATS:
461 __fs_stats((fs_stats_t *)(uintptr_t)arg0);
462 break;
463
464 default:
465 break;
466 }
467}
468
469#endif /* HOST_TEST */
470
471/* ============================================================================
472 * CRITICAL SECTION WRAPPERS
473 * ========================================================================= */
474
478void enter_critical(void) {
479#ifndef HOST_TEST
480 __asm__ volatile ("svc %0\n" : : "I" (SVC_ENTER_CRITICAL));
481#else
483#endif
484}
485
489void exit_critical(void) {
490#ifndef HOST_TEST
491 __asm__ volatile ("svc %0\n" : : "I" (SVC_EXIT_CRITICAL));
492#else
494#endif
495}
496
497/* ============================================================================
498 * KERNEL INIT / START WRAPPERS
499 * ========================================================================= */
500
501void os_init(void) { __os_init(); }
502void os_start(void) { __os_start(); }
503
504/* ============================================================================
505 * SCHEDULER WRAPPERS
506 * ========================================================================= */
507
511void os_yield(void) {
512#ifndef HOST_TEST
513 __asm__ volatile ("svc %0\n" : : "I" (SVC_OS_YIELD));
514#else
515 __os_yield();
516#endif
517}
518
522uint32_t task_active_sleep(uint32_t ticks) {
523#ifndef HOST_TEST
524 uint32_t result;
525 __asm__ volatile (
526 "mov r0, %1\n"
527 "svc %2\n"
528 "mov %0, r0\n"
529 : "=r" (result)
530 : "r" (ticks), "I" (SVC_TASK_ACTIVE_SLEEP)
531 : "r0"
532 );
533 return result;
534#else
535 return __task_active_sleep(ticks);
536#endif
537}
538
542uint32_t task_blocking_sleep(uint32_t ticks) {
543 return __task_blocking_sleep(ticks);
544}
545
549uint32_t task_busy_wait(uint32_t ticks) {
550 return __task_busy_wait(ticks);
551}
552
556uint32_t os_get_tick_count(void) {
557#ifndef HOST_TEST
558 uint32_t result;
559 __asm__ volatile (
560 "svc %1\n"
561 "mov %0, r0\n"
562 : "=r" (result)
564 : "r0"
565 );
566 return result;
567#else
568 return __os_get_tick_count();
569#endif
570}
571
575const char *os_get_current_task_name(void) {
576#ifndef HOST_TEST
577 const char *result;
578 __asm__ volatile (
579 "svc %1\n"
580 "mov %0, r0\n"
581 : "=r" (result)
583 : "r0"
584 );
585 return result;
586#else
588#endif
589}
590
595#ifndef HOST_TEST
596 uint8_t result;
597 __asm__ volatile (
598 "svc %1\n"
599 "mov %0, r0\n"
600 : "=r" (result)
602 : "r0"
603 );
604 return result;
605#else
607#endif
608}
609
614#ifndef HOST_TEST
615 uint32_t result;
616 __asm__ volatile (
617 "svc %1\n"
618 "mov %0, r0\n"
619 : "=r" (result)
621 : "r0"
622 );
623 return result;
624#else
626#endif
627}
628
629/* ============================================================================
630 * TASK LIFECYCLE WRAPPERS
631 * ========================================================================= */
632
636void os_exit_task(void) {
637#ifndef HOST_TEST
638 __asm__ volatile ("svc %0\n" : : "I" (SVC_OS_EXIT_TASK));
639#else
641#endif
642}
643
647void os_task_suicide(void) {
648#ifndef HOST_TEST
649 __asm__ volatile ("svc %0\n" : : "I" (SVC_OS_TASK_SUICIDE));
650#else
652#endif
653}
654
658void os_register_task(void (*function)(void), const char *name) {
659#ifndef HOST_TEST
660 __asm__ volatile (
661 "mov r0, %0\n"
662 "mov r1, %1\n"
663 "svc %2\n"
664 :
665 : "r" (function), "r" (name), "I" (SVC_OS_REGISTER_TASK)
666 : "r0", "r1"
667 );
668#else
669 __os_register_task(function, name);
670#endif
671}
672
676void os_kill_process(uint8_t task_index) {
677#ifndef HOST_TEST
678 __asm__ volatile (
679 "mov r0, %0\n"
680 "svc %1\n"
681 :
682 : "r" ((uint32_t)task_index), "I" (SVC_OS_KILL_PROCESS)
683 : "r0"
684 );
685#else
686 __os_kill_process(task_index);
687#endif
688}
689
693void os_restart_task(uint8_t task_index) {
694#ifndef HOST_TEST
695 __asm__ volatile (
696 "mov r0, %0\n"
697 "svc %1\n"
698 :
699 : "r" ((uint32_t)task_index), "I" (SVC_OS_RESTART_TASK)
700 : "r0"
701 );
702#else
703 __os_restart_task(task_index);
704#endif
705}
706
707/* ============================================================================
708 * KERNEL DATA WRAPPERS
709 * ========================================================================= */
710
714uint32_t *kernel_get_stack(uint8_t task_idx) {
715#ifndef HOST_TEST
716 uint32_t *result;
717 __asm__ volatile (
718 "mov r0, %1\n"
719 "svc %2\n"
720 "mov %0, r0\n"
721 : "=r" (result)
722 : "r" ((uint32_t)task_idx), "I" (SVC_KERNEL_GET_STACK)
723 : "r0"
724 );
725 return result;
726#else
727 return __kernel_get_stack(task_idx);
728#endif
729}
730
734uint32_t *kernel_get_data(uint8_t task_idx) {
735#ifndef HOST_TEST
736 uint32_t *result;
737 __asm__ volatile (
738 "mov r0, %1\n"
739 "svc %2\n"
740 "mov %0, r0\n"
741 : "=r" (result)
742 : "r" ((uint32_t)task_idx), "I" (SVC_KERNEL_GET_DATA)
743 : "r0"
744 );
745 return result;
746#else
747 return __kernel_get_data(task_idx);
748#endif
749}
750
754void *kernel_protected_data(uint16_t num_words) {
755#ifndef HOST_TEST
756 void *result;
757 __asm__ volatile (
758 "mov r0, %1\n"
759 "svc %2\n"
760 "mov %0, r0\n"
761 : "=r" (result)
762 : "r" ((uint32_t)num_words), "I" (SVC_KERNEL_PROTECTED_DATA)
763 : "r0"
764 );
765 return result;
766#else
767 return __kernel_protected_data(num_words);
768#endif
769}
770
771/* ============================================================================
772 * SEMAPHORE WRAPPERS
773 * ========================================================================= */
774
778bool semaphore_init(uint8_t semaphore_idx, uint32_t semaphore_count) {
779#ifndef HOST_TEST
780 uint32_t result;
781 __asm__ volatile (
782 "mov r0, %1\n"
783 "mov r1, %2\n"
784 "svc %3\n"
785 "mov %0, r0\n"
786 : "=r" (result)
787 : "r" ((uint32_t)semaphore_idx), "r" (semaphore_count),
789 : "r0", "r1"
790 );
791 return (bool)result;
792#else
793 return __semaphore_init(semaphore_idx, semaphore_count);
794#endif
795}
796
800bool semaphore_feed(uint8_t semaphore_idx) {
801 return __semaphore_feed(semaphore_idx);
802}
803
807bool semaphore_consume(uint8_t semaphore_idx) {
808 return __semaphore_consume(semaphore_idx);
809}
810
814bool semaphore_consume_timeout(uint8_t semaphore_idx, uint32_t max_ticks) {
815 return __semaphore_consume_timeout(semaphore_idx, max_ticks);
816}
817
821uint32_t semaphore_get_count(uint8_t semaphore_idx) {
822#ifndef HOST_TEST
823 uint32_t result;
824 __asm__ volatile (
825 "mov r0, %1\n"
826 "svc %2\n"
827 "mov %0, r0\n"
828 : "=r" (result)
829 : "r" ((uint32_t)semaphore_idx), "I" (SVC_SEMAPHORE_GET_COUNT)
830 : "r0"
831 );
832 return result;
833#else
834 return __semaphore_get_count(semaphore_idx);
835#endif
836}
837
841uint32_t semaphore_get_max_count(uint8_t semaphore_idx) {
842#ifndef HOST_TEST
843 uint32_t result;
844 __asm__ volatile (
845 "mov r0, %1\n"
846 "svc %2\n"
847 "mov %0, r0\n"
848 : "=r" (result)
849 : "r" ((uint32_t)semaphore_idx), "I" (SVC_SEMAPHORE_GET_MAX_COUNT)
850 : "r0"
851 );
852 return result;
853#else
854 return __semaphore_get_max_count(semaphore_idx);
855#endif
856}
857
858/* ============================================================================
859 * PIPE WRAPPERS
860 * ========================================================================= */
861
865bool pipe_init(uint8_t pipe_idx, uint16_t pipe_capacity_bytes) {
866#ifndef HOST_TEST
867 uint32_t result;
868 __asm__ volatile (
869 "mov r0, %1\n"
870 "mov r1, %2\n"
871 "svc %3\n"
872 "mov %0, r0\n"
873 : "=r" (result)
874 : "r" ((uint32_t)pipe_idx), "r" ((uint32_t)pipe_capacity_bytes),
875 "I" (SVC_PIPE_INIT)
876 : "r0", "r1"
877 );
878 return (bool)result;
879#else
880 return __pipe_init(pipe_idx, pipe_capacity_bytes);
881#endif
882}
883
887bool pipe_enqueue(uint8_t pipe_idx, uint8_t *message, uint8_t message_bytes) {
888 return __pipe_enqueue(pipe_idx, message, message_bytes);
889}
890
894bool pipe_dequeue(uint8_t pipe_idx, uint8_t *message, uint8_t message_bytes) {
895 return __pipe_dequeue(pipe_idx, message, message_bytes);
896}
897
901uint16_t pipe_get_count(uint8_t pipe_idx) {
902#ifndef HOST_TEST
903 uint16_t result;
904 __asm__ volatile (
905 "mov r0, %1\n"
906 "svc %2\n"
907 "mov %0, r0\n"
908 : "=r" (result)
909 : "r" ((uint32_t)pipe_idx), "I" (SVC_PIPE_GET_COUNT)
910 : "r0"
911 );
912 return result;
913#else
914 return __pipe_get_count(pipe_idx);
915#endif
916}
917
921uint16_t pipe_get_max_count(uint8_t pipe_idx) {
922#ifndef HOST_TEST
923 uint16_t result;
924 __asm__ volatile (
925 "mov r0, %1\n"
926 "svc %2\n"
927 "mov %0, r0\n"
928 : "=r" (result)
929 : "r" ((uint32_t)pipe_idx), "I" (SVC_PIPE_GET_MAX_COUNT)
930 : "r0"
931 );
932 return result;
933#else
934 return __pipe_get_max_count(pipe_idx);
935#endif
936}
937
938/* ============================================================================
939 * CALL GATE WRAPPERS (for spinning functions — read kernel state via SVC)
940 * ========================================================================= */
941
946bool sem_can_feed(uint8_t semaphore_idx) {
947#ifndef HOST_TEST
948 uint32_t result;
949 __asm__ volatile (
950 "mov r0, %1\n"
951 "svc %2\n"
952 "mov %0, r0\n"
953 : "=r" (result)
954 : "r" ((uint32_t)semaphore_idx), "I" (SVC_SEM_CAN_FEED)
955 : "r0"
956 );
957 return (bool)result;
958#else
959 return __sem_can_feed(semaphore_idx);
960#endif
961}
962
967bool sem_can_consume(uint8_t semaphore_idx) {
968#ifndef HOST_TEST
969 uint32_t result;
970 __asm__ volatile (
971 "mov r0, %1\n"
972 "svc %2\n"
973 "mov %0, r0\n"
974 : "=r" (result)
975 : "r" ((uint32_t)semaphore_idx), "I" (SVC_SEM_CAN_CONSUME)
976 : "r0"
977 );
978 return (bool)result;
979#else
980 return __sem_can_consume(semaphore_idx);
981#endif
982}
983
988bool pipe_can_enqueue(uint8_t pipe_idx, uint8_t message_bytes) {
989#ifndef HOST_TEST
990 uint32_t result;
991 __asm__ volatile (
992 "mov r0, %1\n"
993 "mov r1, %2\n"
994 "svc %3\n"
995 "mov %0, r0\n"
996 : "=r" (result)
997 : "r" ((uint32_t)pipe_idx), "r" ((uint32_t)message_bytes),
999 : "r0", "r1"
1000 );
1001 return (bool)result;
1002#else
1003 return __pipe_can_enqueue(pipe_idx, message_bytes);
1004#endif
1005}
1006
1011bool pipe_can_dequeue(uint8_t pipe_idx, uint8_t message_bytes) {
1012#ifndef HOST_TEST
1013 uint32_t result;
1014 __asm__ volatile (
1015 "mov r0, %1\n"
1016 "mov r1, %2\n"
1017 "svc %3\n"
1018 "mov %0, r0\n"
1019 : "=r" (result)
1020 : "r" ((uint32_t)pipe_idx), "r" ((uint32_t)message_bytes),
1022 : "r0", "r1"
1023 );
1024 return (bool)result;
1025#else
1026 return __pipe_can_dequeue(pipe_idx, message_bytes);
1027#endif
1028}
1029
1030/* ============================================================================
1031 * WRITE GATE WRAPPERS (for spinning functions — modify kernel state via SVC)
1032 * ========================================================================= */
1033
1038void sem_increment(uint8_t semaphore_idx) {
1039#ifndef HOST_TEST
1040 __asm__ volatile (
1041 "mov r0, %0\n"
1042 "svc %1\n"
1043 :
1044 : "r" ((uint32_t)semaphore_idx), "I" (SVC_SEM_INCREMENT)
1045 : "r0"
1046 );
1047#else
1048 __sem_increment(semaphore_idx);
1049#endif
1050}
1051
1056void sem_decrement(uint8_t semaphore_idx) {
1057#ifndef HOST_TEST
1058 __asm__ volatile (
1059 "mov r0, %0\n"
1060 "svc %1\n"
1061 :
1062 : "r" ((uint32_t)semaphore_idx), "I" (SVC_SEM_DECREMENT)
1063 : "r0"
1064 );
1065#else
1066 __sem_decrement(semaphore_idx);
1067#endif
1068}
1069
1074void pipe_write_bytes(uint8_t pipe_idx, uint8_t *message, uint8_t message_bytes) {
1075#ifndef HOST_TEST
1076 __asm__ volatile (
1077 "mov r0, %0\n"
1078 "mov r1, %1\n"
1079 "mov r2, %2\n"
1080 "svc %3\n"
1081 :
1082 : "r" ((uint32_t)pipe_idx), "r" (message), "r" ((uint32_t)message_bytes),
1084 : "r0", "r1", "r2"
1085 );
1086#else
1087 __pipe_write_bytes(pipe_idx, message, message_bytes);
1088#endif
1089}
1090
1095void pipe_read_bytes(uint8_t pipe_idx, uint8_t *message, uint8_t message_bytes) {
1096#ifndef HOST_TEST
1097 __asm__ volatile (
1098 "mov r0, %0\n"
1099 "mov r1, %1\n"
1100 "mov r2, %2\n"
1101 "svc %3\n"
1102 :
1103 : "r" ((uint32_t)pipe_idx), "r" (message), "r" ((uint32_t)message_bytes),
1105 : "r0", "r1", "r2"
1106 );
1107#else
1108 __pipe_read_bytes(pipe_idx, message, message_bytes);
1109#endif
1110}
1111
1112
1113/* ============================================================================
1114 * TASK METADATA READ GATES (for display/diagnostics from unprivileged mode)
1115 * ========================================================================= */
1116
1123const char *os_get_task_name(uint8_t task_idx) {
1124#ifndef HOST_TEST
1125 const char *result;
1126 __asm__ volatile (
1127 "mov r0, %1\n"
1128 "svc %2\n"
1129 "mov %0, r0\n"
1130 : "=r" (result)
1131 : "r" ((uint32_t)task_idx), "I" (SVC_GET_TASK_NAME)
1132 : "r0"
1133 );
1134 return result;
1135#else
1136 return __os_get_task_name(task_idx);
1137#endif
1138}
1139
1146#ifndef HOST_TEST
1147 uint8_t result;
1148 __asm__ volatile (
1149 "svc %1\n"
1150 "mov %0, r0\n"
1151 : "=r" (result)
1152 : "I" (SVC_GET_NUM_TASKS)
1153 : "r0"
1154 );
1155 return result;
1156#else
1158#endif
1159}
1160
1166uint8_t os_is_running(void) {
1167#ifndef HOST_TEST
1168 uint8_t result;
1169 __asm__ volatile (
1170 "svc %1\n"
1171 "mov %0, r0\n"
1172 : "=r" (result)
1173 : "I" (SVC_OS_IS_RUNNING)
1174 : "r0"
1175 );
1176 return result;
1177#else
1178 return __os_is_running();
1179#endif
1180}
1181
1186#ifndef HOST_TEST
1187 uint32_t result;
1188 __asm__ volatile (
1189 "mov r0, %1\n"
1190 "svc %2\n"
1191 "mov %0, r0\n"
1192 : "=r" (result)
1193 : "r" ((uint32_t)task_idx), "I" (SVC_GET_TASK_STATE)
1194 : "r0"
1195 );
1196 return (icarus_task_state_t)result;
1197#else
1198 return __os_get_task_state(task_idx);
1199#endif
1200}
1201
1205uint32_t os_get_task_dispatch_count(uint8_t task_idx) {
1206#ifndef HOST_TEST
1207 uint32_t result;
1208 __asm__ volatile (
1209 "mov r0, %1\n"
1210 "svc %2\n"
1211 "mov %0, r0\n"
1212 : "=r" (result)
1213 : "r" ((uint32_t)task_idx), "I" (SVC_GET_TASK_DISPATCH_COUNT)
1214 : "r0"
1215 );
1216 return result;
1217#else
1218 return __os_get_task_dispatch_count(task_idx);
1219#endif
1220}
1221
1225uint32_t os_get_stack_watermark(uint8_t task_idx) {
1226#ifndef HOST_TEST
1227 uint32_t result;
1228 __asm__ volatile (
1229 "mov r0, %1\n"
1230 "svc %2\n"
1231 "mov %0, r0\n"
1232 : "=r" (result)
1233 : "r" ((uint32_t)task_idx), "I" (SVC_GET_STACK_WATERMARK)
1234 : "r0"
1235 );
1236 return result;
1237#else
1238 return __os_get_stack_watermark(task_idx);
1239#endif
1240}
1241
1245void os_update_stack_watermark(uint8_t task_idx) {
1246#ifndef HOST_TEST
1247 __asm__ volatile (
1248 "mov r0, %0\n"
1249 "svc %1\n"
1250 :
1251 : "r" ((uint32_t)task_idx), "I" (SVC_UPDATE_STACK_WATERMARK)
1252 : "r0"
1253 );
1254#else
1256#endif
1257}
1258
1259/* ============================================================================
1260 * CDC RX RING BUFFER WRAPPERS
1261 * ========================================================================= */
1262
1263/* Init: void → void. */
1264void cdc_rx_init(void) {
1265#ifndef HOST_TEST
1266 __asm__ volatile ("svc %0\n" : : "I" (SVC_CDC_RX_INIT));
1267#else
1268 __cdc_rx_init();
1269#endif
1270}
1271
1272/* Producer: called from the privileged USB CDC ISR. No SVC — the caller is
1273 * already in privileged handler context, and issuing an SVC from a high-
1274 * priority interrupt would cause a usage fault. */
1275void cdc_rx_push(const uint8_t *data, uint32_t len) {
1276 __cdc_rx_push(data, len);
1277}
1278
1279bool cdc_rx_read_byte(uint8_t *out) {
1280#ifndef HOST_TEST
1281 uint32_t result;
1282 __asm__ volatile (
1283 "mov r0, %1\n"
1284 "svc %2\n"
1285 "mov %0, r0\n"
1286 : "=r" (result)
1287 : "r" ((uint32_t)(uintptr_t)out), "I" (SVC_CDC_RX_READ_BYTE)
1288 : "r0"
1289 );
1290 return (bool)result;
1291#else
1292 return __cdc_rx_read_byte(out);
1293#endif
1294}
1295
1296uint32_t cdc_rx_available(void) {
1297#ifndef HOST_TEST
1298 uint32_t result;
1299 __asm__ volatile (
1300 "svc %1\n"
1301 "mov %0, r0\n"
1302 : "=r" (result)
1303 : "I" (SVC_CDC_RX_AVAILABLE)
1304 : "r0"
1305 );
1306 return result;
1307#else
1308 return __cdc_rx_available();
1309#endif
1310}
1311
1312/* ============================================================================
1313 * EVENT RING BUFFER WRAPPERS
1314 * ========================================================================= */
1315
1316void event_init(void) {
1317#ifndef HOST_TEST
1318 __asm__ volatile ("svc %0\n" : : "I" (SVC_EVENT_INIT));
1319#else
1320 __event_init();
1321#endif
1322}
1323
1324/* os_event packs five user-level args into three SVC registers (R0/R1/R2)
1325 * to stay inside the AAPCS budget without spilling to the caller's stack:
1326 *
1327 * R0 = (event_id << 16) | (severity << 8) | module_id
1328 * R1 = payload pointer
1329 * R2 = payload_len
1330 */
1331void os_event(uint8_t module_id, event_severity_t severity, uint16_t event_id,
1332 const void *payload, uint8_t payload_len) {
1333#ifndef HOST_TEST
1334 uint32_t packed = ((uint32_t)event_id << 16)
1335 | ((uint32_t)((uint8_t)severity) << 8)
1336 | (uint32_t)module_id;
1337 __asm__ volatile (
1338 "mov r0, %0\n"
1339 "mov r1, %1\n"
1340 "mov r2, %2\n"
1341 "svc %3\n"
1342 :
1343 : "r" (packed), "r" ((uint32_t)(uintptr_t)payload),
1344 "r" ((uint32_t)payload_len), "I" (SVC_OS_EVENT)
1345 : "r0", "r1", "r2"
1346 );
1347#else
1348 __os_event(module_id, severity, event_id, payload, payload_len);
1349#endif
1350}
1351
1352void event_set_squelch(uint8_t module_id, event_severity_t min_severity) {
1353#ifndef HOST_TEST
1354 __asm__ volatile (
1355 "mov r0, %0\n"
1356 "mov r1, %1\n"
1357 "svc %2\n"
1358 :
1359 : "r" ((uint32_t)module_id), "r" ((uint32_t)min_severity),
1361 : "r0", "r1"
1362 );
1363#else
1364 __event_set_squelch(module_id, min_severity);
1365#endif
1366}
1367
1369#ifndef HOST_TEST
1370 uint32_t result;
1371 __asm__ volatile (
1372 "mov r0, %1\n"
1373 "svc %2\n"
1374 "mov %0, r0\n"
1375 : "=r" (result)
1376 : "r" ((uint32_t)module_id), "I" (SVC_EVENT_GET_SQUELCH)
1377 : "r0"
1378 );
1379 return (event_severity_t)result;
1380#else
1381 return __event_get_squelch(module_id);
1382#endif
1383}
1384
1385bool event_drain(event_entry_t *out_buf, uint8_t max_entries,
1386 uint8_t *num_drained) {
1387#ifndef HOST_TEST
1388 uint32_t result;
1389 __asm__ volatile (
1390 "mov r0, %1\n"
1391 "mov r1, %2\n"
1392 "mov r2, %3\n"
1393 "svc %4\n"
1394 "mov %0, r0\n"
1395 : "=r" (result)
1396 : "r" ((uint32_t)(uintptr_t)out_buf),
1397 "r" ((uint32_t)max_entries),
1398 "r" ((uint32_t)(uintptr_t)num_drained),
1399 "I" (SVC_EVENT_DRAIN)
1400 : "r0", "r1", "r2"
1401 );
1402 return (bool)result;
1403#else
1404 return __event_drain(out_buf, max_entries, num_drained);
1405#endif
1406}
1407
1408uint32_t event_get_count(void) {
1409#ifndef HOST_TEST
1410 uint32_t result;
1411 __asm__ volatile (
1412 "svc %1\n"
1413 "mov %0, r0\n"
1414 : "=r" (result)
1415 : "I" (SVC_EVENT_GET_COUNT)
1416 : "r0"
1417 );
1418 return result;
1419#else
1420 return __event_get_count();
1421#endif
1422}
1423
1424/* ============================================================================
1425 * GROUND-LOADABLE TABLE ENGINE WRAPPERS
1426 * ========================================================================= */
1427
1428void tbl_init(void) {
1429#ifndef HOST_TEST
1430 __asm__ volatile ("svc %0\n" : : "I" (SVC_TBL_INIT));
1431#else
1432 __tbl_init();
1433#endif
1434}
1435
1437#ifndef HOST_TEST
1438 uint32_t result;
1439 __asm__ volatile (
1440 "mov r0, %1\n"
1441 "svc %2\n"
1442 "mov %0, r0\n"
1443 : "=r" (result)
1444 : "r" ((uint32_t)(uintptr_t)desc), "I" (SVC_TBL_REGISTER)
1445 : "r0"
1446 );
1447 return (bool)result;
1448#else
1449 return __tbl_register(desc);
1450#endif
1451}
1452
1453bool tbl_load(tbl_id_t id, const uint8_t *data, uint16_t len,
1454 uint16_t schema_crc) {
1455#ifndef HOST_TEST
1456 uint32_t result;
1457 __asm__ volatile (
1458 "mov r0, %1\n"
1459 "mov r1, %2\n"
1460 "mov r2, %3\n"
1461 "mov r3, %4\n"
1462 "svc %5\n"
1463 "mov %0, r0\n"
1464 : "=r" (result)
1465 : "r" ((uint32_t)id), "r" ((uint32_t)(uintptr_t)data),
1466 "r" ((uint32_t)len), "r" ((uint32_t)schema_crc),
1467 "I" (SVC_TBL_LOAD)
1468 : "r0", "r1", "r2", "r3"
1469 );
1470 return (bool)result;
1471#else
1472 return __tbl_load(id, data, len, schema_crc);
1473#endif
1474}
1475
1476/* tbl_activate is the only call that must straddle priv ↔ thread mode: the
1477 * registered activate callback runs in unprivileged thread mode between
1478 * the prepare (validate + copy staging into a thread-mode scratch buffer)
1479 * and the commit (copy scratch into the active buffer). This mirrors the
1480 * pattern used by semaphore/pipe spin loops. */
1482 uint8_t scratch[TBL_MAX_SIZE];
1483 uint16_t scratch_len = 0;
1484 tbl_activate_fn activate_cb = NULL;
1485 bool ok;
1486
1487#ifndef HOST_TEST
1488 {
1489 uint32_t result;
1490 __asm__ volatile (
1491 "mov r0, %1\n"
1492 "mov r1, %2\n"
1493 "mov r2, %3\n"
1494 "mov r3, %4\n"
1495 "svc %5\n"
1496 "mov %0, r0\n"
1497 : "=r" (result)
1498 : "r" ((uint32_t)id),
1499 "r" ((uint32_t)(uintptr_t)scratch),
1500 "r" ((uint32_t)(uintptr_t)&scratch_len),
1501 "r" ((uint32_t)(uintptr_t)&activate_cb),
1503 : "r0", "r1", "r2", "r3"
1504 );
1505 ok = (bool)result;
1506 }
1507#else
1508 ok = __tbl_activate_prepare(id, scratch, &scratch_len, &activate_cb);
1509#endif
1510
1511 if (!ok) {
1512 return false;
1513 }
1514
1515 /* Run the user activate callback in thread mode against the scratch
1516 * copy. The active buffer is unchanged at this point. */
1517 if (activate_cb) {
1518 if (!activate_cb(scratch, scratch_len)) {
1519 return false;
1520 }
1521 }
1522
1523#ifndef HOST_TEST
1524 {
1525 uint32_t result;
1526 __asm__ volatile (
1527 "mov r0, %1\n"
1528 "mov r1, %2\n"
1529 "mov r2, %3\n"
1530 "svc %4\n"
1531 "mov %0, r0\n"
1532 : "=r" (result)
1533 : "r" ((uint32_t)id),
1534 "r" ((uint32_t)(uintptr_t)scratch),
1535 "r" ((uint32_t)scratch_len),
1537 : "r0", "r1", "r2"
1538 );
1539 return (bool)result;
1540 }
1541#else
1542 return __tbl_activate_commit(id, scratch, scratch_len);
1543#endif
1544}
1545
1546int16_t tbl_dump(tbl_id_t id, uint8_t *out, uint16_t max) {
1547#ifndef HOST_TEST
1548 int32_t result;
1549 __asm__ volatile (
1550 "mov r0, %1\n"
1551 "mov r1, %2\n"
1552 "mov r2, %3\n"
1553 "svc %4\n"
1554 "mov %0, r0\n"
1555 : "=r" (result)
1556 : "r" ((uint32_t)id), "r" ((uint32_t)(uintptr_t)out),
1557 "r" ((uint32_t)max), "I" (SVC_TBL_DUMP)
1558 : "r0", "r1", "r2"
1559 );
1560 return (int16_t)result;
1561#else
1562 return __tbl_dump(id, out, max);
1563#endif
1564}
1565
1567#ifndef HOST_TEST
1568 uint32_t result;
1569 __asm__ volatile (
1570 "mov r0, %1\n"
1571 "svc %2\n"
1572 "mov %0, r0\n"
1573 : "=r" (result)
1574 : "r" ((uint32_t)id), "I" (SVC_TBL_GET_DESCRIPTOR)
1575 : "r0"
1576 );
1577 return (const tbl_descriptor_t *)(uintptr_t)result;
1578#else
1579 return __tbl_get_descriptor(id);
1580#endif
1581}
1582
1583uint8_t tbl_count(void) {
1584#ifndef HOST_TEST
1585 uint32_t result;
1586 __asm__ volatile (
1587 "svc %1\n"
1588 "mov %0, r0\n"
1589 : "=r" (result)
1590 : "I" (SVC_TBL_COUNT)
1591 : "r0"
1592 );
1593 return (uint8_t)result;
1594#else
1595 return __tbl_count();
1596#endif
1597}
1598
1599/* ============================================================================
1600 * CHECKSUM INTEGRITY MONITOR WRAPPERS
1601 * ========================================================================= */
1602
1603void cs_init(void) {
1604#ifndef HOST_TEST
1605 __asm__ volatile ("svc %0\n" : : "I" (SVC_CS_INIT));
1606#else
1607 __cs_init();
1608#endif
1609}
1610
1612#ifndef HOST_TEST
1613 __asm__ volatile (
1614 "mov r0, %0\n"
1615 "svc %1\n"
1616 :
1617 : "r" ((uint32_t)(uintptr_t)fn), "I" (SVC_CS_SET_CALLBACK)
1618 : "r0"
1619 );
1620#else
1622#endif
1623}
1624
1625bool cs_add_region(uint8_t idx, const uint8_t *addr, uint32_t size) {
1626#ifndef HOST_TEST
1627 uint32_t result;
1628 __asm__ volatile (
1629 "mov r0, %1\n"
1630 "mov r1, %2\n"
1631 "mov r2, %3\n"
1632 "svc %4\n"
1633 "mov %0, r0\n"
1634 : "=r" (result)
1635 : "r" ((uint32_t)idx), "r" ((uint32_t)(uintptr_t)addr),
1636 "r" (size), "I" (SVC_CS_ADD_REGION)
1637 : "r0", "r1", "r2"
1638 );
1639 return (bool)result;
1640#else
1641 return __cs_add_region(idx, addr, size);
1642#endif
1643}
1644
1645bool cs_enable(uint8_t idx, bool enabled) {
1646#ifndef HOST_TEST
1647 uint32_t result;
1648 __asm__ volatile (
1649 "mov r0, %1\n"
1650 "mov r1, %2\n"
1651 "svc %3\n"
1652 "mov %0, r0\n"
1653 : "=r" (result)
1654 : "r" ((uint32_t)idx), "r" ((uint32_t)enabled),
1655 "I" (SVC_CS_ENABLE)
1656 : "r0", "r1"
1657 );
1658 return (bool)result;
1659#else
1660 return __cs_enable(idx, enabled);
1661#endif
1662}
1663
1664bool cs_rebaseline(uint8_t idx) {
1665#ifndef HOST_TEST
1666 uint32_t result;
1667 __asm__ volatile (
1668 "mov r0, %1\n"
1669 "svc %2\n"
1670 "mov %0, r0\n"
1671 : "=r" (result)
1672 : "r" ((uint32_t)idx), "I" (SVC_CS_REBASELINE)
1673 : "r0"
1674 );
1675 return (bool)result;
1676#else
1677 return __cs_rebaseline(idx);
1678#endif
1679}
1680
1681uint8_t cs_check_all(void) {
1682#ifndef HOST_TEST
1683 uint32_t result;
1684 __asm__ volatile (
1685 "svc %1\n"
1686 "mov %0, r0\n"
1687 : "=r" (result)
1688 : "I" (SVC_CS_CHECK_ALL)
1689 : "r0"
1690 );
1691 return (uint8_t)result;
1692#else
1693 return __cs_check_all();
1694#endif
1695}
1696
1697bool cs_get_region(uint8_t idx, cs_region_t *out) {
1698#ifndef HOST_TEST
1699 uint32_t result;
1700 __asm__ volatile (
1701 "mov r0, %1\n"
1702 "mov r1, %2\n"
1703 "svc %3\n"
1704 "mov %0, r0\n"
1705 : "=r" (result)
1706 : "r" ((uint32_t)idx), "r" ((uint32_t)(uintptr_t)out),
1707 "I" (SVC_CS_GET_REGION)
1708 : "r0", "r1"
1709 );
1710 return (bool)result;
1711#else
1712 return __cs_get_region(idx, out);
1713#endif
1714}
1715
1716uint8_t cs_region_count(void) {
1717#ifndef HOST_TEST
1718 uint32_t result;
1719 __asm__ volatile (
1720 "svc %1\n"
1721 "mov %0, r0\n"
1722 : "=r" (result)
1723 : "I" (SVC_CS_REGION_COUNT)
1724 : "r0"
1725 );
1726 return (uint8_t)result;
1727#else
1728 return __cs_region_count();
1729#endif
1730}
1731
1732/* ============================================================================
1733 * BKPRAM WRITE GATE
1734 * ========================================================================= */
1735
1737bool bkpram_write(const void *src, uint32_t offset, uint32_t len) {
1738#ifndef HOST_TEST
1739 uint32_t result;
1740 __asm__ volatile (
1741 "mov r0, %1\n"
1742 "mov r1, %2\n"
1743 "mov r2, %3\n"
1744 "svc %4\n"
1745 "mov %0, r0\n"
1746 : "=r" (result)
1747 : "r" ((uint32_t)(uintptr_t)src), "r" (offset),
1748 "r" (len), "I" (SVC_BKPRAM_WRITE)
1749 : "r0", "r1", "r2"
1750 );
1751 return (bool)result;
1752#else
1753 (void)offset;
1754 if (len == 0u) {
1755 return false;
1756 }
1757 /* HOST_TEST: no BKPRAM hardware — treat as no-op success */
1758 (void)src;
1759 return true;
1760#endif
1761}
USB CDC receive ring buffer.
bool __cdc_rx_read_byte(uint8_t *out)
Definition cdc_rx.c:57
uint32_t __cdc_rx_available(void)
Definition cdc_rx.c:66
void __cdc_rx_init(void)
Definition cdc_rx.c:38
void __cdc_rx_push(const uint8_t *data, uint32_t len)
Definition cdc_rx.c:43
ICARUS OS — Background Checksum integrity monitor.
bool __cs_enable(uint8_t idx, bool enabled)
Privileged implementation of cs_enable().
Definition cs.c:137
void(* cs_mismatch_fn)(uint8_t region_idx, uint16_t expected, uint16_t actual)
Mismatch callback signature.
Definition cs.h:79
void __cs_set_callback(cs_mismatch_fn fn)
Privileged implementation of cs_set_callback().
Definition cs.c:101
bool __cs_get_region(uint8_t idx, cs_region_t *out)
Privileged implementation of cs_get_region().
Definition cs.c:204
uint8_t __cs_region_count(void)
Privileged implementation of cs_region_count().
Definition cs.c:222
bool __cs_add_region(uint8_t idx, const uint8_t *addr, uint32_t size)
Privileged implementation of cs_add_region().
Definition cs.c:118
void __cs_init(void)
Privileged implementation of cs_init().
Definition cs.c:91
uint8_t __cs_check_all(void)
Privileged implementation of cs_check_all().
Definition cs.c:172
bool __cs_rebaseline(uint8_t idx)
Privileged implementation of cs_rebaseline().
Definition cs.c:152
Generic structured event ring buffer for ICARUS OS.
void __event_init(void)
Definition event.c:34
event_severity_t __event_get_squelch(uint8_t module_id)
Definition event.c:81
void __os_event(uint8_t module_id, event_severity_t severity, uint16_t event_id, const void *payload, uint8_t payload_len)
Definition event.c:43
bool __event_drain(event_entry_t *out_buf, uint8_t max_entries, uint8_t *num_drained)
Definition event.c:88
uint32_t __event_get_count(void)
Definition event.c:133
event_severity_t
Definition event.h:30
void __event_set_squelch(uint8_t module_id, event_severity_t min_severity)
Definition event.c:73
ICARUS OS — Internal RAM-backed flat-file filesystem.
bool __fs_write(fs_file_t *f, const uint8_t *data, uint16_t len)
Privileged implementation of fs_write().
Definition fs.c:146
void __fs_init(void)
Privileged implementation of fs_init().
Definition fs.c:76
uint8_t __fs_list(fs_file_info_t *out, uint8_t max)
Privileged implementation of fs_list().
Definition fs.c:227
bool __fs_open(const char *name, fs_file_t *out)
Privileged implementation of fs_open().
Definition fs.c:124
bool __fs_create(const char *name, fs_file_t *out)
Privileged implementation of fs_create().
Definition fs.c:88
void __fs_stats(fs_stats_t *out)
Privileged implementation of fs_stats().
Definition fs.c:249
uint16_t __fs_read(fs_file_t *f, uint8_t *buf, uint16_t len, uint16_t offset)
Privileged implementation of fs_read().
Definition fs.c:175
bool __fs_delete(const char *name)
Privileged implementation of fs_delete().
Definition fs.c:205
#define BSP_RAM_D3_SIZE
Definition mpu.h:47
#define BSP_RAM_D3_BASE
AHB SRAM (RAM_D3) base address (64KB)
Definition mpu.h:46
ICARUS Kernel Core - State and Initialization.
void * __kernel_protected_data(uint16_t num_words)
Privileged implementation of kernel_protected_data.
Definition kernel.c:295
void __exit_critical(void)
Privileged implementation of exit_critical.
Definition kernel.c:124
void __os_init(void)
Privileged implementation of os_init.
Definition kernel.c:212
void __enter_critical(void)
Privileged implementation of enter_critical.
Definition kernel.c:114
uint32_t * __kernel_get_data(uint8_t task_idx)
Privileged implementation of kernel_get_data.
Definition kernel.c:282
void __os_start(void)
Privileged implementation of os_start.
Definition kernel.c:253
uint32_t * __kernel_get_stack(uint8_t task_idx)
Privileged implementation of kernel_get_stack.
Definition kernel.c:269
ICARUS Pipe - Message Pipes (Circular Buffer Queues)
uint16_t __pipe_get_count(uint8_t pipe_idx)
Privileged implementation of pipe_get_count.
Definition pipe.c:123
bool __pipe_init(uint8_t pipe_idx, uint16_t pipe_capacity_bytes)
Privileged implementation of pipe_init.
Definition pipe.c:35
uint16_t __pipe_get_max_count(uint8_t pipe_idx)
Privileged implementation of pipe_get_max_count.
Definition pipe.c:135
bool __pipe_enqueue(uint8_t pipe_idx, uint8_t *message, uint8_t message_bytes)
Privileged implementation of pipe_enqueue.
Definition pipe.c:64
bool __pipe_dequeue(uint8_t pipe_idx, uint8_t *message, uint8_t message_bytes)
Privileged implementation of pipe_dequeue.
Definition pipe.c:94
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_dequeue(uint8_t pipe_idx, uint8_t message_bytes)
Privileged call gate: can pipe deliver message_bytes bytes?
Definition pipe.c:163
void __pipe_read_bytes(uint8_t pipe_idx, uint8_t *message, uint8_t message_bytes)
Privileged write gate: read bytes from pipe buffer.
Definition pipe.c:199
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
ICARUS OS — Lightweight Software Bus (pub/sub message router)
uint16_t sb_msg_id_t
Software Bus message identifier.
Definition sb.h:86
uint8_t __sb_subscriber_count(sb_msg_id_t msg_id)
Privileged implementation of sb_subscriber_count().
Definition sb.c:200
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)
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
ICARUS Scheduler - Task Scheduling and Timing.
uint32_t __os_get_tick_count(void)
Privileged implementation of os_get_tick_count.
Definition scheduler.c:48
uint32_t __task_blocking_sleep(uint32_t ticks)
Privileged implementation of task_blocking_sleep.
Definition scheduler.c:121
uint8_t __os_get_running_task_count(void)
Privileged implementation of os_get_running_task_count.
Definition scheduler.c:56
uint8_t __os_get_num_created_tasks(void)
Privileged implementation of os_get_num_created_tasks.
Definition kernel.c:345
icarus_task_state_t __os_get_task_state(uint8_t task_idx)
Privileged implementation of os_get_task_state.
Definition kernel.c:363
const char * __os_get_current_task_name(void)
Privileged implementation of os_get_current_task_name.
Definition scheduler.c:65
uint8_t __os_is_running(void)
Privileged implementation of os_is_running.
Definition kernel.c:354
uint32_t __os_get_task_dispatch_count(uint8_t task_idx)
Privileged implementation of os_get_task_dispatch_count.
Definition kernel.c:375
const char * __os_get_task_name(uint8_t task_idx)
Privileged implementation of os_get_task_name.
Definition kernel.c:315
void __os_update_stack_watermark(uint8_t task_idx)
Scan a task's stack from the base upward for the sentinel pattern (0xDEADC0DE) and update the waterma...
Definition kernel.c:399
uint32_t __os_get_stack_watermark(uint8_t task_idx)
Privileged implementation of os_get_stack_watermark.
Definition kernel.c:387
uint32_t __task_busy_wait(uint32_t ticks)
Privileged implementation of task_busy_wait.
Definition scheduler.c:133
uint32_t __task_active_sleep(uint32_t ticks)
Privileged implementation of task_active_sleep.
Definition scheduler.c:108
void __os_yield(void)
Privileged implementation of os_yield.
Definition scheduler.c:99
uint32_t __os_get_task_ticks_remaining(void)
Privileged implementation of os_get_task_ticks_remaining.
Definition scheduler.c:87
ICARUS Semaphore - Counting Semaphores.
uint32_t __semaphore_get_count(uint8_t semaphore_idx)
Privileged implementation of semaphore_get_count.
Definition semaphore.c:146
bool __semaphore_consume_timeout(uint8_t semaphore_idx, uint32_t max_ticks)
Privileged implementation of semaphore_consume_timeout.
Definition semaphore.c:116
uint32_t __semaphore_get_max_count(uint8_t semaphore_idx)
Privileged implementation of semaphore_get_max_count.
Definition semaphore.c:158
void __sem_decrement(uint8_t semaphore_idx)
Privileged write gate: decrement semaphore count.
Definition semaphore.c:213
bool __semaphore_feed(uint8_t semaphore_idx)
Privileged implementation of semaphore_feed.
Definition semaphore.c:54
bool __sem_can_consume(uint8_t semaphore_idx)
Privileged call gate: can semaphore be consumed?
Definition semaphore.c:186
bool __semaphore_init(uint8_t semaphore_idx, uint32_t semaphore_count)
Privileged implementation of semaphore_init.
Definition semaphore.c:35
bool __sem_can_feed(uint8_t semaphore_idx)
Privileged call gate: can semaphore accept a feed?
Definition semaphore.c:172
void __sem_increment(uint8_t semaphore_idx)
Privileged write gate: increment semaphore count.
Definition semaphore.c:199
bool __semaphore_consume(uint8_t semaphore_idx)
Privileged implementation of semaphore_consume.
Definition semaphore.c:81
Descriptor for a monitored memory region.
Definition cs.h:85
Definition event.h:49
Per-file metadata returned by fs_list().
Definition fs.h:46
Opaque file handle — callers hold one of these per open file.
Definition fs.h:40
Aggregate filesystem statistics.
Definition fs.h:52
Static descriptor registered by a table producer.
Definition tables.h:59
uint32_t semaphore_get_max_count(uint8_t semaphore_idx)
Get semaphore maximum count.
Definition svc.c:841
void os_yield(void)
Voluntarily yield CPU to scheduler.
Definition svc.c:511
void os_event(uint8_t module_id, event_severity_t severity, uint16_t event_id, const void *payload, uint8_t payload_len)
Emit a structured event into the ring buffer.
Definition svc.c:1331
bool semaphore_consume(uint8_t semaphore_idx)
Decrement semaphore count — spin-wait in thread mode.
Definition svc.c:807
void cdc_rx_push(const uint8_t *data, uint32_t len)
Append bytes to the ring buffer.
Definition svc.c:1275
uint16_t pipe_get_max_count(uint8_t pipe_idx)
Get pipe capacity.
Definition svc.c:921
bool pipe_enqueue(uint8_t pipe_idx, uint8_t *message, uint8_t message_bytes)
Enqueue bytes to pipe — spin-wait in thread mode.
Definition svc.c:887
bool sem_can_feed(uint8_t semaphore_idx)
Check if semaphore can accept a feed (count < max && engaged)
Definition svc.c:946
void os_start(void)
Start the ICARUS scheduler.
Definition svc.c:502
uint32_t semaphore_get_count(uint8_t semaphore_idx)
Get current semaphore count.
Definition svc.c:821
event_severity_t event_get_squelch(uint8_t module_id)
Get the current squelch level for a given module.
Definition svc.c:1368
void os_task_suicide(void)
Terminate current task (suicide)
Definition svc.c:647
uint16_t pipe_get_count(uint8_t pipe_idx)
Get current byte count in pipe.
Definition svc.c:901
bool semaphore_consume_timeout(uint8_t semaphore_idx, uint32_t max_ticks)
Decrement semaphore count with timeout.
Definition svc.c:814
icarus_task_state_t os_get_task_state(uint8_t task_idx)
Get a task's current state.
Definition svc.c:1185
const tbl_descriptor_t * tbl_get_descriptor(tbl_id_t id)
Look up a registered descriptor by id.
Definition svc.c:1566
uint32_t cdc_rx_available(void)
Definition svc.c:1296
bool cdc_rx_read_byte(uint8_t *out)
Definition svc.c:1279
bool pipe_init(uint8_t pipe_idx, uint16_t pipe_capacity_bytes)
Initialize a message pipe.
Definition svc.c:865
void cdc_rx_init(void)
Definition svc.c:1264
uint32_t os_get_task_ticks_remaining(void)
Get remaining ticks in current time slice.
Definition svc.c:613
bool tbl_activate(tbl_id_t id)
Activate a staged table after CRC validation.
Definition svc.c:1481
void sem_decrement(uint8_t semaphore_idx)
Decrement semaphore count atomically in privileged mode.
Definition svc.c:1056
const char * os_get_current_task_name(void)
Get name of currently executing task.
Definition svc.c:575
void cs_set_callback(cs_mismatch_fn fn)
Register the mismatch callback.
Definition svc.c:1611
bool cs_add_region(uint8_t idx, const uint8_t *addr, uint32_t size)
Add a memory region to the monitor.
Definition svc.c:1625
void exit_critical(void)
Exit critical section (re-enable scheduler if outermost)
Definition svc.c:489
bool cs_enable(uint8_t idx, bool enabled)
Enable or disable scanning of a region.
Definition svc.c:1645
void pipe_read_bytes(uint8_t pipe_idx, uint8_t *message, uint8_t message_bytes)
Read bytes from pipe buffer atomically in privileged mode.
Definition svc.c:1095
uint32_t * kernel_get_data(uint8_t task_idx)
Get data pointer for task index.
Definition svc.c:734
uint32_t * kernel_get_stack(uint8_t task_idx)
Get stack pointer for task index.
Definition svc.c:714
uint32_t os_get_stack_watermark(uint8_t task_idx)
Get a task's stack high-water mark.
Definition svc.c:1225
void os_init(void)
Initialize the ICARUS kernel.
Definition svc.c:501
void event_init(void)
Initialize the event system.
Definition svc.c:1316
void tbl_init(void)
Initialise the table registry.
Definition svc.c:1428
bool tbl_register(const tbl_descriptor_t *desc)
Register a table descriptor.
Definition svc.c:1436
void cs_init(void)
Initialize the checksum monitor.
Definition svc.c:1603
bool tbl_load(tbl_id_t id, const uint8_t *data, uint16_t len, uint16_t schema_crc)
Load raw bytes into the staging buffer for a registered table.
Definition svc.c:1453
void enter_critical(void)
Enter critical section (disable scheduler)
Definition svc.c:478
uint32_t task_blocking_sleep(uint32_t ticks)
Blocking sleep — spin-wait in thread mode (cannot run in SVC handler)
Definition svc.c:542
void event_set_squelch(uint8_t module_id, event_severity_t min_severity)
Set the minimum severity accepted for a given module.
Definition svc.c:1352
uint32_t os_get_tick_count(void)
Get current system tick count.
Definition svc.c:556
const char * os_get_task_name(uint8_t task_idx)
Get task name by index (read from task_list in privileged mode)
Definition svc.c:1123
bool event_drain(event_entry_t *out_buf, uint8_t max_entries, uint8_t *num_drained)
Drain queued events into a caller-provided buffer.
Definition svc.c:1385
bool pipe_can_dequeue(uint8_t pipe_idx, uint8_t message_bytes)
Check if pipe has message_bytes available (count >= bytes && engaged)
Definition svc.c:1011
uint8_t cs_region_count(void)
Return the number of registered (non-empty) regions.
Definition svc.c:1716
void os_update_stack_watermark(uint8_t task_idx)
Scan and update a task's stack watermark.
Definition svc.c:1245
bool pipe_dequeue(uint8_t pipe_idx, uint8_t *message, uint8_t message_bytes)
Dequeue bytes from pipe — spin-wait in thread mode.
Definition svc.c:894
void * kernel_protected_data(uint16_t num_words)
Allocate protected data words for current task.
Definition svc.c:754
void os_exit_task(void)
Exit current task.
Definition svc.c:636
void SVC_Handler_C(uint32_t *stack_frame)
C-level SVC dispatcher called from SVC_Handler assembly trampoline.
Definition svc.c:50
uint32_t task_busy_wait(uint32_t ticks)
Busy-wait for specified ticks — spin in thread mode.
Definition svc.c:549
uint32_t task_active_sleep(uint32_t ticks)
Sleep for specified ticks (cooperative, via SVC)
Definition svc.c:522
bool cs_rebaseline(uint8_t idx)
Re-compute and store the baseline CRC for a region.
Definition svc.c:1664
bool sem_can_consume(uint8_t semaphore_idx)
Check if semaphore can be consumed (count > 0 && engaged)
Definition svc.c:967
bool pipe_can_enqueue(uint8_t pipe_idx, uint8_t message_bytes)
Check if pipe has room for message_bytes (free >= bytes && engaged)
Definition svc.c:988
uint32_t event_get_count(void)
Number of events currently buffered.
Definition svc.c:1408
uint8_t os_is_running(void)
Check if OS is running (safe from unprivileged mode)
Definition svc.c:1166
uint8_t cs_check_all(void)
Scan all enabled regions and invoke the mismatch callback for any CRC failures.
Definition svc.c:1681
bool semaphore_feed(uint8_t semaphore_idx)
Increment semaphore count — spin-wait in thread mode.
Definition svc.c:800
uint8_t os_get_num_created_tasks(void)
Get number of created tasks (read num_created_tasks in privileged mode)
Definition svc.c:1145
bool semaphore_init(uint8_t semaphore_idx, uint32_t semaphore_count)
Initialize a counting semaphore.
Definition svc.c:778
uint32_t os_get_task_dispatch_count(uint8_t task_idx)
Get a task's dispatch count.
Definition svc.c:1205
void sem_increment(uint8_t semaphore_idx)
Increment semaphore count atomically in privileged mode.
Definition svc.c:1038
uint8_t os_get_running_task_count(void)
Get number of active tasks.
Definition svc.c:594
void os_kill_process(uint8_t task_index)
Kill a task by index.
Definition svc.c:676
uint8_t tbl_count(void)
Return the number of registered tables.
Definition svc.c:1583
void pipe_write_bytes(uint8_t pipe_idx, uint8_t *message, uint8_t message_bytes)
Write bytes to pipe buffer atomically in privileged mode.
Definition svc.c:1074
void os_restart_task(uint8_t task_index)
Restart a killed/finished task in-place (cold restart)
Definition svc.c:693
bool bkpram_write(const void *src, uint32_t offset, uint32_t len)
Copy data into battery-backed RAM (RAM_D3) via SVC.
Definition svc.c:1737
void os_register_task(void(*function)(void), const char *name)
Register a task with the scheduler.
Definition svc.c:658
bool cs_get_region(uint8_t idx, cs_region_t *out)
Read back a region's configuration.
Definition svc.c:1697
int16_t tbl_dump(tbl_id_t id, uint8_t *out, uint16_t max)
Copy the active table bytes into out.
Definition svc.c:1546
ICARUS Supervisor Call (SVC) Definitions.
#define SVC_TASK_BLOCKING_SLEEP
Definition svc.h:33
#define SVC_ENTER_CRITICAL
Definition svc.h:35
#define SVC_FS_DELETE
Definition svc.h:149
#define SVC_SEMAPHORE_INIT
Definition svc.h:52
#define SVC_SEM_CAN_CONSUME
Definition svc.h:72
#define SVC_CDC_RX_AVAILABLE
Definition svc.h:90
#define SVC_SB_PUBLISH
Definition svc.h:139
#define SVC_TBL_COUNT
Definition svc.h:108
#define SVC_TBL_ACTIVATE_PREPARE
Definition svc.h:104
#define SVC_EVENT_INIT
Definition svc.h:93
#define SVC_TASK_BUSY_WAIT
Definition svc.h:61
#define SVC_OS_GET_CURRENT_TASK_NAME
Definition svc.h:46
#define SVC_OS_TASK_SUICIDE
Definition svc.h:50
#define SVC_SEMAPHORE_FEED
Definition svc.h:54
#define SVC_GET_TASK_DISPATCH_COUNT
Definition svc.h:118
#define SVC_OS_EVENT
Definition svc.h:94
#define SVC_OS_REGISTER_TASK
Definition svc.h:45
#define SVC_TBL_REGISTER
Definition svc.h:102
#define SVC_FS_LIST
Definition svc.h:150
#define SVC_SEMAPHORE_CONSUME
Definition svc.h:53
#define SVC_OS_RESTART_TASK
Definition svc.h:111
#define SVC_GET_NUM_TASKS
Definition svc.h:84
#define SVC_GET_STACK_WATERMARK
Definition svc.h:119
#define SVC_TBL_LOAD
Definition svc.h:103
#define SVC_TBL_GET_DESCRIPTOR
Definition svc.h:107
#define SVC_KERNEL_GET_STACK
Definition svc.h:65
#define SVC_CS_GET_REGION
Definition svc.h:129
#define SVC_EVENT_GET_SQUELCH
Definition svc.h:96
#define SVC_FS_OPEN
Definition svc.h:146
#define SVC_PIPE_DEQUEUE
Definition svc.h:40
#define SVC_SB_ROUTE_COUNT
Definition svc.h:141
#define SVC_SEM_CAN_FEED
Definition svc.h:71
#define SVC_PIPE_GET_MAX_COUNT
Definition svc.h:59
#define SVC_CS_REBASELINE
Definition svc.h:127
#define SVC_EXIT_CRITICAL
Definition svc.h:36
#define SVC_PIPE_ENQUEUE
Definition svc.h:39
#define SVC_OS_EXIT_TASK
Definition svc.h:48
#define SVC_CS_SET_CALLBACK
Definition svc.h:124
#define SVC_CS_REGION_COUNT
Definition svc.h:130
#define SVC_EVENT_GET_COUNT
Definition svc.h:98
#define SVC_OS_GET_RUNNING_TASK_COUNT
Definition svc.h:62
#define SVC_SEMAPHORE_GET_COUNT
Definition svc.h:55
#define SVC_KERNEL_GET_DATA
Definition svc.h:66
#define SVC_SB_UNSUBSCRIBE
Definition svc.h:138
#define SVC_CS_CHECK_ALL
Definition svc.h:128
#define SVC_OS_GET_TICK_COUNT
Definition svc.h:47
#define SVC_CS_ENABLE
Definition svc.h:126
#define SVC_CS_ADD_REGION
Definition svc.h:125
#define SVC_PIPE_WRITE_BYTES
Definition svc.h:79
#define SVC_UPDATE_STACK_WATERMARK
Definition svc.h:120
#define SVC_EVENT_SET_SQUELCH
Definition svc.h:95
#define SVC_OS_KILL_PROCESS
Definition svc.h:49
#define SVC_FS_INIT
Definition svc.h:144
#define SVC_GET_TASK_NAME
Definition svc.h:83
#define SVC_FS_WRITE
Definition svc.h:147
#define SVC_SB_SUBSCRIBE
Definition svc.h:137
#define SVC_OS_IS_RUNNING
Definition svc.h:85
#define SVC_FS_READ
Definition svc.h:148
#define SVC_FS_CREATE
Definition svc.h:145
#define SVC_TASK_ACTIVE_SLEEP
Definition svc.h:32
#define SVC_FS_STATS
Definition svc.h:151
#define SVC_OS_GET_TASK_TICKS_REMAINING
Definition svc.h:63
#define SVC_PIPE_READ_BYTES
Definition svc.h:80
#define SVC_SB_INIT
Definition svc.h:136
#define SVC_OS_YIELD
Definition svc.h:44
#define SVC_CDC_RX_INIT
Definition svc.h:88
#define SVC_KERNEL_PROTECTED_DATA
Definition svc.h:67
#define SVC_SEMAPHORE_CONSUME_TIMEOUT
Definition svc.h:114
#define SVC_BKPRAM_WRITE
Definition svc.h:133
#define SVC_SEM_DECREMENT
Definition svc.h:78
#define SVC_TBL_INIT
Definition svc.h:101
#define SVC_EVENT_DRAIN
Definition svc.h:97
#define SVC_PIPE_GET_COUNT
Definition svc.h:58
#define SVC_SB_SUBSCRIBER_COUNT
Definition svc.h:140
#define SVC_TBL_DUMP
Definition svc.h:106
#define SVC_TBL_ACTIVATE_COMMIT
Definition svc.h:105
#define SVC_GET_TASK_STATE
Definition svc.h:117
#define SVC_CS_INIT
Definition svc.h:123
#define SVC_CDC_RX_READ_BYTE
Definition svc.h:89
#define SVC_SEM_INCREMENT
Definition svc.h:77
#define SVC_PIPE_CAN_ENQUEUE
Definition svc.h:73
#define SVC_SEMAPHORE_GET_MAX_COUNT
Definition svc.h:56
#define SVC_PIPE_CAN_DEQUEUE
Definition svc.h:74
#define SVC_PIPE_INIT
Definition svc.h:38
ICARUS OS — Generic ground-loadable table engine.
bool __tbl_load(tbl_id_t id, const uint8_t *data, uint16_t len, uint16_t schema_crc)
Definition tables.c:100
uint8_t tbl_id_t
Generic table identifier.
Definition tables.h:43
uint8_t __tbl_count(void)
Definition tables.c:216
#define TBL_MAX_SIZE
Maximum bytes per table buffer
Definition tables.h:33
bool __tbl_register(const tbl_descriptor_t *desc)
Definition tables.c:76
bool __tbl_activate_prepare(tbl_id_t id, uint8_t *out_data, uint16_t *out_len, tbl_activate_fn *out_activate)
Validate a staged table and copy it into a caller-provided scratch buffer for the activate callback.
Definition tables.c:139
int16_t __tbl_dump(tbl_id_t id, uint8_t *out, uint16_t max)
Definition tables.c:190
bool(* tbl_activate_fn)(const void *data, uint16_t len)
Callback invoked when a staged table passes all CRC checks.
Definition tables.h:54
bool __tbl_activate_commit(tbl_id_t id, const uint8_t *data, uint16_t len)
Commit a previously prepared table into the active buffer.
Definition tables.c:176
const tbl_descriptor_t * __tbl_get_descriptor(tbl_id_t id)
Definition tables.c:211
void __tbl_init(void)
Definition tables.c:71
ICARUS Task Management - Creation and Lifecycle.
void __os_kill_process(uint8_t task_index)
Privileged implementation of os_kill_process.
Definition task.c:110
void __os_exit_task(void)
Privileged implementation of os_exit_task.
Definition task.c:90
void __os_restart_task(uint8_t task_index)
Privileged implementation of os_restart_task.
Definition task.c:154
void __os_register_task(void(*function)(void), const char *name)
Privileged implementation of os_register_task.
Definition task.c:74
void __os_task_suicide(void)
Privileged implementation of os_task_suicide.
Definition task.c:136
icarus_task_state_t
Task state enumeration.
Definition types.h:75