Columna is a reusable embedded software foundation for regulated medical devices. It provides the architecture, the infrastructure services and the verification and documentation record, so the team's work goes into what makes your device yours.

What Columna gives you Delivery options

Weeks, not months

Start with the foundation already built, and put the team on what really matters.

Any silicon

Hardware agnostic by design, so a shortage or an end-of-life notice never becomes a redesign.

Audit-ready

Developed from the ground up to IEC 62304 Class C, with a record of everything. No SOUP justification.

THE PROBLEM

Most of your budget and time goes where the value isn't.

In embedded development, only a fraction of the effort goes into what makes the product yours. The rest disappears into building the low-level foundation, debugging it, and writing the documentation the auditor will ask for.

Months before the device does anything

The first phase goes into buses, drivers and board bring-up. The function the device is built around waits behind work no user will ever see, and no investor will ever pay a premium for.

Budget spent before the first prototype

Your most expensive software time goes into the low-level layer. For a first product that is runway; for a company with several products it is the same invoice arriving again.

A late foundation delays the whole development

Every week added before a working prototype pushes verification, submission and market entry by the same week, and burns cash while it does.

Debugging without visibility

With no logger, no live terminal and no structured error records, every question about a failure costs another build, another mount and dismount of the device, another day.

Bugs surface where they cost most

Low-level code that was never tested in isolation fails during EMC, integration or in the field, exactly where a fix means re-verification, re-documentation and a slipped date.

The regulatory record written afterwards

Requirements, design records and test evidence for code that already exists get written under submission pressure. It is a frequent source of findings, and it repeats with every product you add.

THE LIBRARY

Everything below your application, already built.

Columna is the layer below your application: drivers, interfaces, runtime tooling and error management, developed under IEC 62304 with the documentation already written. It is designed for constrained memory: each capability is enabled or disabled at compile time, so a device only carries what it actually uses.

A growing catalogue of drivers

The hardware your device already contains, already written and verified: LEDs, ADCs, DACs, sensors, chargers, battery gauges, touch panels, displays, network PHYs, external memories and more.

LED ADC DAC SENSORS CHARGER BATTERY TOUCH PANEL PHY

Interfaces that decouple manufacturer SDKs

Your software calls Columna interfaces, never a vendor SDK. A port exists per silicon family, so choosing or changing supplier stays a business decision instead of a rewrite.

ST RENESAS TI NXP NORDIC MICROCHIP

Structure for your application layer

RTOS ports and a formal state-machine engine give your team a frame to build in: states, events and transitions declared once, in clean and modular code. No more switch statements that grow with every feature.

THREADX FREERTOS BARE-METAL FSM ENGINE

A CLI and a Logger in every build

Talk to the software while it runs: inspect tasks and memory usage, read and write any device through its own driver, scan a bus for what is answering. Alongside it, a levelled Logger traces what the software is doing, readable line by line in development and compiled out in production.

UART RTT TCP SYSPROC SYSDEV LOGGER

Error management, at every moment

Error management comes built into every component, so your team never writes it: what failed, where and when is captured on its own and kept queryable by component, severity or time. It can be exported as JSON, so a failure is caught the same way on the bench and in the field.

PER COMPONENT QUERYABLE JSON EXPORT

IEC 62304 development, documentation included

Class C from the start, MISRA-C as the coding standard, requirement-to-test traceability throughout. Every component ships with its own record, so it enters your device file as developed software instead of SOUP you have to justify. We lay the regulatory base layer; your team writes the device-level documentation on top of it.

CLASS C MISRA-C SRS SDS TRACEABILITY V&V FMEA SBOM

SIDE BY SIDE

The same project, with and without Columna.

Plug in Columna so your team focuses on the clinical function nobody else can write for you.

Without Columna

Start from the ground, on every project.

  • Time, budget and schedule risk go into reading one more datasheet just to get the minimum performance out of a driver. Self-test, health counters, lifecycle and diagnostics are extra work nobody scheduled.
  • Your team starts from vendor examples that were written to demonstrate a chip capability, not to go into production.
  • Software is tied to one chip vendor, so a shortage or an end-of-life part becomes a rewrite. With no layered architecture and a mesh of includes, unit testing is not even possible.
  • Testing waits on hardware and depends on it, so nothing runs in parallel and the first defects appear on the bench.
  • Debugging means adding print statements and rebuilding the software for every test you want to run.

