Ofertas TFGs/TFMs curso 2018/2019

flashing-led-rookie-electronics-2

Comenzamos el curso y, como siempre, en el B105 apostamos por la formación.

Si te apetece hacer el Trabajo Fin de Grado o Trabajo Fin de Máster con nosotros aquí tienes nuestras ofertas:

propuesta2018sep_TFTs

Habla con los tutores de los trabajos y envíanos tus preferencias antes del 30 de Septiembre. A continuación asignaremos los trabajos, intentando satisfacer vuestros gustos.

Os esperamos!

The Twelve Of B105 – WSN & Firefighting

sep18

Y aquí estamos de nuevo, tras unas buenas vacaciones y con las pilas cargadas. Eso sí, conscientes de que la vuelta puede ser algo dura, esperamos suavizarla con una nueva entrega de…

theTwelveOfB105

Todos habremos oído de los graves incendios forestales que se producen periódicamente en nuestro país. Acrecentados por el cambio climático, estos desastres naturales ya no solo se limitan a periodos estivales (enlace), extendiéndose a primavera y otoño.

Con el fin de atajar este problema, hace unos años se realizó una gran inversión en investigación e innovación para la prevención y lucha contra incendios con Prometeo. Este proyecto se enfoca desde un punto de vista integral, considerando todos los actores involucrados en las labores de monitorización y extinción.

Imagen post (2)

El papel de nuestro grupo fue el desarrollo de una red de sensores inalámbrica para detectar la presencia de fuego, y monitorizar variables ambientales relacionadas con el proceso de ignición. El sistema se diseñó con vistas al bajo coste y baja ocupación del espectro, además de no requerir de otras infraestructuras de telecomunicaciones (p.e. GSM, WiFi, etc.).

La red a desplegar consta de dos tipos de nodos:

Centrales: con un alcance de comunicación de hasta 15 Km, estos nodos agrupan y coordinan la información recopilada por los nodos sensores, además de incorporar otras funciones de gestión de red.

Sensores: encargados de la monitorización del entorno, incorporan sensores de temperatura, humedad, niveles de CO y CO2, y velocidad y dirección del viento. Su diseño de bajo consumo, basado en el procesador MSP430 de Texas Intrument, garantiza una vida útil de dos años con tan solo una batería de 600 mAh.

Nueva imagen de mapa de bits (2)

Este proyecto, probado y finalizado hace unos años, tuvo recientemente un impacto mediático considerable.

Y con esto acabamos por este mes. Esperamos que os haya resultado interesante, al igual que las pasadas entregas, y… ¡nos vemos el mes que viene!

 

How to deploy a Node-Red environment on a GCP instance

node-red

Son numerosos los tutoriales en Internet que explican cómo montar un servidor Node-RED sobre GCP haciendo uso de clústers. Sin embargo cuesta encontrar (si es que los hay), tutoriales sobre como desplegar dicho servidor en una instancia, por lo que en este tutorial, nos centraremos en este caso. ¿Te suena a chino todo lo que hemos dicho? ¿Por qué montarlo sobre una instancia y no un clúster? Expliquemos brevemente los conceptos más raros de la frases anteriores para entendernos mejor.

  • Node-RED: es una herramienta de programación, de libre distribución, la cual nos permite de una forma rápida, y sobretodo muy intuitiva, desplegar una web con un estilo moderno y funcional. Node-RED hace uso de la programación “en cajas”, en la cual interconectamos distintos bloques ya pre hechos de las librerías disponibles. Node-RED usa Javascript y permite introducir bloques con nuestro propio código, pero para las tareas más sencillas no será siquiera necesario saber Javascript. Un ejemplo de un desarrollo simple en Node-RED sería el siguiente:

node_red_example

Node-RED permite además añadir librerías creadas por usuarios, siendo la librería “dashboard” una de las más populares, pues incorpora cajas con elementos visuales que permiten la interacción con el usuario así como la visualización de datos. Un ejemplo de ello:

maxresdefault

¿Fácil, verdad? Quien diría viendo esa web que se ha hecho sin necesidad de saber ningún lenguaje, solo juntando las cajas correctas. Existen otras opciones, como thingsboard.io, pero para gustos los colores, además de no ser la mayoría gratuitas (o tener planes gratuitos muy limitados). Nosotros preferimos Node-RED porque integra soporte para comunicaciones por UDP, TCP y el reciente MQTT, lo que permite comunicaciones con cualquier tipo de dispositivo, especialmente con dispositivos IoT. Además, la comunidad de desarrolladores es enorme y podemos encontrar muchos ejemplos ya hechos para su libre distribución, siendo estos ejemplos a veces, justo lo que buscamos.

