viernes, 27 de enero de 2017

Tipos de memoria en Arduino



Existen tres tipos de memoria en los micro-controladores Arduino: memoria Flash, memoria SRAM y memoria EEPROM.(Memorias tipo AVR compatibles con toda la gama de Arduino excepto Arduino DUE, que utiliza otro tipo de arquitectura)



La configuración de Harvard resulta ser una buena elección para las aplicaciones embebidas y el chip Atmega 328 usado en el UNO de Arduino utiliza una arquitectura relativamente pura de Harvard. 


 









Los programas se almacenan en la memoria Flash y los datos se almacenan en SRAM.


El resto de componentes de la placa arduino sirven para regular voltajes, su gestión en las diferentes salidas, y conxiones y buses que interconectan otros componentes para la comunicación.


A continuanción, se pueden ver las caracterisiticas de los diferentes tipos de memoria más utilizadas.
Memoria
Características
RAM
Se pueden leer y escribir pero son volátiles
DRAM
Dynamic Random Access Memory,Son las memoria típicas de los PCs. Se construyen a base de condensadores y se pueden integrar cantidades ingentes de ellas en un único chip de forma barata.A cambio tiene que ser refrescadas cada poco, lo que complica el diseño con mecanismos de refresco de la memoria ( Por supuesto fuera de los ojos del orgullosos propietario)
SDRAM
 Synchronous Dynamic Random Access Memory. Como las DRAM, pero el mecanismo de refresco es síncrono
DDR
Double Data Rate Synchronous Dynamic Random Access Memory.Estas son las actuales memorias utilizadas en los PCS de sobremesa. Actualmente están en la versión DDR4
ROM
Read Only Memory,  son no volátiles, pero solo se pueden leer, no escribir.
PROM
Programable Read Only MemoryNo son volátiles y se pueden escribir y reescribir en unos equipos especiales. Hoy prácticamente están en desuso
EEPROM
Electically Erasable Programable Read only MemorySon igual que las PROM, pero con la curiosidad que se pueden reescribir eléctricamente lo que evita el engorro de llevarlas a reprogramar a maquinas raras.A cambio son lentas de escribir y tienen un número limitado de escrituras antes de morir.
FLASH
Es un derivado de la EEPROM, con varias ventajas, la principal es que no pierde la información cuando le quitamos la corriente y además pueden leerse y escribirse sobre la marcha.El inconveniente es que son lentas. Es la clase de memoria que se utiliza para fabricar las memorias USBs pendrives y demás


Diagrama de bloques de un microcontrolador:

Diagrama de bloques simplificado de un microcontrolador. Se compone de tres bloques fundamentales: la CPU (central Processing Unit), memoria (RAM y ROM) y las entrada y salidas. Los bloques se conectan entre sí mediante grupos de líneas eléctricas denominadas buses o pistas. Los buses pueden ser de direcciones (si transportan direcciones de memoria o entrada y salida), de datos (si transportan datos o instrucciones) o de control (si transportan señales de control diversas).



La CPU es el cerebro central del microprocesador y actúa bajo control del programa almacenado en la memoria. La CPU se ocupa básicamente de traer las instrucciones del programa desde la memoria, interpretarlas y hacer que se ejecuten. La CPU también incluye los circuitos para realizar operaciones aritméticas y lógicas elementales con los datos binarios, en la denominada Unidad Aritmética y Lógica (ALU: Aritmetic and Logic Unit).

En un registro interno del microcontrolador se encuentran 5 opciones diferentes de reloj que son seleccionadas por medio de un Multiplexor.




La señal de reloj es distribuida por la unidad de control a los diferentes bloques existentes: la CPU, las memorias, los módulos de entrada/salida, los contadores/timers, el SPI y la USART, al igual que el conversor Análogo Digital ADC.


Memoria Flash (espacio del programa) en Arduino:

La memoria Flash (espacio del programa) es donde Arduino almacena el sketch. Un sketch es el nombre que usa Arduino para un programa. Es la unidad de código que se sube y ejecuta en la placa Arduino. Esta memoria es no volátil, si Arduino deja de ser alimentado eléctricamente los datos que haya en esta memoria permanecerán. 

El tamaño de la memoria Flash de Arduino puede variar dependiendo del microcontrolador, aunque no es muy grande. Por ejemplo, para el chip ATmega168 el tamaño de la memoria Flash es de 16 kilobytes, de los cuales 2 kilobytes son utilizados por el bootloader. Para el caso del microcontrolador ATmega328 (como el que incorpora Arduino UNO) el tamaño de la memoria Flash es de 32KB, de los cuales el bootloader usa 0,5KB. Por lo que debemos desarrollar los programas de forma muy optimizada, usando los tipos de variables que menos memoria requieran, en la medida de lo posible. También debemos optimizar el código fuente de la aplicación para no repetir líneas de código.


La memoria flash se utiliza para almacenar la imagen del programa y cualquier información inicializada. Puede ejecutar código de programa desde flash, pero no puede modificar los datos en la memoria flash de su código de ejecución. Para modificar los datos, primero se debe copiar en SRAM.

La memoria flash es la misma tecnología utilizada para las unidades de pulgar y tarjetas SD. 

La memoria Flash tiene una vida útil limitada de unos 100.000 ciclos de escritura. Así que si subes 10 programas al día, todos los días durante los próximos 27 años, podrías agotarlo.

En un dispositivo simple, como un microcontrolador, es un desafío implementar un asignador de memoria dinámica que sea lo suficientemente simple para que los requisitos de tamaño de código se mantengan bajos, pero lo suficientemente potente como para evitar la fragmentación de memoria innecesaria y para hacer todo con unos ciclos de CPU razonablemente bajos. Los microcontroladores a menudo son bajos en el espacio y también funcionan a velocidades mucho más bajas que la PC típica en estos días.
El asignador de memoria implementado en avr-libc intenta hacer frente a todas estas restricciones, y ofrece algunas opciones de ajuste que se pueden usar si hay más recursos disponibles que en la configuración predeterminada.

Cuando se utiliza la asignación de memoria dinámica y la pila y el montón se separan en distintas áreas de memoria, esta es la forma más segura de evitar una colisión de pila.


Memoria SRAM (Static Random Access Memory ó memoria estática de acceso aleatorio) en Arduino
La memoria SRAM (Static Random Access Memory ó memoria estática de acceso aleatorio) es de tipo volátil, es el espacio donde los sketches (programas) almacenan y manipulan variables al ejecutarse. La información guardada en esta memoria será eliminada cuando Arduino pierda la alimentación. Esta memoria es de uso exclusivo para el programa en ejecución.
La memoria SRAM de Arduino es muy pequeña, por lo que debemos optimizar nuestros programas al máximo y no abusar de variables de tipo char muy grandes. Hay que tener en cuenta que cada carácter de una variable char utiliza un byte. En el microcontrolador ATmega 168 el tamaño de la memoria SRAM es de 1024 bytes, para el caso de un chip ATmega328 (como el que incorpora Arduino UNO) el tamaño es de 2KB (2048 bytes). 




Si la SRAM se queda sin espacio, el programa de Arduino fallará de forma imprevista, aunque se compile y se suba a Arduino correctamente la aplicación no se ejecutará o se ejecutara de manera extraña.
Variables locales, datos parciales. Usualmente se trata como banco de registros (PIC), Memoria volátil. Donde el sketch crea y manipula las variables cuando se ejecuta.
La memoria SRAM se utiliza para varios propósitos por un programa en ejecución:
  • Datos estáticos - Este es un bloque de espacio reservado en SRAM para todas las variables globales y estáticas de su programa. Para las variables con valores iniciales, el sistema de ejecución copia el valor inicial de Flash cuando se inicia el programa.
  • Heap - El montón es para elementos de datos asignados dinámicamente. El montón crece desde la parte superior del área de datos estáticos hasta que se asignan los elementos de datos.
  • Stack - La pila es para variables locales y para mantener un registro de interrupciones y llamadas de función. La pila crece desde la parte superior de la memoria hacia abajo hacia el montón. Cada interrupción, llamada de función y / o asignación de variable local hace que la pila crezca. Al regresar de una llamada de interrupción o de función, se recuperará todo el espacio de pila utilizado por esa interrupción o función.