With Columna

Start with a suite of components that pushes your development forward.

  • Every driver arrives with lifecycle, self-test, telemetry and error reporting already built around its core function.
  • You get the full library of every component and use only the parts your device needs. Freedom, not a fixed bundle.
  • Silicon stops being a risk on your roadmap. The application is agnostic by design, so a shortage, a price change or a redesign becomes a configuration decision instead of a rewrite.
  • Stop worrying about what happened at the EMC test. Ask the device and know instantly, by component, what failed, when and how.
  • Everything is unit tested with a TDD methodology and emulators, before a board exists.
  • Debugging is easier than ever, with an advanced logger, a live CLI connection and error management already in the build.

REGULATORY

100% traceable, by design.

Columna is developed inside an ISO 13485 quality system, under a software lifecycle that follows IEC 62304 and targets Class C from the first line. Requirements, architecture, detailed design, verification and release records exist for every component and are versioned with the code they describe.

Traceability is maintained end to end: every requirement links to a design element, every design element to a test case, and every test case to a recorded pass for that release. MISRA-C is the coding standard, and static analysis, unit tests and coverage run in the release pipeline, not as a one-off exercise.

That record is what changes the software's regulatory status. Third-party code normally enters your file as SOUP, software of unknown provenance, and has to be justified with nothing behind it. Software that can be shown to have been developed under a compliant lifecycle is developed software: the strongest provenance a component can carry into a device file.

DOCUMENTATION PACKAGE
  • SRS / SDS per module, versioned with the code
  • Traceability matrix, requirement to design to test
  • V&V reports archived for every release
  • Software FMEA, failure characterisation per component
  • Safety manual and anomaly list, per component
  • Software architecture, interfaces, ports and dependencies described per module
  • Unit test suite and coverage reports, run on the host at every release
  • Configuration and release records, versions, build hashes and change history

Columna is a software component, not a medical device, and carries no CE mark of its own. We deliver the foundation, you build on top of it: the component record comes complete, and the device-level claims, hazard analysis and clinical evidence stay where they belong, with you.

DELIVERY

Delivery options and subscriptions

The engineering core is the same in every option. What changes is how much of it you receive, and what your regulatory submission can claim about it.

01

Binary

Compiled library for your MCU targets, plus a qualification kit: a runnable test suite you execute on your own hardware to verify the delivered binary.

Enters your device file with a verified binary and test evidence.

02

Binary + documentation

Adds the full Class C package: SRS, SDS, traceability matrix, V&V reports, software FMEA, safety manual with anomaly list, and an SBOM per release.

Enters as developed software, with the record behind it.

03

Custom or full development

Components adapted to your device, new components developed for it, or the complete software built by our team, all executed inside an ISO 13485 quality system with the design records delivered as part of the work.

Engineering by Perdigó Medical, scoped per project.

Subscriptions

Maintenance and compliance

Columna keeps growing: bug fixes, improvements, new versions and new components in development, with support for new MCUs as they arrive. The documentation package moves with it, revised for each release and for changes in the applicable standards, including per-release V&V reports, SBOM and anomaly list.

Support

Adds engineering support with agreed response times, and assistance during integration and board bring-up.

Licences are scoped by field of use. A licence sold for non-regulated products cannot be used in a regulated device without an upgrade.

Clients developing a device with Perdigó Medical receive the documentation package as part of the engagement.

Pricing on request · start a conversation.

Columna. in detail

Developed by engineers, for engineers: time spent where it counts, on well-written code that stays modular and scales with your product.

columna --in --detail — zsh

Written for constrained targets

Columna is plain C, with no C++, no runtime and no framework hiding under the API.

Nothing in it allocates. Each module tells you how many bytes it needs, you hand it that memory, and that is your footprint for the life of the product. There is no heap to fragment and nothing to run out of in the field.

