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 File Reference

ICARUS Supervisor Call (SVC) Implementation. More...

#include "icarus/svc.h"
#include "icarus/kernel.h"
#include "icarus/task.h"
#include "icarus/scheduler.h"
#include "icarus/pipe.h"
#include "icarus/semaphore.h"
#include "icarus/cdc_rx.h"
#include "icarus/event.h"
#include "icarus/tables.h"
#include "icarus/cs.h"
#include "icarus/sb.h"
#include "icarus/fs.h"
#include "bsp/mpu.h"
#include <stddef.h>
#include <string.h>

Go to the source code of this file.

Functions

void SVC_Handler_C (uint32_t *stack_frame)
 C-level SVC dispatcher called from SVC_Handler assembly trampoline.
 
void enter_critical (void)
 Enter critical section (disable scheduler)
 
void exit_critical (void)
 Exit critical section (re-enable scheduler if outermost)
 
void os_init (void)
 Initialize the ICARUS kernel.
 
void os_start (void)
 Start the ICARUS scheduler.
 
void os_yield (void)
 Voluntarily yield CPU to scheduler.
 
uint32_t task_active_sleep (uint32_t ticks)
 Sleep for specified ticks (cooperative, via SVC)
 
uint32_t task_blocking_sleep (uint32_t ticks)
 Blocking sleep — spin-wait in thread mode (cannot run in SVC handler)
 
uint32_t task_busy_wait (uint32_t ticks)
 Busy-wait for specified ticks — spin in thread mode.
 
uint32_t os_get_tick_count (void)
 Get current system tick count.
 
const char * os_get_current_task_name (void)
 Get name of currently executing task.
 
uint8_t os_get_running_task_count (void)
 Get number of active tasks.
 
uint32_t os_get_task_ticks_remaining (void)
 Get remaining ticks in current time slice.
 
void os_exit_task (void)
 Exit current task.
 
void os_task_suicide (void)
 Terminate current task (suicide)
 
void os_register_task (void(*function)(void), const char *name)
 Register a task with the scheduler.
 
void os_kill_process (uint8_t task_index)
 Kill a task by index.
 
void os_restart_task (uint8_t task_index)
 Restart a killed/finished task in-place (cold restart)
 
uint32_t * kernel_get_stack (uint8_t task_idx)
 Get stack pointer for task index.
 
uint32_t * kernel_get_data (uint8_t task_idx)
 Get data pointer for task index.
 
void * kernel_protected_data (uint16_t num_words)
 Allocate protected data words for current task.
 
bool semaphore_init (uint8_t semaphore_idx, uint32_t semaphore_count)
 Initialize a counting semaphore.
 
bool semaphore_feed (uint8_t semaphore_idx)
 Increment semaphore count — spin-wait in thread mode.
 
bool semaphore_consume (uint8_t semaphore_idx)
 Decrement semaphore count — spin-wait in thread mode.
 
bool semaphore_consume_timeout (uint8_t semaphore_idx, uint32_t max_ticks)
 Decrement semaphore count with timeout.
 
uint32_t semaphore_get_count (uint8_t semaphore_idx)
 Get current semaphore count.
 
uint32_t semaphore_get_max_count (uint8_t semaphore_idx)
 Get semaphore maximum count.
 
bool pipe_init (uint8_t pipe_idx, uint16_t pipe_capacity_bytes)
 Initialize a message pipe.
 
bool pipe_enqueue (uint8_t pipe_idx, uint8_t *message, uint8_t message_bytes)
 Enqueue bytes to pipe — spin-wait in thread mode.
 
bool pipe_dequeue (uint8_t pipe_idx, uint8_t *message, uint8_t message_bytes)
 Dequeue bytes from pipe — spin-wait in thread mode.
 
uint16_t pipe_get_count (uint8_t pipe_idx)
 Get current byte count in pipe.
 
uint16_t pipe_get_max_count (uint8_t pipe_idx)
 Get pipe capacity.
 
bool sem_can_feed (uint8_t semaphore_idx)
 Check if semaphore can accept a feed (count < max && engaged)
 
bool sem_can_consume (uint8_t semaphore_idx)
 Check if semaphore can be consumed (count > 0 && engaged)
 
bool pipe_can_enqueue (uint8_t pipe_idx, uint8_t message_bytes)
 Check if pipe has room for message_bytes (free >= bytes && engaged)
 
bool pipe_can_dequeue (uint8_t pipe_idx, uint8_t message_bytes)
 Check if pipe has message_bytes available (count >= bytes && engaged)
 
void sem_increment (uint8_t semaphore_idx)
 Increment semaphore count atomically in privileged mode.
 
void sem_decrement (uint8_t semaphore_idx)
 Decrement semaphore count atomically in privileged mode.
 
void pipe_write_bytes (uint8_t pipe_idx, uint8_t *message, uint8_t message_bytes)
 Write bytes to pipe buffer atomically in privileged mode.
 
void pipe_read_bytes (uint8_t pipe_idx, uint8_t *message, uint8_t message_bytes)
 Read bytes from pipe buffer atomically in privileged mode.
 