Tenemos muchas formas de ejecutar Node-RED, en nuestro PC (esto es corriendo en un servidor local), en páginas que ponen a nuestra disposición servidores ya montados y listos para empezar a trabajar (FRED) o en servidores virtuales privados (VPS) de los cuales hay cientos de ofertas en Internet (aunque destacan por su catálogo y precios Microsoft Azure, Amazon Web Services [AWS] y Google Cloud Platform [GCP]). Las ventajas de ejecutar nuestro entorno en un VPS frente a nuestro ordenador o un entorno ya hecho (y cerrado) son inmensas: disponibilidad total, herramientas de protección, escalabilidad, no compromiso de nuestros datos privados, gestión de recursos… y esas son solo alguna de ellas.

  • Google Cloud Platform: es uno de los tantos servicios de gestión de VPS que hay hoy en día. Si bien es cierto que uno de los que más fuerza tiene es AWS, Google ofrece algo que no ofrece el resto: un servidor gratuito al año con 24/7 en ejecución. Vale que es un servidor muy modestito (10 GB de almacenamiento; 0.6 GB de RAM y un único procesador), pero es gratis y para diseños simples puede ser más que suficiente. Es por esto que nos centraremos en este gestor VPS en este tutorial.
  • Instancia vs. cluster: Google denomina a cada uno de los VPS que creamos instancia. Un grupo de instancias trabajando de forma conjunta, compartiendo recursos y distribuyéndose el tráfico de red entre ellas forma un clúster. Claro, a priori parece que el clúster es mejor (y lo es), pero no es gratis. La instancia, sin embargo, sí. Siempre y cuando esa instancia sea de las más simples de Google, como ya hemos comentado antes.

Ahora que ya hemos explicado todo un poco, relee si quieres el primer párrafo del post. Ahora ya parece obvio por qué queremos desplegar Node-RED (y no otro) sobre una instancia (y no un clúster), porque…

free

 

Empecemos…

Lo primero, lógicamente, es tener una cuenta de Google activa. Nos dirigiremos a la consola de Google Cloud y activaremos nuestra cuenta, registrándonos en la versión de prueba gratuita.  Solo por registrarnos Google nos regala 300 $ en servicios GCP. Para nuestros propósitos no nos harán falta, pero nos vendrán genial si queremos cacharrear con todas las opciones que GCP ofrece. Completaremos todos nuestros datos (incluida la tarjeta de crédito, pero no pasa nada: Google nos avisará previamente en caso de que hiciéramos algo que incurriera en un desembolso). Tras registrarnos se nos creará nuestro primer proyecto (que podremos renombrar si queremos pinchando en configuración de proyecto).

En el buscador escribimos Compute Engine y en la nueva ventana, una vez cargue, creamos una nueva instancia, con la configuración que vemos en la siguiente imagen:

g1
La zona da igual siempre que sea en América (salvo Virginia del Norte). América es la única región con VPS gratuitas. El tipo de máquina ha de ser micro y permitir el tráfico HTTP y HTTPS. Nosotros hemos elegido Ubuntu por familiaridad con los comandos, pero cualquier otra distribución de las gratuitas que ofrece Google es válida. Notad que para saber que estáis siguiendo los pasos correctos, debe apareceros el texto de la derecha donde os informa de que la máquina seleccionada es gratuita. Pulsamos en crear y esperamos.

Una vez creada, hay diferentes cosas que sería interesante hacer antes de empezar a cacharrear (asignarnos una IP estática y abrir algunos puertos).

-Asignando IP estática podremos entrar en nuestro servidor sin necesidad de consultar qué IP nos ha concedido Google esta vez: siempre será la misma. Para ello escribimos Red de VPC en el buscador y entraremos en la sección del menú lateral izquierdo “Direcciones IP externas”. Seleccionaremos nuestra instancia y cambiaremos su tipo a estática. Le ponemos un nombre identificativo a esta IP y aceptamos.

-Abriendo puertos (bien sea TCP o UDP) permitiremos un acceso remoto a nuestro servidor. Hay que notar que esto es un arma de doble filo, pues si bien no podemos hacer mucho sin tener acceso a nuestro servidor remoto también es una puerta abierta a hackers, por lo que recomendamos abrir solamente los puertos que vayamos a necesitar. En nuestro caso será obligatorio abrir el puerto TCP 1880, pues será el que usará Node-RED tanto para la interfaz de diseño (donde colocaremos las cajitas) como para la interfaz web (donde nos mostrará el resultado de colocar y conexionar esas cajitas). Para ellos tecleamos en el buscador “Reglas de cortafuegos” y elegimos la opción que lleve también escrito Red de VPC.

