# Overview

This page gives a high-level overview of the shared libraries described so far, what each one is for, how they fit together, and how they are meant to be used in the codebase.

<p class="callout warning"><span style="white-space: pre-wrap;">The goal is not to replace the detailed documentation for each module. </span></p>

These libraries are all small, but they are not random utilities. Together they form a set of shared infrastructure for building embedded application code that is:

- more consistent
- easier to reason about
- easier to extend
- less likely to devolve into every subsystem inventing its own incompatible habits

Which, naturally, is what happens the moment shared infrastructure is missing.

# Design philosophy of the shared library layer

Before going into the individual libraries, it helps to understand the common design pattern behind them.

<p class="callout info"><span style="white-space: pre-wrap;">These libraries are not trying to be a giant framework. They are trying to provide </span>**targeted, reusable building blocks**<span style="white-space: pre-wrap;"> for recurring embedded problems:</span></p>

- reporting success and failure consistently
- logging runtime behavior in a uniform way
- storing shared variable-sized state in a controlled memory region
- scheduling work by discrete priority
- decoding and dispatching incoming protocol messages to the correct subsystem

The philosophy behind them is mostly this:

### Centralize recurring patterns

If every module invents its own result codes, logging style, queueing scheme, and packet dispatching logic, the system becomes harder to maintain very quickly.

These libraries centralize those patterns so the rest of the application can focus on subsystem logic instead of re-solving the same infrastructure problems over and over.

### Keep APIs small and practical

The libraries generally expose narrow APIs with very specific purposes.

### Prefer explicit ownership and caller-provided resources

Several of these modules rely on the caller to provide memory, configuration, or queue storage.

<p class="callout info">That is not accidental. It keeps ownership visible and lets the application control where resources live.</p>

### Separate policy from mechanism where useful

A few libraries expose a generic interface while allowing board-specific or implementation-specific backends.

Examples:

- the logging API is conceptually transport-agnostic even though the current implementation uses UART
- the packet dispatcher API is conceptually about routing decoded packets even though the current implementation uses FreeRTOS queues and tasks
- the KV pool lets callers decide where metadata and storage memory live

### Be honest about constraints

These are embedded libraries and we are not that good at coding.

A lot of their usefulness depends on respecting their assumptions:

- some are single-consumer by design
- some are not ISR-safe
- some assume static lifetime of configuration objects
- some have concurrency limitations that matter a lot

<p class="callout success">That is why documentation matters here. These modules are only “simple” if you already know their rules.</p>

# How the libraries fit together

At a system level, the libraries can be thought of as falling into a few categories.

### Core utility infrastructure

These are foundational and broadly reusable:

- `<span class="editor-theme-code">result</span>`
- `<span class="editor-theme-code">logging</span>`

<p class="callout info">They define how modules report status and how the system reports runtime information.</p>

### Storage and local scheduling infrastructure

These are reusable building blocks for internal system behavior:

- `<span class="editor-theme-code">bucketed_pqueue</span>`
- `<span class="editor-theme-code">kv_pool</span>`

They solve internal resource management and work scheduling problems.

### Communication and protocol infrastructure

These are more application-flow oriented:

- packet dispatcher / decoding task
- packet dispatcher macros

<p class="callout info">They take incoming protocol messages and move them to the right processing logic.</p>

A good mental model is:

- `<span class="editor-theme-code">result</span>`<span style="white-space: pre-wrap;"> defines how functions communicate success and failure</span>
- `<span class="editor-theme-code">logging</span>`<span style="white-space: pre-wrap;"> defines how the system communicates information outward</span>
- `<span class="editor-theme-code">bucketed_pqueue</span>`<span style="white-space: pre-wrap;"> defines how work can be prioritized internally</span>
- `<span class="editor-theme-code">kv_pool</span>`<span style="white-space: pre-wrap;"> defines how variable-sized keyed data can be stored safely in managed memory</span>
- the dispatcher layer defines how external messages enter the application and get routed to the correct handlers