RTOS para sistemas integrados

He visto muchos artículos que me dicen que debería usar RTOS para la gestión del tiempo y la gestión de recursos. Mi tiempo no me ha permitido investigar por mi cuenta, así que acudo a chiphacker en busca de consejo.

Uso microcontroladores de bajo recurso (MSP430, PIC) y estaba buscando RTOS que pueda usar.

Al punto:

  1. Costo de recursos del sistema
  2. ventajas del sistema
  3. Desventajas del sistema
  4. Trucos de implementación
  5. Situaciones en las que el RTOS debe/no debe usarse.

No uso sistemas como el arduino, los proyectos con los que trabajo no pueden soportar el costo de dicho sistema.

Estoy confundido en cuanto a por qué recibió un voto negativo. Si el votante pudiera darme su opinión, intentaré evitar tal acción en el futuro.
ídem. Es una gran pregunta....
Acepté una pregunta porque, a pesar de que tiene un final abierto, obtuve varias respuestas excelentes y quería recompensar al menos a un escritor por el esfuerzo.

Respuestas (9)

No he tenido mucha experiencia personal con RTOS aparte de QNX (que es genial en general, pero no es barato y he tenido una muy mala experiencia con un proveedor de placas en particular y la actitud de QNX de que no nos importan los sistemas otros que el más común) que es demasiado grande para PIC y MSP430.

Donde se beneficiará de un RTOS es en áreas como

  • gestión/programación de subprocesos
  • comunicaciones entre subprocesos + sincronización
  • E/S en sistemas con stdin/stdout/stderr o puertos seriales o soporte de ethernet o un sistema de archivos (no un MSP430 o PIC en su mayor parte, excepto para los puertos seriales)

Para periféricos de un PIC o MSP430: para puertos serie usaría un búfer de anillo + interrupciones... algo que escribo una vez por sistema y simplemente reutilizo; otros periféricos No creo que encuentre mucho soporte de un RTOS, ya que son muy específicos del proveedor.

Si necesita una temporización que sea sólida como una roca al microsegundo, un RTOS probablemente no ayudará: los RTOS tienen una temporización limitada, pero generalmente tienen fluctuaciones de temporización en su programación debido a retrasos en el cambio de contexto ... QNX ejecutándose en un PXA270 tenía jitter en las decenas de microsegundos típicos, 100-200us como máximo, por lo que no lo usaría para cosas que tienen que funcionar más rápido que aproximadamente 100Hz o que necesitan una sincronización mucho más precisa que aproximadamente 500us. Para ese tipo de cosas, probablemente tendrá que implementar su propio manejo de interrupciones. Algunos RTOS jugarán bien con eso, y otros lo convertirán en un dolor real: es posible que su tiempo y el tiempo de ellos no puedan coexistir bien.

Si el tiempo/programación no es demasiado complejo, es mejor que utilice una máquina de estado bien diseñada. Recomiendo encarecidamente leer Practical Statecharts en C/C++ si aún no lo ha hecho. Hemos utilizado este enfoque en algunos de nuestros proyectos en los que trabajo, y tiene algunas ventajas reales sobre las máquinas de estado tradicionales para administrar la complejidad... que es realmente la única razón por la que necesita un RTOS.

