Asignación dinámica de memoria para una aplicación incrustada

2

Estoy trabajando en un Proyecto que requiere el uso de una MCU para recibir paquetes de cuadros con una longitud de cuadro desconocida en la recepción, pero cada recepción tiene un octeto del cual puede deducir el número de cuadros que quedan por recibir y, por lo tanto, calcular la longitud de Todo el marco.

En otro, para evitar asignar una memoria fija para la trama receptora que podría no ser utilizada (si la longitud de la trama de recepción es menor que la longitud máxima de la trama a recibir), opino que asignar dinámicamente una memoria para la Trama restante a recibir.

Por ejemplo. Si asumimos un paquete de 20 octetos y el 3er octeto le indica el número de octetos restantes que quedan por recibir (que podrían ser 2, 3, incluso 17 octetos máximo). En lugar de crear un registro de tamaño 17, que podría no estar agotado, ¿cómo puedo asignar dinámicamente esta memoria especialmente para una aplicación integrada, de modo que si el 3er octeto revela que hay 6 octetos para recibir, simplemente asigno un regístrese con el tamaño 6 para el resto del marco, sin utilizar el "malloc".

El lenguaje de programación es C.

Espero que mi pregunta sea lo suficientemente clara. Por favor, comparta sus opiniones, ya que necesito el mejor enfoque posible sobre esto.

Gracias.

    
pregunta Paul A.

2 respuestas

5

En este caso, diría que el mejor enfoque es probablemente asignar el tamaño máximo de memoria y reutilizarlo para tantas otras cosas como sea posible.
Algunos compiladores tienen una opción para que las variables compartan espacio en la memoria siempre que no estén activas al mismo tiempo. Por ejemplo, el compilador PIC18 C (ahora reemplazado por HI-Tech C) tiene un atributo overlay que se puede usar con variables para hacer esto.
También puede manejar matrices de tamaño variable que serían perfectas para lo que deseas hacer (menos gastos generales que malloc). Comprueba si tu compilador puede hacer esto.

    
respondido por el Oli Glaser
3

En muchos sistemas de microcontroladores, los compiladores y enlazadores asignan datos desde la parte inferior y / o superior de la RAM; la RAM no utilizada generalmente estará en un área contigua, y generalmente es posible convencer al enlazador para que haga que las direcciones de inicio y final de esa área estén disponibles para el programador (por ejemplo, se puede pedir al enlazador que coloque una variable de un byte como el la última cosa antes del área libre, y otra como la primera que sigue, las direcciones de esas variables delinearían el espacio libre).

Aunque muchos sistemas ofrecen una función malloc() , es más complicado de lo necesario en muchos escenarios. Por ejemplo, si uno necesita asignar objetos en función de la información recibida en el tiempo de ejecución, pero los objetos siempre se liberarán en el orden inverso de asignación, uno simplemente puede mantener un puntero al "siguiente espacio disponible". Para asignar un objeto, copie ese puntero agregue el tamaño del nuevo objeto y devuelva el puntero copiado. Para liberar un objeto (y todo lo que se haya asignado después de él), simplemente establezca el puntero del "siguiente espacio disponible" al inicio de ese objeto.

Algunos escenarios son un poco más complejos de lo que se permitiría con ese enfoque, pero aún no necesitan un enfoque completo "malloc / free". Por ejemplo, en algunos escenarios, uno puede tener dos grupos de objetos que obedecen entre sí a la regla del último en el primero en salir, pero los objetos en un grupo pueden sobrevivir a los del otro. Para lidiar con esa situación, use un puntero de "siguiente espacio disponible" que comience en la parte inferior del espacio libre, y un puntero de "anterior espacio disponible" que comience en la parte superior. Asigna las cosas en el primer grupo como antes. Para aquellos en el segundo grupo, reste el tamaño del nuevo objeto del puntero de "espacio disponible anterior" y devuelva el resultado. Para liberar un objeto en el segundo grupo (y todos los objetos del segundo grupo asignados después de él), agregue el tamaño del objeto a su dirección y almacene el resultado en el puntero del "espacio disponible anterior".

Tenga en cuenta que malloc y free están diseñados para que sea posible liberar objetos en medio de la memoria, mientras que los objetos anteriores y posteriores siguen siendo válidos. Si bien esto puede ser útil a veces, también puede conducir a la fragmentación de la memoria. Si los objetos de uno no encajan con un modelo de último en entrar, primero, puede ser una buena idea hacer que los objetos sean reubicables. Por ejemplo, uno puede tener una cola de objetos de tamaño variable que se almacenan consecutivamente en la memoria siempre que haya espacio. Cuando la memoria se llena (o en algún momento conveniente antes de eso), uno copiaría el primer objeto que aún no se había leído al comienzo de la cola, el siguiente objeto que no se había leído inmediatamente después, etc. hasta que todos los objetos se habían copiado, consolidando el espacio libre que había al principio de la cola, hasta el final. Se debe tener cuidado al mover los datos para garantizar que los punteros a esos datos se actualicen en consecuencia, pero a menudo no es demasiado difícil. Mover la memoria puede requerir más ciclos de CPU que administrar áreas discontinuas de espacio libre, pero el comportamiento del enfoque de memoria en movimiento puede ser más predecible.

    
respondido por el supercat

Lea otras preguntas en las etiquetas