const char * os_get_task_name (uint8_t task_idx)
 Get task name by index (read from task_list in privileged mode)
 
uint8_t os_get_num_created_tasks (void)
 Get number of created tasks (read num_created_tasks in privileged mode)
 
uint8_t os_is_running (void)
 Check if OS is running (safe from unprivileged mode)
 
icarus_task_state_t os_get_task_state (uint8_t task_idx)
 Get a task's current state.
 
uint32_t os_get_task_dispatch_count (uint8_t task_idx)
 Get a task's dispatch count.
 
uint32_t os_get_stack_watermark (uint8_t task_idx)
 Get a task's stack high-water mark.
 
void os_update_stack_watermark (uint8_t task_idx)
 Scan and update a task's stack watermark.
 
void cdc_rx_init (void)
 
void cdc_rx_push (const uint8_t *data, uint32_t len)
 Append bytes to the ring buffer.
 
bool cdc_rx_read_byte (uint8_t *out)
 
uint32_t cdc_rx_available (void)
 
void event_init (void)
 Initialize the event system.
 
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.
 
void event_set_squelch (uint8_t module_id, event_severity_t min_severity)
 Set the minimum severity accepted for a given module.
 
event_severity_t event_get_squelch (uint8_t module_id)
 Get the current squelch level for a given module.
 
bool event_drain (event_entry_t *out_buf, uint8_t max_entries, uint8_t *num_drained)
 Drain queued events into a caller-provided buffer.
 
uint32_t event_get_count (void)
 Number of events currently buffered.
 
void tbl_init (void)
 Initialise the table registry.
 
bool tbl_register (const tbl_descriptor_t *desc)
 Register a table descriptor.
 
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.
 
bool tbl_activate (tbl_id_t id)
 Activate a staged table after CRC validation.
 
int16_t tbl_dump (tbl_id_t id, uint8_t *out, uint16_t max)
 Copy the active table bytes into out.
 
const tbl_descriptor_ttbl_get_descriptor (tbl_id_t id)
 Look up a registered descriptor by id.
 
uint8_t tbl_count (void)
 Return the number of registered tables.
 
void cs_init (void)
 Initialize the checksum monitor.
 
void cs_set_callback (cs_mismatch_fn fn)
 Register the mismatch callback.
 
bool cs_add_region (uint8_t idx, const uint8_t *addr, uint32_t size)
 Add a memory region to the monitor.
 
bool cs_enable (uint8_t idx, bool enabled)
 Enable or disable scanning of a region.
 
bool cs_rebaseline (uint8_t idx)
 Re-compute and store the baseline CRC for a region.
 
uint8_t cs_check_all (void)
 Scan all enabled regions and invoke the mismatch callback for any CRC failures.
 
bool cs_get_region (uint8_t idx, cs_region_t *out)
 Read back a region's configuration.
 
uint8_t cs_region_count (void)
 Return the number of registered (non-empty) regions.
 
bool bkpram_write (const void *src, uint32_t offset, uint32_t len)
 Copy data into battery-backed RAM (RAM_D3) via SVC.
 

Detailed Description

ICARUS Supervisor Call (SVC) Implementation.

Version
0.1.0

SVC handler and public wrapper functions for MPU-protected kernel calls. Non-spinning wrappers issue SVC instructions to execute in privileged handler mode. Spinning wrappers (semaphore_feed/consume, pipe_enqueue/dequeue, task_blocking_sleep/busy_wait) call __func directly in thread mode — they cannot run inside the SVC handler because PendSV is lower priority and cannot preempt it.

Author
Souham Biswas
Date
2025

Definition in file svc.c.

Function Documentation

◆ bkpram_write()

bool bkpram_write ( const void *  src,
uint32_t  offset,
uint32_t  len 
)

Copy data into battery-backed RAM (RAM_D3) via SVC.

Copy data into battery-backed RAM (RAM_D3) via SVC.

On target this issues an SVC that runs a validated memcpy in privileged mode, allowing unprivileged tasks to persist data into BKPRAM without an MPU region grant. Under HOST_TEST the call is a no-op that returns true.

Parameters
[in]srcSource buffer (caller-owned, any memory domain).
[in]offsetByte offset into BKPRAM (0 .. BSP_RAM_D3_SIZE-1).
[in]lenNumber of bytes to copy (must be > 0).
Return values
trueWrite completed successfully.
falseValidation failed (offset+len exceeds BKPRAM, or len==0).

Copy data into battery-backed RAM (RAM_D3) via SVC.

Definition at line 1737 of file svc.c.

References SVC_BKPRAM_WRITE.

◆ cdc_rx_available()

uint32_t cdc_rx_available ( void  )

Definition at line 1296 of file svc.c.

References __cdc_rx_available(), and SVC_CDC_RX_AVAILABLE.

◆ cdc_rx_init()

void cdc_rx_init ( void  )

Definition at line 1264 of file svc.c.

References __cdc_rx_init(), and SVC_CDC_RX_INIT.

◆ cdc_rx_push()

void cdc_rx_push ( const uint8_t *  data,
uint32_t  len 
)

Append bytes to the ring buffer.

