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 fondos | A 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-S3 | A 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-S31 | Dos, 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ás | A 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:
| Windows | ESP32 / ESP32-S3 | ESP32-P4 | ESP32-S31 | |
|---|---|---|---|---|
memUse() | Lo que la VM ha reservado para tu programa | Igual | Igual | Igual |
memFree() | Siempre 0 | La RAM interna libre, sin la PSRAM | Toda la memoria libre, con la PSRAM | Toda 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 placa | Ficheros en el ESP32 y el ESP32-S3 | Ficheros en el ESP32-P4 y el ESP32-S31 |
|---|---|---|
| 4 MB | 2.624 KB | 960 KB |
| 8 MB | 6.720 KB | 5.056 KB |
| 16 MB | 14.912 KB | 13.248 KB |
| 32 MB | 31.296 KB | 29.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:
| Mensaje | Qué 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 sobra | No 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.».
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 comoImages\fondo.bmpno 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.mapsolo 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.intStatsyMQTT.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ódulo | En Windows |
|---|---|
| GPIO | Los pines son los del simulador GPIO. |
| LED | La tira se ve en la tarjeta WS2812 Strip del simulador GPIO. |
| I2C | Escribir sale bien, y leer da 0. |
| Power | Power.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.backlight | No hace nada. |
Power.sleep() en la Waveshare 2.8 y la JaruCadeTras 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
| Windows | ESP32 / ESP32-S3 | ESP32-P4 | ESP32-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.getPixeldevuelve 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.fontelige una de las letras de la pantalla:
draw.font | Letra en la placa |
|---|---|
0, 1 (la de serie), 3 y 5 | La pequeña, de 6 × 8 píxeles |
2 | De 16 píxeles de alto |
4 | De 26 píxeles |
6 | De 48 píxeles, para relojes |
7 | De 48 píxeles, de siete segmentos |
8 | De 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.