2010-03-18 14 views
6

¿Cómo debo administrar la memoria en mi aplicación incrustada de misión crítica?Recursos para la administración de la memoria en la aplicación integrada

Encontré algunos artículos con google, pero no pude identificar 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 tener la forma de respuesta regular, referencia a un recurso o referencia al buen sistema integrado de fuente abierta, por ejemplo.

aclaración: La cuestión aquí no es si o no la gestión de memoria es dotados para el sistema embebido. 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.

Respuesta

3

Como alguien que ha tratado con los sistemas integrados, aunque no tanto rigor hasta el momento (He leído DO-178B, sin embargo):

  • Si nos fijamos en el gestor de arranque u-boot, mucho es hecho con una estructura colocada globalmente 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, utilícela donde sea necesario, pero tenga cuidado, ya que puede ser fácil seguir asignando hasta que no 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 la 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 podrían encontrarse en unirse http://www.do178site.com/

0

La asignación de todo lo que ocurre en la pila se realiza comúnmente en sistemas integrados o en cualquier otro lugar donde la posibilidad de una asignación fallando 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.

+0

El DO-178b es un estándar para software de aviónica. El problema no es la disponibilidad de malloc, sino un buen diseño de software de misión crítica. –

1

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.

0

No hay forma de estar 100% seguro.

Puede consultar los ejemplos de asignadores de memoria de FreeRTOS. Aquellos usan el conjunto estático, si no me equivoco.

+0

Pero, ¿la memoria asignada dinámica usa pools estáticos aceptables en aplicaciones de misión crítica? –

+0

Sí y no. Al igual que en el caso de cualquier tipo de asignación dinámica, existe la posibilidad de quedarse sin grupo. Debe preguntarse si puede tolerar eso. Aparte de eso, hay un montón de problemas relacionados con la implementación del asignador personalizado (fragmentación, optimización, yada yada) –

0

También puede encontrar this question interesante, la asignación dinámica a menudo está prohibida en configuraciones de espacio endurecido (en realidad, la memoria interna sigue siendo útil allí).

Normalmente, cuando malloc() no está disponible, simplemente 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 lo que va a estar expuesto el tablero.

+0

Realmente, realmente no entiendo cómo su malloc implementado internamente puede hacerse a prueba de fallas. Si realmente estás tratando de calcular algo (digamos, numera la ruta que tu robot debe tomar para llegar a su destino) y tienes una entrada demasiado larga, podrías tener espacio para almacenar todos los pasos que el robot necesita tomar. Tienes que encargarse de eso, ya sea que uses asignación de memoria estática o dinámica. –

+0

@Elazar Leibovich: si tiene un grupo asignado estáticamente, sabe que tiene memoria para realizar la tarea, dadas las limitaciones de diseño de lo que sea que esté trabajando. Un robot que tenía que cruzar un continente sugería una configuración de hardware completamente diferente a la que tenía que caminar de una habitación a otra. Además, probablemente no implementaría un malloc interno() en una placa dura de rad. Su pregunta es buena, pero bastante general ya que estos problemas tienden a ser extremadamente específicos de la tarea. –

+0

Bastante justo, debe tener suficiente memoria para realizar la tarea específica que su hardware incrustado debe hacer. Pero a veces te encuentras escribiendo fragmentos generales de código, que pueden ser relevantes para otro proyecto integrado. Por ejemplo, estás implementando Dijkstra. Su Dijkstra de propósito general podría necesitar asignar memoria y fallar con elegancia si no tiene suficiente memoria. Por supuesto, el sistema nunca fallaría, ya que no usaría Dijkstra si no tuviera suficiente memoria, pero el propio Dijkstra podría fallar. –

1

Descargo de responsabilidad: No he trabajado específicamente con DO-178b, pero he escrito software para sistemas certificados.

En los sistemas certificados para los cuales he sido un desarrollador, ...

  1. asignación de memoria dinámica era aceptable sólo durante la fase de inicialización .
  2. La asignación de memoria dinámica NUNCA fue aceptable.

Esto nos dejó con las siguientes opciones ...

  • Uso estructuras estáticamente asignados.
  • Cree un conjunto de estructuras y luego consiga/libérelas de/de vuelta al grupo.
  • Para mayor flexibilidad, podríamos asignar dinámicamente el tamaño de las agrupaciones 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/de vuelta a la piscina era muy útil. Pudimos mantener el modelo y mantener las cosas deterministas con problemas mínimos.

Espero que ayude.

+1

Pero, ¿los pools de get/release memory no son equivalentes a la implementación de la asignación dinámica usted mismo? –

+2

No. Son similares pero no equivalentes. La asignación dinámica utilizando malloc() y free() conduce a la fragmentación de la memoria y la posibilidad de que malloc() falle debido a la fragmentación. Los sistemas certificados lo evitan porque es un PITA real para certificar. Los elementos del conjunto pueden estar dispersos, pero se garantiza que la rutina de obtención de elementos tendrá éxito siempre que haya elementos no utilizados. No importa qué tan dispersos estén los elementos en el grupo. – Sparky

+0

No soy de ninguna manera un experto en SO, así que corrígeme si me equivoco, pero, suponiendo que solo haya un hilo que use malloc() y free(), no habrá fragmentación si eres de hecho libre ' ing todo lo que malloc'd? Y en caso de que no lo haga, por supuesto que se encontrará con problemas de todos modos ... De todos modos, el hecho de que dos hilos usen el mismo conjunto es, de hecho, un gran problema con la gestión de memoria tradicional. –

2

He trabajado en un ambiente 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 de 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, debe escribir una gran cantidad de grupos de estructuras y funciones de asignación que le garanticen que tiene 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 manera determinista para demostrar que linux + gcc es determinista en la asignación de memoria.

Sólo 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.

Cuestiones relacionadas