Note
Designed for the privileged USB CDC ISR. The wrapper calls the priv-mode implementation directly (no SVC) because issuing an SVC from a high-priority interrupt is unsafe. Thread-mode callers can use it too — the priv-mode access works because the wrapper itself runs in handler / privileged context when called from an ISR; on host tests it is just a direct call.

Definition at line 1275 of file svc.c.

References __cdc_rx_push().

◆ cdc_rx_read_byte()

bool cdc_rx_read_byte ( uint8_t *  out)

Definition at line 1279 of file svc.c.

References __cdc_rx_read_byte(), and SVC_CDC_RX_READ_BYTE.

◆ cs_add_region()

bool cs_add_region ( uint8_t  idx,
const uint8_t *  addr,
uint32_t  size 
)

Add a memory region to the monitor.

Parameters
[in]idxRegion index (0 .. CS_MAX_REGIONS-1).
[in]addrStart address of the region.
[in]sizeSize in bytes (must be > 0).
Return values
trueRegion registered; baseline CRC computed and stored.
falseInvalid index, NULL addr, or zero size.
Note
The baseline CRC is computed immediately from the current memory contents. Call this after the region is fully initialized (e.g. after flash boot or table activation).

Definition at line 1625 of file svc.c.

References __cs_add_region(), and SVC_CS_ADD_REGION.

◆ cs_check_all()

uint8_t cs_check_all ( void  )

Scan all enabled regions and invoke the mismatch callback for any CRC failures.

Returns
Number of regions that failed the CRC check.
Note
Designed to be called periodically from a low-priority task (e.g. 1 Hz from the FDIR monitor loop).

Definition at line 1681 of file svc.c.

References __cs_check_all(), and SVC_CS_CHECK_ALL.

◆ cs_enable()

bool cs_enable ( uint8_t  idx,
bool  enabled 
)

Enable or disable scanning of a region.

Parameters
[in]idxRegion index.
[in]enabledTrue to enable, false to disable.
Return values
trueSuccess.
falseInvalid index.

Definition at line 1645 of file svc.c.

References __cs_enable(), and SVC_CS_ENABLE.

◆ cs_get_region()

bool cs_get_region ( uint8_t  idx,
cs_region_t out 
)

Read back a region's configuration.

Parameters
[in]idxRegion index.
[out]outDestination for the region descriptor.
Return values
trueSuccess.
falseInvalid index or out is NULL.

Definition at line 1697 of file svc.c.

References __cs_get_region(), and SVC_CS_GET_REGION.

◆ cs_init()

void cs_init ( void  )

Initialize the checksum monitor.

Clears all regions and sets the mismatch callback to NULL.

Definition at line 1603 of file svc.c.

References __cs_init(), and SVC_CS_INIT.

◆ cs_rebaseline()

bool cs_rebaseline ( uint8_t  idx)

Re-compute and store the baseline CRC for a region.

Parameters
[in]idxRegion index.
Return values
trueBaseline updated.
falseInvalid index or region not registered.
Note
Call after a legitimate write to a monitored region (e.g. table activation) to prevent false mismatch reports.

Definition at line 1664 of file svc.c.

References __cs_rebaseline(), and SVC_CS_REBASELINE.

◆ cs_region_count()

uint8_t cs_region_count ( void  )

Return the number of registered (non-empty) regions.

Definition at line 1716 of file svc.c.

References __cs_region_count(), and SVC_CS_REGION_COUNT.

◆ cs_set_callback()

void cs_set_callback ( cs_mismatch_fn  fn)

Register the mismatch callback.

Parameters
[in]fnFunction to call when a CRC mismatch is detected. Pass NULL to disable mismatch reporting.

Definition at line 1611 of file svc.c.

References __cs_set_callback(), and SVC_CS_SET_CALLBACK.

◆ enter_critical()

void enter_critical ( void  )

Enter critical section (disable scheduler)

Note
Supports nesting

Definition at line 478 of file svc.c.

References __enter_critical(), and SVC_ENTER_CRITICAL.

Referenced by __task_blocking_sleep().

◆ event_drain()

bool event_drain ( event_entry_t out_buf,
uint8_t  max_entries,
uint8_t *  num_drained 
)

Drain queued events into a caller-provided buffer.

Parameters
out_bufDestination array of event_entry_t.
max_entriesMaximum number of entries to copy.
num_drained[out] Number of entries actually copied.
Returns
true if at least one entry was copied; false if the ring was empty or out_buf was NULL.

Definition at line 1385 of file svc.c.

References __event_drain(), and SVC_EVENT_DRAIN.

◆ event_get_count()

uint32_t event_get_count ( void  )

Number of events currently buffered.

Definition at line 1408 of file svc.c.

References __event_get_count(), and SVC_EVENT_GET_COUNT.

◆ event_get_squelch()

event_severity_t event_get_squelch ( uint8_t  module_id)

Get the current squelch level for a given module.

Definition at line 1368 of file svc.c.

References __event_get_squelch(), and SVC_EVENT_GET_SQUELCH.

◆ event_init()

void event_init ( void  )

Initialize the event system.

Clears the ring buffer and resets every module's squelch level to EVENT_DEBUG (accept all).

