
En el resto de la serie "Toda la verdad sobre RTOS", examinaremos en detalle cómo se implementa y despliega RTOS. Para hacer esto, consideraremos un RTOS específico: Nucleus SE. Incluso si no va a utilizar este núcleo en particular u otros núcleos relacionados con él, comprender cómo funciona proporcionará una buena base para trabajar con cualquier RTOS.
Para comprender por qué Nucleus SE se diseñó de esta manera, es importante resaltar las tareas y objetivos centrales que seguí al comienzo de este proyecto.
Artículos anteriores de la serie:
Artículo # 6. Otros servicios RTOSArtículo # 5. Interacción de tareas y sincronizaciónArtículo # 4. Tareas, cambio de contexto e interrupcionesArtículo # 3. Tareas y planificaciónArtículo # 2. RTOS: estructura y modo en tiempo real
Artículo # 1. RTOS: introducción.
SimplicidadEl código del núcleo debe ser simple, directo, bien comentado y documentado. Nucleus SE está destinado principalmente para uso educativo.
TamañoEste debería ser un núcleo pequeño y bien escalable (ya que la memoria, especialmente la memoria operativa (RAM), puede ser escasa).
FuncionalidadEl núcleo debe tener un alto nivel de funcionalidad que admita servicios RTOS estándar.
Soporte de 8/16 bitsDebe admitir arquitecturas de 8 y 16 bits: en la medida de lo posible, utilice datos del tamaño de un byte; las estructuras de datos no deberían requerir métodos de direccionamiento exóticos; los datos persistentes no deben copiarse en RAM innecesariamente.
El futuroDebe haber una ruta de desarrollo de Nucleus SE a Nucleus RTOS. Los usuarios deberían poder transferir fácilmente el código entre núcleos. Más importante aún, su conocimiento también debe ser transferido. La API Nucleus SE implementa efectivamente un subconjunto de la API Nucleus RTOS.
CostoEl modelo de negocio debería ser atractivo para todos los usuarios potenciales: desarrolladores de dispositivos de 8/16 bits, aquellos que primero usan el RTOS y aquellos que solo están estudiando la tecnología en sí. Por lo tanto, Nucleus SE está disponible de forma gratuita, absolutamente libre de usar con fines comerciales y educativos; El código puede ser utilizado y modificado.
Público objetivo Núcleo SEEl resultado de este enfoque es un núcleo que puede ser útil para tres tipos de desarrolladores:
- Programadores de dispositivos de 8/16 bits que requieren un núcleo simple o un programador de tareas. Esto es especialmente atractivo si los desarrolladores están interesados en adquirir ciertas habilidades para usar RTOS o cuando desarrollan un sistema que usa otros dispositivos de 32 bits donde Nucleus RTOS puede ser una buena opción.
- Desarrolladores de aplicaciones integradas que utilizan dispositivos de 32 bits donde la complejidad del software no vale el costo de un RTOS comercial tradicional. Usar Nucleus SE puede ser útil y permitirá el desarrollo (hasta Nucleus RTOS) si aumenta la complejidad de la aplicación.
- Los estudiantes en el proceso de aprendizaje pueden usar Nucleus SE como base para aprender RTOS. Las habilidades adquiridas serán útiles más tarde cuando comiencen a funcionar.
Decisiones de diseño y compensacionesPara lograr los objetivos anteriores, se tuvieron que tomar varias decisiones de diseño cuidadosamente pensadas. Los detalles se describirán más adelante cuando consideremos funciones específicas, pero aquí hay un breve resumen de los puntos clave.
Configuración estáticaNucleus SE es un RTOS estático, lo que significa que todas las decisiones de configuración se toman en el momento de la compilación, no dinámicamente en el tiempo de ejecución. Esto tiene muchas ventajas, incluida la simplificación de la estructura de datos y la reducción del tamaño del código, por lo que no es necesario llamar a las funciones de creación y eliminación de API. Para la mayoría de las aplicaciones, no se requiere la creación dinámica de objetos.
Numero de objetosEl número de objetos de cada tipo está limitado en una aplicación basada en Nucleus SE. Puede ser de una a dieciséis tareas y de cero a dieciséis tipos diferentes de objeto kernel. Esto simplifica el direccionamiento de objetos (ver más abajo). Esta restricción no es difícil para aplicaciones pequeñas para las que está destinado el núcleo.
Dirigiendo objetosLos objetos se abordan mediante un "índice", que puede variar de cero a quince. En comparación con el uso habitual de punteros, esto puede ser más eficiente en procesadores más pequeños y permitir menos memoria: el índice requiere solo 4 bits de memoria; La dirección es de 16-32 bits.
PlanificadorEl planificador pertenecía al área de la arquitectura del núcleo que se simplificó. En lugar de proporcionar un mecanismo flexible con diferentes políticas de programación, hay cuatro tipos de planificador disponibles en el núcleo; el planificador específico para la aplicación se selecciona durante la configuración.
Funcionalidad limitadaAlgunas funciones disponibles en Nucleus RTOS no se implementan en Nucleus SE. En algunos casos, esto se hace por simplicidad. En otros casos, una ligera pérdida de funcionalidad en un área hace que la otra funcionalidad sea más fácil de implementar. Estas incompatibilidades se destacan en los artículos relevantes de la serie.
Uso de la memoriaDado que Nucleus SE debe admitir aplicaciones de memoria limitadas, se ha prestado especial atención al uso de la memoria. Se suponía que debía usar la ROM y la RAM "clásicas": la ROM se usaba para el código y los datos persistentes; RAM: para almacenar variables, una pila, etc. Aunque un objetivo específico puede tener un esquema diferente, el código Nucleus SE es bastante flexible; Las definiciones (#defines) de ROM y RAM se utilizan para prefijar todas las estructuras de variables y datos para indicar su ubicación. Esto se puede lograr utilizando herramientas.
El requisito clave era evitar la copia innecesaria de datos de la ROM a la RAM, ya que la RAM puede no ser suficiente. El mecanismo por el cual se logra esto se describe en la sección Estructuras de datos del siguiente artículo.
Implementación APILa API para Nucleus SE se implementa de la manera tradicional: la función del lenguaje C implementa cada llamada API. Estas llamadas están agrupadas lógicamente. Aunque las llamadas a la API en Nucleus SE no son exactamente las mismas que en Nucleus RTOS, la funcionalidad general es simulada y la asignación entre las API es fácil. Se incluirán detalles de la API Nucleus RTOS.
Secciones críticasEl código para muchas llamadas a funciones API incluye secuencias de instrucciones que manipulan los datos del núcleo. En general, los datos pueden estar en un estado no válido durante la ejecución de estas instrucciones, por lo que se debe tener cuidado para evitar la interrupción. O bien, puede estar prohibido ejecutar código desde otra tarea o interrumpir el controlador si pudiera acceder a estos datos (actualmente no válidos). Dichas secuencias de instrucciones se denominan secciones críticas.
Se define un par de macros llamadas NUSE_CS_Enter () y NUSE_CS_Exit (). Todos los códigos de funciones de la API de Nucleus SE los utilizan para abarcar la sección crítica, por lo tanto:
NUSE_CS_Enter ();
<código no interrumpible>
NUSE_CS_Exit ();
Típicamente, estas macros se expandirán en instrucciones de interrupción de instrucciones de desactivación e instrucciones de interrupción de habilitación respectivamente. Esto deberá verificarse si Nucleus SE se implementa en una arquitectura de procesador diferente. En el próximo artículo se describirá más información sobre la migración de Nucleus SE.
EscalabilidadComo todos los RTOS modernos, Nucleus SE es escalable. Para asegurarse de que solo se incluyan componentes RTOS usados, todas las funciones API se presentan en forma de biblioteca. Por lo tanto, durante el enlace, las funciones a las que se hace referencia se extraen y se incluyen en la imagen final de la aplicación. Nucleus RTOS utiliza este enfoque tanto para el núcleo como para todos los demás componentes del sistema operativo. Nucleus SE utiliza una técnica diferente.
En lugar de confiar en la biblioteca en la caja de herramientas seleccionada, todos los archivos fuente en la distribución de Nucleus SE contienen directivas de compilación condicional. Para configurar Nucleus SE para el programa, el desarrollador necesita instalar varios caracteres #define (más sobre esto en el próximo artículo). Esto determina qué funciones de API se compilan y, por lo tanto, se incluyen en el programa.
Nucleus SE mejora este enfoque al ofrecer un objeto que yo llamo "escalabilidad extrema". Varios aspectos de la funcionalidad del núcleo pueden activarse y desactivarse, o configurarse de otras formas utilizando caracteres #definidos similares. Por lo tanto, el desarrollador tiene un punto de control sobre el uso de la memoria.
Cual API?Nucleus SE tiene su propia API, que se describirá en detalle en futuros artículos. Para muchos usuarios, basta con incluir estas llamadas a las funciones API en el código.
Algunos usuarios pueden preferir usar una API diferente: estándar o con la que estén familiarizados. La API de Nucleus SE es bastante flexible y le permite crear un contenedor que transforma una interfaz a otra API.
Uno de los objetivos principales del desarrollo de Nucleus SE es un alto grado de compatibilidad a nivel de usuario con Nucleus RTOS. Aunque las API son diferentes, están diseñadas para ser fáciles de combinar. Habrá un contenedor disponible para facilitar el uso de la API Nucleus RTOS en Nucleus SE.
En el próximo artículo, continuaremos revisando Nucleus SE y nos centraremos en la estructura interna y la implementación de RTOS.