Saltar al contenido principal

Memoria y límites

Una placa tiene mucha menos memoria que un PC, y algunas cosas funcionan distinto que en Windows. Aquí están las cifras que dicen la VM y el IDE, y lo que cambia en tu programa.

RAM interna y PSRAM​

Una placa tiene dos memorias para tu programa:

  • La RAM interna, la que lleva el chip.
  • La PSRAM, un chip de memoria aparte, más grande. No todas las placas la tienen, y el perfil no lo dice.

La VM del ESP32 y la del ESP32-S3 funcionan con PSRAM y sin ella. La del ESP32-P4 y la del ESP32-S31 la necesitan: es donde guardan los fotogramas de la pantalla.

QuéDónde va
Lo que crea tu programa: cadenas, listas, mapas, objetos…Lo decide el sistema por su tamaño: los bloques pequeños, a la RAM interna, y los grandes, a la PSRAM si la hay. La frontera es de 4 KB en el ESP32 y el ESP32-S3, y de 16 KB en el ESP32-P4 y el ESP32-S31.
Las imágenes: bitmaps, sprites y fondosA la PSRAM si la hay; si no, a la RAM interna. Cada píxel ocupa 2 bytes: una imagen de 320 × 240 ocupa 153.600 bytes.
El doble buffer de la pantalla, en el ESP32 y el ESP32-S3A la RAM interna, y si no cabe, a la PSRAM. Un byte por píxel del view: 76.800 bytes para 320 × 240.
Los fotogramas de la pantalla, en el ESP32-P4 y el ESP32-S31Dos, del tamaño del panel, en la PSRAM. Dos bytes por píxel: 1.036.800 bytes cada uno en un panel de 720 × 720.
Los samples y la música de 4 KB o másA la PSRAM si la hay; si no, a la RAM interna.

Para ver cuánta memoria gastas, usa memUse() y memFree(), de la librería estándar:

WindowsESP32 / ESP32-S3ESP32-P4ESP32-S31
memUse()Lo que la VM ha reservado para tu programaIgualIgualIgual
memFree()Siempre 0La RAM interna libre, sin la PSRAMToda la memoria libre, con la PSRAMToda la memoria libre, con la PSRAM

En la placa, el recolector de basura salta más a menudo que en Windows: su factor de crecimiento es 1,2, y en Windows, 1,7 (ver GC).

Si la memoria se acaba, la VM recoge la basura y lo vuelve a intentar, tres veces. Si no lo consigue, escribe en el monitor serie «Fallo en ReallocAlloc Null», con los bytes que pedía, y se cierra.

El tamaño del programa y de los ficheros​

La flash de la placa se reparte en una tabla de particiones que el IDE hace cada vez que la graba. La VM va en un sitio fijo, y la memoria de ficheros (LittleFS), donde van el programa y sus recursos, ocupa desde el final de la VM hasta el final de la flash. El tamaño de la flash lo lee el IDE de la placa (ver Grabar el firmware y ejecutar).

Flash de la placaFicheros en el ESP32 y el ESP32-S3Ficheros en el ESP32-P4 y el ESP32-S31
4 MB2.624 KB960 KB
8 MB6.720 KB5.056 KB
16 MB14.912 KB13.248 KB
32 MB31.296 KB29.632 KB

El sitio de la VM mide 1.408 KB en el ESP32 y el ESP32-S3, y 3.072 KB en el ESP32-P4 y el ESP32-S31; delante, en los primeros 64 KB de la flash, van el arranque, la tabla de particiones y dos particiones pequeñas del sistema (nvs y phy_init). Las cifras salen de las plantillas de particiones de JARU IDE, en Compiler\ESP32\<chip>\partitions_template.csv.

En la memoria de ficheros va todo lo que hay en la carpeta Build/flash del proyecto: el programa compilado, el boot.cfg y los recursos (ver La memoria de ficheros).

Check Storage, en la página Storage de ESP32 Tools (grupo LittleFS Storage Check), te dice si cabe. Lee de la placa el tamaño de su flash, suma lo que hay en Build/flash, contando cada fichero en bloques enteros de 4 KB, y lo enseña en una barra:

MensajeQué quiere decir
«OK. Used Space: … KB / Total: … KB (…%)»Cabe.
«WARNING: Low storage space…»Cabe, pero ocupa más del 90 %.
«ERROR: Capacity exceeded…», con lo que sobraNo cabe.

Es una cuenta aproximada: no graba nada. Si los ficheros no caben de verdad, Run se para en el paso 1, antes de grabar nada: el Output dice «File system is full.» y «DEPLOYMENT FAILED: Error during LittleFS build.».