Definition at line 1316 of file svc.c.

References __event_init(), and SVC_EVENT_INIT.

◆ event_set_squelch()

void event_set_squelch ( uint8_t  module_id,
event_severity_t  min_severity 
)

Set the minimum severity accepted for a given module.

Events below the threshold are silently dropped at emission time.

Definition at line 1352 of file svc.c.

References __event_set_squelch(), and SVC_EVENT_SET_SQUELCH.

◆ exit_critical()

void exit_critical ( void  )

Exit critical section (re-enable scheduler if outermost)

Definition at line 489 of file svc.c.

References __exit_critical(), and SVC_EXIT_CRITICAL.

Referenced by __task_blocking_sleep().

◆ kernel_get_data()

uint32_t * kernel_get_data ( uint8_t  task_idx)

Get data pointer for task index.

Get data pointer for task index (internal use)

Definition at line 734 of file svc.c.

References __kernel_get_data(), and SVC_KERNEL_GET_DATA.

◆ kernel_get_stack()

uint32_t * kernel_get_stack ( uint8_t  task_idx)

Get stack pointer for task index.

Get stack pointer for task index (internal use)

Definition at line 714 of file svc.c.

References __kernel_get_stack(), and SVC_KERNEL_GET_STACK.

◆ kernel_protected_data()

void * kernel_protected_data ( uint16_t  num_words)

Allocate protected data words for current task.

Definition at line 754 of file svc.c.

References __kernel_protected_data(), and SVC_KERNEL_PROTECTED_DATA.

◆ os_event()

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.

Parameters
module_idSource module identifier (0..EVENT_MOD_MAX-1).
severityEvent severity level.
event_idApplication-defined event identifier.
payloadOptional payload bytes (may be NULL).
payload_lenPayload length in bytes (truncated to 12).
Note
Never blocks. When the ring is full the oldest entry is implicitly overwritten.

Definition at line 1331 of file svc.c.

References __os_event(), and SVC_OS_EVENT.

◆ os_exit_task()

void os_exit_task ( void  )

Exit current task.

Terminate current task normally.

Definition at line 636 of file svc.c.

References __os_exit_task(), and SVC_OS_EXIT_TASK.

Referenced by __os_restart_task(), and os_create_task().

◆ os_get_current_task_name()

const char * os_get_current_task_name ( void  )

Get name of currently executing task.

Returns
Task name string or "unknown"

Definition at line 575 of file svc.c.

References __os_get_current_task_name(), and SVC_OS_GET_CURRENT_TASK_NAME.

Referenced by os_heartbeat_task().

◆ os_get_num_created_tasks()

uint8_t os_get_num_created_tasks ( void  )

Get number of created tasks (read num_created_tasks in privileged mode)

Get number of created tasks (safe from unprivileged mode)

Returns
Number of tasks registered with os_register_task()
Note
Safe to call from unprivileged mode once DTCM is priv-only

Definition at line 1145 of file svc.c.

References __os_get_num_created_tasks(), and SVC_GET_NUM_TASKS.

Referenced by display_init().

◆ os_get_running_task_count()

uint8_t os_get_running_task_count ( void  )

Get number of active tasks.

Returns
Count of tasks in RUNNING/READY/BLOCKED state

Definition at line 594 of file svc.c.

References __os_get_running_task_count(), and SVC_OS_GET_RUNNING_TASK_COUNT.

◆ os_get_stack_watermark()

uint32_t os_get_stack_watermark ( uint8_t  task_idx)

Get a task's stack high-water mark.

Get a task's stack high-water mark (minimum free words).

Definition at line 1225 of file svc.c.

References __os_get_stack_watermark(), and SVC_GET_STACK_WATERMARK.

◆ os_get_task_dispatch_count()

uint32_t os_get_task_dispatch_count ( uint8_t  task_idx)

Get a task's dispatch count.

Get a task's dispatch count (times scheduled to run).

Definition at line 1205 of file svc.c.

References __os_get_task_dispatch_count(), and SVC_GET_TASK_DISPATCH_COUNT.

◆ os_get_task_name()

const char * os_get_task_name ( uint8_t  task_idx)

Get task name by index (read from task_list in privileged mode)

Get task name by index (safe from unprivileged mode)

Parameters
task_idxTask index (0 to num_created_tasks-1)
Returns
Pointer to task name string, or NULL if invalid index
Note
Safe to call from unprivileged mode once DTCM is priv-only

Definition at line 1123 of file svc.c.

References __os_get_task_name(), and SVC_GET_TASK_NAME.

Referenced by display_init().

◆ os_get_task_state()

icarus_task_state_t os_get_task_state ( uint8_t  task_idx)

Get a task's current state.

Get a task's current state (safe from unprivileged mode).

Definition at line 1185 of file svc.c.

References __os_get_task_state(), and SVC_GET_TASK_STATE.

◆ os_get_task_ticks_remaining()

uint32_t os_get_task_ticks_remaining ( void  )

Get remaining ticks in current time slice.

Returns
Ticks remaining before preemption

Definition at line 613 of file svc.c.

