- Sistema de almacanamiento persistente con AT+SYSMFG
El firmware AT del ESP32-C6 implementa un mecanismo de gestión de datos no volátiles a través del comando AT+SYSMFG, que permite operaciones dinámicas sobre espacios de nombres dedicados en la partición NVS (Non-Volatile Storage) sin requerir modificaciones del firmware. Esta característica es fundamental para actualizaciones de configuración en campo, inyección de certificados o registro de estado OTA.
1.1 Ciclo de vida de los espacios de nombres
Los espacios de nombres (Namespaces) actúan como contenedores lógicos, creados implícitamente al realizar la primera escritura de un par clave-valor. El ciclo completo incluye las siguientes operaciones:
- Escritura: Formato
AT+SYSMFG=<tipo>,"<namespace>","<clave>",<valor>. El parámetro<tipo>corresponde a un código de tipo de dato (1-8). - Consulta:
AT+SYSMFG?lista todos los espacios de nombres.AT+SYSMFG?"<namespace>"devuelve todos los pares de un namespace específico. - Borrado: Borrado granular por clave (
AT+SYSMFG=0,"<namespace>","<clave>") o borrado completo de un espacio de nombres (AT+SYSMFG=0,"<namespace>").
Ejemplo práctico con el espacio de nombres config_dispositivo:
// Escritura de parámetro numérico (intervalo de latido = 60s, tipo 4 = uint32_t)
AT+SYSMFG=4,"config_dispositivo","intervalo_latido",60
OK
// Escritura de cadena de texto (ID del dispositivo, tipo 7 = string)
AT+SYSMFG=7,"config_dispositivo","id_equipo","DEV-2024-007A"
OK
// Escritura de certificado binario (tipo 8 = binario, codificado en Base64)
AT+SYSMFG=8,"almacen_certificados","certificado_raiz","MIIB...[datos_base64]..."
OK
// Consulta de todos los pares en config_dispositivo
AT+SYSMFG?"config_dispositivo"
+SYSMFG:"config_dispositivo","intervalo_latido",4,4,60
+SYSMFG:"config_dispositivo","id_equipo",7,12,"DEV-2024-007A"
OK
// Borrado de una clave específica
AT+SYSMFG=0,"config_dispositivo","id_equipo"
OK
// Borrado completo del espacio de nombres de certificados
AT+SYSMFG=0,"almacen_certificados"
OK
Especificaciones técnicas importantes:
- Los tipos 1-6 representan enteros de diferentes anchos (1=uint8_t, 2=uint16_t, 4=uint32_t, 6=uint64_t).
- Las cadenas (tipo 7) tienen un límite de 4096 bytes incluyendo el terminador nulo.
- Los datos binarios (tipo 8) deben codificarse en Base64, con un tamaño original máximo de 4096 bytes.
- Los nombres de espacios y claves son sensibles a mayúsculas y minúsculas.
1.2 Directrices de implementación
Para una integración robusta en proyectos reales, se recomiendan las siguientes prácticas:
| Área | Directriz | Riesgo si se ignora |
|---|---|---|
| Aislamiento de datos | Separar espacios de nombres por dominio funcional: cfg_aplicacion para configuraciones, repositorio_certs para certificados TLS, registros_sistema para logs circulares. |
Colisiones de claves entre módulos, borrados accidentales. |
| Nomenclatura de claves | Utilizar formato subdomino_clave, como wifi_ssid, mqtt_broker_puerto, tls_huella_ca. |
Dificultad para identificar el origen de los datos. |
| Tipado consistente | Estandarizar el uso de uint32_t (tipo 4) para valores numéricos y verificar la respuesta tras cada escritura. |
Desbordamientos silenciosos o lecturas erróneas. |
| Operaciones atómicas | Realizar escrituras masivas mediante scripts que verifiquen la respuesta OK después de cada operación. |
Escrituras parciales por fallos de alimentación. |
Nota importante: Los datos almacenados mediante AT+SYSMFG persisten a través de reinicios y actualizaciones OTA, salvo que se eliminen explícitamente. Las actualizaciones de firmware deben incluir rutinas de migración para asegurar la compatibilidad con versiones anteriores de los esquemas de datos.
- Comunicación TCP/IP con el ESP32-C6
El subsistema de red del ESP32-C6 gestiona las conexiones a través de un modelo de recursos explícitos, donde cada conexión se identifica con un ID de Conexión (CID) único que se asigna al establecer la conexión.
2.1 Establecimeinto de una conexión TCP como cliente
El flujo completo para establecer una conexión TCP saliente implica configurar el modo Wi-Fi, conectar al router y, finalmente, iniciar la conexión con el servidor remoto. A continuación se muestra un ejemplo completo:
// 1. Configurar el dispositivo en modo estación (Station)
AT+CWMODE=1
OK
// 2. Conectar al punto de acceso Wi-Fi (se requiere esperar la IP)
AT+CWJAP="RedLocal","ClaveSegura123"
WIFI CONNECTED
WIFI GOT IP
OK
// 3. Establecer conexión TCP con el servidor remoto (puerto 9000)
AT+CIPSTART="TCP","192.168.1.50",9000
CONNECT
OK
// 4. Enviar datos (el módulo gestiona la fragmentación TCP)
AT+CIPSEND=12
> Hola servidor!
Recv 12 bytes
SEND OK
En el paso 2, la aparición del mensaje WIFI GOT IP indica que la asignación DHCP ha finalizado. Si no se recibe, se debe verificar la configuración del router.
2.2 Gestión de múltiples conexiones
Para escenarios más complejos que requieran múltiples conexiones simultáneas, se puede habilitar el modo multiconexión y utilizar el parámetro de ID de enlace (link ID) en los comandos. Esto permite, por ejemplo, mantener una conexión persistente con un servidor MQTT mientras se atienden peticiones HTTP entrantes.
// Habilitar modo multiconexión
AT+CIPMUX=1
OK
// Abrir dos conexiones TCP simultáneas (IDs 0 y 1)
AT+CIPSTART=0,"TCP","servidor_mqtt.example.com",1883
0,CONNECT
OK
AT+CIPSTART=1,"TCP","servidor_http.example.com",80
1,CONNECT
OK
// Enviar datos específicos a cada conexión por su ID
AT+CIPSEND=0,25
> publicar/topic {\"status\":\"ok\"}
0,SEND OK
AT+CIPSEND=1,35
> GET /datos HTTP/1.1\r\nHost: ejemplo\r\n
1,SEND OK
Cada conexión se gestiona de forma independiente, pudiendo cerrar una sin afectar a las otras mediante AT+CIPCLOSE=<link_id>.