segmentacion - primer ajuste mejor ajuste peor ajuste
Recursos para la gestiĆ³n de memoria en aplicaciones integradas (7)
¿Cómo debo administrar la memoria en mi aplicación incrustada de misión crítica?
Encontré algunos artículos con google, pero no pude encontrar una guía práctica realmente útil.
El DO-178b
prohíbe las asignaciones dinámicas de memoria, pero ¿cómo gestionará la memoria? ¿Preasigna todo con anticipación y envía un puntero a cada función que necesita asignación? Asignarlo en la pila? Use un asignador estático global (pero luego es muy similar a la asignación dinámica)?
Las respuestas pueden ser de respuesta regular, referencia a un recurso o referencia al buen sistema integrado de fuente abierta, por ejemplo.
aclaración: El problema aquí no es si la administración de memoria está disponible o no para el sistema integrado. Pero, ¿qué es un buen diseño para un sistema integrado, para maximizar la fiabilidad?
No entiendo por qué la preasignación estática de un grupo de búferes y obtenerlo y soltarlo dinámicamente es diferente de la asignación dinámica de memoria.
Como alguien que ha tratado con sistemas integrados, aunque no con el mismo rigor hasta ahora (aunque he leído DO-178B):
- Si miras el gestor de arranque u-boot, se hace mucho con una estructura global. Dependiendo de su aplicación exacta, es posible que pueda salirse con la suya con una estructura y pila globales. Por supuesto, hay problemas de reentrada y relacionados allí que realmente no se aplican a un gestor de arranque, pero podrían serlo para usted.
- Preasignar, preasignar, preasignar. Si puede, en tiempo de diseño, vincular el tamaño de una matriz / estructura de lista / etc., declararlo como global (o estático global - busque Ma, encapsulación).
- La pila es muy útil, úsala donde sea necesario, pero ten cuidado, ya que puede ser fácil seguir distribuyéndola hasta que no te quede espacio en la pila. Algún código que una vez encontré a mí mismo depurando asignaría 1k búferes para la administración de cadenas en múltiples funciones ... de vez en cuando, el uso de los búferes golpearía el espacio de pila de otro programa, ya que el tamaño de pila predeterminado era 4k.
- El caso de agrupación de almacenamiento intermedio puede depender exactamente de cómo se implemente. Si sabe que necesita pasar almacenamientos intermedios de tamaño fijo conocidos en tiempo de compilación, es más fácil demostrar la corrección de un grupo de búferes que un asignador dinámico completo. Solo necesita verificar que los búfers no se pueden perder, y validar su manejo no fallará. Parece que hay algunos buenos consejos aquí: http://www.cotsjournalonline.com/articles/view/101217
Realmente, sin embargo, creo que sus respuestas se pueden encontrar en unirse a http://www.do178site.com/
Descargo de responsabilidad: no he trabajado específicamente con DO-178b, pero he escrito software para sistemas certificados.
En los sistemas certificados para los que he sido desarrollador, ...
- La asignación de memoria dinámica fue aceptable SÓLO durante la fase de inicialización.
- La desasignación de memoria dinámica NUNCA era aceptable.
Esto nos dejó con las siguientes opciones ...
- Use estructuras asignadas estáticamente.
- Cree un grupo de estructuras y luego consiga / libérelas de / de vuelta al grupo.
- Para mayor flexibilidad, podríamos asignar dinámicamente el tamaño de los grupos o el número de estructuras durante la fase de inicialización. Sin embargo, una vez pasada la fase de inicio, nos quedamos atrapados con lo que teníamos.
Nuestra empresa descubrió que las agrupaciones de estructuras y luego obtener / liberar desde / hacia la piscina eran las más útiles. Pudimos mantener el modelo y mantener las cosas deterministas con problemas mínimos.
Espero que ayude.
He trabajado en un entorno DO-178B (sistemas para aviones). Lo que he entendido es que la razón principal para no permitir la asignación dinámica es principalmente la certificación. La certificación se realiza a través de pruebas (unitarias, cobertura, integración, ...). Con esas pruebas debe demostrar que el comportamiento de su programa es 100% predecible, casi al punto que la huella de memoria de su proceso es la misma de una ejecución a la siguiente. Como la asignación dinámica se realiza en el montón (y puede fallar), no es fácil probarlo (imagino que debería ser posible si domina todas las herramientas del hardware a cualquier parte del código escrito, pero ...). No tiene este problema con la asignación estática. Eso también explica por qué C ++ no se usó en este momento en dichos entornos. (Fue hace unos 15 años, eso podría haber cambiado ...)
Prácticamente, tienes que escribir muchos grupos de estructuras y funciones de asignación que te garanticen que tienes algo determinista. Puedes imaginar muchas soluciones. La clave es que tienes que demostrar (con TONELADAS de pruebas) un alto nivel de comportamiento determinista. Es más fácil probar que su mano diseñó el desarrollo de forma determinista para demostrar que linux + gcc es determinista en la asignación de memoria.
Solo mis 2 centavos. Fue hace mucho tiempo, las cosas podrían haber cambiado, pero con respecto a la certificación como DO-178B, el punto es demostrar que su aplicación funcionará igual en cualquier momento y en cualquier contexto.
La asignación de todo desde la pila se realiza comúnmente en sistemas integrados o en cualquier otro lugar donde la posibilidad de que una asignación falle es inaceptable. No sé qué es DO-178b, pero si el problema es que malloc no está disponible en su plataforma, también puede implementarlo usted mismo (implementando su propio montón), pero esto puede llevar a una asignación que falla cuando se ejecuta fuera del espacio, por supuesto.
Los sistemas de misión crítica en tiempo real, de larga ejecución, no deben asignar dinámicamente y liberar memoria de la pila. Si necesita y no puede diseñarlo, escriba su propio esquema de administración de grupo asignado y fijo. Sí, asignado fijo por adelantado siempre que sea posible. Cualquier otra cosa está pidiendo un problema eventual.
No hay forma de estar 100% seguro.
Puede ver ejemplos de asignadores de memoria de FreeRTOS. Aquellos usan el conjunto estático, si no me equivoco.
También puede encontrar esta pregunta interesante, la asignación dinámica a menudo está prohibida en configuraciones con espacio reducido (en realidad, la memoria interna sigue siendo útil allí).
Normalmente, cuando malloc () no está disponible, solo uso la pila. Como dijo Tronic , la razón detrás de no usar malloc () es que puede fallar. Si está utilizando un conjunto estático global, es concebible que su implementación interna de malloc () pueda hacerse a prueba de fallas.
Realmente, realmente, realmente depende de la tarea en cuestión y de a qué va a estar expuesto el tablero.