References __os_get_task_ticks_remaining(), and SVC_OS_GET_TASK_TICKS_REMAINING.

◆ os_get_tick_count()

uint32_t os_get_tick_count ( void  )

Get current system tick count.

Returns
Ticks since os_start()
Note
Placed in ITCM for zero wait-state execution

Definition at line 556 of file svc.c.

References __os_get_tick_count(), and SVC_OS_GET_TICK_COUNT.

Referenced by __task_busy_wait().

◆ os_init()

void os_init ( void  )

Initialize the ICARUS kernel.

Must be called before any other kernel function. Initializes:

  • Task pool and task list
  • Semaphore pool
  • Message pipe pool
  • System tasks (idle, heartbeat)
Precondition
HAL must be initialized (hal_init() called)
Postcondition
Kernel is ready for task registration

Definition at line 501 of file svc.c.

References __os_init().

Referenced by main().

◆ os_is_running()

uint8_t os_is_running ( void  )

Check if OS is running (safe from unprivileged mode)

Returns
1 if OS is running, 0 otherwise
Note
Safe to call from unprivileged mode once DTCM is priv-only

Definition at line 1166 of file svc.c.

References __os_is_running(), and SVC_OS_IS_RUNNING.

Referenced by os_heartbeat_task().

◆ os_kill_process()

void os_kill_process ( uint8_t  task_index)

Kill a task by index.

Terminate another task by index.

Definition at line 676 of file svc.c.

References __os_kill_process(), and SVC_OS_KILL_PROCESS.

◆ os_register_task()

void os_register_task ( void(*)(void)  function,
const char *  name 
)

Register a task with the scheduler.

Register a task with automatic stack allocation.

Definition at line 658 of file svc.c.

References __os_register_task(), and SVC_OS_REGISTER_TASK.

◆ os_restart_task()

void os_restart_task ( uint8_t  task_index)

Restart a killed/finished task in-place (cold restart)

Restart a killed or finished task (cold restart from entry point).

Definition at line 693 of file svc.c.

References __os_restart_task(), and SVC_OS_RESTART_TASK.

◆ os_start()

void os_start ( void  )

Start the ICARUS scheduler.

Begins task execution. This function does not return.

Precondition
os_init() must have been called
At least one task must be registered
Warning
This function never returns!

Definition at line 502 of file svc.c.

References __os_start().

Referenced by main().

◆ os_task_suicide()

void os_task_suicide ( void  )

Terminate current task (suicide)

Definition at line 647 of file svc.c.

References __os_task_suicide(), and SVC_OS_TASK_SUICIDE.

◆ os_update_stack_watermark()

void os_update_stack_watermark ( uint8_t  task_idx)

Scan and update a task's stack watermark.

Scan a task's stack for the sentinel pattern and update the watermark field in the TCB.

Definition at line 1245 of file svc.c.

References __os_update_stack_watermark(), and SVC_UPDATE_STACK_WATERMARK.

◆ os_yield()

void os_yield ( void  )

Voluntarily yield CPU to scheduler.

Note
Placed in ITCM for zero wait-state execution

Definition at line 511 of file svc.c.

References __os_yield(), and SVC_OS_YIELD.

Referenced by os_idle_task().

◆ pipe_can_dequeue()

bool pipe_can_dequeue ( uint8_t  pipe_idx,
uint8_t  message_bytes 
)

Check if pipe has message_bytes available (count >= bytes && engaged)

Check if pipe has data available (SVC call gate)

Note
Runs in privileged mode — safe once DTCM is priv-only

Definition at line 1011 of file svc.c.

References __pipe_can_dequeue(), and SVC_PIPE_CAN_DEQUEUE.

Referenced by __pipe_dequeue().

◆ pipe_can_enqueue()

bool pipe_can_enqueue ( uint8_t  pipe_idx,
uint8_t  message_bytes 
)

Check if pipe has room for message_bytes (free >= bytes && engaged)

Check if pipe can accept data (SVC call gate)

Note
Runs in privileged mode — safe once DTCM is priv-only

Definition at line 988 of file svc.c.

References __pipe_can_enqueue(), and SVC_PIPE_CAN_ENQUEUE.

Referenced by __pipe_enqueue().

◆ pipe_dequeue()

bool pipe_dequeue ( uint8_t  pipe_idx,
uint8_t *  message,
uint8_t  message_bytes 
)

Dequeue bytes from pipe — spin-wait in thread mode.

Dequeue bytes from pipe.

Definition at line 894 of file svc.c.

References __pipe_dequeue().

◆ pipe_enqueue()

bool pipe_enqueue ( uint8_t  pipe_idx,
uint8_t *  message,
uint8_t  message_bytes 
)

Enqueue bytes to pipe — spin-wait in thread mode.

Enqueue bytes to pipe.

Definition at line 887 of file svc.c.

References __pipe_enqueue().

◆ pipe_get_count()

uint16_t pipe_get_count ( uint8_t  pipe_idx)

Get current byte count in pipe.

Parameters
pipe_idxPipe index
Returns
Current count, or 0 if invalid

Definition at line 901 of file svc.c.

