Estoy trabajando en un proyecto que requerirá 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 a partir del cual puede deducir la cantidad de cuadros que quedan por recibir y, por lo tanto, calcular la longitud del cuadro completo. .
En otro caso, para evitar asignar una memoria fija para el marco de recepción que podría no agotarse (si la longitud del marco de recepción es menor que la longitud máxima del marco para recibir), soy de la opinión de asignar dinámicamente una memoria para el marco restante para ser recibido.
Por ejemplo. Si asumimos paquetes de 20 octetos y el tercer octeto le dice el número de octetos restantes que quedan por recibir (que podrían ser 2, 3, incluso 17 octetos como máximo). En lugar de crear un registro de tamaño 17, que podría no agotarse, ¿cómo puedo asignar dinámicamente esta memoria especialmente para una aplicación integrada, de modo que si el tercer octeto revela que hay 6 octetos para recibir, entonces simplemente asigno un registre con tamaño 6 para el resto del marco, sin usar el "malloc".
El lenguaje de programación es C.
Espero que mi pregunta sea lo suficientemente clara. Comparta sus opiniones, ya que necesito el mejor enfoque posible sobre esto.
Gracias.
En este caso, diría que el mejor enfoque es probablemente solo asignar el tamaño máximo de memoria y reutilizarlo para tantas otras cosas como sea posible también.
Algunos compiladores tienen una opción para que las variables compartan espacio de memoria siempre que no estén activas al mismo tiempo. Por ejemplo, el compilador PIC18 C (ahora reemplazado por HI-Tech C) tiene un overlay
atributo 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 desea hacer (menos gastos generales que malloc). Verificaría si su compilador puede hacer esto.
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, por lo general, es posible convencer al enlazador de que ponga a disposición del programador las direcciones de inicio y final de esa área (por ejemplo, se podría pedir al enlazador que coloque una variable de un byte como el lo último antes del área libre, y otro como lo primero que sigue; las direcciones de esas variables delimitarían el espacio libre).
Aunque muchos sistemas ofrecen una malloc()
función, es más complicada de lo necesario en muchos escenarios. Por ejemplo, si necesita asignar objetos en función de la información recibida en tiempo de ejecución, pero los objetos siempre se liberarán en el orden inverso de asignación, 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 asignado después de él), simplemente coloque el puntero de "siguiente espacio disponible" al comienzo de ese objeto.
Algunos escenarios son un poco más complejos de lo que se permitiría con ese enfoque, pero aún así no necesitan un enfoque completo "malloc/free". Por ejemplo, en algunos escenarios, uno puede tener dos grupos de objetos que obedezcan la regla de último en entrar, primero en salir entre ellos, pero los objetos de un grupo pueden sobrevivir a los del otro. Para hacer frente a esa situación, utilice un puntero de "espacio disponible siguiente" que comienza en la parte inferior del espacio libre y un puntero de "espacio disponible anterior" que comienza en la parte superior. Asigne 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 del segundo grupo (y todos los objetos del segundo grupo asignados después),
Tenga en cuenta que malloc
yfree
están diseñados para que sea posible liberar objetos en el medio de la memoria, mientras que los objetos anteriores y posteriores siguen siendo válidos. Si bien esto a veces puede ser útil, 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 en salir, puede ser una buena idea hacer que los objetos sean reubicables. Por ejemplo, uno podría mantener 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 todos los objetos habían sido copiados, consolidando el espacio libre que había al principio de la cola, hasta el final. Se debe tener cuidado al mover cualquier dato para asegurarse de que los punteros a esos datos se actualicen en consecuencia, pero eso 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 móvil puede ser más predecible.
bruno ferreira
marcajes
pablo a
pablo a
marcajes
bruno ferreira
solojeff