pub:dglab_esp8266

esp8266-chip.jpgEl ESP8266 ofrece una solución de conectividad WiFi que puede tanto alojar la aplicación o descargar a un procesador de aplicación de las tareas relacionadas con la comunicación WiFi.

Es un SOC desarrollado por la empresa Espressif capaz de establecer conexiones a través de una red WiFi o de crear una red en forma de punto de acceso software (soft access point). Entre otras cosas, integra conectividad con otros procesadores y sistemas a través de SPI (Serial Peripheral Interface), UART (Universal Asynchronous Receiver/Transmitter) y SDIO (Secure Digital Input/Output).

Adicionalmente, el chip incluye pines de propósito general (GPIO) que pueden ser utilizados como entradas y salidas para el microcontrolador que integra el SOC.

La mayoría de los SOC's disponibles comercialmente integran un firmware de comandos AT que permite la conexión a redes, la creación de las mismas, y la comunicación mediante TCP y paquetes UDP. No es necesario modificar tal firmware para utilizarlo con estos propósitos, pero si se quiere tomar provecho de el SOC para actividades más concretas, donde se puedan utilizar los pines GPIO, personalizar las comunicaciones a través de UART, y en general, desarrollar un firmware distinto al que trae, será necesario programar el dispositivo mediante un SDK (Software Development Kit) que el fabricante nos proporciona.

El SDK proporcionado por Espressif se puede descargar de la web, pero se encuentra instalado y compilado por defecto en Dglab para facilitar el trabajo al estudiante. El SDK se encuentra en la siguiente ruta:

/opt/Espressif/ESP8266_SDK

Espressif proporciona proyectos de ejemplo para poder alterar el firmware del dispositivo con comportamientos comunes. Estos ejemplos se encuentran ubicados en la siguiente ruta:

/opt/Espressif/source-code-examples

Para ejemplificar cómo se integra el SDK en Eclipse y cómo se programa la placa de desarrollo de un esp8266 se va a partir de el ejemplo blinky.

Creación del proyecto en Eclipse

Para crear el proyecto en eclipse, seleccionamos:

File -> New -> C Project

Una vez nos aparece el cuadro de diálogo, seleccionamos dentro de Makefile project un proyecto vacío. Esto nos permitirá introducir las fuentes que queramos utilizar para el programa y editar nuestro propio makefile para dar comandos al compilador y al linker sobre como debe compilar y enlazar cada fichero.

En cuanto a la Toolchain, dado que utilizaremos la que se encuentra en el SDK, seleccionaremos –Other Toolchain–.

Configuración del proyecto

Una vez creado el proyecto está vacío por completo, y deberemos añadir las fuentes necesarias para construirlo. Para ello, comencemos añadiendo a la variable de entorno PATH la dirección donde se encuentra la toolchain xtensa-lx106. Para ello, nos vamos a la configuración del proyecto y en C/C++ Build seleccionamos Environment y añadimos a la variable PATH la siguiente ruta:

/opt/Espressif/crosstool-NG/builds/xtensa-lx106-elf/bin

NOTA: No se deben eliminar las rutas existentes en el path, sino añadir al final la nueva ruta, utilizando el separador :. Por ejemplo:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/Espressif/crosstool-NG/builds/xtensa-lx106-elf/bin
La configuración debe quedar tal y como se aprecia la siguiente imagen.

Es importante seleccionar que las variables se añadan a la ruta ya establecida por el sistema, puesto que de lo contrario, Eclipse no podría encontrar los programas de terminal de uso habitual.

Una vez añadida la ruta a la toolchain, debemos añadir la ruta para los Include de las librerías que se utilizarán en el proyecto. Estas librerías se encuentran ubicadas en el SDK, en la siguiente ruta:

/opt/Espressif/ESP8266_SDK/include

Para incluirlas en el proyecto, nos iremos a la configuración del mismo, en la pestaña C/C++ General, seleccionamos Paths and symbols, y una vez dentro, seleccionamos Includes. Añadimos la ruta anterior a todas las configuraciones y para todos los lenguajes tal y como se muestra en la siguiente imagen.

Utilización del Makefile

Este proyecto que hemos creado, utilizará un Makefile que nosotros le indiquemos para construir las fuentes del mismo, enlazarlas correspondientemente, generar el binario y programar el SOC.

Utilizaremos un Makefile genérico proporcionado en el SDK para evitar invertir tiempo en la escritura del mismo. Lo podemos obtener de la siguiente ruta:

/opt/Espressif/source-code-examples/example.Makefile

Arrastramos el fichero hasta la raíz del proyecto para añadirlo al mismo. Si Eclipse nos preguntara si queremos copiarlo, seleccionamos si. Será necesario renombrar el fichero a Makefile