Memoria EEPROM en Arduino

EEPROM es un espacio de memoria que puede ser utilizado por los programadores para almacenar información a largo plazo. Este tipo de memoria es no volátil, por lo que los datos guardados en ella permanecerán aunque Arduino pierda la alimentación. Esta memoria puede ser usada para guardar valores si es necesario. 

El tamaño de la EEPROM para un chip ATmega128 es de 512 bytes, para un chip ATmega328 es de 1KB (1024 bytes). Hay que tener en cuenta que el tamaño de la memoria EEPROM interna de Arduino es "pequeño" pero Arduino admite añadir módulos de memoria EEPROM externa de mayor tamaño.
 Se puede grabar desde el programa del microcontrolador. Usualmente, constantes de programa. Memoria no volátil para mantener datos después de un reset. Las EEPROMs tienen un número limitado de lecturas/escrituras.
Una desventaja de la memoria EEPROM es que es mucho más lenta que la memoria SRAM. El proceso de escritura de una celda (byte) cuesta en torno a 3.3 ms. El proceso de lectura es mucho más rápido (aunque sigue siendo más lento que la SRAM), leer 1024 bytes cuesta en torno a 0.3ms, es decir, 10.000 veces más rápida que la escritura.

Para escribir en la memoria EEPROM, tenemos que incluir la librería correspondiente:

#include <EEPROM.h>

for (int i = 0; i < 255; i++)
     EEPROM.write(i, i);
Y para leer de la EEPROM
#include <EEPROM.h>
 value = EEPROM.read(pos);


Donde pos, es la posición de EEPROM que queremos escribir. Para un UNO pos puede llegar hasta un máximo de 1.024, que es la longitud de EEPROM disponible. Para un Arduino Mega puede alcanzar 4k = 4.096


Diagrama de memorias utilizadas en Arduino  y su espacio asignado para cada tarea:


 Una vez endentemos el uso que Arduino realiza con los datos que maneja a través de las diferentes memorias, debemos saber que nuestra placa dispone de unos LED para informar al usuario de su correcto funcionamiento.

Cuando el microcontrolador esta leyendo o escribiendo datos, estos circulan a través de varias pistas donde los led parpadeando nos indican que se estan realziando lecturas/escrituras, además de un botón de reset si quieremos "vaciar" la memoria SRAM y volver a cargar el sketch:


 En la placa electrónica, podemos identificar estos LED que indican el funcionamiento de arduino mientra trabaja con los datos por las sigas TX y RX.



 Pero además de saber si a nivel de harware todo esta funcionando correctamente, cuando cargamos el skecht en Arduino, puede que nos quedemos sin espacio de memoria. 

Muchos problemas de mal funcionamiento pueden estar ocasionados por falta de memoria volátil al cargar el valor de las variables. Sin embargo, no percibimos que algo este fallando pues al cargar el sketch no hemos recibido ningún aviso de error.

Esto es ocasionado por que al cargar el sketch, la memoria utilizada es la flash, donde puede alojarse el programa, peor al ejecutarlo haga un uso excesivo de la memoria SRAM, dando problemas de funcionamiento pero no de compilación.

Para solucionar estos errores, siempre es bueno observar al cargar el sket el espacio de memoria que estamos ocupando por si resulta excesivo:










Bibliografía:

No hay comentarios:

Publicar un comentario