Creamos una regla nueva:allowtcp

 

El nombre es opcional, todo lo demás, recomiendo dejarlo a esos valores. Cuando cojáis más soltura con GCP os recomiendo etiquetar vuestras distintas instancias para poder elegir destinos de reglas del cortafuegos y así que cada máquina tenga abiertos los puertos que necesita. Por ahora, y como solo tenemos una máquina creada, no pasa nada por aplicar en el campo destinos “todas las instancias de la red”. Guardamos y ya estaremos listos para empezar la instalación de Node-RED sobre nuestro VPS.

Volvemos a la vista de Compute Engine, donde estará nuestra instancia. En el campo “Conectar” pulsamos sobre SSH. Se nos abrirá una ventana nueva y cuando cargue ya estaremos dentro de nuestro VPS.

Para poder empezar a trabajar, tecleamos los siguientes comandos:

Nótese que entre los comandos, se instalará nodejs. En nuestro caso hemos instalado la versión 8.x por ser la recomendada en el momento de realizar este tutorial, pero se aconseja mirar en la página de nodejs cual es la última versión recomendada. Escribimos ahora el comando que instalará Node-RED en nuestro VPS.

Es también interesante instalar algunas herramientas de node-red que nos harán más fácil la gestión de nuestro servidor, por lo que teclearemos:

Después de esto ya podemos probar que Node-RED está correctamente instalado. Para ellos tecleamos:

Lo que debería arrojar en el terminal una salida que acaba con:

Esto es indicativo de que todo está correcto. ¡Probémoslo! Escribamos en nuestra barra del navegador la IP estática concedida por Google (sin http ni https delante seguida del puerto de acceso a Node-RED, separado por dos puntos “:”), algo así como 123.123.123.123:1880. Deberíamos ver esto:

node-red1

 

¡Todo funciona! Sin embargo esto presenta un enorme, enorme inconveniente: cualquiera que sepa nuestra IP puede acceder a nuestro servidor Node-RED y borrarnos todo el trabajo o inyectar código malicioso. Por ello, el siguiente paso, de vital importancia, es proteger nuestro servidor. Volviendo a la terminal abierta por SSH, pulsamos ctrl+C para parar la ejecución de Node-RED y escribiremos:

Lo que nos preguntará por la contraseña con la que deseamos proteger el servidor. Tras escribirla y pulsar intro, nos devolverá una secuencia hash con nuestra contraseña encriptada, que deberemos copiar, pues usaremos ahora. Escribiremos sobre el archivo de configuración de Node-RED. En el terminal tecleamos:

y dentro de este archivo buscaremos el siguiente texto:

adminAuth: {
type: “credentials”,
users: [{
username: “USUARIO“,
password: “HASH_GENERADO“,
permissions: “*”
}]
},

// To password protect the node-defined HTTP endpoints (httpNodeRoot), or
// the static content (httpStatic), the following properties can be used.
// The pass field is a bcrypt hash of the password.
// See http://nodered.org/docs/security.html#generating-the-password-hash
httpNodeAuth: {user:”USUARIO“,pass:”HASH_GENERADO“},
httpStaticAuth: {user:”USUARIO“,pass:”HASH_GENERADO“},