It makes no assumptions about an operating system. Scheduling, locking and timing are reached the same way as any peripheral, so the same code runs bare metal or under an RTOS.

Opt-in

You list the modules you want and nothing else gets compiled, so unused functionality costs zero flash and zero RAM rather than relying on the linker to strip it.

Modules and ports are declared in a single configuration step that is checked before the first file compiles. Dependencies get resolved, ports are matched to their interfaces, config headers are verified. Enable a driver without its bus and the build stops right there and tells you why.

The port boundary

Every vendor HAL call in the system lives inside a port, and above that line there is no vendor code at all, so the whole library builds on a host machine and drivers can be unit tested with no board attached.

Which port gets built is controlled by CMake: one line names the port, and nothing above the boundary changes.

CMakeLists.txt: port selection
# select the ports for this target

set(MCU_I2C_PORT  "mcu_nxp_i2c")
set(LOGGER_PORT   "logger_threadx")

add_subdirectory(columna)
target_link_libraries(app PRIVATE columna_enabled)

RUNS ON THE DEVICE

interfaces abstract buses and peripherals +

i2c · spi · uart · gpio · timer · pwm

Underneath sit the ports, one per silicon vendor, plus the contracts that let modules plug into each other.

drivers functional building blocks +

adc · dac · sensors · panel · touch · charger · battery · phy · led

Hardware independent, testable on a host machine.

utilities leaf services +

logger · state machine engine

Services with no dependencies of their own.

middlewares subsystems that compose other modules +

HMI · networking · hardware access arbitration · managers

Built from interfaces, drivers and utilities, through the same contracts.

THE SUPPORT

config declare what you want +

One place to declare which modules and which ports you want.

build CMake orchestrator +

Validates the configuration and produces a single link target for the application.

test host, integration and system tests +

Unit tests on the host, integration tests mocked at the port boundary, system tests in emulation on CI and on real boards.

bsp reference boards +

For hardware-in-the-loop runs.

examples worked usage +

Worked usage for every component.

docs documentation +

Library-wide documentation, plus per-module docs next to the code.

scripts tooling +

Codegen, SBOM, MISRA checks and CI helpers.

Most driver libraries give you read and write. The rest you write yourself: version tracking, clean bring-up and shutdown, health checks, and some way to find out what failed.

In Columna that comes with the driver. Every device is the same stack of capabilities over its core logic.

PER INSTANCE

Identity & metadata

Version, build hash and spec reference, queryable at runtime through sysProc. The traceability record, live in the binary.

Lifecycle & power

Activate, deactivate, kill, low-power. Driven by a formal state machine, so illegal transitions are impossible by construction.

Self-test / POST

Startup and on-demand health checks. Pass or fail feeds the error log.

Telemetry & health

Uptime, retry and error counters per component.

Fault-injection hooks

Force a component into an error state to prove recovery paths under Class C verification. Development builds only, compiled out of production.

SHARED SERVICES

sysProc & sysDev

The diagnostics terminal: inspect and operate registered components at runtime. See runtime services.

HW server

One sleeping task per bus arbitrates every peripheral sharing it, through kernel queues and mutexes. Thread safety is a property of the bus, not reinvented per driver.

Error management

Structured fault records in tiered storage, queryable by component, severity and time.

Logger

Levelled, human-readable output with a port-selected backend. Compiled out in production.

Component field update

Parameters, calibration tables and feature flags changed in the field without reflashing, as versioned, CRC-protected data. The code stays fixed and validated; only qualified data changes.

driver architecture
APPLICATION DRIVER Identity Lifecycle & power Self-test Telemetry Fault injection CORE LOGIC — read / write the part every driver already has INTERFACES — WR_i2c · WR_spi · WR_uart · WR_gpio abstract buses only NO VENDOR CODE ABOVE THIS LINE ST HAL NXP HAL NORDIC HAL

An interface instance does more than move bytes. Blocking, interrupt and DMA transfers are the core; around them, each instance carries the electrical know-how and the instrumentation a bench usually provides.

PER INTERFACE INSTANCE

Bus recovery, on request