References __pipe_get_count(), and SVC_PIPE_GET_COUNT.

◆ pipe_get_max_count()

uint16_t pipe_get_max_count ( uint8_t  pipe_idx)

Get pipe capacity.

Parameters
pipe_idxPipe index
Returns
Maximum capacity, or 0 if invalid

Definition at line 921 of file svc.c.

References __pipe_get_max_count(), and SVC_PIPE_GET_MAX_COUNT.

◆ pipe_init()

bool pipe_init ( uint8_t  pipe_idx,
uint16_t  pipe_capacity_bytes 
)

Initialize a message pipe.

Parameters
pipe_idxPipe index (0 to ICARUS_MAX_MESSAGE_QUEUES-1)
pipe_capacity_bytesMaximum bytes the pipe can hold
Returns
true on success, false on error

Definition at line 865 of file svc.c.

References __pipe_init(), and SVC_PIPE_INIT.

◆ pipe_read_bytes()

void pipe_read_bytes ( uint8_t  pipe_idx,
uint8_t *  message,
uint8_t  message_bytes 
)

Read bytes from pipe buffer atomically in privileged mode.

Read bytes from pipe (SVC call gate)

Note
Called after pipe_can_dequeue() spin loop exits

Definition at line 1095 of file svc.c.

References __pipe_read_bytes(), and SVC_PIPE_READ_BYTES.

Referenced by __pipe_dequeue().

◆ pipe_write_bytes()

void pipe_write_bytes ( uint8_t  pipe_idx,
uint8_t *  message,
uint8_t  message_bytes 
)

Write bytes to pipe buffer atomically in privileged mode.

Write bytes to pipe (SVC call gate)

Note
Called after pipe_can_enqueue() spin loop exits

Definition at line 1074 of file svc.c.

References __pipe_write_bytes(), and SVC_PIPE_WRITE_BYTES.

Referenced by __pipe_enqueue().

◆ sem_can_consume()

bool sem_can_consume ( uint8_t  semaphore_idx)

Check if semaphore can be consumed (count > 0 && engaged)

Check if semaphore can be consumed (SVC call gate)

Note
Runs in privileged mode — safe once DTCM is priv-only

Definition at line 967 of file svc.c.

References __sem_can_consume(), and SVC_SEM_CAN_CONSUME.

Referenced by __semaphore_consume(), and __semaphore_consume_timeout().

◆ sem_can_feed()

bool sem_can_feed ( uint8_t  semaphore_idx)

Check if semaphore can accept a feed (count < max && engaged)

Check if semaphore can accept a feed (SVC call gate)

Note
Runs in privileged mode — safe once DTCM is priv-only

Definition at line 946 of file svc.c.

References __sem_can_feed(), and SVC_SEM_CAN_FEED.

Referenced by __semaphore_feed().

◆ sem_decrement()

void sem_decrement ( uint8_t  semaphore_idx)

Decrement semaphore count atomically in privileged mode.

Decrement semaphore count (SVC call gate)

Note
Called after sem_can_consume() spin loop exits

Definition at line 1056 of file svc.c.

References __sem_decrement(), and SVC_SEM_DECREMENT.

Referenced by __semaphore_consume(), and __semaphore_consume_timeout().

◆ sem_increment()

void sem_increment ( uint8_t  semaphore_idx)

Increment semaphore count atomically in privileged mode.

Increment semaphore count (SVC call gate)

Note
Called after sem_can_feed() spin loop exits

Definition at line 1038 of file svc.c.

References __sem_increment(), and SVC_SEM_INCREMENT.

Referenced by __semaphore_feed().

◆ semaphore_consume()

bool semaphore_consume ( uint8_t  semaphore_idx)

Decrement semaphore count — spin-wait in thread mode.

Decrement semaphore count (P operation / wait)

Definition at line 807 of file svc.c.

References __semaphore_consume().

◆ semaphore_consume_timeout()

bool semaphore_consume_timeout ( uint8_t  semaphore_idx,
uint32_t  max_ticks 
)

Decrement semaphore count with timeout.

Decrement semaphore count with timeout (timed P / wait).

Definition at line 814 of file svc.c.

References __semaphore_consume_timeout().

◆ semaphore_feed()

bool semaphore_feed ( uint8_t  semaphore_idx)

Increment semaphore count — spin-wait in thread mode.

Increment semaphore count (V operation / signal)

Definition at line 800 of file svc.c.

References __semaphore_feed().

◆ semaphore_get_count()

uint32_t semaphore_get_count ( uint8_t  semaphore_idx)

Get current semaphore count.

Parameters
semaphore_idxSemaphore index
Returns
Current count, or 0 if invalid

Definition at line 821 of file svc.c.

References __semaphore_get_count(), and SVC_SEMAPHORE_GET_COUNT.

◆ semaphore_get_max_count()

uint32_t semaphore_get_max_count ( uint8_t  semaphore_idx)

Get semaphore maximum count.

Parameters
semaphore_idxSemaphore index
Returns
Maximum count, or 0 if invalid

Definition at line 841 of file svc.c.

References __semaphore_get_max_count(), and SVC_SEMAPHORE_GET_MAX_COUNT.

