Skip to content

Core & Utility Modules

SyntropicOS provides header-only foundation macros, ISR-safe data structures, binary structure packing, and fixed-point math utilities.


Technical Specifications

Feature Specification
RAM Cost Zero heap allocation. All structures (SYN_RingBuf, SYN_Stream, SYN_PingPong) are caller-owned.
ISR Safety SPSC (Single-Producer / Single-Consumer) ring buffers and streams are lock-free and ISR-safe.
Asserts Runtime checks strippable in production via #define SYN_DISABLE_ASSERT.

1. Cooperative Byte Stream (util/syn_stream.h)

SYN_Stream wraps an SPSC ring buffer with protothread-aware readability conditions. It supports 3 operational modes: - Default Mode: De-blocks when any byte is available. - Threshold Mode: De-blocks when $\ge N$ bytes arrive (packet-oriented protocols). - Delimiter Mode: De-blocks when a specific delimiter byte (e.g. \n or 0x00) arrives.

Stream Data Flow

flowchart LR
    ISR["UART ISR / DMA"] -- syn_stream_put() --> RingBuffer["Lock-Free Ring Buffer"]
    RingBuffer -- PT_STREAM_WAIT() --> Protothread["Protothread Task"]
    Protothread -- Read Line / Frame --> Processing["Process Message"]

Complete Code Example (Line-Oriented Serial Stream)

#include <syntropic/util/syn_stream.h>
#include <syntropic/pt/syn_pt.h>

static uint8_t raw_buffer[128];
static SYN_Stream rx_stream;

void stream_setup(void) {
    syn_stream_init(&rx_stream, raw_buffer, sizeof(raw_buffer));

    // De-block task only when a newline '\n' character is received
    syn_stream_set_delimiter(&rx_stream, '\n');
}

// ISR Producer: Lock-free put
void USART1_IRQHandler(void) {
    uint8_t byte = (uint8_t)USART1->DR;
    syn_stream_put(&rx_stream, byte);
}

// Consumer Protothread: Reads complete lines
SYN_PT_Status line_consumer_task(SYN_PT *pt, SYN_Task *task) {
    static uint8_t line_buf[64];
    static size_t bytes_read;

    PT_BEGIN(pt);
    for (;;) {
        // Yields CPU until '\n' delimiter arrives in rx_stream
        PT_STREAM_WAIT(pt, &rx_stream);

        bytes_read = syn_stream_read_line(&rx_stream, line_buf, sizeof(line_buf));
        process_cmd((char*)line_buf, bytes_read);
    }
    PT_END(pt);
}

2. Binary Serialization & Structure Packing (util/syn_pack.h)

Provides endianness-independent serialization (pack_u16_be, pack_u32_le, etc.) to prevent unaligned memory access traps on Cortex-M0/M3 microcontrollers.

#include <syntropic/util/syn_pack.h>

void serialize_packet(uint8_t *dest, uint16_t id, uint32_t val) {
    size_t offset = 0;
    offset += syn_pack_u16_be(&dest[offset], id);
    offset += syn_pack_u32_be(&dest[offset], val);
}