A wedged I2C bus is clocked free: up to nine SCL pulses, a STOP, a peripheral re-init. The mechanism lives in the interface; the application decides when to use it.

Line checks before failures

SCL and SDA idle high, pull-ups present, bus not stuck, verified before the first transfer ever fails. SPI and UART use loopback. Zero extra hardware.

Counters that predict failure

Transfers, NACKs, timeouts, recoveries, hard-fails. A bus with many recoveries and zero hard-fails is degrading but still working: the signal to schedule maintenance before it dies.

VISIBLE WHILE IT RUNS

Capabilities as a bitmask

Each instance reports its feature set as a version-gated bitmask, so callers query, then act. sysProc enumerates exactly what a validated build exposes: a compliance artefact generated from the binary itself, so it cannot drift from it.

Bus scan from the CLI

Which devices ACK on this bus, right now. A small feature with large value during bring-up and field service.

Transaction trace

A ring buffer of the last N transfers: address, register, length, result, timestamp. A logic analyser built into the software.

interface architecture
DRIVER INTERFACE TRANSFERS — blocking · IT · DMA raw and register-addressed read / write Signals & events Error recovery Retry / backoff Self-test Health counters Capability introspection NO VENDOR CODE ABOVE THIS LINE MCU PORT selected by name at configure time VENDOR HAL physical bus on the board FAKE_* PORT host tests and fault injection HOST PC no hardware attached

Columna builds can carry a diagnostics terminal that talks over UART, SEGGER RTT or TCP, with the same command set on all three. From it you can inspect tasks and memory, read and drive devices through the same drivers the application uses, and pull the error log. During development it replaces the printf you were about to add; in the field it is the port a service technician plugs into.

Access is gated by what you are trying to do. Reading is always open, but anything that operates or actuates hardware needs an authenticated service-mode session, and those paths are compiled out of production builds entirely.

columna cli
> connect --rtt
  link up · node columna-01 · access: OBSERVE

> login
  password: ********
  service session open · OPERATE unlocked

> ps
  ID  TASK        STATE    STACK  CPU
  01  app_main    running    62%  41%
  02  comms_rx    blocked    38%   7%
  03  sensor_hub  waiting    44%  12%

> dev list
  ID    NAME    DRIVER     MANUF   STATE
  dev0  adc0    ads7066    TI      active
  dev1  dac0    dacx0501x  TI      active
  dev2  touch0  gt911      Goodix  inactive

> dev read adc0 ch3
  adc0.ch3 = 1.2418 V

> errors --last 3
  [00:14:22.019]  WARN   i2c1    NACK addr 0x48, recovered
  [00:14:22.021]  INFO   adc0    retry 1/3 ok
  [01:02:44.700]  ERROR  touch0  self-test failed, device deactivated

> 

SYSPROC

System introspection

A read-only, /proc-style view of the running node: tasks, stack and heap usage, uptime, comms counters, error statistics. Side-effect free, no dynamic allocation, never touches hardware. One producer feeds the CLI, telemetry, logs and tests alike.

SYSDEV

Uniform device access

A /dev-style front door to every registered driver: read, write and ioctl through the same interfaces the application uses. Existing drivers register through a thin adapter, without rewriting. The HW server arbitrates, so terminal traffic and application traffic never collide.

ERROR LOG

Structured fault capture

Faults at the library boundary become structured records with component, severity and timestamp. Always-on RAM ring buffer, optional flash persistence, optional streaming export. Queryable by component, severity or time, from the same terminal.

:wq

WHO WE ARE

The backbone of every project.

Columna is Latin for column, the structural member everything else rests on. Buses, drivers, logging and error handling are the code every product carries, so build that layer once and each new device starts from a standing structure rather than from zero.

The library is written by embedded engineers at Perdigó Medical, an ISO 13485-certified medical device consultancy in Barcelona. It came out of building regulated software for real devices and rewriting the same drivers for every one of them, until we wrote them once, properly.

CONTACT

Build medical devices with less cost, less risk, and more in the box.

Start your next device on a tested, documented foundation, with the runtime tooling and the Class C record already there. Delivery is scoped per project, from a compiled library to full software development. Tell us about the device.

Start a conversation