◆ semaphore_init()

bool semaphore_init ( uint8_t  semaphore_idx,
uint32_t  semaphore_count 
)

Initialize a counting semaphore.

Parameters
semaphore_idxSemaphore index (0 to ICARUS_MAX_SEMAPHORES-1)
semaphore_countInitial and maximum count
Returns
true on success, false on error

Definition at line 778 of file svc.c.

References __semaphore_init(), and SVC_SEMAPHORE_INIT.

◆ SVC_Handler_C()

void SVC_Handler_C ( uint32_t *  stack_frame)

C-level SVC dispatcher called from SVC_Handler assembly trampoline.

C-level SVC dispatcher called from SVC_Handler assembly.

Parameters
stack_framePointer to exception stack frame (R0-R3, R12, LR, PC, xPSR)
Note
SVC number is extracted from the SVC instruction encoding: The SVC instruction is at [PC - 2], and the immediate is the low byte.

Definition at line 50 of file svc.c.

References __cdc_rx_available(), __cdc_rx_init(), __cdc_rx_read_byte(), __cs_add_region(), __cs_check_all(), __cs_enable(), __cs_get_region(), __cs_init(), __cs_rebaseline(), __cs_region_count(), __cs_set_callback(), __enter_critical(), __event_drain(), __event_get_count(), __event_get_squelch(), __event_init(), __event_set_squelch(), __exit_critical(), __fs_create(), __fs_delete(), __fs_init(), __fs_list(), __fs_open(), __fs_read(), __fs_stats(), __fs_write(), __kernel_get_data(), __kernel_get_stack(), __kernel_protected_data(), __os_event(), __os_exit_task(), __os_get_current_task_name(), __os_get_num_created_tasks(), __os_get_running_task_count(), __os_get_stack_watermark(), __os_get_task_dispatch_count(), __os_get_task_name(), __os_get_task_state(), __os_get_task_ticks_remaining(), __os_get_tick_count(), __os_is_running(), __os_kill_process(), __os_register_task(), __os_restart_task(), __os_task_suicide(), __os_update_stack_watermark(), __os_yield(), __pipe_can_dequeue(), __pipe_can_enqueue(), __pipe_get_count(), __pipe_get_max_count(), __pipe_init(), __pipe_read_bytes(), __pipe_write_bytes(), __sb_init(), __sb_publish(), __sb_route_count(), __sb_subscribe(), __sb_subscriber_count(), __sb_unsubscribe(), __sem_can_consume(), __sem_can_feed(), __sem_decrement(), __sem_increment(), __semaphore_consume_timeout(), __semaphore_get_count(), __semaphore_get_max_count(), __semaphore_init(), __task_active_sleep(), __tbl_activate_commit(), __tbl_activate_prepare(), __tbl_count(), __tbl_dump(), __tbl_get_descriptor(), __tbl_init(), __tbl_load(), __tbl_register(), BSP_RAM_D3_BASE, BSP_RAM_D3_SIZE, SVC_BKPRAM_WRITE, SVC_CDC_RX_AVAILABLE, SVC_CDC_RX_INIT, SVC_CDC_RX_READ_BYTE, SVC_CS_ADD_REGION, SVC_CS_CHECK_ALL, SVC_CS_ENABLE, SVC_CS_GET_REGION, SVC_CS_INIT, SVC_CS_REBASELINE, SVC_CS_REGION_COUNT, SVC_CS_SET_CALLBACK, SVC_ENTER_CRITICAL, SVC_EVENT_DRAIN, SVC_EVENT_GET_COUNT, SVC_EVENT_GET_SQUELCH, SVC_EVENT_INIT, SVC_EVENT_SET_SQUELCH, SVC_EXIT_CRITICAL, SVC_FS_CREATE, SVC_FS_DELETE, SVC_FS_INIT, SVC_FS_LIST, SVC_FS_OPEN, SVC_FS_READ, SVC_FS_STATS, SVC_FS_WRITE, SVC_GET_NUM_TASKS, SVC_GET_STACK_WATERMARK, SVC_GET_TASK_DISPATCH_COUNT, SVC_GET_TASK_NAME, SVC_GET_TASK_STATE, SVC_KERNEL_GET_DATA, SVC_KERNEL_GET_STACK, SVC_KERNEL_PROTECTED_DATA, SVC_OS_EVENT, SVC_OS_EXIT_TASK, SVC_OS_GET_CURRENT_TASK_NAME, SVC_OS_GET_RUNNING_TASK_COUNT, SVC_OS_GET_TASK_TICKS_REMAINING, SVC_OS_GET_TICK_COUNT, SVC_OS_IS_RUNNING, SVC_OS_KILL_PROCESS, SVC_OS_REGISTER_TASK, SVC_OS_RESTART_TASK, SVC_OS_TASK_SUICIDE, SVC_OS_YIELD, SVC_PIPE_CAN_DEQUEUE, SVC_PIPE_CAN_ENQUEUE, SVC_PIPE_DEQUEUE, SVC_PIPE_ENQUEUE, SVC_PIPE_GET_COUNT, SVC_PIPE_GET_MAX_COUNT, SVC_PIPE_INIT, SVC_PIPE_READ_BYTES, SVC_PIPE_WRITE_BYTES, SVC_SB_INIT, SVC_SB_PUBLISH, SVC_SB_ROUTE_COUNT, SVC_SB_SUBSCRIBE, SVC_SB_SUBSCRIBER_COUNT, SVC_SB_UNSUBSCRIBE, SVC_SEM_CAN_CONSUME, SVC_SEM_CAN_FEED, SVC_SEM_DECREMENT, SVC_SEM_INCREMENT, SVC_SEMAPHORE_CONSUME, SVC_SEMAPHORE_CONSUME_TIMEOUT, SVC_SEMAPHORE_FEED, SVC_SEMAPHORE_GET_COUNT, SVC_SEMAPHORE_GET_MAX_COUNT, SVC_SEMAPHORE_INIT, SVC_TASK_ACTIVE_SLEEP, SVC_TASK_BLOCKING_SLEEP, SVC_TASK_BUSY_WAIT, SVC_TBL_ACTIVATE_COMMIT, SVC_TBL_ACTIVATE_PREPARE, SVC_TBL_COUNT, SVC_TBL_DUMP, SVC_TBL_GET_DESCRIPTOR, SVC_TBL_INIT, SVC_TBL_LOAD, SVC_TBL_REGISTER, and SVC_UPDATE_STACK_WATERMARK.