En usuario escribiremos el usuario que queramos, y en los campos password y pass, el hash generado anteriormente. La primera parte protegerá la parte de gestión (donde colocamos las cajitas), la segunda, la parte de visualización (la web que crean las cajitas). Es importante descomentar las lineas necesarias (esto es, eliminar los caracteres “//” con los que empiezan algunas lineas), para que el resultado quede tal y como hemos puesto arriba. Guardamos con CTRL+O y salimos con CTRL+X.

Por último, será interesante que nuestro servidor cargue automáticamente Node-RED cuando se reinicie, lo que hará más tolerante a fallos nuestra implementación. Para ello, escribimos:

Que nos indicará nuestro nombre de usuario. A continuación:

donde copiaremos el siguiente texto:

[Unit]
Description=Node-RED
After=syslog.target network.target

[Service]
ExecStart=/usr/bin/node-red
Restart=on-failure
KillSignal=SIGINT

# log output to syslog as ‘node-red’
SyslogIdentifier=node-red
StandardOutput=syslog

# non-root user to run as
WorkingDirectory=/home/TUUSUARIO/
User=TUUSUARIO
Group=TUUSUARIO

[Install]
WantedBy=multi-user.target

Hay que modificar solo los campos en rojo. Nuevamente, guardamos con CTRL+O y salimos con CTRL+X. Activamos el servicio creado escribiendo:

Comprobaremos que todo se haya hecho correctamente. Para ello primero es necesario reiniciar, por lo que escribimos:

Y tras esperar unos dos minutos, cargamos de nuevo la página con la IP del servidor en nuestro navegador. Ahora, al cargar node-RED debería pedirnos login, tanto a la parte de gestión como a la de visualización.

¡Eso es todo por nuestra parte! Ahora, a jugar.

The Twelve of B105 – Brain Patterns

aug18

Para ambientar este caluroso mes tenemos una nueva entrega de …

theTwelveOfB105

En este caso, hemos decidido recuperar la temática relacionada con la bioingeniería, campo que ya introdujimos en el cartel de Abril de 2018 con las Redes Neuronales Inalámbricas.

Este post está relacionado con el Trabajo Fin de Máster finalizado titulado “Diseño de estrategias para la detección de potenciales de acción en acciones basadas en movimientos”.

El objetivo de este trabajo es obtener patrones que nos permitan saber cuando alguien ha pensado en moverse, sin haber realizado el movimiento. Tras un largo trabajo para conocer este tipo de señales, llegamos a la conclusión de que era necesario un filtrado que permitiera utilizar sólo las señales de la banda de frecuencia relacionada con los movimientos, a saber, la banda alfa y la banda beta de la imagen (8-30 Hz aproximadamente).

stages

También concluimos que no sería suficiente con un procesado único, sino que el algoritmo debería estar formado por un conjunto de características o parámetros obtenidos de manera sencilla, de tal forma que la suma de varias de éstas nos permitiera saber si la persona quería moverse o no.

Se implementaron varios algoritmos que agrupaban ciertas características de las señales y después se probaron sobre unas señales obtenidas de una base de datos pública, de diferentes personas.

Ampliando el número de personas que se utilizaron en el TFM nombrado anteriormente, se ha llegado a tener un acierto de entre el 50 y el 80 %. Al ser este porcentaje muy variable y bajo para lo que nosotros queremos, hemos decidido proceder de la siguiente forma:

– Obtener nuestras propias señales para controlar totalmente el entorno.
– Implementar otros algoritmos que permiten detectar patrones, lo que supone aumentar la complejidad.

Para conocer el resto de temáticas del resto de meses, no dudéis en consultar la siguiente página.

El mes que viene se publicaran las ofertas de TFG/TFM/PFC para el siguiente curso, ¡Estad atentos! ¡Os esperamos!

The Twelve of B105 – Customized Foosball

jul18

Llegan las vacaciones, y qué mejor manera de empezar que disfrutando de un nuevo número de…

theTwelveOfB105

Y volvemos nada menos que con uno de los iconos del grupo: el futbolín. Tras una década con nosotros, este ya indispensable miembro del laboratorio ha sido objeto de múltiples mejoras y experimentos (véase su historia).

Mucho tiempo ha pasado desde el primer (y ahora arcaico) sistema para contabilizar los goles. Algunas de las últimas mejoras son:

Red inalámbrica de sensores/actuadores en el futbolín.  Las funcionalidades soportadas por esta red incluyen la gestión de la iluminación, detección de goles, lectura de huellas dactilares (ver TFG asociado), medición de la velocidad de la bola, etc.

Nuevas funcionalidades en la Raspberry Pi. Además del control de la pantalla táctil, esta plataforma actúa como nodo pasarela de la red de sensores/actuadores, registra las estadísticas de jugadores y equipos, e incluso envía notificaciones de los resultados a Slack y Twitter. Por otro lado, incorporamos una cámara para grabar las últimas jugadas, evitando así acaloradas discusiones.

Enlace con otros sistemas del AMIB105 (Ambient Intelligence). Periódicamente se transmite información de estadísticas de juego y replays.

Futbolín -Esquema (2)

Y aquí termina nuestro número de julio. Mientras esperáis al mes que viene, podéis echar un ojo a temáticas anteriores en el siguiente enlace.

¡Hasta el mes que viene!

 

 

The Twelve Of B105: Intelligent TAGs

jun18

Y para esta nueva entrega de….

theTwelveOfB105

… hablaremos del estado de otro de los proyectos en los que estamos trabajando.

Éste se basa en el uso de etiquetas inteligentes activas que almacenan información sobre la señal vial y el entorno que le rodea, como por ejemplo, el estado de la carretera. El esquema de cada una de éstas es el que puede verse en la imagen de abajo.

esquema

El sistema deberá encenderse periódicamente para detectar si hay alguien cercano pidiendo datos. La cercanía a la cual los datos pueden ser obtenidos por un receptor es uno de los problemas que encontramos al implementar este tipo de sistema, ya que el receptor puede estar en movimiento, debiendo poder realizarse la lectura/escritura desde un vehículo a cierta velocidad.

La gran diferencia con respecto a las etiquetas pasivas es que necesitan energía para poder funcionar, el cual es el otro problema que encontramos, porque los sistemas tienen que funcionar de forma autónoma durante varios años. Para ello, existen las técnicas de Energy Harvesting, las cuales se fundamentan en obtener energía del medio que está desaprovechada normalmente.

La técnica más implementada por el momento es la que permite obtener energía solar. Sin embargo, si buscamos la innovación en este tipo de técnicas, encontramos la energía de la radio frecuencia, dónde se pretende utilizar la energía de las ondas que se propagan por el aire; la energía mecánica que pretende utilizar las vibraciones y el flujo del aire; y la energía térmica, que intenta aprovechar los cambios de temperatura que hay en el entorno.

Esta energía debe no solo ser suficiente para alimentar el sistema, sino también para ser almacenada en baterías o supercondensadores, garantizando así el funcionamiento del sistema en condiciones límites. La elección de uno u otro dependerá de muchos factores, como la cantidad de energía generada, el tiempo en generarla, la cantidad de energía que necesitaría el sistema y cada cuanto. Aunque, preferiblemente, preferiríamos utilizar supercondensadores.

Como ya sabéis, podéis leer más sobre nuestros otros trabajos consultando los antiguos posts. También estamos en las redes sociales (@elb105) y en el edificio B, salas 104 y 105. ¡No seáis tímidos, os esperamos!

STM32F4: Depuración con OpenOCD de programas con múltiples hebras

RTOSdebug

Dentro de la serie de publicaciones relacionadas con la placa de desarrollo STM32F411-DISCOVERY, hoy os traemos un breve tutorial para activar la opción de soporte de RTOS del depurador OpenOCD, que es el que viene por defecto con el entorno de desarrollo SW4STM32. Esta opción facilita enormemente la depuración de programas en los que existen múltiples hebras corriendo en paralelo, ya que en cada paso nos proporciona información del estado de cada una de ellas. Esta técnica se conoce como thread awareness. Los sistemas operativos soportados por OpenOCD a día de hoy son: FreeRTOS, Linux, ChibiOS, embKernel, eCos, ThreadX, mqx y uCOS-III.

Para activar esta opción, que por defecto viene deshabilitada, debemos seguir los siguientes pasos:

1.- Editar el fichero stm32f4x.cfg, o el correspondiente a nuestro microcontrolador de la serie STM32, añadiendo la opción -rtos auto en la siguiente línea:

Este fichero se encuentra en la siguiente ruta:

 

2.- En Debug Configurations, en la pestaña de Startup, hay que cambiar la función donde se pone el breakpoint inicial al lanzar la depuración. Por defecto, esta función es main(), pero para que esta opción funcione correctamente, necesitamos que la función en la que pare sea posterior a la inicialización y puesta en marcha del sistema operativo, es decir, debe ser una función dentro de una hebra.

Figura 1. Captura de Debug Configurations. En este caso el punto de parada se pone en la función InitTask_main, que es la primera función de la primera hebra que se lanza.
Figura 1. Captura de Debug Configurations. En este caso el punto de parada se pone en la función InitTask_main, que es la primera función de la primera hebra que se lanza.

 

3.- Por último, al menos para el caso concreto de FreeRTOS, hay que añadir la siguiente línea en el fichero en el que se halle la función en la que hemos fijado el punto de parada anterior. En concreto, hay que colocarlo en las declaraciones globales, de forma que pueda ser leída por el depurador. De lo contrario, fallará al intentar parar la ejecución.

Esto se debe a que, en versiones anteriores de FreeRTOS, la variable uxTopUsedPriority contenía el máximo nivel de prioridad de las tareas, necesario al adquirir la información de las mismas. Esta variable cambió de nombre, pero los desarrolladores de OpenOCD aún no lo han corregido.

 

Una vez hayamos hecho todo lo anterior, al lanzar la depuración debemos poder ver todas nuestras hebras en la ventana de Debug.

Imagen 2. Captura de la ventana de Debug con el soporte de RTOS de OpenOCD activado.
Imagen 2. Captura de la ventana de Debug con el soporte de RTOS de OpenOCD activado.

 

Puede ser que, en ocasiones, sea necesario parar la ejecución antes de que se llegue a la función fijada en el punto 2, o pararla en cualquier momento antes del inicio del planificador del sistema operativo. En estos casos, será necesario revertir el argumento del paso 1 para desactivar el thread awareness, ya que si no lo hacemos OpenOCD fallará al intentar leer las hebras.

The Twelve Of B105: Augmented Reality

mar18

Ha pasado un mes más, y con él llega otra entrega más de…

theTwelveOfB105

… en la que aprovecharemos para ahondar en otra temática de actualidad: la realidad aumentada.

Esta tecnología y relacionadas (conocidas como RX – realidad virtual, mixta, aumentada –) se introducen discretamente en nuestro día a día, impulsadas por gigantes de la talla de Microsoft, Google, Intel o Apple. Sólo echando una ojeada en las webs de Intel o Qualcomm podemos observar algunos de los últimos avances en el sector, los cuales probablemente disfrutemos con nuestro próximo smartphone, consola, etc.

Chicago-Bean-AR

El continuo desarrollo de dichas tecnologías RX nos deja en herencia dispositivos muy versátiles, algunos de los cuales ya está aprovechando nuestro grupo. En esta línea, el proyecto LAZARO utiliza Google Tango para la detección y caracterización de barreras arquitectónicas en edificios. Con la aplicación desarrollada, y un smartphone compatible, un operario podría realizar de forma sencilla e intuitiva medidas clave de las instalaciones, y caracterizar así el grado de accesibilidad para personas con movilidad reducida.

A día de hoy, seguimos valorando aplicar este y otros tantos avances de este campo en nuestra labor. Para saber más sobre nuestro trabajo, tanto en esta línea como en otras tantas descritas en números pasados, recordad que podéis visitarnos en las redes sociales, o contactar con nosotros directamente. ¡Os esperamos!

STM32F4: Consideraciones para el uso de la memoria flash (Parte I)

nandflash

Siguiendo la serie de tutoriales y guías sobre el uso de la placa de desarrollo STM32F411-DISCOVERY, hoy hablaremos de la escritura, lectura y manejo de la memoria flash del microcontrolador (MCU). Como ya sabréis, el STM32F411VET6 cuenta con 128 Kbytes de memoria SRAM y 512 Kbytes de flash. La principal diferencia entre estos dos tipos de memoria es que la flash, al contrario que la SRAM, es no volátil, es decir, no pierde la información que almacena al desactivar la alimentación.  Esta característica hace que, en general:

  • La memoria SRAM se destine para el almacenamiento y manipulación de datos parciales, variables locales, cambios de contexto, etc.
  • La memoria flash se utilice parte para la memoria de programa, donde se almacena el código del programa a ejecutar por el procesador, y parte para el almacenamiento de datos de configuración o de los procesos que se controlan y se quieren conservar tras una desactivación temporal del sistema.

En este artículo nos centraremos en este último tipo de memoria, aportando algunas claves importantes para su uso, así como una serie de consideraciones y buenas prácticas a tener en cuenta para evitarnos algunos problemas frecuentes.

Lo primero que es importante tener claro es cómo se organiza la memoria flash de nuestro microcontrolador. Esto suele variar bastante de unos a otros. En general, la memoria se divide en bloques o bancos, que a su vez se pueden subdividir en sectores. La siguiente unidad de división de la memoria serían las páginas y, por último, las palabras, que se componen de un determinado número de bytes. En general, la palabra suele ser la unidad mínima de lectura/escritura en flash aunque, en algunos casos, es posible hacerlo a nivel de byte, y en otros se opera en double-word, es decir, de dos en dos palabras simultáneamente.

Para saber la organización en particular de un microcontrolador, lo mejor es acudir al manual de referencia del mismo. A continuación, podéis consultar tres ejemplos distintos del propio STMicroelectronics, para que podáis comprobar de primera mano cómo en cada uno la organización es de una forma distinta:

Este último ejemplo, el STM32F411VE, se corresponde con el MCU de nuestra placa Discovery, y será el caso concreto que utilizaremos en este artículo. En la siguiente imagen se muestra la información principal de nuestra memoria.

flashMemory
Figura 1. Captura de la sección “Embedded Flash memory in STM32F411xC/E”

En la tabla anterior podemos observar que los 512 Kbytes de memoria flash que tiene el MCU según se especifica en sus características, son en realidad un gran bloque llamado Main memory.  A parte, vemos que existen otros tres bloques reservados para usos específicos y que, por lo tanto, no contabilizan como memoria flash.

Lo primero que debemos decidir es qué parte de la memoria principal queremos reservarnos para nuestra disposición. En este caso, utilizaremos el Sector 7, al que nos referiremos como USER_FLASH. Una vez tenemos esto claro, es muy importante asegurarnos de que ese sector no se va a utilizar para nada más, de modo que ni nosotros machaquemos información de otra utilidad, ni otra utilidad sobrescriba nuestra información. Para garantizar esto, es necesario editar el linker script de nuestro proyecto, que ha sido generado automáticamente por CubeMX, y se encuentra en la ruta:

Este fichero es el encargado de dar las instrucciones al linker del uso y tamaño de cada área de memoria y, por lo tanto, debe editarse con sumo cuidado. Se escapa del alcance de esta publicación explicarlo en detalle, por lo que únicamente daremos las indicaciones básicas de las modificaciones necesarias. Para profundizar en su comprensión, os dejamos algo de documentación.

En primer lugar, en la sección MEMORY del fichero STM32F411VETx_FLASH.ld, que es donde se especifican las áreas de memoria, debemos reducir FLASH en los 128 Kbytes correspondientes al Sector 7, y añadir USER_FLASH indicando sus permisos, dirección de origen y tamaño. Con ello, esta sección pasa de esta configuración:

A esta otra:

En segundo lugar, hay que editar el apartado SECTIONS del mismo fichero, que es donde se definen las distintas secciones de memoria, ya sean para guardar código o datos. En concreto, vamos crear una nueva para guardar nuestros datos no volátiles en el área de memoria USER_FLASH. De este modo, desde nuestro código de programa, podremos declararnos variables de cualquier tipo que se almacenen en dicha sección y, por lo tanto, sean no volátiles. Para ello, al principio de este apartado, antes de la sección .isr_vector, añadimos el siguiente código:

Con estos pasos, ya tendríamos nuestra área de memoria flash delimitada de una manera segura y preparada para utilizarse desde nuestro código.

Para probar que todo está correctamente, vamos a proceder a leer y escribir un dato en memoria flash. Para ello, partiremos del proyecto desarrollado en el tutorial previo STM32F4: Interrupción externa. En concreto, lo que haremos es aprovechar la interrupción producida al pulsar el botón de usuario para conmutar la frecuencia de parpadeo del LED verde entre dos valores, que definiremos en main.c dentro de USER CODE BEGIN Includes.

Sin embargo, lo que haremos es guardar la variable que contiene el valor del delay que se esté utilizando en cada instante en la memoria flash. De este modo, en cualquier momento el sistema puede apagarse o resetearse y, al volver a funcionar, mantiene la última frecuencia de conmutación que tuvo operativa. Para ello, en main.c, dentro de USER CODE BEGIN PV, nos declaramos la variable globar current_delay del siguiente modo:

Lo más llamativo de esta declaración es el atributo:

Esta parte es justo la que le indica al linker que la variable current_delay de tipo uint32_t debe guardarse en la sección .user_data_flash, en vez de donde se guardan las variables por defecto. De este modo, el valor de la variable es no volátil. Hay que tener en cuenta que si bien esta variable se puede leer como cualquier otra, para escribir en ella, al tratarse de memoria flash, hay que seguir un procedimiento especial que comentaremos más adelante. Además, también hay que destacar que el atributo __section__ no se puede emplear para variables locales.

Por otra parte, si recordáis, en el tutorial de la interrupción externa se comentó que es recomendable minimizar el número de operaciones a realizar dentro del callback de la interrupción. Por ello, para este caso utilizaremos un flag que declararemos e inicializaremos en main.c, también dentro de USER CODE BEGIN PV, como:

Modificar el valor de este flag será lo único que haremos dentro del callback de la interrupción, que quedará del siguiente modo. Recordamos que este callback se encuentra en el fichero gpio.c.

Es importante destacar que para poder emplear la variable swap_flag en este otro fichero, hay que declararla en gpio.c, dentro de  USER CODE BEGIN 0, como extern.

Para este ejemplo, todo lo demás lo programamos dentro de la función main(). Queda en la mano del lector reorganizar este código en las funciones que considere oportunas para lograr un código de mayor calidad. Del mismo modo, queda pendiente el tratamiento de errores. Para el ejemplo, la función quedaría así:

Como asumimos ciertos conocimientos de programación por parte del lector, en este punto únicamente comentaremos ciertos aspectos relevantes:

  • Antes de escribir en memoria, hay que borrarla mediante la función HAL_FLASHEx_Erase(&EraseInitStruct, &PAGError), definida en el fichero stm32f4xx_hal_flash_ex.c. En la Sección 3.5.4 del Reference Manual RM0383 Rev 2 podéis encontrar más información al respecto.
  • La estructura EraseInitStruct se utiliza para configurar la operación de borrado de la memoria. En este caso, utilizamos siempre la misma configuración y por eso sólo se rellena una vez, pero esto no tiene por qué ser así. Podéis leer más sobre sus distintos campos en la cabecera de su definición, FLASH_EraseInitTypeDef, en el fichero stm32f4xx_hal_flash_ex.h.
  • Antes de realizar cualquier operación de borrado o escritura de la flash, es necesario desbloquearla con la función HAL_FLASH_Unlock(). Del mismo modo, al concluir dichas operaciones, hay que volver a bloquearla con la función HAL_FLASH_Lock().
  • Para escribir en memoria flash utilizamos la función HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (uint32_t)&current_delay, (uint32_t)data), definida en el fichero stm32f4xx_hal_flash.c.
    • El primer argumento que le pasamos es una macro definida en stm32f4xx_hal_flash.h que indica que haremos una escritura de una palabra, es decir, un dato de 32 bits. En ese fichero podéis ver qué otras opciones permite este microcontrolador.
    • El segundo argumento que le pasamos es la dirección de la variable donde queremos guardar el dato.
    • El tercer argumento que le pasamos es el dato a guardar que, en este caso, debe coincidir con el tamaño de palabra.