Trabajo en una empresa nueva donde los tipos de sistemas integrados más experimentados acaban de salir de la universidad (es decir, yo y el otro tipo que ha estado trabajando conmigo durante aproximadamente 2 años). Paso una gran parte del tiempo aprendiendo sobre la práctica de la industria durante mi semana laboral. Como he estado leyendo, me han informado que todo, excepto nuestro sistema de menor costo, un RTOS sería una gran mejora.
Parece que hay un sistema RTOS de muy pocos recursos para cosas como PIC y MSP430 que pueden ayudar a crear un sistema determinista a partir de uno muy complicado, y también limpian en gran medida nuestra gestión de mantener los módulos separados. He sido parte de un equipo de dos hombres que construyó efectivamente un sistema de enrutamiento y recopilación de datos en el campo. Ahora que miro RTOS, veo que es perfecto para lo que diseñamos.
Perdón por usar tres espacios para publicaciones, su respuesta es muy útil, estoy buscando una solución de muy pocos recursos, pero es valioso tener esta información, gracias por la ayuda.
no se preocupe por el recuento de comentarios (en mi humilde opinión, una de las cosas que le faltan al marco de StackExchange es la compatibilidad con las discusiones... el formato de preguntas y respuestas cubre la mayoría de las cosas, pero no algunas)... parece que tiene un buen manejo de lo que estas buscando. No he mirado el FreeRTOS que ha mencionado Steve, pero si se ha portado a microcontroladores de gama baja, tal vez haga la gestión de programación que necesita.
Parece guardar el estado de cada subproceso a través de la pila (algo así como 50 declaraciones push/pull) y puede manejar interrupciones temporizadas. Mi sistema normalmente usaría una interrupción de puerto para el cambio de subprocesos, pero la tarea parece factible. Deseo que este tipo de sitio maneje la discusión en un mejor formato.

¿Has probado FreeRTOS ? Es gratis (sujeto a T&C) y ha sido portado tanto al MSP430 como a varias versiones de PIC.

Es pequeño en comparación con otros, pero esto también lo hace fácil de aprender, especialmente si no ha usado un RTOS antes.

Está disponible una licencia comercial (no gratuita), así como una versión IEC 61508/SIL 3.

Muchas gracias, lo investigaré dentro de la semana, dejaré la pregunta abierta para otras respuestas, ¡pero eres de gran ayuda!
@Kortuk, ¿aprendió FreeRTOS o ThreadX al final?

Acabo de enterarme de NuttX RTOS, que incluso puede funcionar en un sistema 8052 (8 bits). No tiene muchos puertos, pero parece interesante. El POSIX puede ser una ventaja, ya que puede hacer que parte de su código sea un poco más portátil si pasa a un procesador más robusto y desea ejecutar Linux en tiempo real o QNX.

No tengo ninguna experiencia con los RTOS comerciales, ¡pero he usado los caseros durante años! Son excelentes para ayudarlo a dividir el desarrollo de su código entre muchos programadores, porque esencialmente cada uno puede obtener una "tarea" o "hilo" para trabajar en su parte. Todavía tiene que coordinar y alguien debe supervisar todo el proyecto para asegurarse de que cada tarea pueda cumplir con su fecha límite.

También le recomiendo que investigue el análisis monotónico de tasas o RMA cuando utilice un RTOS. Esto le ayudará a garantizar que sus tareas críticas cumplirán con los plazos.

También buscaría en el marco de programación basado en eventos QP-nano de Miro Samek que puede funcionar con o sin un RTOS y aun así brindarle capacidad en tiempo real. Con él, está dividiendo su diseño en máquinas de estado jerárquicas en lugar de tareas tradicionales. Jason S mencionó el libro de Miro en su publicación. ¡Una excelente lectura!

Una cosa que he encontrado útil en varias máquinas es un conmutador de pila simple. En realidad, no he escrito uno para el PIC, pero espero que el enfoque funcione bien en el PIC18 si ambos/todos los subprocesos usan un total de 31 o menos niveles de pila. En el 8051, la rutina principal es:

_cambio de tareas:
  xch a,SP
  xch a,_altSP
  xch a,SP
  retirado

En el PIC, olvidé el nombre del puntero de la pila, pero la rutina sería algo como:

_cambio de tareas:
  movlb _altSP >> 8
  movf _altSP ,w,b
  movff_STKPTR,altSP
  movwf_STKPTR,c
  devolver

Al comienzo de su programa, llame a una rutina task2() que carga altSP con la dirección de la pila alternativa (16 probablemente funcionaría bien para un PIC18Fxx) y ejecuta el bucle task2; esta rutina nunca debe volver o las cosas morirán de una muerte dolorosa. En su lugar, debe llamar a _taskswitch cada vez que quiera ceder el control a la tarea principal; la tarea principal debe llamar a _taskswitch cada vez que quiera ceder el paso a la tarea secundaria. A menudo, uno tendrá lindas pequeñas rutinas como:

void delay_t1 (valor corto sin firmar)
{
  hacer
    cambio de tareas();
  while((corto sin signo)(millisecond_clock - val) > 0xFF00);  
}

Tenga en cuenta que el conmutador de tareas no tiene ningún medio para hacer ninguna 'espera de condición'; todo lo que admite es un spinwait. Por otro lado, el cambio de tarea es tan rápido que intentar un cambio de tarea () mientras la otra tarea está esperando que expire un temporizador cambiará a la otra tarea, verificará el temporizador y volverá más rápido que un cambio de tarea típico. determinaría que no necesita cambiar de tarea.

Tenga en cuenta que la multitarea cooperativa tiene algunas limitaciones, pero evita la necesidad de una gran cantidad de bloqueo y otros códigos relacionados con mutex en los casos en que las invariantes que se alteran temporalmente se pueden restablecer rápidamente.

(Editar): un par de advertencias con respecto a las variables automáticas y demás:

  1. si se llama a una rutina que utiliza el cambio de tareas desde ambos subprocesos, generalmente será necesario compilar dos copias de la rutina (posiblemente #incluyendo el mismo archivo fuente dos veces, con diferentes declaraciones #define). Cualquier archivo fuente dado contendrá código para un solo subproceso, o contendrá código que se compilará dos veces, una para cada subproceso, por lo que puedo usar macros como "#define delay(x) delay_t1(x)" o #define delay(x) delay_tx(x)" según el hilo que esté usando.
  2. Creo que los compiladores de PIC que no pueden "ver" una función que se está llamando asumirán que dicha función puede desechar todos y cada uno de los registros de la CPU, evitando así la necesidad de guardar cualquier registro en la rutina de cambio de tareas [un buen beneficio en comparación con Multi tareas preventivo]. Cualquiera que esté considerando un conmutador de tareas similar para cualquier otra CPU debe conocer las convenciones de registro en uso. Empujar los registros antes de un cambio de tarea y abrirlos después es una manera fácil de ocuparse de las cosas, suponiendo que exista el espacio de pila adecuado.

La multitarea cooperativa no permite escapar por completo de los problemas de bloqueo y demás, pero realmente simplifica mucho las cosas. En un RTOS preventivo con un recolector de elementos no utilizados compactador, por ejemplo, es necesario permitir que se anclen los objetos. Cuando se usa un conmutador cooperativo, esto no es necesario siempre que el código asuma que los objetos GC pueden moverse cada vez que se llama a taskswitch(). Un recolector de compactación que no tiene que preocuparse por los objetos clavados puede ser mucho más sencillo que uno que sí lo tenga.

Impresionante respuesta. Creo que sería interesante obtener algunos enlaces sobre recursos para abordar mi propio RTOS. Mi enfoque aquí realmente fue obtener un RTOS de alta calidad de un proveedor que ha hecho el trabajo de garantizar un tiempo real duro, pero este podría ser un proyecto de aficionado divertido para mí.
Genial, nunca pensé en las tareas como simplemente cambiar el SP...
@JGord: he hecho pequeños conmutadores de tareas en el 8x51 y en un TI DSP. El 8051, que se muestra arriba, está diseñado precisamente para dos tareas. El DSP se usa con cuatro y es un poco más complicado. Sin embargo, acabo de tener una idea loca: uno podría manejar cuatro tareas simplemente usando tres conmutadores de tareas. Cada vez que una de las dos primeras tareas quiera cambiar de tarea, debe llamar a TaskSwitch1 y TaskSwitch2. Cuando una de las dos tareas siguientes quiere cambiar de tarea, debe llamar a Taskswitch1 y Taskswitch3. Suponga que el código comienza en stack0 y cada selector de tareas se establece con su número de pila correspondiente.
@JGord: Hmm... eso no funciona del todo; parece producir un round-robin de 3 vías e ignora el tercer conmutador. Bueno, experimenta y creo que probablemente encontrarás una buena fórmula.

He usado Salvo en el MSP430. Esto fue muy ligero en los recursos del procesador y, siempre que obedezca las reglas de implementación, muy fácil de usar y confiable. Este es un sistema operativo cooperativo y requiere que los cambios de tarea se realicen en el nivel de llamada de función externa de las funciones de tarea. Esta restricción permite que el sistema operativo funcione en dispositivos de memoria muy pequeños sin usar grandes cantidades de espacio de pila para mantener contextos de tareas.

En el AVR32 estoy usando FreeRTOS. Nuevamente, muy confiable hasta ahora, pero he tenido algunas discrepancias de configuración/versión entre la versión que publica FreeRTOS y la versión provista con el marco Atmel. ¡Sin embargo, esto tiene la ventaja de que es gratis!

La edición de diciembre de Everyday Practical Electronics tiene la parte 3 de una serie sobre sistemas operativos en tiempo real para PIC (en la columna PIC n' Mix) y tiene detalles sobre cómo configurar FreeRTOS con MPLAB y un PICKit 2. Los dos artículos anteriores (que no he visto) parecen haber discutido los méritos de varios RTOS y se decidieron por FreeRTOS. Una vez que el artículo actual ha configurado el entorno de desarrollo, comienzan a diseñar un reloj digital binario. Parece que hay al menos una parte más por venir sobre este tema.

No estoy seguro de cuán disponible está EPE en los EE. UU., pero parece que hay una tienda de EE. UU. vinculada desde su sitio y puede haber copias electrónicas disponibles.

El compilador CCS para PIC viene con un RTOS simple. No lo he probado, pero si tienes este compilador, sería fácil experimentar con él.

De hecho, probé esto como el primero. No es un RTOS en ningún sentido real de la palabra. No es preventivo de ninguna manera. Requiere el uso regular de comandos de rendimiento para que el RTOS pueda decidir quién se ejecuta a continuación, debe colocarlos intencionalmente constantemente en caso de que otro programa necesite tomar el control.
Creo que todavía se llama RTOS. Simplemente parece que tiene un programador cooperativo en lugar de un programador totalmente preventivo.
Sí, sigue siendo técnicamente un RTOS, pero tenía y todavía tengo muy poco valor para él. Sé que es algo personal, pero para mí tiene que ser preventivo para ser valioso. Todavía hago +1 porque fue una buena respuesta y de valor.
¡Gracias! Parece que la mayoría de la gente no entendió la pregunta, pero sigue siendo interesante.
Publiqué la pregunta sobre SO invitando al usuario a acudir a E&R en busca de ayuda.
Creo que "obtuvimos" la pregunta en SO, estaba preguntando algo diferente pero relacionado con esta pregunta. En cuanto a su comentario sobre la certificación; eso depende de muchas cosas. Mirando las respuestas aquí, me gusta la respuesta de DoxaLogos que se refiere a QP-nano; mi experiencia me lleva a preferir el código basado en eventos sobre los hilos y el cambio de contexto implícito de los hilos.

No ha dicho mucho sobre su solicitud. Si usa un RTOS depende mucho de lo que necesita hacer en el PIC. A menos que esté haciendo varias cosas asincrónicas diferentes, que requieren límites de tiempo estrictos, o tiene varios subprocesos en ejecución, entonces un RTOS podría ser excesivo.

Hay muchas formas de organizar el tiempo en un microcontrolador dependiendo de lo que sea más importante:

  1. Velocidad de fotogramas constante: para un PIC que ejecuta un servocontrolador que debe funcionar a 1000 Hz, por ejemplo. Si el algoritmo PID tarda menos de 1 ms en ejecutarse, puede usar el resto del milisegundo para realizar otras tareas, como verificar el bus CAN, leer sensores, etc.

  2. Todas las interrupciones: Todo lo que sucede en el PIC se desencadena por una interrupción. Las interrupciones se pueden priorizar según la importancia del evento.

  3. Mételo en un bucle y haz todo lo más rápido que puedas. Es posible que encuentre que esto proporciona límites de tiempo adecuados.

Entiendo otros métodos, pero quiero expandirme a un RTOS. Ejecutaré múltiples tareas y tendré un sistema de tiempo real estricto, pero estoy dispuesto a comenzar sin los requisitos del tiempo real estricto. Gracias por tomarse el tiempo para responder, pero quiero aprender un RTOS para poder usarlo en una situación de alta demanda.