Posteriormente necesitaremos añadir los ficheros fuente del proyecto. Para ello, veremos que los subdirectorios que podemos utilizar para los mismos (según el Makefile se establecen los directorios de los que se tomarán las fuentes en la línea 34) son user y driver.

Por tanto, creamos el directorio user en el directorio del proyecto e introducimos el siguiente código en el fichero user_main.c.

#include "ets_sys.h"
#include "osapi.h"
#include "gpio.h"
#include "os_type.h"
#include "user_config.h"
 
#define user_procTaskPrio        0
#define user_procTaskQueueLen    1
os_event_t    user_procTaskQueue[user_procTaskQueueLen];
static void user_procTask(os_event_t *events);
 
static volatile os_timer_t some_timer;
 
void some_timerfunc(void *arg)
{
    //Do blinky stuff
    if (GPIO_REG_READ(GPIO_OUT_ADDRESS) & BIT2)
    {
        //Set GPIO2 to LOW
        gpio_output_set(0, BIT2, BIT2, 0);
    }
    else
    {
        //Set GPIO2 to HIGH
        gpio_output_set(BIT2, 0, BIT2, 0);
    }
}
 
//Do nothing function
static void ICACHE_FLASH_ATTR
user_procTask(os_event_t *events)
{
    os_delay_us(10);
}
 
//Init function
void ICACHE_FLASH_ATTR
user_init()
{
    // Initialize the GPIO subsystem.
    gpio_init();
 
    //Set GPIO2 to output mode
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
 
    //Set GPIO2 low
    gpio_output_set(0, BIT2, BIT2, 0);
 
    //Disarm timer
    os_timer_disarm(&some_timer);
 
    //Setup timer
    os_timer_setfn(&some_timer, (os_timer_func_t *)some_timerfunc, NULL);
 
    //Arm the timer
    //&some_timer is the pointer
    //1000 is the fire time in ms
    //0 for once and 1 for repeating
    os_timer_arm(&some_timer, 1000, 1);
 
    //Start os task
    system_os_task(user_procTask, user_procTaskPrio,user_procTaskQueue, user_procTaskQueueLen);
}

Se puede observar que el código utiliza un temporizador que cada segundo llama la rutina some_timerfunc en la que se activa y desactiva el GPIO2. Por otro lado, genera una tarea dummy en la que simplemente se produce un retardo de 10 us.

El último fichero de código necesario es un fichero de configuración, en el que se establecerían detalles sobre la configuración del SDK y el proyecto. Este fichero se denomina user_config.h y se almacena en la carpeta user. En este proyecto, dado que no se necesita, estará vacío. Es importante, sin embargo, que exista, puesto que el SDK trata de incluir en ocasiones este fichero, y en caso de no existir, recibiríamos un error.

Construyendo el proyecto

Para construir el proyecto, una vez tenemos la estructura de ficheros que se muestra en la siguiente figura, deberemos hacer click en Project y posteriormente en Build Project.

Al llamar a la rutina Build Project, se lanza como target all, que significa que según el makefile trata de construir todos los ficheros y enlazarlos, según las subcarpetas en las que se encuentren.

Si todo el proceso ha ido bien, debemos obtener la siguiente salida por la consola:

18:43:10 **** Build of configuration Default for project ESP8266_Blinky ****
make all
CC user/user_main.c
AR build/app_app.a
LD build/app.out
FW firmware/

18:43:11 Build Finished (took 382ms)

Descarga del firmware al ESP8266

Para descargar el firmware al ESP8266 será necesario utilizar una utilidad de comunicación por puerto serie escrita en Python que se encuentra integrado en el SDK de Espressif. El nombre de esta herramienta es esptool.py.

El Makefile incluye un Target para poder programarlo directamente simplemente llamando:

make flash

Por otro lado, desde el punto de vista de la conexión hardware del dispositivo, se deberán conectar las siguientes lineas:

  • Rx: Receptor del ESP8266. Deberá conectarse al transmisor del ordenador o del adaptador usb/serie utilizado.
  • Tx: Transmisor del ESP8266. Deberá conectarse al receptor del ordenador o del adaptador usb/serie utilizado.
  • CH_PD: Es una señal de enable del módulo ESP8266. Para que el SOC se encuentre en funcionamiento será necesario mantener esta línea en alto a VDD (3.3V).
  • VDD: Alimentación del ESP8266. Es muy importante fijarnos en que, por lo general, los módulos comerciales se alimentan a 3.3 V. Alimentar un voltaje mayor a través de este puerto puede resultar en la destrucción del módulo.
  • GND: Conexión a masa del ESP8266.
  • GPIO0: El puerto GPIO0 se utiliza en los módulos para arrancar el bootloader cuando este se encuentra llevado a nivel bajo durante el arranque mediante una resistencia de pull-down. Si no iniciamos el bootloader, no seremos capaces de grabar el firmware en el microcontrolador.

