Descargo de responsabilidad. El autor no aboga por el uso de sistemas operativos multitarea para microcontroladores.
La vida obliga sin piedad al uso de sistemas operativos (SO) para microcontroladores. Hay una inmensa cantidad de tales sistemas en el mercado. Los desarrolladores de sistemas operativos, que compiten entre sí, intentan maximizar la funcionalidad de sus productos. Esto a menudo conduce a un aumento en el "peso" del sistema, y también aumenta significativamente el "umbral de entrada" para un programador que desarrolla software para sistemas integrados.
Para no ser atormentado con la elección del sistema operativo para nuestros proyectos, así como para no nublar la mente con el estudio del producto de otra persona, así como para dominar la técnica de escribir aplicaciones integradas para sistemas operativos, así como para descubrir de qué se trata, decidí escribir mi sistema operativo. No es olor.
El sistema operativo propuesto (sistema operativo, el lenguaje no se atreve a llamar a su sistema operativo, y especialmente OSRV) cooperativo con tareas estáticas. Como se señaló anteriormente, no soy partidario del uso del sistema operativo para microcontroladores, pero aún más no soy partidario del uso de sistemas operativos preventivos en microcontroladores. La multitarea preventiva, en comparación con la cooperativa, no es solo procedimientos complejos de cambio de contexto, sino también una sincronización de subprocesos intensiva en recursos. El uso de tareas dinámicas también complica significativamente el sistema operativo.
El sistema operativo fue desarrollado para el procesador de la familia Cortex-M0. Con cambios menores en las reglas para guardar y restaurar el contexto, se puede usar para otros tipos de procesadores.
Código fuente
Archivo IntorOS.h#ifndef __INTOROS_H #define __INTOROS_H
Archivo IntorOS.c #define _INTOROS_C #include "stm32l0xx.h" #include "IntorOS.h"
Archivo IntorOSSleepIAR.s #define SHT_PROGBITS 0x1 EXTERN KolvoTask EXTERN TaskList EXTERN TaskNum PUBLIC Sleep SECTION `.text`:CODE:NOROOT(2) THUMB
Archivo IntorOSSleepGCC.s .cpu cortex-m0 .text .cfi_sections .debug_frame .section .text.Sleep,"ax",%progbits .align 1 .global Sleep .syntax unified .thumb .thumb_func .type Sleep, %function .extern KolvoTask .extern TaskList .extern TaskNum .cfi_startproc
Constantes de compilación del sistema operativo
#define IntorOSMaxKolvoZadach (2)
Por razones religiosas, no puedo usar la asignación dinámica de memoria, por lo que la cantidad de memoria requerida debe especificarse en la etapa de compilación.
OS OS Services
void InitTask(void (*TaskPointer)(void), unsigned long Stek);
Inicialización de tareas. La tarea se ejecuta en forma de una función, se pasa un puntero a una función al procedimiento de inicialización. Durante la inicialización, debe especificar el tamaño de pila asignado a la tarea. El orden en que se inicializan las tareas determina sus identificadores. La tarea que se inicializa primero tiene el identificador 0. Si especifica un tamaño de pila total mayor que el reservado, se producirá un error. Cuando se inicializa la tarea, se establece el puntero a la pila de tareas, la pila se carga por el contexto de la tarea.
void StartOS(unsigned long Num);
El inicio del sistema operativo. Como argumento para la función, se pasa el identificador de la tarea con la que comenzar la ejecución. Cuando se inicia el sistema operativo, el temporizador del sistema se establece en un cuanto de un milisegundo. El contexto se borra de la pila de la tarea iniciada y se llama a la tarea.
void Sleep(unsigned long ms);
Planificador Cuando se llama a esta función desde una tarea, el control se transfiere al sistema operativo. El sistema operativo selecciona una tarea lista para la ejecución de la lista y le transfiere el control. El argumento de la función es el tiempo en milisegundos después del cual es necesario devolver el control a la tarea actual. Cuando se llama a una función con el argumento 0xFFFFFFFF, el control nunca volverá.
Es imposible escribir esta función en C, por lo que el algoritmo de su funcionamiento destruye por completo la lógica del lenguaje. El código fuente contiene pruebas de programas en lenguaje ensamblador para los sistemas de programación IAR y GCC. Para los enfermos, se proporciona el código en C. Pero me gustaría señalar que solo puede compilar correctamente con ciertas "fases de la luna". En mi caso, esto sucedió solo cuando se usaba el nivel medio de optimización, en los niveles bajo y alto el código se compilaba erróneamente.
Archivo Sleep.c extern Task_t TaskList[IntorOSMaxKolvoZadach];
void EndTask(void);
Finalización de la tarea. Como se señaló anteriormente, las tareas son estáticas, la descarga de tareas es imposible. Si necesita completar la tarea, puede usar esta función. La tarea permanece en la lista, pero el control no se transfiere a ella.
void StopTask(unsigned long Num); void StartTask(unsigned long Num);
Parar o comenzar una tarea. El argumento es el identificador de la tarea. Estas funciones le permiten implementar el administrador de tareas. Debe tenerse en cuenta que solo puede iniciar una tarea detenida anteriormente, el tiempo hasta que se inicia es 0xFFFFFFFF.
Usando OS
Por ejemplo, un microcontrolador tradicional "helword" para un sistema operativo desarrollado.
#include "stm32l0xx.h" #include "stm32l0xx_ll_gpio.h" #include "IntorOS.h"
En conclusión, me gustaría sinceramente esperar que esto, por diversión, el SO desarrollado sea interesante y útil para los desarrolladores de software para sistemas integrados.