Cierra el monitor serie antes de Check Storage

Check Storage lee la placa por su puerto, y no aparta el monitor serie: si está abierto en ese puerto, no puede leerla. Ciérralo antes con Close Serial.

Las rutas de los ficheros​

En la placa, las rutas se escriben como en la memoria de ficheros, y no como en Windows:

  • Con /, nunca con \. En Windows valen las dos; en la placa, una ruta como Images\fondo.bmp no encuentra el fichero.
  • Con las mayúsculas y las minúsculas de su nombre. Windows no las distingue, y la memoria de ficheros de la placa sí: si el fichero se llama Images/Fondo.bmp, "images/fondo.bmp" funciona en Windows y no en la placa.

Las unidades flash: y sd: y los modos de apertura, que también cambian en la placa, están en File.

Lo que no hay en la placa​

  • readLine(). En la placa espera una línea por el puerto serie, y en la 0.9.7 no le llega nada: el monitor serie del IDE no envía lo que escribes. El programa se queda esperando para siempre. Les pasa a los ejemplos que piden un dato, como CheckPrime, Factorial_ForLoop, FibonacciGenerator y Palindromes. En Windows funciona.
  • Las teclas. En la placa, Input.map solo acepta GPIO, salvo en el ESP32-S31, que lee un teclado USB (ver Botones, pines y mando). No hay tecla para salir: un programa con un bucle sin fin no acaba nunca.
  • La ventana. Window Scale y cerrar la ventana para acabar el programa son de Windows.
  • MQTT.intStats y MQTT.resetIntStats. Solo existen en Windows.
  • El depurador. Debug corre siempre en la VM de Windows, y Stop no para un programa de la placa (ver Run en la placa).

Lo que solo funciona en la placa​

Estos módulos hablan con el hardware de la placa. En Windows se pueden usar, pero no hacen lo mismo:

MóduloEn Windows
GPIOLos pines son los del simulador GPIO.
LEDLa tira se ve en la tarjeta WS2812 Strip del simulador GPIO.
I2CEscribir sale bien, y leer da 0.
PowerPower.sleep() espera el tiempo de Power.wakeOnTimer la primera vez que duerme después de llamarlo, y si no, 100 ms; Power.wakeReason() devuelve siempre Power.WAKE_TIMER.
Display.backlightNo hace nada.
Power.sleep() en la Waveshare 2.8 y la JaruCade

Tras el primer Power.sleep(), estas placas se quedan sin USB: el monitor serie no recibe nada más, y el IDE no puede grabarlas hasta que las arrancas en modo de descarga (ver Placas soportadas).

Todos los problemas conocidos de JARU, juntos, están en Problemas conocidos.

Lo que se ve distinto que en Windows​

Los colores​

WindowsESP32 / ESP32-S3ESP32-P4ESP32-S31
Con doble buffer (Display.mode(2), el de serie)16,7 millones de colores (24 bits)256 colores (8 bits)65.536 colores (16 bits)65.536 colores (16 bits)

En el ESP32 y el ESP32-S3, el doble buffer guarda cada píxel en un byte: 3 bits de rojo, 3 de verde y 2 de azul. Hay 8 tonos de rojo, 8 de verde y 4 de azul, así que:

  • dos colores parecidos se ven iguales;
  • un degradado se ve a escalones;
  • draw.getPixel devuelve el color tal como ha quedado en el fotograma, no el que pediste.

Las imágenes y los sprites se cargan con 65.536 colores, pero al pintarse en el doble buffer pasan también a 256. Con el modo directo, Display.mode(1), se pinta con 65.536 colores, pero se ve cómo se pinta cada cosa (ver Display). Para un juego, elige colores que se distingan bien con 256.

El texto​

draw.text no usa la misma letra en Windows que en la placa:

  • En Windows, el texto sale siempre con la misma letra, de 13 píxeles de alto, diga lo que diga draw.font.
  • En la placa, draw.font elige una de las letras de la pantalla:
draw.fontLetra en la placa
0, 1 (la de serie), 3 y 5La pequeña, de 6 × 8 píxeles
2De 16 píxeles de alto
4De 26 píxeles
6De 48 píxeles, para relojes
7De 48 píxeles, de siete segmentos
8De 75 píxeles

Con la de serie, el texto de la placa mide algo más de la mitad que en Windows. Si tu juego coloca el texto a ojo en Windows, mira en la placa que no se monte ni se salga: el ancho de cada letra también cambia.