Según la documentación de Arduino, el ATmega328 tiene 32 KB de memoria Flash para el cargador de arranque + boceto cargado, y solo 2 KB de SRAM para datos de tiempo de ejecución. El ATmega2560 tiene bastante más, totalizando 256 KB y 8 KB respectivamente.
En cualquier caso, esos límites parecen bastante pequeños, especialmente cuando se comparan con dispositivos de consumo de tamaño similar, como los teléfonos inteligentes.
¿Qué puedes hacer si se te acaba? Por ejemplo, si su boceto es demasiado grande o si necesita procesar una gran cantidad de datos (como cadenas) en tiempo de ejecución? ¿Hay alguna forma de expandir Flash o SRAM?
flash
sketch-size
Peter Bloomfield
fuente
fuente
Respuestas:
Optimización
La programación de bajo nivel para sistemas integrados es bastante diferente de la programación para dispositivos de uso general, como computadoras y teléfonos celulares. La eficiencia (en términos de velocidad y espacio) es mucho más importante porque los recursos son muy importantes. Eso significa que lo primero que debe hacer si se queda sin espacio es mirar qué partes de su código puede optimizar.
En términos de reducir el uso del espacio del programa (Flash), el tamaño del código puede ser bastante difícil de optimizar si no tiene experiencia o si está más acostumbrado a programar para computadoras de escritorio que no tienden a necesitar esa habilidad. Desafortunadamente, no existe un enfoque de 'bala mágica' que funcione para todas las situaciones, aunque ayuda si considera seriamente lo que realmente necesita tener su boceto . Si no se necesita una función, elimínela.
A veces también es útil identificar dónde varias partes de su código son iguales (o muy similares). Es posible que pueda condensarlos en funciones reutilizables que se pueden llamar desde varios lugares. Sin embargo, tenga en cuenta que a veces tratar de hacer que el código sea demasiado reutilizable en realidad termina haciéndolo más detallado. Es un equilibrio difícil de alcanzar que tiende a venir con la práctica. Dedicar un tiempo a observar cómo los cambios en el código afectan la salida del compilador puede ayudar.
La optimización de datos de tiempo de ejecución (SRAM) tiende a ser un poco más fácil cuando estás acostumbrado. Una trampa muy común para los programadores principiantes es utilizar demasiados datos globales. Todo lo declarado a nivel mundial existirá durante toda la vida útil del boceto, y eso no siempre es necesario. Si una variable solo se usa dentro de una función, y no necesita persistir entre llamadas, entonces conviértala en una variable local. Si un valor necesita ser compartido entre funciones, considere si puede pasarlo como un parámetro en lugar de hacerlo global. De esa manera, solo usará SRAM para esas variables cuando realmente lo necesite.
Otro asesino para el uso de SRAM es el procesamiento de texto (por ejemplo, usando la
String
clase). En términos generales, debe evitar realizar operaciones de cadena si es posible. Son enormes cerdos de memoria. Por ejemplo, si está generando una gran cantidad de texto en serie, use varias llamadas a enSerial.print()
lugar de usar la concatenación de cadenas. También trate de reducir el número de literales de cadena en su código si es posible.Evite la recursividad si es posible también. Cada vez que se realiza una llamada recursiva, lleva a la pila un nivel más profundo. Refactorice sus funciones recursivas para que sean iterativas.
Usar EEPROM
EEPROM se usa para el almacenamiento a largo plazo de cosas que solo cambian ocasionalmente. Si necesita utilizar listas grandes o tablas de búsqueda de datos fijos, considere almacenarlos en EEPROM por adelantado y solo extraiga lo que necesite cuando sea necesario.
Obviamente, EEPROM es bastante limitado en tamaño y velocidad, y tiene un número limitado de ciclos de escritura. No es una gran solución para las limitaciones de datos, pero podría ser suficiente para aliviar la carga de Flash o SRAM. También es bastante posible interactuar con un almacenamiento externo similar, como una tarjeta SD.
Expansión
Si ha agotado todas las demás opciones, la expansión puede ser una posibilidad. Desafortunadamente, no es posible expandir la memoria Flash para aumentar el espacio del programa. Sin embargo, es posible expandir SRAM. Esto significa que puede refactorizar su boceto para reducir el tamaño del código a expensas de aumentar el tamaño de los datos.
Obtener más SRAM es bastante sencillo. Una opción es usar uno o más chips 23K256 . Se accede a ellos a través de SPI, y existe la biblioteca SpiRAM para ayudarlo a usarlos. ¡Solo tenga en cuenta que funcionan a 3.3V, no a 5V!
Si está utilizando el Mega, también puede obtener escudos de expansión SRAM de Lagrangian Point o Rugged Circuits .
fuente
Cuando cargue su código en su Arduino, diga un Uno, por ejemplo, le dirá cuántos bytes usa de los 32K disponibles. Esa es la cantidad de memoria flash que tiene (piense en el disco duro de la computadora). Mientras su programa se está ejecutando, está utilizando lo que se llama SRAM, y hay mucho menos de eso disponible.
A veces notarás que tu programa se comporta de manera extraña en un punto que ni siquiera has tocado en mucho tiempo. Podría ser que sus cambios más recientes causen que se quede sin memoria (SRAM). Aquí hay algunos consejos sobre cómo liberar algo de SRAM.
Almacenar cadenas en Flash en lugar de SRAM.
Una de las cosas más comunes que he visto es que el chip se está quedando sin memoria porque hay demasiadas cadenas largas.
Use la
F()
función cuando use cadenas para que se almacenen en Flash en lugar de SRAM, ya que tiene mucho más de eso disponible.Use los tipos de datos correctos
Puede guardar un byte cambiando de
int
(2 bytes) abyte
(1 byte). Un byte sin signo le dará 0-255, así que si tiene números que no superan los 255, ¡guarde un byte!¿Cómo sé que me estoy quedando sin memoria?
Por lo general, observará que su programa se comporta de manera extraña y se preguntará qué salió mal ... No cambió nada en el código cerca del punto en el que está en mal estado, entonces, ¿qué le pasa? Se está quedando sin memoria.
Hay un par de funciones para decirle cuánta memoria disponible tiene.
Memoria disponible
fuente
F()
cosa es una función específica de Arduino o está en las bibliotecas AVR? Podría considerar mencionarPROGMEM const ...
también.Además de lo que otros han dicho (en lo que estoy totalmente de acuerdo), recomendaría leer este artículo de adafruit sobre la memoria; Está bien escrito, explica muchas cosas sobre la memoria y proporciona pistas sobre cómo optimizarla.
Al final de la lectura, creo que obtendría una respuesta bastante completa a su pregunta.
Para resumir, tiene 2 posibles objetivos de optimización (dependiendo de dónde se encuentren los problemas de memoria):
F()
macro)También se describe un enfoque adicional para reducir el uso de SRAM (pero rara vez se usa, porque es un poco pesado al codificar y no es muy eficiente), consiste en usar EEPROM para almacenar datos construidos por su programa, pero no se usa hasta más tarde cuando algunas condiciones ocurrir, cuando los datos se pueden volver a cargar desde EEPROM.
fuente
Hay dos cosas que hacer si se queda sin almacenamiento:
Hay muchos consejos en línea sobre cómo hacer lo primero (y para la gran mayoría de las cosas que las personas hacen con el Arduino, el almacenamiento incorporado es más que suficiente después de "optimizar"). Entonces me enfocaré en el segundo:
Hay 3 cosas que usan flash o SRAM; cada uno necesita un enfoque ligeramente diferente para agregar almacenamiento:
almacenamiento variable: es posible expandir SRAM, como ya ha señalado sachleen. SRAM, FRAM y NVSRAM son todos apropiados para variables que cambian rápidamente. (Si bien, en principio, podría usar flash para almacenar variables, entonces debe preocuparse por el desgaste del flash). SPI (un protocolo en serie) es el más fácil de conectar al Arduino. La biblioteca SpiRAM funciona con el chip SRAM serie MicroKip 23K256 . El chip FRAM serie FM25W256 de Ramtron (ahora propiedad de Cypress) también usa SPI. El Cypress CY14B101 NVSRAM también usa SPI. Etc.
datos constantes que aún deben estar allí la próxima vez que se active la alimentación: esto es casi tan simple como expandir la SRAM. Hay muchos dispositivos externos de almacenamiento EEPROM, FRAM, NVSRAM y FLASH disponibles. Actualmente, el costo más bajo por MB son las tarjetas flash SD (a las que se puede acceder a través de SPI). El Ramtron FM25W256 (ver arriba), el Cypress CY14B101 (ver arriba), etc. también pueden almacenar datos constantes. Muchos protectores de expansión incluyen una ranura para tarjeta SD, y varias bibliotecas y tutoriales admiten lectura y escritura en tarjetas SD (flash). (No podemos usar SRAM para esto, porque SRAM olvida todo cuando se va la luz).
código ejecutable: Desafortunadamente, no es posible expandir la memoria Flash de Arduino para aumentar el espacio del programa. Sin embargo, un programador siempre puede refactorizar un boceto para reducir el tamaño del código a expensas de aumentar el tamaño de los datos y hacer que se ejecute un poco más lento. (En teoría, podría ir tan lejos como traducir todo su boceto a algún idioma interpretado, almacenar esa versión de su boceto en una tarjeta SD y luego escribir un intérprete para ese idioma que se ejecuta en el Arduino para buscar y ejecutar instrucciones del Tarjeta SD: adelante en Arduino , un intérprete BÁSICO, un intérprete Tom Napier Picaro, un lenguaje específico de la aplicación, etc.).
fuente