Por tanto, una vez realizadas las conexiones, sólo quedan por establecer algunos parámetros, relativos al puerto serie listado en linux y la frecuencia de comunicación de la UART (Usualmente 115200 baudios).

Estos dos parámetros deben indicarse en el Makefile, en las líneas 27 y 28. En mi caso concreto, he necesitado listar los dispositivos (con ls /dev/) y detectar el puerto serie, que se llama ttyACM0 en mi caso. Modificamos estos valores en el Makefile, y sólo nos queda llamar el target flash. Para ello, hacemos click en la pestaña Project, Make target y Create, y rellenamos la ventana tal y como se muestra en la siguiente imagen:

Una vez añadida la receta para el target flash, sólo hace falta correrla, de nuevo en el menú Project, Make target y Build donde seleccionamos el target añadido, y se procede a la descarga del firmware en el dispositivo. La salida por la consola deberá ser similar a la siguiente:

19:21:27 **** Build of configuration Default for project ESP8266_Blinky ****
make flash
esptool.py --port /dev/ttyACM0 write_flash 0x00000 firmware/0x00000.bin 0x40000 firmware/0x40000.bin
Connecting...
Erasing flash...

Writing at 0x00000000... (3 %)
Writing at 0x00000400... (6 %)
Writing at 0x00000800... (10 %)
Writing at 0x00000c00... (13 %)
Writing at 0x00001000... (17 %)
Writing at 0x00001400... (20 %)
Writing at 0x00001800... (24 %)
Writing at 0x00001c00... (27 %)
Writing at 0x00002000... (31 %)
Writing at 0x00002400... (34 %)
Writing at 0x00002800... (37 %)
Writing at 0x00002c00... (41 %)
Writing at 0x00003000... (44 %)
Writing at 0x00003400... (48 %)
Writing at 0x00003800... (51 %)
Writing at 0x00003c00... (55 %)
Writing at 0x00004000... (58 %)
Writing at 0x00004400... (62 %)
Writing at 0x00004800... (65 %)
Writing at 0x00004c00... (68 %)
Writing at 0x00005000... (72 %)
Writing at 0x00005400... (75 %)
Writing at 0x00005800... (79 %)
Writing at 0x00005c00... (82 %)
Writing at 0x00006000... (86 %)
Writing at 0x00006400... (89 %)
Writing at 0x00006800... (93 %)
Writing at 0x00006c00... (96 %)
Writing at 0x00007000... (100 %)
Wrote 29696 bytes at 0x00000000 in 2.9 seconds (81.9 kbit/s)...
Erasing flash...

Writing at 0x00040000... (0 %)
Writing at 0x00040400... (1 %)
Writing at 0x00040800... (2 %)
Writing at 0x00040c00... (3 %)
Writing at 0x00041000... (3 %)
Writing at 0x00041400... (4 %)
Writing at 0x00041800... (5 %)
Writing at 0x00041c00... (6 %)
Writing at 0x00042000... (6 %)
Writing at 0x00042400... (7 %)
Writing at 0x00042800... (8 %)
Writing at 0x00042c00... (9 %)
Writing at 0x00043000... (9 %)
Writing at 0x00043400... (10 %)
Writing at 0x00043800... (11 %)
Writing at 0x00043c00... (12 %)
Writing at 0x00044000... (12 %)
Writing at 0x00044400... (13 %)
...
...
Writing at 0x0005c000... (84 %)
Writing at 0x0005c400... (85 %)
Writing at 0x0005c800... (86 %)
Writing at 0x0005cc00... (87 %)
Writing at 0x0005d000... (87 %)
Writing at 0x0005d400... (88 %)
Writing at 0x0005d800... (89 %)
Writing at 0x0005dc00... (90 %)
Writing at 0x0005e000... (90 %)
Writing at 0x0005e400... (91 %)
Writing at 0x0005e800... (92 %)
Writing at 0x0005ec00... (93 %)
Writing at 0x0005f000... (93 %)
Writing at 0x0005f400... (94 %)
Writing at 0x0005f800... (95 %)
Writing at 0x0005fc00... (96 %)
Writing at 0x00060000... (96 %)
Writing at 0x00060400... (97 %)
Writing at 0x00060800... (98 %)
Writing at 0x00060c00... (99 %)
Writing at 0x00061000... (100 %)
Wrote 136192 bytes at 0x00040000 in 13.4 seconds (81.4 kbit/s)...

Leaving...

19:21:47 Build Finished (took 19s.685ms)

Una vez realizado el proceso, el SOC está programado con el nuevo Firmware y listo para ser utilizado.

  • pub/dglab_esp8266.txt
  • Última modificación: 2020/09/28 11:44
  • (editor externo)