◆ task_active_sleep()

uint32_t task_active_sleep ( uint32_t  ticks)

Sleep for specified ticks (cooperative, via SVC)

Sleep for specified ticks (cooperative)

Definition at line 522 of file svc.c.

References __task_active_sleep(), and SVC_TASK_ACTIVE_SLEEP.

Referenced by __pipe_dequeue(), __pipe_enqueue(), __semaphore_consume(), __semaphore_consume_timeout(), __semaphore_feed(), CDC_Write(), LED_Blink(), and os_heartbeat_task().

◆ task_blocking_sleep()

uint32_t task_blocking_sleep ( uint32_t  ticks)

Blocking sleep — spin-wait in thread mode (cannot run in SVC handler)

Sleep with scheduler disabled (blocking)

Definition at line 542 of file svc.c.

References __task_blocking_sleep().

Referenced by __io_putchar().

◆ task_busy_wait()

uint32_t task_busy_wait ( uint32_t  ticks)

Busy-wait for specified ticks — spin in thread mode.

Busy-wait for specified ticks.

Definition at line 549 of file svc.c.

References __task_busy_wait().

Referenced by __task_blocking_sleep().

◆ tbl_activate()

bool tbl_activate ( tbl_id_t  id)

Activate a staged table after CRC validation.

Steps:

  1. Verify staged_len == descriptor.size.
  2. Verify staged_schema_crc == descriptor.schema_crc.
  3. Recompute CRC16-CCITT over staged data; verify against stored crc.
  4. Call descriptor.activate(staged, size).
  5. On success, copy staging → active buffer.
Returns
true on success; false on any validation failure or activate callback returning false.

< Maximum bytes per table buffer

Definition at line 1481 of file svc.c.

References __tbl_activate_commit(), __tbl_activate_prepare(), SVC_TBL_ACTIVATE_COMMIT, SVC_TBL_ACTIVATE_PREPARE, and TBL_MAX_SIZE.

◆ tbl_count()

uint8_t tbl_count ( void  )

Return the number of registered tables.

Definition at line 1583 of file svc.c.

References __tbl_count(), and SVC_TBL_COUNT.

◆ tbl_dump()

int16_t tbl_dump ( tbl_id_t  id,
uint8_t *  out,
uint16_t  max 
)

Copy the active table bytes into out.

Returns
Number of bytes copied, or -1 on error (unknown id / no active).

Definition at line 1546 of file svc.c.

References __tbl_dump(), and SVC_TBL_DUMP.

◆ tbl_get_descriptor()

const tbl_descriptor_t * tbl_get_descriptor ( tbl_id_t  id)

Look up a registered descriptor by id.

Returns
Pointer to descriptor, or NULL if not found.

Definition at line 1566 of file svc.c.

References __tbl_get_descriptor(), and SVC_TBL_GET_DESCRIPTOR.

◆ tbl_init()

void tbl_init ( void  )

Initialise the table registry.

Must be called before any other table function.

Definition at line 1428 of file svc.c.

References __tbl_init(), and SVC_TBL_INIT.

◆ tbl_load()

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.

Supports chunked loads: call repeatedly with sequential offsets. The first call clears the staging buffer; subsequent calls append. Once a full descriptor-size load completes the data CRC16 is computed and the staging buffer is marked valid.

Returns
true on success; false on unknown id or out-of-bounds write.

Definition at line 1453 of file svc.c.

References __tbl_load(), and SVC_TBL_LOAD.

◆ tbl_register()

bool tbl_register ( const tbl_descriptor_t desc)

Register a table descriptor.

Returns
true on success; false if registry is full or id is duplicate.

Definition at line 1436 of file svc.c.

References __tbl_register(), and SVC_TBL_REGISTER.