Por último, para poder confirmar que la escritura se ha realizado correctamente, durante su ejecución en Debug, podemos monitorizar las distintas posiciones de memoria desde la pestaña Memory del entorno Eclipse. En este caso vemos como la variable current_delay se encuentra al principio de la sección .user_data_flash, en la dirección 0x0806 0000. 

memory
Figura 2. Herramienta de Eclipse para monitorizar la memoria del MCU.

Además, como esta memoria es no volátil, podría suceder, dependiendo de la configuración del Debugger, que al reprogramar el MCU no se borrase la flash de usuario. Para hacerlo manualmente, podemos usar la herramienta Erase chip del siguiente modo.

La herramienta Erase chip permite borrar toda la memoria del MCU por completo.
Figura 3. La herramienta Erase chip permite borrar toda la memoria del MCU por completo.

Hasta aquí la publicación de hoy. Esperemos que os haya parecido interesante y os animéis a profundizar en las distintas líneas que se quedan abiertas. En la siguiente parte, comentaremos más aspectos importantes a tener en cuenta al trabajar con la memoria flash, por ejemplo, el almacenamiento de múltiples datos en ella.

Aprende Electrónica con la placa de desarrollo STM32F411-DISCOVERY

discovery

“Me lo contaron y lo olvidé; lo ví y lo entendí; lo hice y lo aprendí.”

