Muchas veces, cuando usamos un microcontrolador, escribimos código muy específico enfocado en ejecutar una tarea puntual. El dispositivo queda configurado para correr código que hace exactamente lo que queremos, con la menor sobrecarga posible. Sin embargo, a veces hay escenarios donde conviene ir con un montaje algo más pesado, en el que el microcontrolador corre un sistema operativo por los beneficios que eso ofrece.

Federico Terraneo llegó a Hackaday Europe para hablar justamente de ese tema. Su charla aborda arquitectura de kernel, sistemas operativos de tiempo real y cómo aprovechar mejor C++ en el mundo de los microcontroladores.

¿Qué es exactamente un sistema operativo?

La charla empieza en un buen lugar. Federico parte explicando qué es realmente un sistema operativo: básicamente, el software que existe entre el hardware y las aplicaciones que corren sobre él. Desglosado en partes, un sistema operativo suele consistir en un kernel principal, sobre el cual se apoyan cosas como los servicios básicos del sistema, las bibliotecas y los controladores de dispositivo, junto con los programas utilitarios necesarios para mantener el sistema y trabajar con él. La interfaz de usuario va encima de todo eso.

Federico habla del sistema operativo de tiempo real Miosix como implementación práctica de la arquitectura de kernel fluido
Federico habla del sistema operativo de tiempo real Miosix como implementación práctica de la arquitectura de kernel fluido

Por supuesto, distintos sistemas operativos difieren en los detalles de su arquitectura.

Los kernels monolíticos, como el que usa Linux, mantienen una separación entre el espacio de kernel y el espacio de usuario. El kernel tiene acceso completo al hardware y corre en la CPU en modo sistema, mientras las aplicaciones corren en modo usuario sin ese acceso directo. Los kernels monolíticos normalmente solo funcionan en arquitecturas con unidad de gestión de memoria (MMU), es decir, computadores completos con procesadores propiamente tales, como un notebook o un equipo de escritorio.

Los sistemas operativos de tipo unikernel, como FreeRTOS, son algo distintos: las aplicaciones y el sistema operativo se colapsan en un único binario ejecutable que corre con acceso directo al hardware. No hay abstracción, ni protección de memoria, ni nada por el estilo, lo que hace que la arquitectura sea más fácil de correr en microcontroladores típicos.

También están los microkernels, que buscan minimizar la cantidad de código que corre en modo sistema y empujan cosas como los controladores y el acceso al sistema de archivos hacia el espacio de usuario. Esta arquitectura igual necesita una MMU y se ve sobre todo en usos de nicho donde la seguridad o la atención a la seguridad funcional son críticas.

ArquitecturaNecesita MMUProtección de memoriaEjemplo citado
MonolíticoSí, kernel y usuario separadosLinux
UnikernelNoNoFreeRTOS
MicrokernelSí, con controladores en espacio de usuariousos críticos de nicho
Kernel fluidoNo, le basta una MPUSí, básicaMiosix

¿Qué problema resuelve el kernel fluido?

Cuando se trata de microcontroladores, los unikernels son la arquitectura más pertinente. Sin embargo, tienen limitaciones: en estabilidad, en seguridad y en el hecho de que no hay carga de código en tiempo de ejecución ni ninguna forma sencilla de actualizar el sistema por partes.

El kernel fluido que vino a explicar Federico apunta a resolver algunos de esos problemas. Busca ofrecer una solución de sistema operativo escalable que funcione a lo largo del mundo de la computación embebida, donde a veces los recursos del microcontrolador son limitados y donde rara vez existe una unidad de gestión de memoria. También está pensado para ser compatible con las APIs estándar, es decir POSIX, las bibliotecas estándar de C++ y todo eso. Federico llama a esto el concepto de "UNIX en un chip".

Una cámara térmica corriendo sobre un sistema de kernel fluido sirve como aplicación de demostración de la plataforma, mostrando funciones importantes como multihilo y DMA
Una cámara térmica corriendo sobre un sistema de kernel fluido sirve como aplicación de demostración de la plataforma, mostrando funciones importantes como multihilo y DMA

¿Cómo funciona por dentro?

El kernel fluido busca existir en la intersección entre el kernel monolítico y el unikernel. Permite hospedar aplicaciones en espacio de kernel o en espacio de usuario, según se necesite. Además, está construido para cumplir POSIX dos veces, con la misma API sin importar si se está operando en espacio de kernel o de usuario.

El concepto se diseñó alrededor de conseguir la abstracción de proceso mediante la unidad de protección de memoria (MPU) por hardware, común en los microcontroladores modernos de 32 bits. No es exactamente una MMU y no puede hacer todos los mismos trucos de memoria virtual, pero alcanza para entregar un nivel básico de protección de memoria en una plataforma de microcontrolador.

El kernel fluido también puede convertirse en un unikernel si así se desea, mediante una opción en tiempo de compilación, lo que elimina el soporte de procesos y reduce el tamaño del código de forma significativa. Eso permite desarrollar como unikernel y después subir a kernel fluido con solo mover esa opción de compilación en el otro sentido.

Ese detalle es el más práctico de toda la propuesta. En un proyecto embebido, la decisión de arquitectura suele tomarse al principio, cuando menos se sabe del producto final, y cambiarla después significa reescribir. Aquí la decisión queda diferida a una bandera del compilador, con el mismo código de aplicación de un lado y del otro.

¿Vale la pena verla?

Federico hace un buen trabajo explicando las ventajas y desventajas de la arquitectura de kernel fluido, y explora las implicancias de seguridad inherentes a tomar este camino. El sistema operativo de tiempo real Miosix aparece como la implementación práctica de esta filosofía, y hay incluso un desvío útil hacia el uso eficiente de C++ en microcontroladores. La demostración con una cámara térmica muestra funciones concretas de la plataforma, como el multihilo y el acceso directo a memoria.

Si estás tomándote en serio el desarrollo embebido, o simplemente quieres conocer una arquitectura nueva que algún día te pueda servir, es una buena charla para ver en la próxima hora de almuerzo.