Confucio

En el B105 tenemos la convicción de que la mejor manera para aprender algo es haciéndolo. Además, actualmente existen en el mercado multitud de placas de desarrollo muy económicas, por lo que ya no hay escusa para no ponerse manos a la obra. 

Por ello, arrancamos esta serie de publicaciones con el objetivo de guiar el aprendizaje del uso de sistemas empotrados. Para ello, hemos escogido la placa de desarrollo STM32F411-DISCOVERY de STMicroelectronics, que tiene un precio inferior a 15€ y el software necesario para desarrollar con ella es gratuito. Aun así, aunque el método variará, los conceptos o fundamentos que esperamos transmitiros con estas publicaciones son aplicables a cualquier plataforma basada en un microcontrolador.

Sin alargarnos mucho más, os dejamos una lista de tutoriales y ejemplos, que irá creciendo con el tiempo, en la que tendréis los enlaces a las distintas publicaciones de esta serie.

  1. STM32F4: Primeros pasos con el entorno de desarrollo
  2. STM32F4: Interrupción externa
  3. STM32F4: Configurar el PWM con timers
  4. STM32F4: Consideraciones para el uso de la memoria flash (Parte I) 
  5. STM32F4: Depuración con OpenOCD de programas con múltiples hebras

¡Suerte y ánimo!