Read the book: «Raspberry Pi® a fondo para desarrolladores»

Font::

Raspberry Pi® a fondo

para desarrolladores

Raspberry Pi® a fondo

para desarrolladores

Derek Molloy


Dedicado a Sally, Daragh, Eoghan, Aidan y Sarah.

(¡Por orden de edad, que no de predilección!)

Acerca del autor

El Dr. Derek Molloy es profesor titular en la Escuela de Ingeniería electrónica, Facultad de ingeniería y computación, de la Dublin City University, en Irlanda. Da clases de programación orientada a objetos en sistemas empotrados, de electrónica digital y analógica y de IoT (Internet of Things, Internet de las cosas, por sus siglas en inglés) a estudiantes de grado y posgrado. Ha realizado sus contribuciones como investigador sobre todo en campos tales como visión por ordenador, gráficos en 3D y visualización, así como en tecnologías de e-Learning o aprendizaje por ordenador.

Derek produce una popular serie de vídeos en YouTube que ha servido a millones de personas para dar sus primeros pasos en los ámbitos de Linux en sistemas empotrados y de la electrónica digital. En 2013 lanzó un blog o web personal, que recibe miles de visitas diariamente, en la que integra sus vídeos de YouTube con otros materiales de apoyo, código fuente y foros de debate para los usuarios. En 2015 escribió un libro sobre la plataforma BeagleBone, Exploring BeagleBone: Tools and Techniques for Building with Embedded Linux, que fue muy bien recibido.

Derek ha recibido varios premios por su labor educativa. Fue merecedor del premio nacional a la innovación educativa "2012 Irish Learning Technology Association (ILTA) national award for Innovation in Teching and Learning". El galardón reconoce su enfoque de aprendizaje por la práctica en la educación de estudiantes de grado de ingeniería, que combina kits de electrónica y contenidos audiovisuales en línea. En 2012, como resultado de la ferviente nominación de sus estudiantes y colegas, recibió también el premio "Dublin City University President's Award for Excellence in Teaching and Learning" que reconoce nuevamente su excelencia en el ámbito de la educación.

El lector puede consultar más datos sobre Dereck, su trabajo y el resto de sus publicaciones en su página web personal: www.derekmolloy.ie.

Acerca del editor técnico

El Dr. Tom Betka llegó al mundo del desarrollo para sistemas empotrados desde su anterior trabajo en la industria aeronáutica. Así mismo, practicó la medicina durante más de diez años. Durante este tiempo, su amor por los ordenadores y el desarrollo de software lo llevó hasta los sistemas empotrados, y su formación en informática, hasta obtener una segunda titulación. Después de abandonar la práctica clínca, el Dr. Betka comenzó a trabajar en el mundo de la programación y como experto en materias de medicina y sistemas empotrados en diferentes compañías de software. Entre sus trabajos más recientes se incluyen proyectos en el Kennedy Space Center de la NASA y la Sierra Nevada Corporation. El primer amor de Tom fueron los lenguajes de programación de la familia del lenguaje C, que empleó para programar microcontroladores de 8 bits. Como usuario de Linux durante más de una década, también ha trabajado unos años con dispositivos BeableBone, BeagleBone Black y Raspberry Pi. Entre sus aficiones se cuentan las matemáticas avanzadas, la aviación, el modelismo de cohetería de gran potencia y la robótica. Es fácil encontrarlo en su taller casero trabajando en proyectos construcción de prototipos de dispositivos. Además, en otra vida por así decir, Tom fue batería profesional y uno de los primeros en adoptar dispositivos con tecnología de percusión digital en sus actuaciones de músca en vivo.

Agradecimientos

Debo dar las gracias a todo el equipo de Wiley Publising una vez más por su trabajo sobresaliente en este proyecto. A Jim Minatel por su empeño en que llevase adelante este concepto de libro y por su apoyo renovado para la realización de un libro que se centrase en el aprendizaje en profundidad. A Aaron Black y Jody Lefevere, por hacer avanzar el proyecto y por su apoyo y ayuda durante todo su desarrollo. A Jennifer Lynn, por hacerme respetar los plazos y por estar siempre disponible para responder a mis preguntas. A Adaobi Obi Tulton, el editor del proyecto, por llevarlo hasta su finalización de la manera más eficiente posible: ha sido un verdadero placer volver a trabajar con un editor de su categoría. A Keith Cline y Marylouise Wiak, los correctores, por hacer este libro legible en inglés americano. A Barath Kumar Rajasekaran, el editor de producción, y Nancy Bell, la revisora, por dar coherencia al conjunto y crear un producto final bien terminado.

Expreso mi más sincero agracedimiento a Tom Betka, el editor técnico, por la increíble cantidad de tiempo y esfuerzo personal que ha invertido para asegurar que el contenido de este libro se pueda utilizar sin problemas por los lectores. Tras la publicación de mi libro sobre BeagleBone, Tom proporcionó motu proprio comentarios muy valiosos en la página web del libro, que sirvieron para afianzar el título.

Así, pensé de inmediato en Tom cuando acepté este proyecto y estuve encantado de que aceptase el papel de editor técnico. Tom es un académico, un erudito e indiscutiblemente toda una inspiración; además siempre ha estado disponible para analizar conmigo cualquier asunto técnico. Este libro se ha beneficiado enormemente de sus conocimientos técnicos, de su experiencia vital y de sus enormes capacidades. Estoy convencido de que no podría haber encontrado mejor editor técnico para el tema tratado.

Debo también agradecer a las miles de personas que se toman la molesta de comentar mis vídeos en YouTube, las entradas de mi blog y los artículos que publico en mi página web. y consejos recibidos, que de verdad me han ayudado en el desarrollo de los temas tratados en mis libros.

La Escuela de ingeniería electrónica de la Dublin City University es un lugar magnífico para trabajar gracias, en gran medida, a su espíritu de grupo y a su compromiso con una educación en ingeniería rigurosa, innovadora y accesible. Agradezco nuevamente a mis colegas de la Escuela por su apoyo, sus ánimos y su tolerancia durante la redacción de este libro. En particular doy las gracias a Noel Murphy y Connor Brenan por compartir la carga de trabajo de la dirección de la Escuela conmigo mientras me encontraba completamente absorto en la escritura del libro. Gracias de nuevo a mi hermano David Molloy por sus expertos consejos de software y por su apoyo. Gracias a Jennifer Bruton por su experta y meticulosa revisión de los circuitos, el software y los contenidos utilizados en este libro. Así mismo, agradezco a Martin Collier, Pascal Landais, Michele Pringle, Robert Sadleir, Ronan Scaife y John Whelan por su continuo apoyo, consejo y asesoramiento experto.

Obviamente, mi mayor agradecimiento es para mi familia. Tardé más de seis meses en escribir este libro; principalmente por las noches y en los fines de semana. Gracias a Sally, mi mujer, y a nuestros hijos Daragah, Eoghan, Aidan y Sarah por aguantarme, una vez más, durante la redacción de este libro. Gracias a mi madre, Catriona, y a mi padre, David, por toda una vida de apoyo, ánimo e inspiración. Por último debo agradecer al resto de mi familia por tolerar, otros seis meses, con buen talante mis ausencias en eventos y fiestas familiares: ya no tengo excusa, ¡a menos que escriba otro libro!

Resumen de contenidos

Introducción

Parte I Aspectos básicos del Raspberry Pi

Capítulo 1 El hardware del Raspberry Pi

Capítulo 2 El software del Raspberry Pi

Capítulo 3 Exploración de sistemas Linux empotrados

Capítulo 4 Interfaz con los componentes electrónicos

Capítulo 5 Programación con Raspberry Pi

Parte II Interfaz, control y comunicaciones

Capítulo 6 Interfaz de entrada/salida en el Raspberry Pi

Capítulo 7 Compilación cruzada y el IDE Eclipse

Capítulo 8 Interfaz con los buses del Raspberry Pi

Capítulo 9 Mejora de las interfaces de entrada/salida en el RPi

Capítulo 10 Cómo interaccionar con el entorno físico

Capítulo 11 Interfaz en tiempo real con el Arduino

Parte III Comunicación e interacción avanzadas

Capítulo 12 IoT (Internet of Things)

Capítulo 13 Control y comunicación inalámbricas

Capítulo 14 Raspberry Pi con una interfaz de usuario enriquecida

Capítulo 15 Imágenes, vídeo y audio

Capítulo 16 Programación del núcleo

Contenidos

Introducción

Estructura del libro

Convenciones utilizadas en este libro

Material necesario

Fe de erratas

Contenido digital y código fuente

Parte I

Aspectos básicos del Raspberry Pi

Capítulo 1

El hardware del Raspberry Pi

Introducción a la plataforma

¿A quién está destinado el RPi?

Cuándo utilizar el RPi

Cuándo no utilizar el RPi

La documentación del RPi

El hardware del RPi

Las versiones del Raspberry Pi

El hardware del Raspberry Pi

Accesorios del Raspberry Pi

Accesorios importantes

Una fuente de alimentación externa de 5 V

Tarjeta micro-SD para iniciar el sistema operativo

Cable Ethernet para conectividad de red

Accesorios recomendados

Cable HDMI para conectar a monitores o televisiones

Cable serie USB a TTL UART 3,3 V para localización de problemas

Accesorios opcionales

Un hub USB para conectar múltiples dispositivos USB

Adaptadores micro-HDMI a VGA para vídeo y sonido

Adaptadores WiFi para conectividad inalámbrica

Dispositivos de almacenamiento USB

Webcam USB para captura de imágenes y streaming de vídeo

Teclado y ratón USB para computación de propósito general

Carcasas para proteger el RPi

Placas de extensión HAT

Cómo destruir su RPi

Resumen

Soporte

Capítulo 2

El software del Raspberry Pi

Linux en el Raspberry Pi

Distribuciones de Linux para el RPi

Cómo crear una imagen Linux en una tarjeta SD para el RPi

Cómo conectarse a una red

Cable Ethernet estándar

Cable Ethernet cruzado

Cómo comunicarse con el RPi

Conexión serie con el cable USB a TTL de 3,3 V

Conexión segura con SSH (Secure Shell)

Conexiones SSH (Secure Shell) mediante PuTTY

Chrome Apps: cliente Secure Shell

Como transferir archivos mediante PuTTY/psftp sobre SSH

Control del Raspberry Pi

Comandos básicos de Linux

Primeros pasos

Comandos básicos del sistema de archivos

Variables de entorno

Edición básica de archivos

¿Qué hora es?

Gestión de paquetes

Configuración del Raspberry Pi

La herramienta de configuración del Raspberry Pi

Actualización del software del RPi

Salida de vídeo

Interacción con los LED de la placa

Apagado y reinicio

Resumen

Capítulo 3

Exploración de sistemas Linux empotrados

Introducción a Linux para sistemas empotrados

Ventajas y desventajas de Linux para sistemas empotrados

¿Es Linux gratuito y de código abierto?

Cómo iniciar el Raspberry Pi

Los gestores de arranque del Raspberry Pi

Espacio del núcleo y espacio de usuario

El gestor de sistema y servicios systemd

Gestión de sistemas Linux

El superusuario

Administración del sistema

El sistema de archivos de Linux

Enlaces a archivos y directorios

Usuarios y grupos

Permisos del sistema de archivos

El directorio raíz (root) de Linux

Comandos para sistemas de archivos

La fiabilidad de los sistemas de archivos en las tarjetas SD

Comandos de Linux

Redirección de entrada y salida (>, >> y <)

Tuberías (| y tee)

Comandos de filtro (de sort a xargs)

Los comandos echo y cat

diff

tar

md5sum

Procesos de Linux

Cómo controlar los procesos en Linux

Procesos en primer y en segundo plano

Otros temas de Linux

Cómo utilizar Git para el control de versiones

Una introducción práctica

Cómo clonar un repositorio (git clone)

Cómo obtener información de estado (git status)

Cómo añadir archivos al área de preparación (git add)

Cómo hacer commit en el repositorio local (git commit)

Envío al repositorio remoto (git push)

Ramas de desarrollo de Git

Cómo crear una rama de desarrollo (git branch)

Cómo fusionar ramas de desarrollo (git merge)

Cómo borrar una rama de desarrollo (git branch -d)

Comandos habituales de Git

Cómo utilizar escritorios virtuales

El código fuente de este libro

Resumen

Otras lecturas

Bibliografía

Capítulo 4

Interfaz con los componentes electrónicos

Cómo analizar nuestros circuitos

Multímetro digital

Osciloscopios

Principios básicos de los circuitos

Voltaje, intensidad de la corriente, resistencia y la ley de Ohm

División de voltaje

División de corriente

Cómo implementar circuitos del RPi en una placa de pruebas

Multímetros digitales (DMM) y placas de pruebas

Circuito de ejemplo: regulación de voltaje

Componentes discretos

Diodos

Diodos emisores de luz (LED)

Condensadores de filtro o aplanamiento y de desconexión

Transistores

Utilización de transistores como conmutadores

Utilización de transistores de efecto campo (FET) como conmutadores

Optoacopladores/optoaisladores

Interruptores y botones

Histéresis

Puertas lógicas

Entradas flotantes

Resistencias pull-up y pull-down

Salidas de colector abierto y de drenador abierto

Interconexión de puertas lógicas

Conversión analógico-digital

Frecuencia de muestreo

Discretización

Amplificadores operacionales

Amplificadores operacionales ideales

Retroalimentación negativa y seguidor de tensiones

Retroalimentación positiva

Consejos finales

Resumen

Otras lecturas

Capítulo 5

Programación con Raspberry Pi

Introducción

Rendimiento de los lenguajes en el RPi

Establecer la frecuencia de trabajo en la CPU del RPi

Un primer circuito para la computación física

Lenguajes de script

Opciones de lenguajes de script

Bash

Lua

Perl

Python

Lenguajes compilados dinámicamente

Javascript y Node.js en el RPi

Java en el RPi

C y C++ en el RPi

Introducción a C y C++

Compilando y enlazando

Cómo escribir el programa C/C++ más corto del mundo

Compilación estática y dinámica

Variables y operadores en C/C++

Punteros en C/C++

Cadenas de caracteres (strings) de estilo C

Control de LED en C

La "C" de C++

Primer ejemplo y gestión de cadenas en C++

Paso por valor, por puntero y por referencia

Control del LED con C++ (sin emplear objetos)

Introducción a la programación orientada a objetos

Clases y objetos

Encapsulación

Herencia

Control de LED orientado a objetos con C++

Interfaz con el sistema operativo Linux

Glibc y syscall

Cómo mejorar el rendimiento de Python

Cython

Cómo ampliar Python con C/C++

La API Python/C

Boost.Python

Resumen

Otras lecturas

Bibliografía

Parte II

Interfaz, control y comunicaciones

Capítulo 6

Interfaz de entrada/salida en el Raspberry Pi

Introducción

Entrada/salida de propósito general

Salida digital GPIO

Entrada digital GPIO

Resistencias pull-up y pull-down internas

Interfaz con circuitos DC con alimentación

Uso de C++ para el control de la salida GPIO con sysfs

Más sobre programación con C++

Funciones de retrollamada

Hilos de ejecución POSIX

Linux poll (sys/poll.h)

Una clase GPIO mejorada

Uso de la memoria para el control de la salida GPIO

Control de GPIO mediante devmem2

Control de GPIO mediante C y /dev/mem

Cambiar la configuración de las resistencias internas

WiringPi

Cómo instalar wiringPi

El comando gpio

Programación con wiringPi

Cambiar el estado de un LED mediante wiringPi

Pulsación de un botón: respuesta LED

Comunicación con sensores One-Wire

PWM y los relojes de propósito general

Pulse-Width Modulation (PWM)

Aplicación PWM: oscurecimiento de un LED

Aplicación PWM: control de un servomotor

Señales de reloj de propósito general

Las salidas GPIO y los permisos

Cómo escribir reglas udev

Los permisos y wiringPi

Resumen

Capítulo 7

Compilación cruzada y el IDE Eclipse

Cómo configurar una toolchain para compilación cruzada

La cadena de herramientas Linaro Toolchain para Raspbian

Comprobación de la toolchain

Cómo actualizar la variable de entorno PATH

Cadenas de herramientas de compilación cruzada para Debian

Emulación de la arquitectura armhf

Compilación cruzada con librerías de terceras partes (multiarch)

Compilación cruzada a través de Eclipse

Cómo instalar Eclipse en Linux

Configuración de Eclipse para compilación cruzada

El explorador de sistemas remotos

Cómo integrar GitHub en Eclipse

Depuración en remoto

Documentación automática en Doxygen

Cómo añadir soporte Doxygen a Eclipse

Compilación de Linux

Cómo descargar el código fuente del núcleo

Compilación del núcleo de Linux

Cómo instalar el núcleo de Linux

Cómo crear una distribución de Linux (avanzado)

Resumen

Otras lecturas

Capítulo 8

Interfaz con los buses del Raspberry Pi

Introducción a las comunicaciones por bus

I2C

Hardware I2C

El bus I2C en el RPi

Cómo habilitar el bus I2C en el RPi

Cómo habilitar un segundo bus I2C

Un circuito de prueba I2C

Un reloj de tiempo real

El acelerómetro ADXL345

Cableado del circuito de pruebas

Utilización de las herramientas I2C-tools de Linux

i2cdetect

i2cdump

i2cget

i2cset

Comunicaciones en C por el bus I2C

Encapsulación de dispositivos I2C en clases C++

SPI

Hardware SPI

SPI en el RPi

Pruebas en el bus SPI

Una primera aplicación SPI (74HC595)

Cableado del circuito de pruebas 74HC595

Comunicaciones SPI utilizando lenguaje C

Comunicación bidireccional SPI en C/C++

La interfaz ADXL345 SPI

Conexión del ADXL345 al RPi

Encapsulación de dispositivos SPI en clases C++

Comunicación SPI de tres hilos

Múltiples dispositivos esclavos SPI en el RPi

UART

El UART del RPi

Ejemplos de UART en C

Cliente serie RPi

Servidor serie LED RPi

Aplicaciones UART: GPS

Traducción de nivel lógico

Resumen

Otras lecturas

Capítulo 9

Mejora de las interfaces de entrada/salida en el RPi

Introducción

Conversión analógico-digital

Conversores analógico-digitales (ADC) SPI

El ADC SPI MCP3208

Cómo cablear el MCP3208 al RPi

Cómo comunicarse con el MCP3208

Una aplicación ADC: fotómetro analógico

Cómo comprobar el rendimiento del ADC SPI

La librería C para el BCM2835 (avanzado)

Conversión digital-analógica

Un conversor digital-analógico de bus I2C

Un conversor digital-analógico SPI

Cómo añadir salidas PWM al RPi

Cómo ampliar las salidas GPIO del RPi

El MCP23017 y el bus I2C

Cómo controlar el circuito LED GPIO

Cómo leer el estado del pulsador GPIO

Un ejemplo de configuración de interrupciones (avanzado)

El MCP23S17 y el bus SPI

Una clase C++ para dispositivos MCP23x17

Cómo añadir UART al RPi

Resumen

Capítulo 10

Cómo interaccionar con el entorno físico

Interfaces con los actuadores

Motores de corriente continua (DC)

Propulsión de motores DC pequeños (hasta 1,5 A)

Propulsión de motores DC mayores (más de 1,5 A)

Motores paso a paso

El controlador de motor paso a paso EasyDriver

Un circuito de control para un motor paso a paso en el RPi

Cómo controlar un motor paso a paso usando C++

Relés

Interfaz con sensores analógicos

Sensores analógicos lineales

Sensores analógicos no lineales

Acondicionamiento de la señal en un sensor analógico

Escalado de la señal mediante división de voltaje

Escalado y voltaje de desequilibrio o desplazamiento (offset) de la señal

Interfaz con un acelerómetro analógico

Interfaz con pantallas locales

Módulos de pantalla MAX7219

Módulos LCD de caracteres

Pantallas OLED

Compilación de librerías C/C++

Makefiles

CMake

Un ejemplo "Hello World"

Compilación de librerías C/C++

Usando una librería compartida (.so) o estática (.a)

Resumen

Capítulo 11

Interfaz en tiempo real con el Arduino

El Arduino

Un dispositivo esclavo serie Arduino

Ejemplo: una prueba de eco UART

Eco de la información de minicom (con parpadeo de LED)

Ejemplos de eco UART en C

Control de comandos UART en un Arduino

Un dispositivo esclavo Arduino I2C

Un circuito de prueba I2C

Ejemplo de eco de registro I2C

Ejemplo de sensor de temperatura I2C

Sensor de temperatura I2C con LED de advertencia

Comunicación en modo esclavo del Arduino usando C/C++

Ejemplo de sensor ultrasónico I2C

Un dispositivo esclavo SPI Arduino

Programación del Arduino en línea de comandos del RPi

Resumen

Parte III

Comunicación e interacción avanzadas

Capítulo 12

IoT (Internet of Things)

IoT (Internet of Things)

El RPi como sensor IoT

El RPi como sensor de servidor web

Nginx

Cómo configurar el servidor web Nginx

Cómo crear scripts y páginas web

PHP en el RPi

Aplicaciones GNU Cgicc (avanzado)

Un cliente web C/C++

Introducción a las comunicaciones en red

Un cliente web C/C++

Comunicaciones seguras mediante OpenSSL

El RPi como "Thing"

ThingSpeak

El programador de tareas Cron de Linux

El sistema crontab

User crontab

Cómo enviar correo electrónico desde el RPi

"Si esto, entonces aquello" (If This Then That, IFTTT)

Frameworks IoT a gran escala

MQ Telemetry Transport (MQTT)

IBM Bluemix Internet of Things

Ejemplo de publicación con IBM IoT MQTT usando Node.js

Ejemplo de publicación con IBM IoT MQTT usando C++

Visualización de datos con IBM Quickstart

Cliente/servidor con C++

Gestión de dispositivos IoT

Monitorización remota del RPi

Temporizadores RPi Watchdog

Direcciones IP estáticas

Alimentación por Ethernet (PoE, Power over Ethernet)

Módulos de extración PoE (PEM) (avanzado)

Resumen

Capítulo 13

Control y comunicación inalámbricas

Introducción a las comunicaciones inalámbricas

Comunicaciones Bluetooth

Cómo instalar un adaptador Bluetooth

Comprobación del módulo LKM

Cómo configurar un adaptador Bluetooth

Cómo hacer que el RPi sea "descubrible"

Desarrollo de aplicaciones Android con Bluetooth

Comunicaciones por WiFi

Cómo instalar un adaptador WiFi

El procesador esclavo WiFi NodeMCU

El firmware más reciente

Cómo conectar NodeMCU a WiFi

Cómo programar el NodeMCU

La interfaz del servidor web NodeMCU

JSON

Comunicación con mensajes JSON

El NodeMCU y el protocolo MQTT

Comunicaciones ZigBee

Introducción a los dispositivos XBee

Modo AT frente a modo API

Configuración XBee

XCTU

Cómo configurar una red XBee usando XCTU

Un ejemplo de XBee en modo AT

Configuración del dispositivo Arduino XBee (XBeeA)

Configuración del dispositivo RPi XBee (XBeePi)

Un ejemplo de XBee en modo API

Configuración del dispositivo RPi XBee (XBee1)

Configuración del dispositivo independiente XBee (XBee2)

El modo XBee API y Node.js

XBee y C/C++

Comunicación de campo cercano (NFC)

Resumen

Capítulo 14

Raspberry Pi con una interfaz de usuario enriquecida

Arquitecturas de interfaz de usuario enriquecida para RPi

El RPi como ordenador de propósito general

Cómo conectar un periférico de entrada Bluetooth

El RPi con una pantalla táctil LCD

Computación virtual en red (VNC)

VNC con el visor VNC Viewer

VNC con Xming y PuTTY

VNC en un PC con Linux

Aplicaciones fat-client o de cliente pesado

Desarrollo de interfaces gráficas de usuario enriquecidas

Introducción a GTK+ en el RPi

Una aplicación "Hello World" GTK+

Modelo de programación orientado a eventos

Aplicación de humedad y temperatura con GTK+

Introducción a Qt en el RPi

Cómo instalar las herramientas de desarrollo Qt en el RPi

La aplicación "Hello World" Qt

Introducción a Qt

Elementos de Qt

La clase QObject

Señales y slots

Herramientas de desarrollo para Qt

Primer ejemplo con Qt Creator

Una aplicación Qt con UI para un sensor meteorológico

Desarrollo de interfaces gráficas remotas

Aplicación GUI Qt para cliente pesado

Aplicaciones servidor con procesamiento multihilo

El servidor meteorológico multihilo

Análisis y representación de la corriente de datos

Resumen

Otras lecturas

Capítulo 15

Imágenes, vídeo y audio

Captura de imágenes y vídeo

La cámara del RPi

Cómo capturar imágenes fijas

Cómo grabar vídeo

Cómo usar la cámara del RPi en el espacio de usuario de Linux

Webcams USB

Video4Linux2 (V4L2)

Utilidad de captura de imágenes

Utilidades Video4Linux2

Desarrollo de programas Video4Linux2

Vídeo en streaming

Procesamiento de imágenes y visión por ordenador

Procesamiento de imágenes con OpenCV

Visión artificial con OpenCV

Boost

Audio en el Raspberry Pi

Principales herramientas software de audio

Dispositivos de audio para el RPi

Dispositivos de reproducción de audio USB y HDMI

Cómo reproducir emisoras de radio por Internet

Grabación de audio

Streaming de audio por la red

Audio Bluetooth A2DP

Lectura automatizada (Text-to-Speech)

Resumen

Otras lecturas

Capítulo 16

Programación del núcleo

Introducción

¿Por qué escribir módulos para el núcleo?

Introducción a los módulos cargables del núcleo (LKM)

Primer ejemplo de un LKM

El LKM Makefile

Cómo compilar un LKM en un ordenador con Linux

Cómo compilar un LKM en el RPi

Nuestro primer ejemplo de LKM a prueba

Comprobación del parámetro LKM

Ejemplo de un LKM empotrado

Rutinas de servicio de interrupción (ISR)

Rendimiento

Controlador GPIO LKM de botón mejorado

La interfaz kobject

Controlador GPIO LKM de LED mejorado

Hilos de ejecución del núcleo

Conclusiones

Resumen

Introducción

La idea básica del proyecto Raspberry Pi (RPi) es la de desarrollar una plataforma de computación pequeña y asequible que sirviera para estimular el interés de los niños por aprender los aspectos fundamentales de las tecnologías de la información y las comunicaciones. La rápida evolución de los dispositivos SoC (System-on a -Chip) de bajo coste para aplicaciones móviles posibilitó una amplísima distribución de la plataforma asequible RPi a principios de 2012. Su impacto fue inmediato: en febrero de 2015 ya se habían vendido más de cinco millones de placas Raspberry Pi. La proliferación de smartphones nos ha permitido dar por sentado que podemos tener ordenadores capaces de llevar a cabo miles de millones de operaciones por segundo en la palma de la mano. No obstante, el hecho de que podamos modificar el hardware y el software de unos dispositivos tan pequeños como potentes y adaptarlos a nuestras necesidades, así como desarrollar nuestras propias creaciones, no deja de resultar asombroso. Mejor aún: ahora es posible adquirir un Raspberry Pi Zero por menos de cinco euros, casi lo mismo que un desayuno.

Las placas Raspberry Pi propiamente dichas resultan demasiado complejas para que las utilice el público general. Es, sin embargo, su capacidad de ejecutar una versión empotrada (embedded) de Linux lo que las convierte en plataformas accesibles, adaptables y potentes. En conjunto, Linux y los sistemas empotrados hacen posible un desarrollo sencillo para este tipo de dispositivos, destinados realizar funciones en edificios inteligentes, dispositivos IoT (Internet of Things, literalmente "Internet de las cosas"), robótica, energía inteligente, ciudades inteligentes, interacción hombre-ordenador (HCI o Human-Computer Interaction por sus siglas en inglés), sistemas ciberfísicos, impresión en 3D, sistemas avanzados para vehículos y muchas más aplicaciones.

La integración del software Linux de alto nivel con unos componentes electrónicos de bajo nivel representa un cambio de paradigma en el ámbito del desarrollo para sistemas empotrados. Poder construir un circuito con componentes electrónicos de bajo nivel e instalar un servidor web Linux, que permitirá su control desde Internet, con solo unos pocos comandos solo se puede definir como revolucionario. Es fácil utilizar el Raspberry Pi como ordenador Linux de propósito general, pero es muchísimo más interesante, y todo un desafío, remangarse y manipular directamente los componentes electrónicos en los circuitos de nuestro propio diseño. ¡Para eso está este libro!

Este libro debería resultar muy atractivo para inventores, manitas, estudiantes, emprendedores, hackers, artistas y soñadores, es decir, para todo el mundo que desee llevar la potencia de Linux empotrado a sus productos, invenciones, creaciones o proyectos y comprender verdaderamente la plataforma RPi con todo detalle. No es este, sin embargo, un libro de recetas. Con escasas excepciones todo lo mostrado aquí se explica a un nivel que permitirá al lector diseñar, construir y depurar sus propias ampliaciones a los conceptos presentados. Tampoco se incluye en el libro ningún gran proyecto de diseño para el que se deba comprar un conjunto predeterminado de componentes y periféricos con los que alcanzar un resultado muy concreto. Más bien, este libro trata de proporcionar al lector el conocimiento básico suficiente, así como los detalles técnicos, que le permita explorar por su cuenta y, además, lo motive a hacerlo.

Creo firmemente en el aprendizaje con la práctica, así, presento ejemplos con hardware de muy bajo coste y muy fácil de encontrar de modo que el lector pueda seguir adelante. Mediante estos ejemplos prácticos, se describe con todo detalle el significado de los pasos a seguir. De este modo, cuando el lector sustituya sus propios componentes, módulos y periféricos hardware, será capaz de adaptar el contenido de este libro a sus propias necesidades. Y respecto a ese "gran proyecto de diseño", lo dejamos a la imaginación del lector.

En 2014 escribí un libro muy bien recibido sobre la plataforma BeagleBone, titulado: Exploring BeagleBone: Tools and Techniques for Building with Embedded Linux. Como este libro se centra en Linux empotrado (embedded Linux) y pone todo el énfasis en presentar los principios fundamentales, existen ciertas similitudes entre el contenido introductorio de aquel libro y el de éste. Sin embargo, este libro se ha escrito desde el principio directamente para la plataforma RPi y en él se analizan sus puntos fuertes y se abordan varias de sus debilidades. Asimismo, he aprovechado la oportunidad de ampliar el material para tratar temas como el desarrollo para el núcleo (kernel) de Linux, el Arduino como procesador de servicios, nodos sensores WiFi, comunicación XBee, mensajería MQTT, dispositivos IoT, el concepto "plataforma como servicio" (Platform as a Service, PaaS por sus siglas en inglés) y mucho más. Si tiene una copia de Exploring BeagleBone, debería visitar el sitio web del libro (www.exploringrpi.com) a fin de comparar el contenido de ambos antes de decidir cuál comprar.

Al escribir este libro me propuse cumplir los objetivos siguientes:

❏Explicar el funcionamiento de Linux en sistemas empotrados y su interacción con los circuitos electrónicos, y guiar para ello al lector por los distintos aspectos y desafíos que presenta la popular plataforma RPi.

❏Proporcionar información detallada y formación en profundidad acerca de Linux, electrónica y programación. Todo ello resulta necesario para dominar una variedad amplia y exhaustiva de temas en este ámbito.

❏Crear una colección práctica de ejemplos tipo "¡Hola, mundo!", tanto en hardware como en software, de todos los temas tratados en el libro, por ejemplo: interfaces a bajo nivel, entrada/salida de propósito general (General Purpose Input/Output, GPIO), buses, conversores analógico-digital (Analog-to-Digital Converter, ADC) conectados a bus, así como transmisores/receptores asíncronos universales (Universal Asynchronous Receiver/Transmitter, UART). Igualmente, se analizan librerías para programación de alto nivel como OpenCV y el Framework Qt. Por último, en el libro se cubren también temas más avanzados como la manipulación de registros a bajo nivel y el desarrollo de módulos cargables del núcleo (Loadable Kernel Module, LKM) de Linux.

❏Mejorar y ampliar las capacidades de interfaz que ofrece la plataforma RPi mediante el desarrollo de frameworks para conectarla a circuitos, por ejemplo ADC basados en SPI, a procesadores de servicio, como Arduino y NodeMCU, y a plataformas y servicios IoT basados en la nube.

❏Asegurar que todos y cada uno de los circuitos y fragmentos de código fuente tengan un amplio alcance pedagógico y que estén diseñados específicamente para funcionar en el Raspberry Pi. Todos y cada uno de los circuitos y ejemplos de código fuente de este libro se compiló y probó en la plataforma RPi; la mayoría, en múltiples versiones de la placa.

❏Utilizar ejemplos "¡Hola, mundo!" para construir una librería de código que el lector pueda emplear y adaptar después a sus propios proyectos con Raspberry Pi.

❏Publicar todo el código fuente en GitHub de forma que resulte fácil de utilizar.

❏Apoyar este libro con un sólido contenido digital, como los vídeos en el canal DerekMolloyDCU de YouTube y el sitio web, www.exploringrpi.com, desarrollado específicamente para este libro.

❏Asegurar que, al finalizar el libro, el lector contará con todo lo necesario para imaginar, crear y construir proyectos avanzados para el Raspberry Pi.

Estructura del libro

No cabe duda de que algunos de los temas tratados en este libro son muy complejos. Después de todo, los Raspberry Pi son dispositivos complejos. Sin embargo, este libro contiene todo lo necesario para dominar dichos temas y lo presenta dividido en tres partes principales:

❏Parte I: Aspectos básicos de Raspberry Pi

❏Parte II: Interfaz, control y comunicaciones

❏Parte III: Comunicación e interacción avanzadas

La primera parte del libro presenta el hardware y el software de las plataformas RPi en los capítulos 1 y 2 y, luego, proporciona tres capítulos introductorios:

❏Capítulo 3, “Exploración de sistemas Linux empotrados”

❏Capítulo 4, “Interfaz con los componentes electrónicos”

❏Capítulo 5, “Programación con Raspberry Pi”

Los lectores expertos en Linux, electrónica o software pueden obviar estas introducciones sin mayores problemas. Sin embargo, para todo el resto, se incluye un conjunto de materiales conciso pero detallado para asegurar que adquieren todos los conocimientos necesarios para trabajar con el Raspberry Pi de manera segura y eficaz. El resto hacen a menudo referencia a estos capítulos introductorios.

La segunda parte del libro, del capítulo 6 al 11, proporciona información detallada sobre las interfaces GPIO de Raspberry Pi, los buses (I2C, SPI), dispositivos UART y periféricos USB. Aprenderemos a configurar un entorno de compilación cruzada para abordar el desarrollo de aplicaciones de software a gran escala para el Raspberry Pi. La parte II describe también cómo combinar el hardware y el software para dotar al Raspberry Pi de la capacidad de interaccionar de forma eficaz con su entorno físico. Además, el capítulo 11 “Interfaz en tiempo real utilizando Arduino”, nos muestra cómo utilizar el Arduino como procesador esclavo con el Raspberry Pi. Esto sirve para superar algunas de las limitaciones de tiempo real que surgen al trabajar con Linux empotrado.

La tercera y última parte del libro, de los capítulos 12 al 16, describen cómo utilizar el Raspberry Pi para aplicaciones avanzadas de interfaz y comunicación, por ejemplo con dispositivos IoT, control y comunicaciones inalámbricas, interfaces gráficas de usuario enriquecidas, imágenes, audio y vídeo, así como la programación del núcleo de Linux. Por el camino nos encontraremos con múltiples tecnologías, como TCP/IP, ThingSpeak, IBM Bluemix, MQTT, Cgicc, alimentación por Ethernet (Power over Ethernet, PoE), WiFi, NodeMCUs, Bluetooth, NFC/RFID, ZigBee, XBee, cron, Nginx, PHP, correo electrónico, IFTTT, GPS, VNC, GTK+, Qt, XML, JSON, multihilo, programación cliente/servidor, V4L2, streaming de vídeo, OpenCV, Boost, audio USB, Bluetooth A2DP, lectura automatizada, LKM y kthreads.

Convenciones utilizadas en este libro

Este libro esta lleno de ejemplos de código fuente, así como de fragmentos completos que el lector podrá usar para construir sus propias aplicaciones. El código fuente y los comandos aparecen así en el libro:

This is what source code looks like.

Cuando se presenta el trabajo desarrollado en un terminal de Linux, suele ser necesario mostrar tanto la entrada como la salida en un solo ejemplo. La tipografía en negrita sirve para distinguir la entrada del usuario de la salida resultante. Por ejemplo:

pi@erpi ~ $ ping www.raspberrypi.org

PING lb.raspberrypi.org (93.93.128.211) 56(84) bytes of data.

64 bytes from 93.93.128.211: icmp_seq=1 ttl=53 time=23.1 ms

64 bytes from 93.93.128.211: icmp_seq=2 ttl=53 time=22.6 ms

...

El símbolo del sistema (prompt) $ indica que un usuario estándar de Linux ejecuta un comando, mientras que el símbolo del sistema # indica que quien ejecuta el comando tiene privilegios de superusuario. Una elipsis, simbolizada por (...), aparece siempre que ni el código fuente ni la salida eliminadas resulten imprescindibles para comprender una materia concreta. Editar de este modo la salida nos permite centrarnos sólo en la información más útil. Asimismo, un símbolo en forma de punta de flecha en una línea nos indica que el comando ocupa varias líneas en el libro, pero que debemos introducirlo en una sola línea. Por ejemplo:

pi@erpi /tmp $ echo "este es un comando largo que ocupa dos líneas en el →

libro pero que debe ser escrito en una sola línea de código" >> test.txt

Animamos al lector a que repita los pasos indicados en el libro por su cuenta, en todos aquellos lugares en los que aparezca la salida completa. Además, existe un repositorio en GitHub con los códigos fuente completos de todo el libro.

Asimismo, el lector encontrará otros estilos de texto en el libro. Por ejemplo:

❏Los nuevos términos y las palabras importantes se escriben entrecomilladas o destacas en su tipografía cuando aparecen por vez primera.

❏Las combinaciones de teclas se muestran así: Ctrl+C.

❏Todas las URL en el libro se refieren a direcciones HTTP o HTTPS y aparecen de este modo: www.exploringrpi.com.

❏Se utiliza, asimismo, un servicio de abreviación para crear alias de las URL más largas que aparecen en el libro. Dichos alias presentan la forma de tiny.cc/erpi102 (por ejemplo el segundo enlace en el capítulo 1). Si la dirección del enlace cambiase una vez publicado el libro, se actualizaría el alias.

Diversas características del libro indican que el contenido reviste especial importancia, o bien cuándo hay disponible información adicional:

ADVERTENCIAContiene información importante que nos permitirá evitar producir daños a la placa Raspberry Pi.

NOTAPresenta información adicional útil, como enlaces a recursos digitales y consejos útiles que pueden facilitar la comprensión de la tarea de que se trate.



Material necesario

Lo ideal sería que el lector contase con una placa Raspberry Pi antes de comenzar con el libro. De este modo podría seguir los numerosos ejemplos que se incluyen. Si todavía no la ha adquirido, le recomiendo que opte por la Raspberry Pi 3 Model B. Aunque se trata de la placa más cara (algo más de 30 euros), es también la más potente. Dicha placa contiene un procesador de 64 bits con cuatro núcleos, un adaptador de red, un adaptador inalámbrico Ethernet y Bluetooth. Es decir, cuenta con todas las características necesarias para ejecutar cualquier ejemplo contenido en este libro. Raspberry Pi en tiendas en línea como Adafruit Industries, Digi-Key, SparkFun y Jameco Electronics si vive en los Estados Unidos. También están disponibles internacionalmente desde tiendas como Farnell, Radionics o Watterott.

En el capítulo 1 se ofrece una lista completa de todos los accesorios recomendados y opcionales para el Raspberry Pi. Si aún no tiene un Raspberry Pi, debería leer ese capítulo antes de comprarlo. Asimismo, la primera página de cada capítulo contiene una lista de los componentes electrónicos con los módulos requeridos para seguirlo. El sitio web del libro (www.exploringrpi.com) proporciona detalles sobre cómo adquirir dichos componentes.

Los ejemplos de este libro utilizan a propósito los componentes, placas para pines (breakout boards) y módulos de más bajo coste y más amplia disponibilidad que nos ha sido posible encontrar, y que cumplen los requisitos de los ejemplos. De este modo, el lector podrá trabajar con muchos de los ejemplos en lugar de centrar su presupuesto en solo unos pocos. Por todo el libro se indican unos precios orientativos de los componentes para que el lector pueda hacerse una idea del dinero que puede necesitar antes de iniciar un proyecto. Se trata de precios de compra reales (generalmente en dólares) encontrados en webs como ebay.com, amazon.com o aliexpress.com.

NOTANingún producto aparece en este libro como resultado de haber establecido acuerdo alguno con vendedores ni fabricantes. El autor ha seleccionado y adquirido todos los productos personalmente basándose sólo en su precio, funcionalidad y disponibilidad comercial. Los precios solo se ofrecen como referencia y pueden estar sujetos a variación. El lector debe indagar personalmente antes de adquirir cualquier elemento listado en este libro con el fin de asegurarse de que se ajusta a sus necesidades.

Fe de erratas

Se ha trabajado muy duro para garantizar que este libro esté libre de errores. Sin embargo, siempre cabe la posibilidad de que se haya deslizado alguno inadvertidamente. La web del libro (en inglés) contiene un listado con los errores detectados en cada capítulo (www.exploringrpi.com). Si el lector encuentra algún error en el texto o en los ejemplos de código fuente, le agradecería muy sinceramente que utilizara la web del libro para enviarlo y que podamos actualizar tanto la fe de erratas como los ejemplos de código fuente en el repositorio.

Contenido digital y código fuente

El sitio web principal asociado a este libro es www.exploringrpi.com. El propio autor se encarga del mantenimiento del sitio web, que contiene vídeos, ejemplos de código fuente y enlaces para ampliar los datos con nuevas lecturas. Cada capítulo tiene su propia página web. En el caso improbable de que el sitio web no se encuentre disponible, el lector puede encontrar el código fuente en www.wiley.com/go/exploringrpi.

Todo el código fuente se encuentra en un repositorio de GitHub, lo que permitirá al lector descargarlo en su Raspberry Pi con un solo comando. También puede acceder al código fuente en línea con facilidad en la dirección tiny.cc/erpi001. Para descargar el código fuente en su Raspberry Pi solo tiene que introducir el comando siguiente en el símbolo de sistema de su shell de Linux:

pi@erpi ~ $ git clone https://github.com/derekmolloy/exploringrpi.git

Si nunca antes ha utilizado GitHub, no se preocupe, lo explicamos con todo detalle en el capítulo 3.

Bien, es hora de empezar.

Parte

I

Aspectos básicos del Raspberry Pi

En esta parte

Capítulo 1: El hardware del Raspberry Pi

Capítulo 2: El software del Raspberry Pi

Capítulo 3: Exploración de sistemas Linux empotrados

Capítulo 4: Interfaz con los componentes electrónicos

Capítulo 5: Programación con Raspberry Pi

Capítulo

1

El hardware del Raspberry Pi

En este capítulo presentamos el hardware de la plataforma Raspberry Pi (RPi). El capítulo se centra en los modelos más recientes de Raspberry Pi y describe los diferentes subsistemas y las entradas/salidas de las placas. Además, el capítulo lista los accesorios que pueden resultar más útiles a la hora de desarrollar nuestros proyectos basados en Raspberry Pi. Cuando lo finalice, el lector debería haber adquirido una idea cabal de la potencia y la complejidad de esta plataforma de computación hardware. Asimismo, debería ser ya consciente de los primeros pasos a seguir para proteger la placa de cualquier daño físico.

Introducción a la plataforma

Los modelos RPi son dispositivos capaces de realizar labores de computación de propósito general. Así, se han hecho un hueco como plataformas para aprender informática y programación. De igual modo, dichos modelos, algunos de los cuales se muestran en la figura 1-1, también son dispositivos de computación física realmente capaces, que se pueden usar para aplicaciones en sistemas empotrados. En particular para aplicaciones empotradas conectadas a Internet.


Figura 1-1: Ejemplos de placas de la plataforma Raspberry Pi (en una escala relativa).

Algunas características generales de los dispositivos RPi son:

❏Su coste se sitúa entre los 5 y los 30 euros aproximadamente.

❏Se trata de dispositivos de computación muy potentes. Por ejemplo, el RPi 3 contiene un procesador ARM Cortex-A53 a 1,2 GHz capaz de realizar más de 700 millones de instrucciones Whetstone por segundo (MWIPS).1

❏Hay disponible un abanico muy amplio de modelos adaptables a distintas aplicaciones, por ejemplo: la placa de gran formato RPi 3 para el prototipado o los diminutos Compute Module y RPi Zero, para su uso práctico.

❏Admiten muchas interfaces estándar para dispositivos electrónicos.

❏Funcionan con poca potencia: entre los 0,5 W de un RPi Zero inactivo y los aproximadamente 5,5 W de un RPi 3 a plena carga.

❏Son ampliables mediante placas de extensión HAT (Hardware Attached on Top) conectables directamente a la placa y dispositivos USB.

❏Reciben soporte por parte de una enorme comunidad de usuarios innovadores y entusiastas que aportan generosamente su tiempo para ayudar a la RPi Foundation en sus objetivos educacionales.

La plataforma RPi puede ejecutar el sistema operativo Linux, lo que nos permite utilizar directamente numerosas aplicaciones y librerías software de código. La disponibilidad de controladores software de código abierto nos permite también conectar dispositivos como cámaras USB, teclados y adaptadores WiFi a nuestros proyectos, sin necesidad de emplear soluciones propietarias. Por lo tanto, tenemos acceso a librerías de código fuente muy completas, desarrolladas por miembros de una comunidad open source sobrada de talento. No obstante, debemos tener presente que ese código fuente suele carecer de garantía alguna. Si se presentan problemas, debemos fiarnos de la buena voluntad de la comunidad a la hora de resolverlos. Ni que decir tiene que también podemos ser nosotros los que resolvamos los problemas y pongamos la solución a disposición del resto de la comunidad.

Una característica impresionante de los modelos de RPi más recientes es la posibilidad de ampliar su funcionalidad mediante placas de extensión, llamadas HAT como ya hemos visto, que se conectan directamente a la doble fila de cuarenta pines (cabecera GPIO) visible en las placas de la figura 1-1. Podemos diseñar nuestras propias HAT y conectarlas con seguridad a la placa RPi mediante esta cabecera. Además, en el mercado existen muchas placas HAT que permiten ampliar la funcionalidad de la plataforma RPi. Hacia el final del presente capítulo describiremos algunos ejemplos de aquellas.

¿A quién está destinado el RPi?

Cualquiera que desee transformar un concepto de ingeniería en un proyecto electrónico interactivo real y tangible, un prototipo o una obra de arte debería plantearse utilizar RPi. Dicho esto, no podemos olvidar que la integración de software de alto nivel con componentes electrónicos de bajo nivel no es una tarea fácil. Sin embargo, la dificultad inherente a cualquier implementación dependerá del nivel de sofisticación que demande el proyecto concreto. La comunidad RPi trabaja muy duro para asegurar que la plataforma sea accesible para todo el mundo que esté interesado en integrarla en sus proyectos, ya sean estudiantes, artistas o aficionados. Por ejemplo, la disponibilidad para el RPi de la herramienta de programación visual Scratch (tiny.cc/erpi101) ofrece una vía excelente para interesar a los niños tanto en la plataforma RPi como en la programación de ordenadores.

Aquellos usuarios más avanzados, que poseen conocimientos de electrónica o computación, pueden alcanzar niveles de desarrollo y personalización de la plataforma RPi suficientes para cumplir todos los requisitos de sus proyectos. Ahora bien, dicha personalización no es una tarea trivial: es posible que el lector sea un experto en la electrónica de bajo nivel, y que, o bien la programación de alto nivel, o bien el sistema operativo Linux, le causen dolores de cabeza. Y viceversa: podría ser todo un gurú de la programación, y no haber soldado un LED en toda su vida. El objetivo de este libro es llegar a todos los tipos de usuarios que estén interesados en interaccionar con el RPi y dar a cada uno la suficiente información sobre Linux, electrónica y software como para que puedan ser productivos, con independencia de su nivel previo de experiencia.

Cuándo utilizar el RPi

La plataforma RPi permite integrar magníficamente software de alto nivel con electrónica de bajo nivel en cualquier tipo de proyecto. Tanto si pretendemos desarrollar un sistema de domótica automatizado, un robot, una pantalla multimedia, una aplicación IoT, una máquina de vending o una obra de arte conectada a Internet, el RPi cuenta con la suficiente potencia de procesamiento para afrontar todo aquello que podamos exigir a un dispositivo empotrado.

La mayor ventaja que el RPi y otros dispositivos Linux empotrados presentan frente a los sistemas empotrados tradicionales, como Arduino, PIC o microcontroladores AVR, se pone de manifiesto cuando basamos nuestros proyectos en Linux. Por ejemplo, si construimos un sistema de automatización con el RPi y decidimos que determinada información esté disponible en Internet, no tenemos más que instalar el servidor web Nginx. Luego, podemos desarrollar scripts en el servidor o utilizar nuestro lenguaje de programación favorito para comunicar con nuestro sistema de domótica automatizado para capturar y compartir información. También es posible que nuestro proyecto exija un acceso remoto seguro. En tal caso, para instalar un servidor SSH (Secure Shell) no tendríamos más que ejecutar el comando Linux sudo apt install sshd, como veremos en el capítulo 2. Esto podría muy bien ahorrarnos semanas de trabajo de desarrollo. Además, tenemos la tranquilidad de saber que ese mismo software se ejecuta con plena seguridad en millones de máquinas por todo el mundo.

Linux proporciona también controladores para numerosos periféricos y adaptadores USB, lo que nos permite conectar cámaras, adaptadores WiFi y otros dispositivos comerciales de bajo coste directamente a nuestra plataforma sin necesidad de desarrollar software caro y complejo.

El RPi es también un magnífico dispositivo para reproducir vídeo de alta definición. Capacidad que debe a su procesador Broadcom BCM2835/6/7 diseñado para aplicaciones multimedia y a que incorpora una implementación hardware de los códecs H.264/MPG-4 y MPG-2/VC-1 (mediante una licencia adicional). Utilizar el RPi para la ejecución de aplicaciones multimedia, como el centro de entretenimiento doméstico Kodi2 (www.kodi.tv) para reproducir vídeo con resolución full-HD, goza de bastante popularidad.

Cuándo no utilizar el RPi

Linux no se diseñó como sistema operativo de tiempo real ni para procesamiento predecible. Esto resultaría problemático, por ejemplo, si pretendemos obtener muestras de un sensor cada millonésima de segundo exactamente. Si el núcleo se halla ocupado con una tarea diferente en el instante preciso de recogida de una muestra, no va a resultar fácil interrumpirlo. Por lo tanto, en su configuración predeterminada, el RPi no resulta una plataforma idónea para aplicaciones de sistemas en tiempo real. Existen versiones de Linux para aplicaciones en tiempo real, pero destinadas a desarrolladores de Linux muy experimentados, y cuyas capacidades en ese ámbito son limitadas. No obstante, el RPi se puede combinar con procesadores de servicio en tiempo real, donde desempeñaría la labor de "inteligencia central" del conjunto. Podemos establecer la conexión de tales microcontroladores de tiempo real con el RPi a través de buses eléctricos, como I2C UART o Ethernet, y dejar que el RPi actúe como procesador central en un sistema de control distribuido. Este concepto se describe en los capítulos 11, 12 y 13.

La plataforma RPi no es ideal para desarrollar proyectos que se tenga intención de comercializar. Raspberry Pi hace un uso amplio de software de código abierto, aunque se usan fragmentos de código propietario en la GPU, pero no es propiamente un hardware de código abierto. Los esquemas de las placas RPi se encuentran disponibles (tiny.cc/erpi102, por ejemplo), pero la documentación del hardware utilizado es escasa. Además, la licencia3 del bootloader de Broadcom indica explícitamente que solo se permite su distribución en código binario si “… va a servir para el desarrollo, la ejecución o el uso en un dispositivo Raspberry Pi”. No es probable que tal licencia se pueda transferir a un producto comercial diseñado por nosotros.

Como describimos anteriormente en este capítulo, la RPi Foundation se centra en la educación; así, la posible comercialización de un producto cae muy lejos de su ámbito. Si el lector planea desarrollar un proyecto de Linux empotrado con la vista puesta en comercializarlo, debería detenerse a examinar la plataforma BeagleBone, que está completamente basada en código abierto y recibe un soporte documental robusto de Texas Instruments. Además, obviamente, recomiendo al lector que adquiera mi libro Exploring BeagleBone, también editado por Wiley.

La documentación del RPi

En este libro integro mis experiencias de desarrollo con la plataforma RPi junto con materiales de apoyo relativos a Linux empotrado, programación y electrónica general, para crear una detallada guía de desarrollo. Sin embargo, simplemente no es posible abarcar todo en un solo libro, así que he evitado incluir información disponible en los documentos principales y los sitios web descritos en esta sección. El primer lugar en el que buscar documentación de apoyo es este sitio web:

❏Sitio web de la Raspberry Pi Foundation: en esta web se ofrece el principal soporte a la plataforma RPi, con blogs, guías de software, enlaces con la comunidad de usuarios y descargas para apoyar nuestros esfuerzos de desarrollo. Diríjase a www.raspberrypi.org.

Existe una enorme cantidad de documentación sobre la plataforma RPi, pero los documentos más importantes para este libro son los siguientes:

❏La documentación del Raspberry Pi: se trata de la documentación oficial de RPi, escrita por la Raspberry Pi Foundation. Incluye guías de introducción, guías de configuración, guías sobre las distribuciones Linux, etc. Diríjase a www.raspberrypi.org/documentation/.

❏Hoja de datos de dispositivos Broadcom BCM2835 ARM: es el documento principal que describe el procesador de la mayoría de los modelos de RPi (salvo RPi 2/3). Con una longitud de 200 páginas, proporciona una descripción técnica de la funcionalidad y las capacidades del procesador en las placas RPi. Diríjase a tiny.cc/erpi103. Existe también una importante fe de erratas en el sitio tiny.cc/erpi104.

❏El documento sobre BCM2836: este documento describe características del procesador en la placa RPi 2 y características relacionadas en el RPi 3. Se debe leer junto con el documento anterior de Broadcom sobre el BCM2835. Diríjase a tiny.cc/erpi105.

Hay varios sitios web claves para el aprendizaje de esta plataforma. En ellas encontramos una combinación de tutoriales, foros de discusión, librerías con código de ejemplo, distribuciones Linux y sugerencias de proyectos con las que estimular nuestra creatividad. Veamos una selección de dichas webs:

❏El sitio web de este libro: www.exploringrpi.com

❏Mi blog personal: www.derekmolloy.ie

❏El sitio web de eLinux.org: www.elinux.org

En el capítulo 2 se desarrolla la introducción a la plataforma software del RPi. El resto de este capítulo analiza el hardware de la plataforma RPi, explica la funcionalidad que ofrece, resume las especificaciones técnicas y proporciona algunos ejemplos de los tipos de periféricos y placas HAT que resultarían interesantes para el RPi.

El hardware del RPi

El núcleo de las placas RPi lo forman los SoC (System on a Chip) Broadcom BCM2835, BCM2836 y BCM2837. Hay disponibles varios modelos de RPi en la actualidad, y el contenido de este libro es perfectamente aplicable a todos ellos. No obstante, aquí nos vamos a centrar sobre todo en las versiones más recientes del RPi, las que tienen una cabecera GPIO de cuarenta pines, como los RPi A+, B+, 2, 3 y Zero. Si aún no ha comprado ningún modelo de RPi, le recomendamos que opte por el RPi 3. Esta placa soporta comunicación en red por cable e inalámbrica y cuenta con un procesador multinúcleo, lo que la hace compatible con todos los conceptos descritos en este libro y sus posibles ampliaciones. Ni el RPi A+ ni el Zero cuentan con una interfaz para cableado de red, y el RPi B+ carece de un procesador multinúcleo, pero la mayoría de los ejemplos de este libro funcionan perfectamente con ellos.Si va a utilizar el RPi A+ o el RPi Zero, es recomendable que se dirija al principio del capítulo 13 para aprender a configurar un adaptador de red inalámbrico USB.

Las versiones del Raspberry Pi

La figura 1-2 presenta una síntesis de las características comparadas de los distintos modelos de RPi disponibles en la actualidad. Veamos un resumen rápido de esta tabla:

❏Si queremos un RPi para computación de propósito general, deberíamos considerar el RPi 3. Con un procesador de cuatro núcleos a 1,2 GHz y 1 GB de memoria, ofrece el mejor rendimiento de todas las placas.

❏Para aplicaciones que deban conectar los circuitos electrónicos con Internet en una red cableada, evaluaremos RPi 3, RPi 2 o RPi B+, y consideraremos el precio el factor decisivo.

❏Si necesitamos un dispositivo muy pequeño con conectividad inalámbrica, optaremos por el RPi Zero. Por su parte, el RPi A+ puede servir perfectamente para el prototipado inicial.

❏Si lo que queremos es diseñar nuestra propia placa PCB (Printed Circuit Board, placa de circuito impreso) que utilice una o varias placas RPi, debemos analizar el módulo Computer.


Figura 1-2: Comparación resumida de los modelos de RPi más comunes.

El hardware del Raspberry Pi

Las figuras 1-3 y 1-4 detallan los sistemas principales de los modelos RPi más habituales. La figura 1-3(a) muestra la placa RPi Zero. Los sistemas clave identificados en las llamadas 1 a 11 de la figura se describen con detalle en la figura 1-4. De forma similar, la figura 1-3(b) muestra la placa RPi 3, y los sistemas clave identificados en las llamadas 1 a 15 se describen igualmente en la figura 1-4.


Figura 1-3: Las entradas/salidas y subsistemas de dos modelos

de RPi (a escala relativa): (a) RPi Zero y (b) RPi 3.

La figura 1-4 detalla las diferentes entradas y salidas disponibles en la cabecera GPIO. En modelos recientes del RPi (A+, B+, 2, 3 y Zero) hay 40 pines en total en esta cabecera (una fila con veinte pares). Sin embargo, no todos están disponibles como entradas/salidas de propósito general (GPIO). Algunos de los conectores tienen una configuración fija.

❏8 de ellos están conectados a tierra.

❏4 están destinados a fuentes de alimentación con distinto voltaje: 3,3 V (hasta 50 mA) y 5 V (hasta 300 mA).

❏2 pines se reservan para placas de extensión HAT, que veremos más adelante en este mismo capítulo, aunque también se pueden reconfigurar para otras tareas (véase el capítulo 8).

Los 26 conectores restantes pueden multiplexarse para funciones muy diferentes, algunas de las cuales se mencionan en la figura 1-4 bajo el encabezamiento "GPIO". La función de cada uno de estos tipos de entrada/salida se describe con detalle en los capítulos 6 y 8.


Figura 1-4: Tabla de conectores y subsistemas generales del RPi.


Accesorios del Raspberry Pi

Los requisitos externos para usar la placa RPi suelen ser mínimos:

❏Un cable USB 2.0 (generalmente micro-USB a USB-A) para conectar el RPi a una fuente de alimentación, como un PC de sobremesa o un cargador USB para teléfono móvil.

❏Una tarjeta micro-SD para guardar el sistema operativo que sirve para iniciar la placa.

❏Un cable Ethernet CAT-5 para conectar el RPi a la red mediante su conector Ethernet RJ-45 10/100.

El RPi se puede conectar a un monitor mediante un cable HDMI (un mini-HDMI con el RPi Zero), pero la mayoría de los ejemplos de este libro asumen que el RPi se utiliza sin monitor (en headless mode).

Accesorios importantes

Es importante que el lector adquiera los accesorios siguientes junto con su placa RPi.

Una fuente de alimentación externa de 5 V

La mejor forma de alimentar al RPi es con un cable micro-USB conectado a una fuente de alimentación de 5 V de buena calidad (±5%) que pueda ofrecer una corriente de al menos 1,1 A (1100 mA) para las placas antiguas y 2,5 A (2500 mA) para el RPi 3. Las placas RPi demandan típicamente entre 500 y 700 mA, pero algunos periféricos USB, como adaptadores WiFi o webcams, necesitan bastante más corriente. La entrada micro-USB de las placas RPi cuenta con un fusible rearmable (polyfuse) que limita la entrada de corriente a unos 1100 mA (con 700 mA de corriente segura, véase el capítulo 4) en la mayoría de los modelos RPi, y 2500 mA en el RPi 3. Podemos conectar una fuente de alimentación USB capaz de suministrar una intensidad de corriente superior a 2500 mA, pero en ningún caso una cuyo voltaje salga del rango de 4,75 V a 5,25 V (5 V ± 5%).

Si surgen problemas de estabilidad, como reinicios y cuelgues aleatorios o problemas de teclado, debemos sospechar enseguida del circuito de alimentación. Puede ser que la fuente de alimentación sea incapaz de proporcionar la corriente adecuada, o bien que sea, ella misma o el cable USB, de mala calidad y estén operando fuera de su rango de tolerancia. Por ejemplo, los fabricantes de ciertas fuentes de alimentación de 5 V genéricas, de escasa calidad, afirman que son capaces de proporcionar 1 A (seguramente se refieran al límite de corriente de cortocircuito) pero seguramente su voltaje de salida caerá a niveles inaceptables a medida que se incremente la demanda de corriente. Cuando se sospecha de que ese es el problema, hay que medir los niveles de voltaje en el RPi. En modelos recientes utilizaremos para ello PP1 o PP2 y GND, o cualquier otro componente de metal protegido, como se muestra en la figura 1-6(a). En modelos más antiguos usaremos TP1 y TP2.


Figura 1-6: (a) Comprobación de que el voltaje en el RPi se encuentra en el rango

4,75-5,25 V (5 V ± 5%). (b) El RPi Zero y sus conectores asociados.

Tarjeta micro-SD para iniciar el sistema operativo

Adquiera una tarjeta micro-SD de una marca de calidad reconocida y con no menos de 8 GB de capacidad. Asimismo, puede que necesite un adaptador micro-SD a SD para poder usarla en el lector de tarjetas de su ordenador. Las placas RPi más antiguas, como la A o la B, utilizan tarjetas SD estándar y pueden beneficiarse también de tal adaptador. En todo caso, no es raro que las tarjetas micro-SD incluyan dicho adaptador, lo que nos evitará tener que comprarlo.

La micro-SD debería ser de Clase 10 o superior, ya que su mayor velocidad de lectura/escritura nos ahorrará tiempo, sobre todo en la escritura de imágenes. Lo ideal sería una micro-SD de entre 8 y 32 GB con funcionalidad de nivelación de desgaste (wear leveling) que ampliará la vida útil de la tarjeta, sobre todo si la formateamos pero no ocupamos toda su capacidad. Tarjetas micro-SD con mayor capacidad también pueden funcionar, pero son mucho más caras. Enfoques de almacenamiento alternativos con dispositivos USB para el RPi también se analizan brevemente.

Cable Ethernet para conectividad de red

Los RPi B/B+/2/3 se pueden conectar a Internet a través de redes locales Ethernet. Los RPi A/A+/Zero se pueden conectar a Internet mediante adaptadores inalámbricos USB. Conectaremos el RPi a la red local enchufando el cable Ethernet CAT 5 en el puerto RJ-45 10/100 correspondiente. Si vamos a utilizar más de un RPi simultáneamente, no estaría de más gastar un poco de dinero en un switch de cuatro bocas económico, que podemos situar cerca de nuestro ordenador.

Accesorios recomendados

Es recomendable que el lector adquiera los accesorios siguientes junto con su placa RPi. Si planea realizar desarrollos en el RPi, probablemente debería adquirirlos todos.

Cable HDMI para conectar a monitores o televisiones

El RPi se puede conectar fácilmente a un monitor o televisión que tenga un conector HDMI o DVI. La mayoría de los modelos de RPi cuentan con un conector HDMI de tamaño estándar. Sin embargo, el RPi Zero presenta un conector mini-HDMI (HDMI-C), así que debemos tener esto en cuenta a la hora de emparejarlo con un monitor o televisión (generalmente con conectores de tipo HDMI-A o DVI-D). Con el RPi Zero necesitaremos, casi con seguridad, un conector macho HDMI-mini-C a HDMI-A. Un cable sobre 1,8 metros no debería superar los 10 euros. Vigile lo que compra: un conector HDMI-D (micro-HDMI) no servirá para el RPi Zero.

Otra posibilidad consiste en adquirir un conector barato de mini-HDMI (HDMI-C) a HDMI estándar (HDMI-A), o bien un cable conversor de mini-HDMI (HDMI-C) a DVI-D. Así podremos utilizar HDMI-A o conectar a dispositivos DVI-D, respectivamente (véase la figura 1-6(b)).


Cable serie USB a TTL UART 3,3 V para localización de problemas

El cable serie UART USB a TTL (véase la figura 1-7(a)) es uno de esos accesorios que demuestran su valía cuando surgen problemas con la instalación de Linux en nuestra placa. Es capaz de proporcionarnos una interfaz de consola con el RPi sin necesidad de conectar un monitor y un teclado externos.

Asegúrese de adquirir la versión de nivel 3,3 V. Asimismo, lo mejor es que el cable incorpore conectores hembra de 0,1 pulgadas. Este cable contiene un chipset y exige la instalación de unos controladores en el ordenador personal, que crean un nuevo puerto COM. El cable FDTI TTL-232R-3V3 funciona bien y proporciona una conexión muy estable por menos de 20 €. En la dirección tiny.cc/erpi106 encontrará la hoja de datos y el enlace VCP a los controladores software para este cable adaptador.


Figura 1-7: (a) El cable serie USB a TTL 3,3 V. (b) Su conexión al RPi.

El cable se conecta al UART serie del RPi, que está disponible a través de la cabecera GPIO. Con el RPi alimentado desde una fuente regular USB de 5 V, conectamos el cable al RPi tal como se muestra en la figura 1-7(b):

❏El hilo negro (tierra, GND) a la patilla 6 de la cabecera GPIO, que es la patilla GND del RPi.

❏El hilo amarillo (receptor, RXD) a la patilla 8 (GPIO14) de la cabecera GPIO, que es la patilla transmisora (TXD0) UART.

❏El hilo naranja (transmisor, TXD) a la patilla 10 (GPIO14) de la cabecera GPIO, que es la patilla receptora (RXD0) UART.

Mencionamos aquí que la cabecera GPIO de 40 pines se describe con todo detalle en el capítulo 6. Asimismo, el uso preciso del cable se trata en los capítulos 2, 3 y 8.

Dicho cable también se empleará para comprobar la conexión UART al RPi en el capítulo 8 y para programar los dispositivos Arduino Pro en el capítulo 11.

ADVERTENCIA El RPi tolera 3,3 V, pero envía alimentación de 5 V a través de los pines 3 y 4 de la cabecera GPIO. La manera más fácil de destruir el RPi pasa por conectarlos accidentalmente a un circuito que requiera niveles lógicos de 3,3 V, o también cortocircuitar dichos pines con otros de la misma cabecera GPIO. Para evitar contactos accidentales, podemos puentearlos con un jumper aislante (véase la figura 1-7(b)). La cubierta de plástico aísla los pines de cualquier contacto y evita que conectemos una alimentación de 5 V a nuestro circuito.

Accesorios opcionales

En las secciones siguientes se describen accesorios opcionales que podríamos necesitar para cierto tipo de aplicaciones que estemos desarrollando.

Un hub USB para conectar múltiples dispositivos USB

La mayoría de los modelos RPi incluyen un hub USB que permite la conexión de varios dispositivos de forma simultánea. Ahora bien, si planeamos conectar muchos de estos dispositivos externos al RPi, necesitaremos un hub USB externo. Los hub USB se pueden alimentar externamente o desde el bus. Los que reciben alimentación externa son algo más caros, pero mucho más versátiles a la hora de conectar dispositivos externos que demanden mucha corriente, por ejemplo adaptadores WiFi.

Un problema a tener en cuenta con los hub USB alimentados externamente es la posible "realimentación" (backfeeding o back powering) hacia el RPi. Esta realimentación ocurre cuando un hub USB alimentado externamente se conecta al hub interno del RPi (no a la toma de corriente micro-USB) y envía corriente hacia la placa a través de dicho hub interno. Tener dos fuentes de alimentación "compitiendo" para enviar corriente al RPi puede ocasionar problemas. Además, el hub del RPi carece de la protección necesaria para evitar que le llege un exceso de corriente.

Por otra parte, esto no es problema en las placas RPi más recientes (RPi 2/3) porque cuentan con la circuitería necesaria para evitar la mencionada realimentación eléctrica. Sin embargo, puede resultar útil también utilizar una única fuente de alimentación para nuestro proyecto. Para ello, lo más fácil es conectar un cable desde el hub USB alimentado externamente a la toma de corriente micro-USB del RPi.

Adaptadores micro-HDMI a VGA para vídeo y sonido

En el mercado podemos encontrar adaptadores HDMI a VGA que convierten la señal HDMI en VGA. Al mismo tiempo que proporcionan salida de vídeo VGA, muchos de estos adaptadores incorporan un conector estándar de audio de 3,5 mm, que sirve para aplicaciones de audio en el RPi. Asimismo, existen también adaptadores de audio USB capaces de proporcionar funcionalidad de reproducción y grabación de audio de alta calidad. Dichos adaptadores se describen en el capítulo 15. Muchos modelos RPi ofrecen también vídeo compuesto y sonido estéreo a través de un conector cuatripolar de 3,5 mm. Para esta tarea se puede conectar un jack estándar tetrapolar de 3,5 mm (con micrófono). La punta envía la señal al canal de audio izquierdo, seguidamente al derecho, luego está la conexión a tierra y, por último, el canal de vídeo.

Adaptadores WiFi para conectividad inalámbrica

El RPi 3 incorpora conectividad WiFi en la placa. No obstante, en modelos anteriores, esta funcionalidad se puede añadir mediante diferentes adaptadores WiFi, como los que se muestran en la figura 1-8(a), aunque el RPi no puede utilizar cualquiera que le enchufemos. Tanto la distribución Linux como el chipset que controle el adaptador determinarán las posibilidades de usarlo. La configuración de la funcionalidad WiFi y sus aplicaciones se analizan con detalle en el capítulo 13. Allí se muestran pruebas de numerosos adaptadores de bajo coste y amplia disponibilidad comercial. Se debe tener presente que los fabricantes pueden cambiar el chipset de un modelo de adaptador de una generación a otra, y que adquirir un adaptador de la lista que mostramos en el capítulo 13 no garantiza inmediatamente su funcionamiento. La mejor forma de acertar pasa por comprobar el chipset concreto del adaptador que queramos adquirir y comprobar su presencia en la lista. Podemos utilizar un pequeño medidor de corriente USB de bajo coste, como el de la figura 1-8(c) (menos de 3 euros), que nos permitirá averiguar rápidamente el consumo de potencia del RPi y el posible impacto de conectar un adaptador WiFi.


Figura 1-8: Adaptadores USB: (a) Adaptadores WiFi. (b) Adaptador para lectura/escritura

de tarjetas de memoria. (c) Monitor de corriente y voltaje USB de bajo coste.

Dispositivos de almacenamiento USB

Las placas RPi admiten la conexión de lápices USB, discos duros externos USB y adaptadores para lectura/escritura de tarjetas de memoria (sobre todo SD). Se puede formatear el dispositivo con un sistema de archivos Linux y montarlo en el sistema de archivos del RPi (véase capítulo 3). Un dispositivo que resulta particularmente útil es un lector de tarjetas de memoria USB como el de la figura 1-8(b). Estos dispositivos cuestan más o menos lo mismo que los lápices de memoria USB y soportan el cambio de tarjetas micro-SD "en caliente". Además, resultan particularmente útiles cuando necesitamos montar el sistema de archivos raíz de un RPi en otro, para intercambiar archivos o para solucionar problemas de configuración de la tarjeta que interrumpan el arranque del otro RPi (véase el capítulo 3). Por otro lado, ese mismo dispositivo se puede usar en un ordenador personal para grabar una nueva imagen de Linux en una tarjeta micro-SD.

Webcam USB para captura de imágenes y streaming de vídeo

Añadir una cámara RPi, como las de las figuras 1-9(a) o 1-9(b), o una webcam, como la de la figura 19(c), permite integrar con un coste muy bajo la funcionalidad de captura de imágenes y vídeo en nuestros proyectos RPi. Además, ciertas librerías de Linux, como Video 4 Linux y Open Source Computer Vision (OpenCV), nos permitirán el desarrollo de aplicaciones de visión artificial. Este tema se trata en profundidad en el capítulo 15.


Figura 1-9: (a) RPi NoIR Camera. (b) Soporte para cámara RPi. (c) Webcam USB Logitech C920.

Teclado y ratón USB para computación de propósito general

Podemos conectar un ratón y un teclado USB al RPi, o bien usar una combinación estándar de teclado y ratón inalámbricos de 2,4 GHz. Existen combinaciones inalámbricas portátiles de muy pequeño tamaño, por ejemplo las Rii 174 Mini, Rii i10 o la ESYNiC mini; todas ellas ofrecen un teclado portátil con su touchpad integrado. Un adaptador Bluetooth USB también resulta útil para conectar periféricos al RPi.

Una combinación de teclado/touchpad se utiliza en el capítulo 14.

Carcasas para proteger el RPi

Existen numerosos tipos de carcasas para proteger nuestro RPi, por ejemplo la que se ilustra en la figura 1-10(a), que cuesta menos de 6 euros. Las carcasas resultan útiles para salvaguardar el RPi de cortocircuitos accidentales, como los que pueden suceder al dejar la placa sobre una superficie metálica, pero también influyen mucho en la temperatura de operación del RPi (véase el capítulo 12). Intente adquirir una carcasa con la ventilación adecuada, pero evite añadir ruidosos ventiladores o esos ridículos sistemas de refrigeración líquida.

Placas de extensión HAT

Las placas de extensión HAT (Hardware Attached on Top, literalmente "hardware que se fija encima", cuyo acrónimo "HAT" es un juego de palabras con el término inglés hat, que significa sombrero) son circuitos impresos que se pueden conectar al RPi mediante la cabecera de ampliación GPIO. Existen placas de extensión para las cabeceras GPIO de 26 pines de los modelos RPi más antiguos, pero el RPi carece de mecanismos formales para identificar el tipo de placa de extensión conectada. Las HAT se presentaron junto con el RPi modelo B+. Algunos de los 40 pins de la cabecera GPIO ampliada (ID_SD e ID_SC) de los modelos más recientes se emplean para identificar automáticamente el tipo de HAT conectada. Esto permite que Linux configure los pines GPIO de forma automática y que cargue los controladores que faciliten el manejo de la HAT.


Figura 1-10: Accesorios RPi: (a) Ejemplo de carcasa. (b) La placa Sense HAT.

(c) La placa T-Cobbler. (d) Una HAT para prototipado.

La figura 1-10(b) ilustra la placa RPi Sense HAT (40 euros). Contiene: una pantalla LED de matriz de puntos de 8x8, acelerómetro, giroscopio, magnetómetro, sensor de presión atmosférica, sensor de temperatura, sensor de humedad y una pequeña palanca de control. La figura 1-10(d) muestra, vacía, una placa HAT de bajo coste para prototipado que podemos usar para diseñar nuestra propia HAT. En su parte inferior derecha incluye un espacio para una EEPROM (Electrically Erasable Programmable Read-Only Memory, demoria de solo lectura programable y borrable eléctricamente) instalable en superficie que puede servir para que el RPi identifique la HAT.

Una alternativa al diseño de nuestras propias placas HAT consiste en utilizar la placa T-Cobbler (véase la figura 1-10(c)) para conectar la cabecera GPIO del RPi a una placa de pruebas (breadboard) mediante un cable plano de cuarenta pines (disponible con la T-Cobbler). Este dispositivo se ajusta perfectamente a la placa de pruebas (véase el capítulo 4) y proporciona etiquetas claras de todos los pines

de la cabecera GPIO del RPi.

Cómo destruir su RPi

Las placas RPi son dispositivos complejos y delicados que se pueden dañar con mucha facilidad si no somos diligentes en su manejo. Si vamos a iniciarnos en la plataforma RPi desde otras placas, por ejemplo Arduino, debemos extremar el cuidado a la hora de conectar los circuitos que hayamos construido para dichas placas. A diferencia del Arduino Uno, el microprocesador del RPi no se puede sustituir. Si dañamos el SoC del microprocesador, tendremos que comprar una nueva placa.

Estas son algunas de las cosas que no debemos hacer jamás:

❏No apague el RPi desenchufando directamente el cable de alimentación USB de la placa. Para hacerlo correctamente, debe emplear un procedimiento de apagado por software (véase el capítulo 2).

❏No coloque un RPi conectado a la fuente de alimentación sobre superficies metálicas, por ejemplo ordenadores con superficies de aluminio, ni en tableros de trabajo que tengan restos metálicos, virutas de cable o componentes electrónicos. Si cortocircuitamos los pines de la cabecera que sobresalen por la parte inferior de la placa, podemos inutilizarla. Como precaución podemos adquirir una pequeña carcasa como la de la figura 1-10(a). Otra posibilidad consiste en fijar unas pequeñas almohadillas de goma autoadhesivas en la parte inferior de la placa.

❏No conecte circuitos source/sink (impulso/drenaje de corriente continua), salvo corrientes muy pequeñas, desde/hacia la cabecera GPIO. La corriente máxima que podemos alimentar o drenar desde muchos de los pines de la cabecera oscila entre 2 y 3 mA. Los pines de alimentación y tierra pueden alimentar y drenar corrientes mayores. Por su parte, algunos modelos de Arduino permiten corrientes de hasta 40 mA en cada entrada/salida. Este tema se trata con detalle en los capítulos 4 y 6.

❏Los pines GPIO toleran 3,3 V. No conecte circuitos alimentados a 5 V o inutilizará la placa. Este tema se trata con detalle en los capítulos 4, 6 y 8.

❏No conecte circuitos que apliquen potencia a la cabecera GPIO en tanto el RPi no esté encendido. Asegúrese de que todos los circuitos autoalimentados se conecten por la línea de 3,3 V o mediante optoacopladores. Este tema se trata en el capítulo 6.

Por otra parte, debería asegurarse de hacer siempre lo siguiente:

❏Compruebe con mucho cuidado el número de cada pin que vaya a utilizar. La cabecera GPIO tiene 40 patillas y resulta muy sencillo equivocarse y conectar algo en la patilla 21 en lugar de en la 19, por ejemplo. La tarjeta T-Cobbler (véase figura 1-10(c)) resulta muy útil para interconectar el RPi con una placa de pruebas. Es muy recomendable contar con una para el trabajo de prototipado.

Resumen

Después de leer este capítulo debería ser capaz de hacer lo siguiente:

❏Describir las posibilidades del Raspberry Pi (RPi) y su idoneidad para diferentes tipos de proyecto.

❏Describir los principales sistemas y subsistemas hardware de las placas RPi.

❏Identificar accesorios importantes, presentes en el mercado, que permitan mejorar las capacidades de nuestro RPi.

❏Apreciar cabalmente la potencia y complejidad del RPi como plataforma de computación física.

❏Ser consciente de los primeros pasos a seguir para proteger la placa de cualquier daño físico.

Soporte

Las principales fuentes de documentación de soporte adicional se listaron anteriormente en este mismo capítulo. Si encuentra dificultades con la plataforma RPi que no estén descritas en la documentación, visite los foros de usuarios de Raspberry Pi en la dirección www.raspberrypi.org/forums/. Por favor, no olvide nunca que los miembros de la comunidad de usuarios que publican en los foros lo hacen de manera altruista y dedican voluntariamente una buena parte de su tiempo a resolver las dudas de otros.

1 www.roylongbottom.org.uk/Raspberry%20Pi%20Benchmarks.htm.

2 Antes conocido como XBMC.

3 github.com/raspberrypi/firmware/blob/master/boot/LICENCE.broadcom.

Capítulo

2

El software del Raspberry Pi

En este capítulo se nos presenta el sistema operativo Linux junto con herramientas software que podremos utilizar con el Raspberry Pi (RPi). El objetivo de este capítulo es aprender a conectar nuestra placa a una red o conexión serie y controlarla mediante comandos de Linux básicos. Asimismo, se examinan herramientas de configuración específicas para personalizar el RPi y para actualizar el software de la placa. Tras completar el capítulo, el lector debería ser capaz de controlar un LED del sistema en la placa a través de comandos Linux que habrá aprendido siguiendo un tutorial paso a paso. Este ejemplo le mostrará cómo enviar comandos del shell de Linux a través de una ventana de terminal. El capítulo finaliza con un análisis de la mejor manera de apagar y reiniciar la placa correctamente y con seguridad.

Materiales necesarios para este capítulo:

❏Una placa Raspberry Pi (idealmente RPi3, 2, o B+).

❏Un cable de alimentación USB y una fuente de alimentación.

❏Una tarjeta micro-SD (a partir de 8 GB e idealmente de Clase 10 o superior).

❏Infraestructura y cableado de red, cable serie o adaptador WiFi.

Puede encontrar más detalles sobre este capítulo en la dirección:

www.exploringrpi.com/chapter2/.

Linux en el Raspberry Pi

Una Linux distribution es una versión de dominio público de Linux que contiene un conjunto determinado de herramientas y programas. Existen numerosísimas distribuciones diferentes de Linux, que suelen estar orientadas a distintas aplicaciones. Por ejemplo, los propietarios de servidores de alto nivel pueden instalar las distribuciones Red Hat Enterprise, Debian u OpenSUSE; los usuarios de ordenadores personales, Ubuntu, Debian, Fedora o Linux Mint. El alma común a todas las distribuciones es el núcleo (kernel) de Linux, concebido y desarrollado por Linus Torvalds en 1991.

A la hora de decidirnos por una u otra distribución de Linux para nuestro sistema empotrado, lo más sensato sería optar por una que cumpliera los siguientes requisitos:

❏Una distribución estable y con buen soporte.

❏Una distribución que incluya un gestor de paquetes de calidad.

❏Que sea compacta y pensada para ocupar poco espacio de almacenamiento.

❏Que cuente con el soporte de una buena comunidad de usuarios para nuestro dispositivo concreto.

❏Que incluya buenos controladores para los periféricos que vayamos a usar.

Distribuciones de Linux para el RPi

En esencia, las abundantes distribuciones Linux para sistemas empotrados utilizan todas el mismo núcleo estándar de Linux. Sin embargo, cada una incluye un conjunto de herramientas y configuraciones que resultan en experiencias de usuario muy diferentes. Las principales distribuciones de Linux de código abierto empleadas por la comunidad de usuarios de RPi son Raspbian, Ubuntu, OpenELEC y Arch Linux.

Raspbian es una versión de Debian concebida específicamente para el RPi. Debian (una abreviación de Debbie e Ian) es una distribución Linux dirigida por su comunidad de usuarios, que pone mucho énfasis en el desarrollo de código abierto. Ninguna organización comercial participa en el desarrollo de Debian. Raspbian amplía Debian con herramientas y paquetes de software, por ejemplo Java, Mathematica o Scratch, específicos para el RPi. En la actualidad tenemos disponibles tres versiones de Raspbian para descargar desde la web de Raspberry Pi:

❏Raspbian Jessie: es una imagen basada en Debian Jessie (Debian versión 8.x) con soporte completo de escritorio. (Tamaño de imagen: sobre 1,3 GB comprimida y unos 4 GB descomprimida).

❏Raspbian Jessie Lite: una imagen con tamaño mínimo basada también en Debian Jessie. Cuenta con un soporte de escritorio limitado, pero que se le puede ampliar fácilmente más adelante. (Tamaño de imagen: sobre 375 MB comprimida y unos 1,4 GB descomprimida).

❏Raspbian Wheezy: una imagen antigua basada en Debian Wheezy (Debian versión 7.x) que está disponible por motivos de compatibilidad con ciertos paquetes de software. Siempre que nos sea posible elegiremos la imagen Jessie, en particular si pretendemos realizar compilación cruzada de aplicaciones.

NOTA Raspbian (Jessie) se utiliza en los ejemplos paso a paso de este libro y, por tanto, es la distribución que recomendamos con insistencia. Asimismo, Debian es la distribución Linux de escritorio que utilizamos en el libro porque ofrece un excelente soporte para el desarrollo multiplataforma gracias a sus toolchain para compilación cruzada (www.debian.org).

Ubuntu es una distribución íntimamente relacionada con Debian. De hecho, la siguiente descripción es la de la propia web de Ubuntu (www.ubuntu.com): "Debian es la piedra sobre la que se edifica Ubuntu." Ubuntu es una de las distribuciones Linux más populares para el escritorio, sobre todo por su empeño en hacer Linux más accesible a los nuevos usuarios. Resulta fácil de instalar, tiene un soporte de controladores para escritorio excelente y también ofrece distribuciones binarias para el RPi. La baza principal de Ubuntu es la experiencia de usuario de su escritorio. Si se va a usar el RPi como dispositivo de computación de propósito general (véase el capítulo 14) Ubuntu puede ser la distribución que mejor se adapte a esa tarea.

OpenELEC (www.openelec.tv) se centra particularmente en las aplicaciones multimedia y sobre todo en Kodi (www.kodi.tv). Si desea utilizar el RPi como dispositivo multimedia para el hogar (home media center), esta distribución ofrece seguramente el mejor rendimiento. Las distribuciones OpenELEC utilizan generalmente un sistema de archivos de solo lectura, como squashfs (squash file system o squashFS), para un mayor rendimiento y fiabilidad. Sin embargo, tales optimizaciones dificultan el trabajo de prototipado y desarrollo.

Arch Linux (www.archlinuxarm.org) es una distribución de Linux ligera y flexible que persigue la simplicidad como objetivo principal. Su público son los usuarios de Linux de nivel medio o avanzado a los que ofrece control total, con la responsabilidad que conlleva, de la configuración del sistema. Hay disponibles versiones de Arch Linux ya compiladas y listas para el RPi. Sin embargo, comparada con otras distribuciones, en la actualidad ofrece menos soporte a los usuarios nuevos de Linux en la plataforma RPi.

La RPi Foundation desarrolló un instalador de Linux para usuarios nuevos llamado NOOBS, que contiene Raspbian pero ofrece la facilidad de descarga e instalación de otras distribuciones Linux. Numerosos kits incluyen una tarjeta SD con NOOBS junto con el hardware RPi. Sin embargo, si optamos por descargar e instalar una imagen Raspbian, deberíamos descargar directamente la imagen siguiendo las instrucciones de la sección siguiente.

Asimismo, han comenzado a aparecer otras soluciones no Linux, como Windows 10 IoT Core y RISC OS, para el RPi. Se trata de desarrollos muy interesantes y sin duda bienvenidos. Sin embargo, en la actualidad tienen un soporte limitado para dispositivos y requisitos de programación muy específicos si se los compara con Linux. Para seguir el libro, que se centra como sabemos en soluciones Linux, es mejor obviar dichas distribuciones.

Cómo crear una imagen Linux en una tarjeta SD para el RPi

La manera más fácil de configurar una tarjeta SD para iniciar con ella el RPi consiste en descargar el archivo de imagen de una distribución Linux (archivo con extensión .IMG , generalmente comprimido a su vez en formato .zip) desde el sitio web

www.raspberrypi.org/downloads y grabarlo en una tarjeta SD mediante una utilidad de grabación de imágenes. Las siguientes utilidades para grabación de imágenes convierten este proceso en algo sencillo y directo.

ADVERTENCIA Cuando grabamos el archivo de imagen de una distribución Linux en una tarjeta SD, se pierde todo el contenido anterior de la misma. Asegúrese de grabar la imagen descargada en el dispositivo correcto cuando utilice las herramientas aquí descritas.

❏Windows: Use Win32DiskImager (disponible en tiny.cc/erpi202). Introduzca la tarjeta SD antes de iniciar la aplicación y asegúrese bien de seleccionar la tarjeta SD correcta.

❏Mac OS y Linux: Utilice, con sumo cuidado, la herramienta para clonar discos dd. En primer lugar, identifique el dispositivo. Debería mostrarse como /dev/mmcblkXp1 o /dev/sddX en Linux, o bien /dev/rdiskX en Mac OS, donde la X es un número. Asegúrese de que X haga referencia a la tarjeta SD en la que desea escribir el archivo de imagen. Para ello puede comprobar, por ejemplo, que el espacio disponible en el dispositivo (escriba cat /proc/partitions) se corresponde con el tamaño de la tarjeta SD. Luego, desde una ventana de terminal, escriba el comando dd con privilegios de root (groso modo, equivalente a una cuenta de administrador de Windows, solo que en el mundo Linux es más apropiado aquel término), donde if será el nombre del archivo de entrada (input file) y of será el nombre del dispositivo de salida (un tamaño de bloque bs de 1M debería ser suficiente):

molloyd@desktop:~$ sudo dd bs=1M if=RPi_image_file.img of=/dev/XXX

NOTA Tanto el programa Win32DiskImager como el comando dd crearán una partición en la tarjeta SD del tamaño justo para grabar la imagen del sistema operativo, con independencia del espacio nominal de la misma. Este tema se tratará más adelante en este mismo capítulo.

Introduzca la tarjeta SD en el RPi, conecte el cable de red y enchufe el cable de alimentación micro-USB de 5 V. También podemos conectar un teclado y un ratón USB y un monitor con su cable HDMI al RPi para usarlo como dispositivo de computación de propósito general (véase el capítulo 14). No obstante, para proyectos de electrónica, el RPi se emplea como dispositivo empotrado independiente que se comunica a través de la interfaz de red. Por lo tanto, los pasos siguientes indican cómo conectar el RPi a una red para establecer comunicación con él.

Cómo conectarse a una red

Hay dos maneras principales de conectarnos y comunicar con el RPi mediante una red: con un cable Ethernet estándar o con un cable Ethernet cruzado. Conectar el RPi a una red puede resultar engorroso para los principiantes. Generalmente es algo sencillo de hacer en casa, donde uno tiene el control total de su propia red. Sin embargo, en redes locales complejas, como las de las universidades, podemos enfrentarnos a múltiples subredes para comunicaciones tanto por cable como inalámbricas. En redes tan complejas, las restricciones de enrutamiento pueden dificultar, si no hacer imposible, conectarse a un RPi mediante un cable Ethernet estándar. Ambos métodos resultan aptos para conectar nuestro RPi a Windows, a un Mac o a una máquina con Linux.

Cable Ethernet estándar

Cuando hablamos de usar un "cable Ethernet estándar", queremos decir que vamos a utilizar uno para conectar el RPi a una red local del mismo modo que haríamos con un ordenador de sobremesa o un portátil. Tanto para el usuario doméstico como para el usuario avanzado, una conexión estándar Ethernet a una red local es probablemente la mejor solución para las comunicaciones en red de su RPi. La tabla 2-1 relaciona las ventajas y desventajas que se presentan al utilizar este tipo de conexión. El problema principal reside en la complejidad de la red local. Si el lector comprende bien la configuración de su red y tiene acceso a los ajustes del router, esta es la mejor opción de lejos. Si el router de su red está instalado lejos de su ordenador de sobremesa, podría adquirir un pequeño switch para la red (entre 10 y 20 euros) o bien un punto de acceso inalámbrico con un router multipuerto integrado (por unos 30 euros). La segunda opción resulta muy útil para aplicaciones inalámbricas que empleen los dispositivos RPi 3, Zero o A+, así como para ampliar el alcance de su red inalámbrica.

NOTA Este análisis es asimismo relevante para la conectividad en red inalámbrica. Si se ve obligado a utilizar una conexión inalámbrica, por ejemplo para el RPi Zero, lea la sección "Comunicaciones por WiFi" al principio del capítulo 13 y, luego, vuelva a este punto. Para modificar los archivos de configuración de un adaptador WiFi puede utilizar un cable USB a TTL, que se describe en la sección siguiente. Asimismo, puede montar la tarjeta micro-SD destinada a la placa RPi en un ordenador con Linux, o en otra RPi, y hacer los cambios necesarios directamente en dichos archivos.

Tabla 2-1: Ventajas y desventajas de una conexión Ethernet estándar para el RPi.


VentajasDesventajas
Tenemos control total sobre la configuración de las direcciones IP, así como de la configuración de las IP estáticas/dinámicas.Podríamos necesitar privilegios de administrador, así como el conocimiento adecuado de la infraestructura de la red.
Podemos interconectar numerosas placas RPi a una sola red, incluidos dispositivos inalámbricos.El RPi necesita una fuente de alimentación, que puede ser un cable de corriente con adaptador, o bien alimentación PoE (Power over Ethernet) (véase el capítulo 12).
El RPi se puede conectar a Internet sin que haga falta que un ordenador lo esté.La configuración resulta más difícil para los principiantes si la estructura de la red es compleja.

El primer desafío de esta configuración es dar con nuestro RPi en la red. De forma predeterminada, el RPi se configura para solicitar una dirección IP al servidor DHCP (Dynamic Host Configuration Protocol, protocolo de configuración dinámica de Host). En un entorno de red local doméstica, este servicio lo provee generalmente un servidor DHCP integrado en el propio router (el aparato que todos tenemos en casa y que es router, módem, cortafuegos, elemento de red local y, en la actualidad, WiFi) que la conecta a Internet a través de nuestro ISP (Internet Service Provider, proveedor de servicio de Internet).

Los servidores DHCP asignan direcciones IP dinámicamente desde un grupo (pool) de direcciones para un intervalo fijo de tiempo llamado "tiempo de cesión" (lease time), que se especifica en la configuración del servidor DHCP. Este tipo de direcciones IP se denominan dinámicas. Una vez que expira el tiempo de cesión, nuestro RPi recibe una nueva dirección IP cuando vuelve a conectarse a la red local. Este cambio puede resultar frustrante porque podríamos tener que volver a buscar el RPi en la red local. El capítulo 13 describe cómo configurar la dirección IP de nuestro RPi para que sea la misma, es decir, para que sea una dirección IP estática, cada vez que la placa se conecte a la red.

Podemos usar cualquiera de los métodos siguientes para identificar la IP dinámica de nuestro RPi:

❏Navegador web: utilice un navegador web para acceder al router de su red local doméstica (generalmente la dirección de acceso es una de estas: 192.168.1.1, 192.168.0.1 o 10.0.0.1). Inicie sesión y busque la opción para acceder al estado de la tabla DHCP. Debería llegar a una entrada que detalle las direcciones IP asignadas, las direcciones físicas MAC y el tiempo de cesión restante para un dispositivo llamado "raspberrypi". El nombre de host de mi placa es "erpi", como ya sabemos, así que:

DHCP IP Assignment Table

IP Address MAC Address Client Host Name Leased Time

192.168.1.116 B8-27-EB-F3-0E-C6 erpi 12:39:56

❏Herramienta de escaneo de puertos: utilice una herramienta como nmap, en Linux, o bien Zenmap, que es una versión con interfaz gráfica de usuario (en adelante GUI, Graphical User Interface), disponible para Windows (diríjase a tiny.cc/erpi203). Para buscar dispositivos en una subred, escribimos nmap -T4 -F 192.168.1.*. Buscamos una entrada que tenga abierto el puerto 22 para SSH. Debería identificarse a sí mismo con la Raspberry Pi Foundation (véase la figura 2-1(a)) como resultado del rango de direcciones MAC asignado a la fundación. Después podrá hacer un ping para comprobar la conexión de red (véase la figura 2-1(b)).


Figura 2-1: (a) Zenmap escanea la red para localizar el RPi. (b) Un ping de prueba desde el ordenador.

❏Zeroconf (resolución de nombres de host con configuración cero): Zeroconf es un conjunto de herramientas para resolución de nombres de host, direccionamiento automático y descubrimiento de servicios. De forma predeterminada, la distribución Raspbian del RPi utiliza un servicio avahi para dar soporte a Zeroconf en nuestra red local, lo que permite que el nombre del host sea visible. Por ejemplo, el nombre de host de mi placa es "erpi". Así, es posible conectarse al RPi utilizando la cadena erpi.local:

pi@erpi:~$ systemctl status avahi-daemon

• avahi-daemon.service - Avahi mDNS/DNS-SD Stack

Loaded: loaded (/lib/systemd/system/avahi-daemon.service; enabled)

Active: active (running) since Thu 2015-12-17 21:53:46 GMT; 8h ago

Main PID: 385 (avahi-daemon)

Status: "avahi-daemon 0.6.31 starting up."

CGroup: /system.slice/avahi-daemon.service

├─385 avahi-daemon: running [erpi.local]

└─419 avahi-daemon: chroot helper

NOTA Las máquinas Windows no soportan Zeroconf de forma predeterminada. Puede instalar el software Bonjour Print Services for Windows (o bien iTunes) desde el enlace tiny.cc/erpi204. Si tiene éxito, ahora debería poder realizar un ping de prueba (de forma predeterminada el nombre es raspberrypi.local):

C:\Users\Derek> ping erpi.local

Pinging erpi.local [fe80::9005:94c0:109e:9ecd%6] with 32 bytes of data:

Reply from fe80::9005:94c0:109e:9ecd%6: time=1ms ...

❏Conexión serie USB a TTL: una última opción consiste en establecer una conexión serie USB a TTL con el RPi y escribir ifconfig para averiguar la dirección IP. La dirección es la “inet addr” asociada al adaptador eth0.

Cable Ethernet cruzado

Un cable Ethernet cruzado es un cable que ha sido modificado para facilitar la conexión y la comunicación directa de dos dispositivos sin necesidad de un switch intermedio. Es posible comprar el cable cruzado como tal, o bien adquirir un adaptador. La tabla 2-2 relaciona las ventajas y desventajas que se presentan al utilizar este tipo de conexión.

Tabla 2-2: Ventajas y desventajas de utilizar un cable de red cruzado.


VentajasDesventajas
Podremos conectar nuestro RPi a la red local aunque carezcamos de acceso a la infraestructura hardware de la misma.Si nuestro ordenador no tiene más que una conexión de red, no será posible conectarlo a Internet a través de la red cableada. Es más conveniente utilizarlo con un dispositivo que cuente con múltiples adaptadores.
El RPi puede gozar de acceso a Internet siempre que el ordenador posea dos adaptadores de red y que tenga activada la opción de compartir.El RPi seguirá precisando de una fuente de alimentación externa, que puede ser un cable con adaptador de corriente.
Proporciona una configuración de red local razonablemente estable.Podría requerir un cable Ethernet cruzado o adaptador especializados. Sin embargo, lo más probable es que nuestro ordenador tenga Auto-MDIX.

La mayoría de los ordenadores actuales son capaces de detectar automáticamente una conexión cruzada (es decir, host a host) gracias a la funcionalidad Auto-MDIX, lo que permite utilizar un cable Ethernet estándar. La interfaz de red del RPi también ofrece funcionalidad Auto-MDIX, de manera que se puede utilizar cuando se carezca de acceso a la infraestructura de la red local. Si dispone de dos adaptadores de red, por ejemplo una toma de red Ethernet y una tarjeta de red inalámbrica, podrá compartir fácilmente la conexión a Internet con su RPi estableciendo un puente entre ambos adaptadores. Como ejemplo, veamos los pasos necesarios para hacerlo en Windows:

1. Conecte uno de los extremos de un cable de red Ethernet estándar, o bien de uno cruzado, al RPi, y el otro a la toma de red de su ordenador.

2. Encienda el RPi conectando un cable de alimentación micro-USB.

3. Establezca ahora el puente entre ambas conexiones de red. En Windows, seleccione "Redes e Internet" y, luego, "Conexiones de red". Seleccione los dos adaptadores de red, tanto el cableado como el inalámbrico, al mismo tiempo. Haga clic con el botón derecho y seleccione la opción para puentear las conexiones. Pasado algún tiempo, las dos conexiones deberían aparecer habilitadas y puenteadas. Asimismo, la ventana de redes de Windows debería mostrar el puente de conexión (véase la figura 2-2).

4. Reinicie el RPi. De forma ideal, debería emplear un cable serie USB a TTL para hacer esto, o también el botón de reinicio descrito en el capítulo 1. Una vez reiniciado el RPi, debería ser capaz de obtener una dirección IP directamente desde el servidor DHCP de nuestra red local.

Después podrá comunicar directamente con el RPi desde cualquier terminal de su red local (incluyendo su propio ordenador principal) siguiendo los pasos descritos en la sección siguiente. La figura 2-2 muestra un ejemplo de configuración a partir de los datos mostrados dicha sección. Podemos observar cómo el servidor DHCP asigna al ordenador portátil la dirección IP 192.168.1.111, y al RPi, la 192.168.1.115. Por lo tanto, una sesión SSH desde el ordenador de sobremesa, que tiene la dirección IP 192.168.1.4, hacia el RPi ofrece la siguiente interacción:

molloyd@desktop:~$ ssh pi@192.168.1.115

pi@192.168.1.115's password: raspberry

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent

permitted by applicable law.

pi@erpi ~ $ echo $SSH_CLIENT

192.168.1.4 60898 22

pi@erpi ~ $ ping www.google.com

PING www.google.com (213.233.153.230) 56(84) bytes of data.

64 bytes from www.google.com (213.233.153.230):icmp_seq=1 ttl=61 time=13.6ms


Figura 2-2: Un ejemplo de configuración con cable Ethernet cruzado.

Los iconos de la imagen fueron creados por los artistas del proyecto GNOME (GNU GPL CC-BY-SA-3.0).

Este tipo de conexión es particularmente útil en el seno de una red local compleja, por ejemplo la de una universidad, porque así el portátil se puede conectar directamente con el RPi. Asimismo, el RPi podrá, a su vez, conectarse a Internet, como queda ilustrado en este ejemplo por su capacidad para enviar un ping al servidor web de Google.

Cómo comunicarse con el RPi

Después de conectar el RPi a la red, lo siguiente sería comunicarnos con él. Podemos conectar con el RPi usando, o bien una conexión serie USB a TTL, o bien una nueva conexión de red, como se ha descrito anteriormente. La conexión de red debería ser nuestro objetivo principal porque es el tipo de conexión que proporciona acceso pleno a Internet al RPi. La conexión serie sirve generalmente como conexión de respaldo para el caso de que surjan problemas con la de red. Por tanto, el lector puede obviar si lo desea la sección siguiente, pero la información estará ahí como referencia.

NOTA La cuenta de usuario predeterminada de la imagen Raspbian es: username pi (nombre de usuario pi) y password raspberry (contraseña raspberry).

Conexión serie con el cable USB a TTL de 3,3 V

Las conexiones serie resultan especialmente útiles cuando tenemos el RPi muy cerca de nuestro ordenador y conectado mediante un cable USB a TTL (como vimos en la figura 1-7(a) del capítulo 1). Es un método de comunicación de seguridad habitual para el caso de que fallen las comunicaciones a través de la red o los servicios en el RPi. También sirve para configurar la conectividad de red inalámbrica en un dispositivo RPi que carezca de toma para cable de red. Podemos conectar el cable al RPi, como se mostró en la figura 1-7(b) del capítulo 1.

Para conectarse al RPi a través de la conexión serie, necesitamos un programa de terminal. Existen varias aplicaciones de este tipo para Windows, por ejemplo RealTerm (tiny.cc/erpi205) o PuTTY (www.putty.org). La mayoría de las distribuciones Linux incluyen un programa de terminal. En Debian pulse Ctrl+Alt+T o Alt+F2 y escriba: gnome-terminal. Mac OS X incluye un emulador de terminal de forma predeterminada, donde puede escribir, por ejemplo, el comando screen /dev/cu.usbserial-XXX 115200). También puede instalar el programa Z-Term (véase dalverson.com/zterm/).

Para conectarse al RPi a través de la conexión serie USB a TTL, necesitamos la información siguiente:

❏Número de puerto: para averiguarlo en Windows, abra el gestor de dispositivos o equivalente según versiones y busque en la sección "Puertos". En la figura 2-3(a) podemos observar una ventana de ejemplo del gestor de dispositivos, donde el dispositivo aparece como puerto COM11. Esta información será diferente en cada ordenador

❏Velocidad de conexión: de forma predeterminada, introduciremos 115.200 baudios para conectar con el RPi.

❏Otra información que podría ser necesaria para otros programas de terminal: Data bits (bits de datos) = 8, Stop bits (bits de parada) = 1, Parity (paridad) = none y Flow control (control de flujo) = XON/XOFF.


Figura 2-3: (a) Identificación de dispositivo en el gestor de dispositivos de Windows.

(b) Una configuración de conexión serie con PuTTY. (c) Un adaptador USB a TTL de bajo coste.

Guarde la configuración con un nombre de sesión, por ejemplo "RPi USB-to-TTL", como se puede ver en la figura 2-3(b), de manera que esté disponible cada vez que desee utilizarla. Haga clic en "Abrir" y, luego, pulse Intro cuando aparezca la ventana. Esto es muy importante. Cuando se conecte a Raspbian, debería observar la salida siguiente:

Raspbian GNU/Linux 8 erpi ttyAMA0

erpi login: pi

Password: raspberry

Last login: Fri Dec 18 02:12:32 GMT 2015 from ...

Linux erpi 4.1.13-v7+ #826 SMP PREEMPT Fri Nov 13 20:19:03 GMT 2015 armv7l

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent

permitted by applicable law.

pi@erpi:~$

El proceso de conexión nos permite conectar con el nombre de usuario "pi" y la contraseña "raspberry". Observe cómo, cuando reinicia la placa, también puede ver toda la salida por la consola durante el inicio del RPi. Esta es la conexión de respaldo definitiva, puesto que nos permite observar lo que sucede durante el proceso de inicio, como veremos en el capítulo 3.

NOTA Existen alternativas baratas al cable USB a TTL de 3,3 V, por ejemplo el dispositivo USB mostrado en la figura 2-3(c), que cuesta alrededor de un euro. Sin embargo, en general carecen de carcasa o proteción de seguridad alguna. En todo caso, antes de comprar un dispositivo de este tipo, asegúrese de que soporta niveles lógicos TTL de 3,3 V. El que aparece en la figura 2-3(c) incorpora un conmutador que permite intercambiar los niveles lógicos entre 3,3 y 5 V. Estos dispositivos se emplean en el capítulo 9 para ampliar el número de dispositivos UART disponibles en el RPi.

En un ordenador con Linux, podrá instalar el programa Screen y conectarse con el dispositivo USB a TTL con los comandos siguientes:

molloyd@debian:~$ sudo apt-get install screen

molloyd@debian:~$ screen /dev/cu.usbserial-XXX/ 115200

Conexión segura con SSH (Secure Shell)

El protocolo de red SSH (Secure Shell) se emplea para establecer conexiones cifradas seguras entre dispositivos en una red. Podemos utilizar un cliente de terminal SSH para conectar con un servidor SSH a través del puerto 22 del RPi, lo que nos permitirá hacer lo siguiente:

❏Conectar en remoto con el RPi y ejecutar comandos.

❏Transferir archivos desde y hacia el RPi usando el protocolo SFTP (SSH File Transfer Protocol, protocolo de transferencia de archivos SSH).

❏Redireccionar conexiones X11, lo que permite la computación en redes virtuales.

De forma predeterminada, las distribuciones Linux para RPi ejecutan un servidor SSH (sshd en Debian) vinculado al puerto 22. Contar con un servidor SSH disponible como medio predeterminado para iniciar sesión remota en el RPi tiene ciertas ventajas.

En particular, nos permite abrir el puerto 22 del RPi a Internet mediante la funcionalidad de redirección de puertos (port forwarding) de nuestro router. Por favor, asegúrese de modificar la contraseña predeterminada para la cuenta de usuario "pi" antes de hacerlo. Después podremos iniciar sesión en nuestro RPi de forma remota desde cualquier lugar del mundo, siempre que conozcamos su dirección IP. El servicio de DNS dinámico (Dynamic DNS, DDNS o DynDNS), permite a la los routers que lo ofrecen (la mayoría) registrar su dirección IP más reciente en un servicio en línea. Acto seguido, dicho servicio en línea hace corresponder un nombre de dominio de nuestra elección con la última dirección IP que nuestro proveedor de acceso nos haya asignado, es decir, los mapea. El servicio de DNS dinámico suele tener un coste anual, a cambio del que obtendremos una dirección con la forma dereksRPi.servicename.com.

Conexiones SSH (Secure Shell) mediante PuTTY

Anteriormente mencionamos PuTTY como un método para conectar con el RPi a través de una conexión serie. PuTTY es una pequeña aplicación, gratuita y de código abierto, emuladora de terminal, consola serie y cliente SSH, que podemos emplear para conectar con el RPi a través de una red local. PuTTY posee varias características útiles:

❏Admite conexiones serie y SSH.

❏Instala una aplicación llamada psftp que permite transferir archivos hacia y desde el RPi por la red desde nuestro ordenador.

❏Acepta el redireccionamiento SSH X11 (exigido en el capítulo 14).

La figura 2-4 muestra los ajustes de configuración de PuTTY. Seleccione SSH como tipo de conexión, introduzca la dirección IP de su RPi (o el nombre de Zeroconf), acepte el puerto 22 (predeterminado) y guarde la sesión con un nombre significativo. Haga clic en "Open" ("Abrir") e inicie sesión con su nombre de usuario y contraseña. Si observa una alerta de seguridad que le advierte de posibles "ataques de intermediario" (man-in-the-middle attacks), que pueden resultar preocupantes en redes inseguras, acepte la huella de clave (fingerprint) ofrecida y continúe. Los usuarios de Mac OS X pueden abrir la aplicación Terminal con una configuración similar (por ejemplo, ssh -XC pi@192.168.1.116 o ssh -XC pi@raspberrypi.local).


Figura 2-4: Ajustes de configuración SSH de PuTTY sobre una ventana de conexión de terminal SSH.

Más adelante en este mismo capítulo veremos los comandos básicos que se pueden enviar al RPi, pero antes es necesario examinar cómo podemos transferir archivos desde y hacia el RPi.

Chrome Apps: cliente Secure Shell

El navegador web Chrome de Google permite la instalación de Chrome Apps. Se trata de aplicaciones que operan igual que las instaladas en el propio ordenador (nativas), pero escritas en HTML5, JavaScript y CSS. Muchas de estas aplicaciones utilizan el cliente nativo Google Native Client (NaCl), que no es otra cosa que una tecnología de aislamiento de procesos, sandbox para abreviar, que permite ejecutar aplicaciones compiladas C/C++ directamente en el navegador, con independencia del sistema operativo (SO) subyacente. La ventaja de NaCl es que posibilita que las aplicaciones alcancen niveles de rendimiento casi iguales a las nativas del SO, puesto que pueden contener código fuente capaz de utilizar instrucciones de bajo nivel.

Existe una aplicación Chrome App capaz de emular un terminal SSH que resulta extremadamente útil. Para instalarla en Chrome, abra una nueva pestaña y haga clic en el icono "Apps". Si en su versión de Chrome no aparece el acceso a Chrome Web Store, escriba "chrome web store" en la barra de direcciones y pulse Intro. En el campo de búsqueda de dicha página, escriba "Secure Shell". Localice la App e instálela. Acabado el proceso, la App Secure Shell aparecerá junto con las demás aplicaciones para Chrome. Si no puede acceder a ellas por su versión o configuración de Chrome, escriba "chrome://apps" en la barra de direcciones y podrá acceder a sus iconos. Cuando inicie la App Secure Shell deberá configurar los ajustes de conexión como en la figura 2-4 y la aplicación se ejecutará en una pestaña como en la figura 2-5.


Figura 2-5: La App Secure Shell para Chrome.

Como transferir archivos mediante PuTTY/psftp sobre SSH

La instalación de PuTTY incluye también compatibilidad con el protocolo FTP (File Transfer Protocol) de transferencia de archivos. Este nos permite transferir archivos hacia y desde el RPi utilizando nuestra conexión de red. Puede iniciar la aplicación PuTTY Secure File Transfer Protocol escribiendo psftp en el intérprete de comandos de Windows. No olvide que para que esto funcione debe incluir el directorio del ejecutable putty.exe en la variable de entorno PATH de su sistema.

En el prompt psftp> , escriba open pi@raspberrypi.local (o la dirección IP) para conectar con el RPi. Nuestro ordenador se identifica ahora como máquina local, local machine, y el RPi, como máquina remota (remote machine). Cuando emita un comando, normalmente lo hará en la máquina remota. Después de conectar, nos encontraremos en la carpeta de usuario (o directorio home directory) de la cuenta que hayamos utilizado. Por lo tanto, bajo la distribución RPi Raspbian, si nos conectamos como "pi", estaremos en el directorio /home/pi/.

Para transferir un solo archivo c:\temp\test.txt desde el ordenador local hasta el RPi, seguiremos los pasos que se detallan a continuación:

psftp: no hostname specified; use "open host.name" to connect

psftp> open pi@erpi.local

Using username "pi".

pi@erpi.local's password: raspberry

Remote working directory is /home/pi

psftp> lcd c:\temp

New local directory is c:\temp

psftp> mkdir test

mkdir /home/pi/test: OK

psftp> cd test

Remote directory is now /home/pi/test

psftp> put test.txt

local:test.txt => remote:/home/pi/test/test.txt

psftp> dir test.*

Listing directory /home/pi/test

-rw-r--r-- 1 pi pi 8 Dec 18 16:45 test.txt

psftp>

Los comandos que contienen el prefijo l se dirigen a la máquina local, por ejemplo lcd (local change directory) para cambiar el directorio local o lpwd (local print working directory) para el directorio de impresión local. Para transferir un solo archivo desde la máquina local a la máquina remota, empleamos el comando put. Para realizar la operación inversa, traer un archivo de la máquina remota a la máquina local, usamos get. Para enviar o traer múltiples archivos están los comandos mput y mget. Si nos olvidamos de un comando, escribimos help para obtener ayuda.

Si utilizamos una máquina cliente con Linux, podemos emplear el comando sftp en lugar de psftp. Casi todo lo demás queda igual. La aplicación cliente sftp también está instalada en la distribución del RPi de manera predeterminada, así que podrá invertir el orden de las comunicaciones, es decir: podremos hacer que el RPi actúe como servidor y otra máquina como cliente.

Aquí mostramos algunos trucos y consejos útiles para el uso de los comandos psftp y sftp :

❏El comando mget -r * realiza una recuperación recursiva de todo un directorio. Esto resulta útil cuando queremos transferir una carpeta que contenga a su vez varias carpetas. También podemos utilizar la opción -r con los comandos get, put y mput.

❏El comando dir *.txt aplica un filtro para mostrar solo los archivos acabados en ".txt" del directorio actual.

❏El comando mv mueve un archivo o directorio de la máquina remota a una nueva ubicación en la propia máquina remota.

❏El comando reget reinicia una recuperación de archivos que se hubiera interrumpido. El archivo recuperado parcialmente debe continuar existiendo en la máquina local.

El comando psftp se puede enviar como una sola línea o como un script local desde el símbolo del sistema. Puede crear un archivo de prueba, test.scr, que contenga un conjunto de comandos psftp que necesite enviar. Ejecute después psftp desde el símbolo del sistema, pasando la contraseña con -pw y el archivo de script con -b (o -be para continuar aun con errores y -bc para mostrar los comandos a medida que se ejecutan), del siguiente modo:

c:\temp>more test.scr

lcd c:\temp\down

cd /tmp/down

mget *

quit

c:\temp>psftp pi@erpi.local -pw mypassword -b test.scr

Using username "pi".

Remote working directory is /home/pi ...

Control del Raspberry Pi

En este punto, deberíamos ser capaces de comunicarnos con el RPi mediante una aplicación cliente SSH. Esta sección analiza los comandos que podemos emitir para interaccionar con el RPi.

Comandos básicos de Linux

Cuando se conecte por primera vez con el RPi mediante SSH, se le pedirá que inicie sesión. Podrá hacerlo la primera vez con el usuario "pi" y la contraseña "raspberry":

login as: pi

pi@erpi.local's password: raspberry

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent

permitted by applicable law.

pi@erpi:~$

Ya estamos conectados al RPi y tenemos la ventana de terminal en Linux lista para recibir los comandos. El símbolo del sistema, $ ,indica que hemos iniciado sesión como un usuario estándar. Por su parte, # indica que hemos iniciado la sesión en la cuenta de superusuario o root (véase el capítulo 3). Para un nuevo usuario de Linux, este paso puede resultar un desafío, puesto que es difícil hacerse con todo el arsenal de comandos a nuestra disposición. En esta sección intentaremos que el lector alcance un nivel de Linux suficiente para empezar con confianza. Se ha escrito como referencia y acompañada de ejemplos, de manera que pueda regresar a ella cuando necesite ayuda.

Primeros pasos

Lo primero que podríamos hacer nada más conectarnos es averiguar la versión de Linux que estamos ejecutando. Esta información resulta muy útil a la hora de publicar preguntas en foros de usuario.

pi@erpi ~ $ uname -a

Linux erpi 4.1.13-v7+ #826 SMP PREEMPT Nov 13 20:19:03 2015 armv7l GNU/Linux

Hemos utilizado Linux 4.1.13, compilado para la arquitectura ARMv7 en la fecha listada.

La versión del núcleo de Linux se describe por tres números, separados por puntos, de la forma: X.Y.Z. El número X cambia muy de tarde en tarde; la versión 2.0, por ejemplo, se publicó en 1996, y la 4.0, en abril de 2015. El número Y cambia un poco más a menudo, pero tampoco demasiado, cada dos años más o menos. Sin embargo, en el núcleo más reciente ha cambiado con bastante frecuencia: la versión 4.1 se publicó en junio de 2015. El número Z sí que cambia frecuentemente.

Después podemos utilizar el comando passwd para establecer una contraseña nueva para la cuenta de usuario "pi".

pi@erpi ~ $ passwd

Changing password for pi.

(current) UNIX password: raspberry

Enter new UNIX password: supersecretpasswordthatImayforget

Retype new UNIX password: supersecretpasswordthatImayforget

La tabla 2-3 lista otros comandos muy útiles.

Tabla 2-3: Esos primeros comandos de Linux tan útiles.


ComandoDescripción
more /etc/issueInforma sobre la distribución Linux que se está ejecutando.
ps -p $$Informa del shell o intérprete de comandos que estamos ejecutando (por ejemplo, bash).
whoamiInforma del usuario que ha iniciado sesión en el sistema.
uptimeDevuelve el tiempo que el sistema lleva en ejecución.
topLista todos los procesos y programas en ejecución. Pulse Control+C para cerrar la vista.

Por último, podrá encontrar información concreta sobre su RPi usando la aplicación host- namectl . También sirve para consultar y realizar cambios en los ajustes del sistema, como la descripción del chasis o el nombre de host:

pi@erpi ~ $ sudo hostnamectl set-chassis server

pi@erpi ~ $ hostnamectl

Static hostname: erpi

Icon name: computer-server

Chassis: server

Machine ID: 3882d14b5e8d408bb132425829ac6413

Boot ID: ea403b96c8984e37820b7d1b0b3fbd6d

Operating System: Raspbian GNU/Linux 8 (jessie)

Kernel: Linux 4.1.18-v7+

Architecture: arm

Comandos básicos del sistema de archivos

Esta sección describe los comandos básicos que nos permiten movernos y manipular el sistema de archivos de Linux. Cuando utilizamos cuentas de usuario Raspbian/Debian y Ubuntu, a menudo debemos anteponer el modificador sudo (superuser do o substitute user do). Lo hacemos porque sudo es un programa que permite a un usuario ejecutar programas que requieran privilegios de seguridad de superusuario, o también de otras cuentas restringidas. Las cuentas de usuario se describen en el capítulo 3. La tabla 2-4 lista los comandos básicos del sistema de archivos.

Tabla 2-4: Comandos básicos del sistema de archivos.


NombreComandoOpciones y más informaciónEjemplos
Listar archivosls-a los muestra todos, incluidos los ocultos.-l muestra el formato largo.-R listado recursivo.-r listado inverso (reverse).-t ordena por la última modificación.-S ordena por tamaños.-h muestra el tamaño en formato legible.ls -alh
Directorio actualpwdIndica el directorio actual.-P muestra la ubicación física.pwd -P
Cambiar directoriocdCambia el directorio.cd e Intro o cd ~/ nos lleva al directorio raíz del usuario.cd / nos lleva al directorio raíz del sistema.cd .. nos lleva a un nivel superior en el árbol de directorios.cd /home/picd /
Crear un directoriomkdirCrea un directorio.mkdir test
Borrar un archivo o directoriormBorrar un archivo.-r borrado recursivo (se usa con directorios; sea precavido).-d borra directorios vacíos.rm bad.txtrm -r test
Borrar un archivo o directoriocp-r copia recursiva.-u copia solo si el origen es más reciente que el destino, o bien si no se encuentra el destino.-v (verbose) muestra la salida durante la copia.cp a.txt b.txtcp -r test testa
Borrar un archivo o directoriomv-i solicita confirmación antes de sobreescribir.No hay opción -r para directorios. Mover al mismo directorio cambia su nombre.mv a.txt c.txtmv test testb
Crear un archivo vacíotouchCrea un archivo vacío o actualiza la fecha de modificación de un archivo existente.touch d.txt
Ver el contenido de un archivomoreMuestra el contenido de un archivo. Usamos la barra espaciadora para pasar a la siguiente página.more d.txt
Obtener calendariocalMuestra un calendario basado en carac-teres.cal 04 2016

Con esto cubrimos lo básico, pero hay mucho más. En el capítulo siguiente hablamos de propiedad y permisos de archivos, búsquedas, redirección de la entrada/salida o E/S (input/output o I/O), etc. El propósito de esta sección no es otro que ponernos en marcha. La tabla 2-5 describe unos cuantos atajos de teclado que nos facilitan mucho la vida con la mayoría de shells de Linux.

Tabla 2-5: Algunos atajos de teclado para Linux.


AtajoDescripción
Flecha arriba (repetir)Con la primera pulsación reproduce el comando que acabamos de escribir; luego, va mostrando los anteriores.
Tecla TabAutocompleta el nombre del archivo, del directorio o incluso del comando ejecutable. Por ejemplo, para cambiar al directorio /tmp de Linux, podemos escribir cd /t y, luego, pulsar Tab, que autocompleta el comando: cd /tmp/. Si aparecen demasiadas opciones, pulse Tab de nuevo y vea todas las opciones en forma de lista.
Ctrl+ALleva el cursor al principio de la línea que estamos escribiendo.
Ctrl+ELleva el cursor al final de la línea que estamos escribiendo.
Ctrl+UElimina el texto desde el cursor hasta el principio de la línea. Ctrl+E y, luego, Ctrl+U borran toda la línea.
Ctrl+LBorra la pantalla.
Ctrl+CCierra cualquier proceso en ejecución en el momento de pulsar.
Ctrl+ZPasa el proceso actual a un segundo plano. Escribir bg después lo deja en ejecución en segundo plano, y con fg lo volvemos a traer al primer plano.

Veamos un ejemplo que utiliza varios de los comandos de la tabla 2-4 para crear un directorio llamado test en el que creamos un archivo de texto vacío llamado hello.txt. Después copiamos todo el directorio test en el directorio /tmp/test2, que cuelga del directorio /tmp:

pi@erpi ~ $ cd /tmp

pi@erpi /tmp $ pwd

/tmp

pi@erpi /tmp $ mkdir test

pi@erpi /tmp $ cd test

pi@erpi /tmp/test $ touch hello.txt

pi@erpi /tmp/test $ ls -l hello.txt

-rw-r--r-- 1 pi pi 0 Dec 17 4:34 hello.txt

pi@erpi /tmp/test $ cd ..

pi@erpi /tmp $ cp -r test /tmp/test2

pi@erpi /tmp $ cd /tmp/test2

pi@erpi /tmp/test2 $ ls -l

total 0

-rw-r--r-- 1 pi pi 0 Dec 17 04:35 hello.txt

ADVERTENCIA Linux asume que sabemos muy bien lo que hacemos. Así, puede muy bien dejarnos hacer un borrado recursivo de todo nuestro directorio raíz si hemos iniciado sesión como root. ¡Piénselo dos veces siempre antes de escribir nada cuando haya iniciado sesión como root!

NOTA A veces es posible recuperar archivos que se hayan perdido por borrados accidentales usando el comando extundelete inmediatamente después del borrado.

Lea cuidadosamente la página del manual para dicho comando y, luego, use los pasos siguientes:

pi@erpi ~ $ sudo apt install extundelete

pi@erpi ~ $ mkdir ~/undelete

pi@erpi ~ $ cd ~/undelete/

pi@erpi ~/undelete $ sudo extundelete --restore-all --restore-directory

. /dev/mmcblk0p2

pi@erpi ~/undelete $ ls -l

drwxr-xr-x 6 root root 4096 Dec 17 04:39 RECOVERED_FILES

pi@erpi ~/undelete $ du -sh RECOVERED_FILES/

100M RECOVERED_FILES/

En este ejemplo se recuperan hasta 100 MB de archivos, que suelen ser archivos temporales borrados como resultado de la instalación de paquetes de software.

Variables de entorno

Las variables de entorno (environment variables) son valores con nombre que describen la configuración de nuestro entorno Linux, por ejemplo la ubicación de archivos ejecutables o el editor de texto predeterminado. Para hacernos una idea de las variables de entorno configuradas en el RPi, ejecute el comando env y verá una lista de dichas variables en nuestra cuenta de usuario. En este caso, env se invoca en la imagen Raspbian:

pi@erpi ~ $ env

TERM=xterm

SHELL=/bin/bash

SSH_CLIENT=fe80::50b4:eb95:2d00:ac3f%eth0 2599 22

USER=pi

MAIL=/var/mail/pi

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:...

PWD=/home/pi

HOME=/home/pi ...

Puede ver y modificar las variables de entorno de acuerdo con el ejemplo siguiente, que añade el directorio /home/pi a la variable de entorno PATH:

pi@erpi ~ $ echo $PATH

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

pi@erpi ~ $ export PATH=$PATH:/home/pi

pi@erpi ~ $ echo $PATH

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/pi

Este cambio se perderá después de reiniciar. Establecer las variables de entorno de manera definitiva requiere modificaciones en el archivo .profile, con los shells sh, ksh o bash, y en el archivo .login cuando usemos csh o tcsh. Para ello, necesitamos saber cómo realizar una edición básica de archivos en una ventana de terminal en Linux.

Edición básica de archivos

Contamos con una variedad de editores de texto, pero uno de los más fáciles de usar es también el más potente: el editor GNU nano editor. Iniciamos el editor escribiendo nano seguido del nombre de un archivo existente, o bien de uno nuevo; por ejemplo, nano hello.txt muestra la vista capturada en la figura 2-6 (una vez se ha introducido el texto). Escribir nano -c hello.txt muestra el número de línea actual, lo que puede resultar muy útil durante la corrección de errores (debug). Podemos movernos libremente por el archivo mediante las teclas de cursor y modificar o escribir nuevo texto a partir de la ubicación del cursor. Puede observar algunos de los atajos de teclado en la barra que ocupa la parte inferior de la ventana del editor, pero existen muchos más, algunos de los cuales mostramos en la tabla 2-6.


Figura 2-6: El GNU nano editor en acción durante la edición de un archivo de ejemplo,

dentro de una ventana de terminal PuTTY en Linux.

Tabla 2-6: Atajos de teclado para Nano. Referencia rápida.


TeclasComandoTeclasComando
Ctrl+GAyudaCtrl+YPágina anterior
Ctrl+CEncuentra el número de línea actualCtrl+_ o Ctrl+/Va a un número de línea
Ctrl+XSalir (¿guardar archivo?)Alt+/Va al final de una línea
Ctrl+LFacilita el ajuste de líneas largasCtrl+6Comienza a marcar texto (usamos las teclas de cursor para el marcado)
Ctrl+OGuardarCtrl+K o Alt+6Corta el texto marcado
Teclas de cursorMueven el cursorCtrl+UPega texto
Ctrl+AVa al inicio de una líneaCtrl+RIntroduce el contenido de otro archivo (pide la ubicación de dicho archivo)
Ctrl+EVa al final de una líneaCtrl+WBusca una cadena de texto
Ctrl+Barra espaciadoraPalabra siguienteAlt+WEncuentra el siguiente
Alt+Barra espaciadoraPalabra anteriorCtrl+DBorra el carácter del cursor
Ctrl+VPágina siguienteCtrl+KBorra una línea entera

NOTA Ctrl+K parece eliminar toda una línea, pero en realidad la envia a un buffer desde el que podemos pegarla con el atajo Ctrl+U. Es una forma ágil de repetir múltiples Asimismo, los usuarios de Mac podrían tener que establecer una metatecla en Terminal para obtener la funcionalidad de la tecla Alt, que no tienen los Mac. Seleccione Terminal ➪ Preferencias ➪ Ajustes ➪ Teclado; luego, seleccione "Usar tecla Opción como metatecla".

¿Qué hora es?

Una pregunta tan sencilla como "¿qué hora es?" causa más problemas de los que uno puede imaginar. Por ejemplo, escribir date después del símbolo del sistema puede mostrar lo siguiente:

pi@erpi ~ $ date

Thu 17 Dec 16:26:59 UTC 2015

Que resulta ser correcto esta vez porque la placa está conectada a una red. Si fuera erróneo, podríamos preguntarnos por qué los fabricantes no han puesto en hora el reloj de la placa. La respuesta es que no pueden. A diferencia de un ordenador personal, el RPi carece de batería que asegure que los ajustes de la BIOS se conservan; de hecho, ni tiene BIOS. Este tema se examina con detalle en el capítulo siguiente, mas por el momento usaremos el protocolo NTP (Network Time Protocol, protocolo de hora de red) para establecer la hora. NTP es un protocolo de red que permite sincronizar relojes entre ordenadores. Si nuestro RPi da fecha y hora correctamente, es porque las obtiene desde la red utilizando un servicio NTP que se ejecuta en la placa:

pi@erpi ~ $ systemctl status ntp

• ntp.service - LSB: Start NTP daemon

Loaded: loaded (/etc/init.d/ntp)

Active: active (running) since Sat 2015-12-19 07:18:04 GMT; 22h ago

Process: 499 ExecStart=/etc/init.d/ntp start (code=exited, status=0/SUCCESS)

CGroup: /system.slice/ntp.service

└─544 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 107:112

El servicio NTP está configurado mediante el archivo /etc/ntp.conf, y las líneas que empiezan con la palabra server identifican los servidores con los que se está comunicando nuestro RPi para obtener la fecha y la hora actuales (de ahí el carácter ^ en la llamada a grep):

pi@erpi ~ $ more /etc/ntp.conf | grep ^server

server 0.debian.pool.ntp.org iburst

server 1.debian.pool.ntp.org iburst

server 2.debian.pool.ntp.org iburst

server 3.debian.pool.ntp.org iburst

Para ser un buen ciudadano NTP, hay que ajustar estas entradas para que hagan referencia al grupo de servidores NTP más próximo. Para ello, diríjase a la web www.pool.ntp.org (el servidor más próximo al autor es ie.pool.ntp.org, para Irlanda) y actualice las entradas según corresponda. Si desea comprobar primero los ajustes, puede instalar y ejecutar el comando ntpdate:

pi@erpi ~ $ sudo apt install ntpdate

pi@erpi ~ $ sudo ntpdate -b -s -u ie.pool.ntp.org

pi@erpi ~ $ date

Sun 20 Dec 16:02:39 GMT 2015

Después de ajustar fecha y hora, podemos establecer nuestra zona horaria. Utilice el comando siguiente, que proporciona una interfaz de usuario de texto para seleccionar nuestra ubicación. El RPi, en este caso, está configurado para Irlanda con el IST (Irish Standard Time, hora estándar de Irlanda):

pi@erpi ~ $ sudo dpkg-reconfigure tzdata

Current default time zone: 'Europe/Dublin'

Local time is now: Sun Dec 20 16:37:48 GMT 2015.

Universal Time is now: Sun Dec 20 16:37:48 UTC 2015.

NOTA Si su RPi no está conectado a Internet, puede configurar fecha y hora manualmente con la herramienta timedatectl:

pi@erpi ~ $ sudo timedatectl set-time '2017-1-2 12:13:14'

pi@erpi ~ $ date

Mon 2 Jan 12:13:16 GMT 2017

Desgraciadamente, tanto la fecha como la hora se perderán cuando reinicie el RPi. En el capítulo 8, se describe cómo conectar al RPi un reloj de tiempo real (RTC, Real Time Clock) con batería para resolver el problema.

Gestión de paquetes

Al principio de este capítulo destacamos que la presencia de un buen gestor de paquetes constituye un característica fundamental de toda distribución Linux aceptable. Un gestor de paquetes (packet manager) es un conjunto de herramientas de software que automatizan el proceso de instalación, configuración, actualización y eliminación de paquetes de software (grosso modo, los programas de aplicación) del sistema operativo Linux. Las diferentes distribuciones de Linux utilizan distintos gestores de paquetes. Ubuntu y Raspbian/Debian usan APT (Advanced Packaging Tool, herramienta avanzada de empaquetado) sobre DPKG (Debian Package Management System, sistema de gestión de paquetes Debian), mientras que Arch Linux emplea Pacman. Los comandos para manejar cada uno tienen su propia sintaxis, pero su forma de operar es prácticamente análoga. La tabla 2-7 lista algunos comandos básicos para la gestión de paquetes.

Tabla 2-7: Comandos habituales para gestión de paquetes (usando nano como paquete de ejemplo).


ComandoRaspbian/Debian/Ubuntu
Instalar un paquete.sudo apt install nano
Actualizar el índice del paquete.sudo apt update
Actualizar los paquetes en nuestro sistema.sudo apt upgrade
¿Está instalado Nano?dpkg-query -l | grep nano
¿Hay disponible un paquete con la cadena nano?apt-cache search nano
Obtener más información de un paquete.apt-cache show nanoapt-cache policy nano
Obtener ayuda.apt help
Descargar un paquete en el directorio actual.apt-get download nano
Eliminar un paquete.sudo apt remove nano
Limpiar paquetes antiguos.sudo apt-get autoremovesudo apt-get clean

NOTA Con el tiempo, el comando binario apt va integrando poco a poco las funcionalidades tanto de apt-get como de apt-cache. Este cambio debería reducir el número de herramientas necesario para la gestión de paquetes. Sin embargo, las distribuciones Linux más antiguas podrían exigir el uso del comando apt-get en lugar de apt.

Wavemon es una herramienta muy útil para configurar las conexiones WiFi (véase el capítulo 13). Si ejecutamos el comando siguiente, veremos que el paquete no se instala de manera predeterminada:

pi@erpi ~ $ wavemon

-bash: wavemon: command not found

Podemos utilizar el gestor de paquetes específico de la plataforma para instalarlo, una vez conozcamos su nombre de paquete:

pi@erpi ~ $ apt-cache search wavemon

wavemon - Wireless Device Monitoring Application

pi@erpi ~ $ sudo apt install wavemon

Reading package lists... Done

Building dependency tree ...

Setting up wavemon (0.7.6-2) ...

El comando wavemon se ejecutará ahora, pero desgraciadamente no hará nada en tanto no configuremos un adaptador inalámbrico (véase el capítulo 13).

pi@erpi ~ $ wavemon

wavemon: no supported wireless interfaces found

También merece la pena destacar que los paquetes se pueden descargar e instalar manualmente. Este método resulta útil cuando deseamos conservar una versión concreta o si necesitamos distribuir un paquete por múltiples dispositivos. Por ejmplo, el paquete Wavemon se puede eliminar, descargar manualmente como archivo .deb y, finalmente, instalarse:

pi@erpi ~ $ sudo apt remove wavemon

pi@erpi ~ $ wavemon

-bash: /usr/bin/wavemon: No such file or directory

pi@erpi ~ $ apt-get download wavemon

pi@erpi ~ $ ls -l wavemon*

-rw-r--r-- 1 pi pi 48248 Mar 28 2014 wavemon_0.7.6-2_armhf.deb

pi@erpi ~ $ sudo dpkg -i wavemon_0.7.6-2_armhf.deb

pi@erpi ~ $ wavemon

wavemon: no supported wireless interfaces found

NOTA Las instalaciones de los paquetes fallan a veces, tal vez porque no aparecen otros paquetes que son necesarios. Los comandos ponen a nuestra disposición opciones (force options) para obviar las comprobaciones. Por ejemplo, --force-yes del comando apt-get. Siempre que sea posible es mejor evitar estas opciones, porque vernos obligados a emplearlas es un síntoma de otros problemas. Cuando los paquetes no se instalan, puede resultar útil escribir: sudo apt-get autoremove.

Configuración del Raspberry Pi

La comunidad RPi y la Raspberry Pi Foundation han desarrollado herramientas específicas para configurar nuestra placa. Estas herramientas simplifican algunas tareas que, de otro modo, resultarían complejas, como veremos en las secciones siguientes.

La herramienta de configuración del Raspberry Pi

La herramienta de configuración del Raspberry Pi, Raspberry Pi Configuration Tool o raspi-config, resulta muy útil para los primeros pasos con nuestro RPi. La figura 2-7 muestra la interfaz de la herramienta, que podemos iniciar con un sencillo comando:

pi@erpi:~$ sudo raspi-config


Figura 2-7: La herramienta de configuración raspi-config.

Las siguientes tareas se deberían llevar a cabo casi inmediatamente después de iniciar el RPi a partir de una imagen recién grabada en una tarjeta SD:

❏Expandir el sistema de archivos para que ocupe toda la tarjeta SD: esta es la primera opción en la figura 2-7. Cuando escribimos una imagen en una tarjeta SD, suele ser más pequeña que la capacidad total de la misma. Esta opción permite expandir el sistema de archivos para que utilice el espacio de la tarjeta en su totalidad. Después de usar esta opción podemos comprobar la capacidad total del siguiente modo:

pi@erpi ~ $ df -kh

Filesystem Size Used Avail Use% Mounted on

/dev/root 15G 7.7G 6.2G 56% /

...

pi@erpi ~ $ lsblk

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT

mmcblk0 179:0 0 14.9G 0 disk

├─mmcblk0p1 179:1 0 56M 0 part /boot

└─mmcblk0p2 179:2 0 14.8G 0 part /

Como puede verse, la tarjeta SD muestra ahora una capacidad de 15 GiB,1 consistente con el espacio de almacenamiento total de la misma.

❏Habilitar la cámara: si ha conectado una cámara al RPi mediante la interfaz CSI, puede habilitar su uso. Este tema se trata en profundidad en el capítulo 15.

❏Overclock: esta opción permite elevar la frecuencia de trabajo del procesador de la placa por encima de la prevista originalmente por el fabricante. Por ejemplo, el procesador del RPi 2 puede funcionar a 1 GHz en lugar de los 900 MHz que el fabricante indica como frecuencia máxima. Eso sí, acelerar el microprocesador puede acortar su vida útil así como hacer más inestable su funcionamiento. Sin embargo, muchos usuarios realizan overclocking en sus placas sin mayores problemas. Esta opción introduce cambios en el archivo /boot/config.txt.

❏Overscan (dentro de las opciones avanzadas, Advanced Options, véase la figura 2-8): nos permite ajustar la salida de vídeo a la pantalla completa de nuestra televisión. Esta opción introduce cambios en el archivo /boot/config.txt.


Figura 2-8: El menú de opciones avanzadas (Advanced Options) de la herramienta raspi-config.

❏Nombre de host (Host Name, Advanced Options): esta opción nos permite ajustar el nombre de host del RPi en la red. Asimismo, actualiza los archivos hostname y hosts y reinicia el servicio de red:

pi@erpi ~ $ cat /etc/hostname

erpi

pi@erpi ~ $ cat /etc/hosts

...

127.0.1.1 erpi

Esta entrada significa ahora que mi placa RPi se encuentra en la dirección Zeroconf erpi.local.

❏División de memoria (Memory Split, Advanced Options): la CPU y el procesador gráfico o GPU del RPi comparten la memoria DDR de la placa. Esta opción nos permite ajustar la asignación de memoria a la GPU. En general, 64 MG suele ser una cantidad correcta. Sin embargo, si vamos a utilizar la cámara CSI del RPi deberemos aumentarla, normalmente a 128 MB (véase el capítulo 15), o bien si vamos a usar la GPU para gráficos en 3D. Este valor queda establecido durante el arranque (cuando se lee del archivo /boot/config.txt) y no se puede modificar en tiempo de ejecución.

❏SSH (Advanced Options): esta opción nos permite habilitar o deshabilitar el servidor SSH en el RPi. Obviamente, nunca deberíamos desactivar el modo SSH cuando nuestro RPi esté en modo headless, sobre todo si carecemos de un modo alternativo de conectarnos a la placa. Esta opción deshabilita el servicio SSH:

pi@erpi ~ $ systemctl status sshd

• ssh.service - OpenBSD Secure Shell server

Loaded: loaded (/lib/systemd/system/ssh.service; enabled)

Active: active (running) since Thu 2015-12-17 21:53:47 GMT

Process: 628 ExecReload=/bin/kill -HUP $MAINPID

Main PID: 492 (sshd)

CGroup: /system.slice/ssh.service

└─492 /usr/sbin/sshd -D

Las restantes opciones de la figura 2-8 modifican también el archivo /boot/config.txt y se analizan en los capítulos 6 y 8. Muchas de estas opciones exigen el reinicio del RPi para que las acciones surtan efecto, puesto que se trata de ajustes de inicialización que pasan al núcleo durante el inicio.

Actualización del software del RPi

La distribución Raspbian se puede actualizar en el RPi siguiendo unos cuantos pasos sencillos. No obstante, tenga en cuenta que algunos de ellos, la actualización en particular, pueden tardar bastante en completarse, hasta varias horas, dependiendo de lo actualizada que esté la imagen y de la velocidad de nuestra red.

Una llamada a apt update descargará las listas de paquetes desde las ubicaciones de Internet identificadas en el archivo /etc/apt/sources.list. Esta acción no instala nuevas versiones del software, sino que actualiza las listas de paquetes y sus interdependencias:

pi@erpi ~ $ sudo apt update

Get:1 http://archive.raspbian.org jessie InRelease [15.0 kB]

Hit http://archive.raspberrypi.org jessie InRelease ...

Building dependency tree Reading state information... Done

Cuando se complete esta actualización, podremos descargar e instalar automáticamente las últimas versiones del software disponible usando el comando apt upgrade. Como es lógico, deberemos siempre realizar un apt update antes de un apt upgrade:

pi@erpi ~ $ sudo apt upgrade

Reading package lists... Done Building dependency tree

Reading state information... Done Calculating upgrade... Done ...

After this operation, XXXXX B of additional disk space will be used.

Do you want to continue? [Y/n]

Existe una herramienta adicional específica para el RPi que nos permite actualizar el núcleo de Linux, los controladores y las librerías del RPi. La herramienta rpi-update puede recibir llamadas directas, sin argumentos, pero también cuenta con determinados ajustes avanzados, que se describen en github.com/Hexxeh/rpi-update. Por ejemplo, estos ajustes permiten actualizar el firmware sin tener que sustituir el núcleo:

pi@erpi ~ $ sudo apt install rpi-update

pi@erpi ~ $ sudo rpi-update

*** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS and Dom

This update bumps to rpi-4.1.y linux tree ...

*** Updating firmware

*** Updating kernel modules

*** depmod 4.1.15-v7+

*** Updating VideoCore libraries

*** Using HardFP libraries ...

*** A reboot is needed to activate the new firmware

pi@erpi ~ $ sudo reboot

Después de reiniciar la placa, la versión actual del núcleo debería quedar alineada con el núcleo y el firmware recién instalado:

molloyd@desktop:~$ ssh pi@erpi.local

pi@erpi ~ $ uname -a

Linux erpi 4.1.15-v7+ #830 SMP Tue Dec 15 17:02:45 GMT 2015 armv7l GNU/Linux

Salida de vídeo

La salida de vídeo del RPi se puede reconfigurar mediante la aplicación tvservice

(/opt/vc/bin/tvservice). Deberíamos conectar el cable del monitor HDMI en el RPi y utilizar la aplicación tvservice para listar los modos de conexión de la pantalla CEA (típicamente televisiones) o DMT (típicamente monitores de ordenador) conectada:

pi@erpi ~ $ tvservice --modes CEA

Group CEA has 0 modes:

pi@erpi ~ $ tvservice --modes DMT

Group DMT has 13 modes:

…

mode 51: 1600x1200 @ 60Hz 4:3, clock:162MHz progressive

mode 58: 1680x1050 @ 60Hz 16:10, clock:146MHz progressive

(prefer) mode 82: 1920x1080 @ 60Hz 16:9, clock:148MHz progressive

pi@erpi ~ $ tvservice --status

state 0x120006 [DVI DMT(82) RGB full 16:9], 1920x1080 @ 60.00Hz, progressive

Podemos fijar explícitamente la resolución del RPi con la misma herramienta. Por ejemplo, podemos actualizar la resolución de salida a un modo DVI 1600 × 1200, disponible en la lista de más arriba:

pi@erpi ~ $ tvservice --explicit="DMT 51"

Powering on HDMI with explicit settings (DMT mode 51)

pi@erpi ~ $ tvservice --status

state 0x120006 [DVI DMT (51) RGB full 4:3], 1600x1200 @ 60.00Hz, progressive

pi@erpi ~ $ fbset -depth 8 && fbset -depth 16

La última línea fuerza un refresco del buffer de cuadro o frame buffer (una área de la memoria de vídeo) para actualizar la pantalla. Después de comprobar la nueva resolución, podemos establecer de forma explícita el valor en el archivo /boot/config.txt, donde hdmi_group=1 establece un modo CEA, y hdmi_group=2 un modo DMT:

pi@erpi /boot $ more config.txt | grep ^hdmi

hdmi_group=2

hdmi_mode=51

Si no estamos usando la salida HDMI, podemos desconectarla completamente. Ello nos permitiría ahorrar una corriente de entre 25 y 30 mA.

pi@erpi ~ $ tvservice --off

Powering off HDMI

Existen herramientas adicionales también diseñadas para el RPi que permiten capturar datos de imagen y vídeo, que describiremos con detalle en el capítulo 15.

Interacción con los LED de la placa

Esta sección describe cómo podemos alterar el comportamiento de los LED incorporados a la placa del RPi. Estos LED están en la esquina superior izquierda de la placa del RPi 2 y en la parte inferior izquierda de la del RPi 3. Ambas placas incorporan dos LED que sirven para dar información del estado de las mismas.

❏El ACT LED (llamado OK en los modelos antiguos) parpadea de forma predeterminada durante la actividad de la tarjeta micro-SD. Desde Linux nos referimos a ese LED como led0.

❏El PWR LED se ilumina cuando el RPi está encendido. Desde Linux, este LED se conoce como led1 en algunos modelos, como el RPi 2, pero en modelos más antiguos está soldado directamente a la entrada de alimentación.


Figura 2-9: Los LED de actividad y alimentación de los RPi.

Podemos cambiar el comportamiento de estos LED para que se ajusten a nuestras necesidades, pero durante ese tiempo perderemos estas útiles informaciones de estado y alimentación del dispositivo.

NOTA Observe que el RPi Zero carece de PWR LED físico (led1), a pesar de que existan entradas en archivos de Linux que indiquen lo contrario. Podemos programar el disparador del ACT LED (led0) como se describe más adelante. Observe que la polaridad del LED está invertida. En modo disparador (trigger mode) "none" (ninguno), un valor de "0" para el brillo enciende el LED, mientras que un valor de "1" lo apaga. Este comportamiento se puede ajustar a lo largo del tiempo.

Sysfs es un sistema de archivos virtual disponible en las versiones más recientes del núcleo de Linux. Nos proporciona acceso a dispositivos y controladores que de otro modo solo serían accesibles en un espacio restringido del núcleo. Este tema se trata en profundidad en el capítulo 6. Sin embargo, en este punto, resultaría útil explorar brevemente la manera de usar sysfs para modificar el comportamiento de los LED de la placa.

Usando el cliente SSH, nos conectamos al RPi y navegamos hasta el directorio /sys/class/leds/. La salida que mostramos a continuación es para el RPi 2:

pi@erpi ~ $ cd /sys/class/leds/

pi@erpi /sys/class/leds $ ls

led0 led1

NOTA Las ubicaciones del directorio de sysfs varían ligeramente entre las distintas versiones del núcleo de Linux, así como entre las diferentes versiones.

Puede observar el mapeo de ambos LED en sysfs: led0 and led1. Es posible cambiar el directorio para modificar las propiedades de uno de los LED. Por ejemplo, para modificar el comportamiento del ACT LED (led0):

pi@erpi /sys/class/leds $ cd led0

pi@erpi /sys/class/leds/led0 $ ls

brightness device max_brightness subsystem trigger uevent

Aquí vemos varias entradas de archivo diferentes que nos aportan más información y acceso a los ajustes. Observe que esta sección utiliza algunos comandos que veremos detalladamente en el capítulo siguiente.

Para determinar el estado de un LED escribiremos lo siguiente:

pi@erpi /sys/class/leds/led0 $ cat trigger

none [mmc0] timer oneshot heartbeat backlight gpio cpu0 cpu1 cpu2

cpu3 default-on input

donde se observa que el ACT LED está configurado para mostrar actividad en el dispositivo mmc0, la tarjeta micro-SD. Para anular este disparador, escribimos:

pi@erpi /sys/class/leds/led0 $ sudo sh -c "echo none > trigger"

pi@erpi /sys/class/leds/led0 $ cat trigger

[none] mmc0 timer oneshot heartbeat backlight gpio cpu0 cpu1 ...

Veremos que el LED deja de parpadear por completo. Utilizaremos cat trigger para ver el nuevo estado. Ahora que el disparador del LED está apagado, podemos conectar o desconectar completamente el ACT LED mediante:

NOTA sudo sh -c sirve para ejecutar un comando del shell desde un comando de cadena de caracteres que requiera acceso de superusuario. No es posible ejecutar el comando utilizando la instrucción "sudo" únicamente, puesto que también se hace uso de la redirección (>)

del comando echo hacia un archivo (por ejemplo, brightness). Este tema se trata en el capítulo 3.

pi@erpi /sys/class/leds/led0 $ sudo sh -c "echo 1 > brightness"

pi@erpi /sys/class/leds/led0 $ sudo sh -c "echo 0 > brightness"

Incluso podemos establecer el intervalo que nos convenga para que el LED parpadee. Si observamos cuidadosamente, observaremos la naturaleza dinámica de sysfs. Si ejecutamos el comando ls en este punto, el directorio aparecerá como sigue, pero cambiará en breve:

pi@erpi /sys/class/leds/led0 $ ls

brightness device max_brightness subsystem trigger uevent

Para que el LED parpadee, debemos configurar el disparador en modo temporizador con el comando echo timer > trigger. Verá cómo el LED ACT parpadea a intervalos de 1 segundo. Observe las nuevas entradas delay_on y delay_off en el directorio led0:

pi@erpi /sys/class/leds/led0 $ sudo sh -c "echo timer > trigger"

pi@erpi /sys/class/leds/led0 $ ls

brightness delay_off delay_on device max_brightness subsystem

trigger uevent

El temporizador del LED emplea los tiempos definidos en ambas entradas. Puede encontrar más información sobre estos valores empleando el comando concatenate (concatenar). Por ejemplo, las líneas siguientes informan del retardo en milisegundos:

pi@erpi /sys/class/leds/led0 $ cat delay_on

500

pi@erpi /sys/class/leds/led0 $ cat delay_off

500

Para que el ACT LED parpadee con una frecuencia de 5 Hz (100 milisegundos encendido y 100 apagado), escribiremos:

pi@erpi /sys/class/leds/led0 $ sudo sh -c "echo 100 > delay_on"

pi@erpi /sys/class/leds/led0 $ sudo sh -c "echo 100 > delay_off"

El comando echo mmc0 > trigger devuelve el LED a su estado predeterminado, lo que provoca la desaparición de las entradas delay_on y delay_off:

pi@erpi /sys/class/leds/led0 $ sudo sh -c "echo mmc0 > trigger"

pi@erpi /sys/class/leds/led0 $ ls

brightness device max_brightness subsystem trigger uevent


Apagado y reinicio

ADVERTENCIA Desconectar el cable de alimentación sin que el núcleo de Linux pueda desmontar la tarjeta micro-SD puede corromper el sistema de archivos.

Por último, vamos a analizar el procedimiento correcto para apagar el RPi. Una desconexión inapropiada puede corromper el sistema de archivos ext4 o, como poco, prolongar los tiempos de inicio a causa de las comprobaciones del mismo. Veamos algunos puntos importantes a la hora de encender, apagar o reiniciar el RPi:

❏Escribir sudo shutdown -h now apaga la placa de forma correcta. Si escribimos sudo shutdown -h +5 retrasaremos el apagado cinco minutos.

❏Escribir sudo reboot reiniciará correctamente la placa.

Si el diseño de nuestro proyecto contempla una carcasa para el RPi y necesitamos un medio para apagarlo correctamente desde el exterior, es posible cablear un botón externo a la cabecera GPIO y escribir un script que se ejecute durante el inicio y que solicite una entrada a la GPIO. Si se detecta esa entrada, se podrá llamar directamente a /sbin/shutdown -h now.

Resumen

Después de leer este capítulo debería ser capaz de hacer lo siguiente:

❏Comunicarse con el RPi desde su ordenador mediante una conexión de red.

❏Comunicarse con el RPi usando una conexión de respaldo serie mediante un cable USB a TTL de 3,3 V.

❏Interaccionar con el RPi y controlarlo mediante sencillos comandos de Linux.

❏Realizar la edición básica de archivos desde una ventana de terminal del intérprete de comandos de Linux.

❏Gestionar los paquetes de software de Linux y establecer la fecha y la hora del sistema.

❏Emplear utilidades específicas para la configuración avanzada del RPi.

❏Utilizar el sysfs de Linux para modificar el estado de los LED de la placa del RPi.

❏Iniciar y apagar el RPi con seguridad.

1 Las tarjetas SD y los discos duros se comercializan generalmente con un valor ajustado de 1 gigabyte (GB) a 1.000.000.000 de bytes (es decir, 1.0003 bytes). Linux utiliza el gigabyte con potencias de dos (técnicamente GiB, o Gibibyte), es decir, 1.0243 bytes. Así pues, se produce una discrepancia cuando formateamos una tarjeta SD; por ejemplo, una tarjeta de 16 GB mostrará un espacio máximo de 14,901 GiB, es decir, 16 × 109/1.0243, una vez formateada.

Capítulo

3

Exploración de sistemas Linux empotrados

Este capítulo presenta los conceptos, comandos y herramientas esenciales para manejar con eficiencia el sistema Linux empotrado en el Raspberry Pi. La primera parte de este capítulo es descriptiva. Explica los aspectos básicos de Linux en sistemas empotrados y del proceso de inicio de Linux. Después aprenderemos a gestionar los sistemas Linux paso a paso. Para este ejercicio es muy recomendable abrir una conexión terminal con nuestro Raspberry Pi, o bien una ventana de terminal en el propio RPi, antes de continuar. Luego, en el capítulo se describe el sistema de gestión de versiones de código fuente Git. Se trata de un tema importante porque los ejemplos de código fuente de este libro se distribuyen a través de GitHub. La virtualización de escritorios se describe igualmente, puesto que resultará útil para el desarrollo multiplataforma en posteriores capítulos. El capítulo finaliza describiendo cómo descargar los ejemplos de código fuente para este libro.

Materiales necesarios para este capítulo:

❏Cualquier modelo de Raspberry Pi con una conexión terminal (véase el capítulo 2, "El software del Raspberry Pi") o una ventana de terminal, preferiblemente ejecutando Raspbian.

Puede encontrar más detalles sobre este capítulo en la dirección:

www.exploringrpi.com/chapter3/.

Introducción a Linux para sistemas empotrados

Lo primero es lo primero: aun cuando la expresión "Linux empotrado" (embedded Linux) está presente ya en el título del capítulo, ¡no hay nada que pueda denominarse "Linux empotrado"! No existe una versión especial del núcleo de Linux para sistemas empotrados: es el mismo núcleo estándar de Linux el que se ejecuta en dichos sistemas. Dicho esto, lo cierto es que la expresión Linux empotrado resulta de uso común y está ampliamente aceptada. Así pues, este libro utiliza "Linux empotrado" en lugar de "Linux ejecutándose en un sistema empotrado", que sería más correcta.

La palabra "empotrado" (embedded) sirve para indicar la presencia de un sistema hardware empotrado (embedded system), concepto que se puede definir libremente como un tipo de hardware con software integrado, diseñado específicamente para una determinada aplicación. Es un concepto que contrasta vivamente con el de ordenador personal (PC), que es una plataforma de computación de propósito general diseñada para ejecutar una infinidad de aplicaciones diferentes, tales como navegadores de Internet, procesadores de texto o videojuegos. Ahora bien, la línea que separa unos sistemas de otros se va difuminando progresivamente. Sin ir más lejos, el Raspberry Pi puede actuar de las dos maneras, y son muchos los usuarios que deciden emplearlo exclusivamente como ordenador personal bastante capaz, o bien como dispositivo multimedia. Sin embargo, los sistemas empotrados presentan algunas características diferenciadoras:

❏Suelen incluir aplicaciones específicas y dedicadas a tareas concretas.

❏Su capacidad de procesamiento, memoria y almacenamiento son a menudo limitadas.

❏En general forman parte de sistemas más grandes que suelen estar conectados a sensores y actuadores externos.

❏A menudo desempeñan su labor en sistemas para los cuales la fiabilidad es un elemento crucial, como controles en automóviles, aviones y equipos médicos.

❏Operan muchas veces en tiempo real, es decir, donde sus salidas están relacionadas directamente con las entradas presentes, por ejemplo en sistemas de control.

Los sistemas empotrados se encuentran en todas partes. Como ejemplos podemos citar: máquinas de vending, aplicaciones para el hogar, teléfonos, smartphones, cadenas de fabricación y ensamblaje, televisiones, consolas de videojuegos, automóviles (por ejemplo, la dirección asistida o los sensores de aparcamiento), elementos de red (como switches, routers o puntos de acceso inalámbricos), sistemas de sonido, equipos médicos, impresoras, controles de acceso a edificios, parquímetros, sistemas de control de agua y energía, relojes, herramientas de construcción, cámaras digitales, monitores, tabletas, lectores de libros digitales, robots, sistemas de pago inteligentes, etc.

La gran proliferación de dispositivos con Linux empotrado se debe, en parte, a la rápida evolución de la tecnología smartphone, que ha presionado a la baja los precios de los microprocesadores con tecnología ARM. ARM Holdings PLC es la compañía británica que comercializa, para los modelos del RPi, las licencias de uso de los diseños ARMv6 y ARMv7 por una cantidad aproximada de entre el 1 y el 2% del precio real de venta del procesador. Avago Technologies Ltd., la propietaria de Broadcom Corporation desde mayo de 2015, no comercializa en la actualidad procesadores directamente a minoristas, pero sus microprocesadores similares a los BCM2835/6/7 tienen un precio de venta de entre 5 y 10 dólares.

Ventajas y desventajas de Linux para sistemas empotrados

Hay muchos tipos de plataformas empotradas, cada una con sus propias ventajas e inconvenientes. Las hay con un coste muy bajo para pedidos de gran volumen, por debajo de 1 euro, por ejemplo Amtel AVR (8/16 bits), Microchip PIC o TI Stellaris, pero también muy caras y especializadas que pueden llegar hasta los 150 euros, como microprocesadores de señales digitales (DSP, Digital Signal Processor) multinúcleo. Generalmente, dichas plataformas se programan en lenguajes C o ensamblador (assembly language), lo que exige un conocimiento muy solvente de los detalles hardware de más bajo nivel de las arquitecturas antes de empezar siquiera a plantearse el desarrollo de aplicaciones útiles. Linux empotrado ofrece una alternativa a tales plataformas en el sentido de que elimina la exigencia de conocer al detalle la arquitectura subyacente del sistema para emprender el desarrollo de aplicaciones. Ahora bien, si nuestras aplicaciones van a tener que comunicarse a bajo nivel con dispositivos electrónicos, sí que será necesario un cierto conocimiento de las arquitecturas.

Veamos algunas de las razones por las que Linux empotrado ha experimentado un crecimiento tan reseñable:

❏Linux es un sistema operativo (SO) eficiente y escalable que se ejecuta sobre una amplia variedad de dispositivos, desde los de coste más bajo, orientados al gran consumo, hasta los servidores más grandes y caros. Asimismo, ha evolucionado con el correr del tiempo desde la época en que los ordenadores tenían una mínima fracción de la potencia que ofrecen ahora, pero conservando casi intacta su eficiencia.

❏Existe un inmenso conjunto de aplicaciones y herramientas de código abierto, listas para su instalación y uso en un sistema empotrado. Si necesitamos, por ejemplo, un servidor web para nuestra aplicación empotrada, podremos usar el mismo que instalaríamos en un servidor Linux.

❏Existen excelentes controladores de código abierto para una gran variedad de periféricos y dispositivos, desde adaptadores de red hasta monitores.

❏Linux es un sistema de código abierto y no hay que pagar nada por usarlo.

❏Su núcleo y sus aplicaciones se ejecutan a diario en una cantidad tal de sistemas por todo el mundo que los errores son extremadamente infrecuentes y además se detectan y corrigen rápidamente.

Una desventaja de Linux empotrado es su falta de idoneidad para las aplicaciones en tiempo real debido a la sobrecarga, fundamentalmente de tiempo en este caso, del propio SO. Así pues, para aplicaciones de gran precisión y mínima latencia, como el procesamiento de señales analógicas, Linux empotrado podría no ser la solución perfecta. Sin embargo, incluso en aplicaciones de tiempo real, se emplea a menudo como cerebro e interfaz de control dentro de un conjunto interconectado de sensores (véase el capítulo 12). Además, el desarrollo de las capacidades de Linux RTOS (Real Time Operating Systems, sistemas operativos de tiempo real) continúa avanzando y progresa en su objetivo de agilizar las interrupciones del SO para su uso en tiempo real.

¿Es Linux gratuito y de código abierto?

Linux se publica bajo licencia GNU GPL (General Public License, licencia pública general), que garantiza a los usuarios el derecho de uso y modificación del código fuente sin límites. Así pues, la palabra free hace aquí más referencia al concepto de "libre" que al de "gratuito" (ambos son significados del término en inglés). De hecho, algunas de las distribuciones de Linux más caras son precisamente las destinadas a las arquitecturas empotradas. Podrá encontrar una guía rápida para familiarizarse con la licencia GPLv3 en la web www.gnu.org, que relaciona nuestros derechos como usuarios (Smith, 2013):

Derecho a utilizar el software para cualquier propósito.

Derecho a modificar el software para que se ajuste a sus necesidades.

Derecho a compartir el software con amigos y vecinos.

Y derecho a compartir todos aquellos cambios que introduzca en él.

Aun si estamos utilizando una distribución descargada de forma gratuita, puede que nos cueste un esfuerzo significativo modificar las librerías y los controladores de dispositivo para adaptar los componentes y módulos particulares que deseemos utilizar en el desarrollo de los productos.

Cómo iniciar el Raspberry Pi

Lo primero que deberíamos ver cuando arrancamos un ordenador es la UEFI (Unified Extensible Firmware Interface, interfaz de firmware ampliable unificada), que brinda compatibilidad con las rutinas de servicio de la antigua BIOS (Basic Input/Output System, sitema básico de entrada/salida). La pantalla de inicio muestra información del sistema y nos invita a pulsar una tecla para modificar estos ajustes. La UEFI comprueba los componentes del hardware, como la memoria, y, luego, carga el SO, generalmente desde una unidad de disco duro SSD (Solid State Disk, disco de estado sólido). Así pues, cuando encendemos un ordenador, la UEFI, o la BIOS, ejecutan las tareas siguientes:

1. Toma el control del procesador del equipo.

2. Inicializa y comprueba los componentes hardware.

3. Carga el SO desde la unidad SSD o disco duro convencional.

La UEFI/BIOS ofrece una capa de abstracción que permite al SO interaccionar con la pantalla y otros periféricos de entrada/salida del sistema, como ratón, teclado y almacenamiento externo. Sus ajustes se guardan en una memoria flash NAND alimentada por una pila de botón (que se puede ver en las placas madre de los ordenadores) que alimenta también el reloj del sistema.

Los gestores de arranque del Raspberry Pi

Como la mayoría de los dispositivos Linux empotrados, el RPi carece de BIOS y de batería de alimentación, al menos de forma predeterminada (veremos cómo se añade un reloj en tiempo real al RPi en el capítulo 9). En lugar de eso, utiliza una combinación de gestores de arranque (bootloaders). Generalmente, los gestores de arranque son pequeños programas que realizan la función crítica de vincular el hardware concreto de cada placa con Linux:

❏Inicializan los controladores (memoria, gráficos, E/S).

❏Preparan y asignan la memoria del sistema para el SO.

❏Localizan el SO y preparan su carga.

❏Cargan el SO y le pasan el control.

El gestor de arranque de Linux empotrado es un programa personalizado para cada tipo de placa, incluido el RPi. Existen gestores de arranque de código abierto para Linux, tales como Das U-Boot (el cargador universal de referencia), que se puede personalizar, siempre que se cuente con un conocimiento detallado del hardware de la plataforma de Linux empotrado, mediante parches de software específicos de cada plataforma (diríjase a tiny.cc/erpi301). El RPi utiliza un enfoque distinto: utiliza unos gestores de arranque muy eficientes pero de código cerrado, desarrollados específicamente para el RPi por Broadcom. Tanto el gestor de arranque como los archivos de configuración se encuentran en el directorio /boot de la imagen en el RPi:

pi@erpi /boot $ ls -l *.bin start.elf *.txt *.img fixup.dat

-rwxr-xr-x 1 root root 17900 Jun 16 01:57 bootcode.bin

-rwxr-xr-x 1 root root 120 May 6 23:23 cmdline.txt

-rwxr-xr-x 1 root root 1581 May 30 14:49 config.txt

-rwxr-xr-x 1 root root 6174 Jun 16 01:57 fixup.dat

-rwxr-xr-x 1 root root 137 May 7 00:31 issue.txt

-rwxr-xr-x 1 root root 3943888 Jun 16 01:57 kernel7.img

-rwxr-xr-x 1 root root 3987132 Jun 16 01:57 kernel.img

-rwxr-xr-x 1 root root 2684312 Jun 16 01:57 start.elf

La figura 3-1 ilustra el proceso de arranque en el RPi, donde cada etapa del mismo se carga e invoca por la precedente. Los archivos bootcode.bin y tart.elf son gestores de arranque de código cerrado que están en código binario y se ejecutan en la GPU del RPi, y no en la propia CPU. El archivo de licencia que podemos encontrar en github.com/raspberrypi/firmware/tree/master/boot indica que se autoriza la redistribución "en código binario, sin modificaciones" y que "solo se puede utilizar con propósitos de desarrollo y ejecución en un dispositivo Raspberry Pi". Podemos encontrar una imagen comprimida del núcleo en /boot/kernel.img. Por descontado, es código abierto.

La salida que sigue es una secuencia de arranque típica, capturada con el cable serie USB a TTL de 3,3 V que vimos en el capítulo 1. El cable estaba fijo a los pines 6 (GND), 8 (UART_TXD) y 10 (UART_RXD) de la cabecera del RPi, y los datos se capturaron a 115.200 baudios. A diferencia de los gestores U-boot, que se ejecutan en la CPU, los gestores tempranos del RPi no ofrecen salida por consola, aunque sí hacen parpadear los LED de la placa con patrones específicos si surgen problemas. Lo que sigue es un extracto de la salida por consola durante el arranque del RPi 3. Muestra una importante información del sistema, como el mapeo de la memoria:


Figura 3-1: La secuencia de arranque completa en el RPi.

Uncompressing Linux... done, booting the kernel.

[ 0.000000] Booting Linux on physical CPU 0x0

...

[ 0.000000] Linux version 4.1.18-v7+ (dc4@dc4-XPS13-9333) (gcc version

4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611) ) #846 SMP Thu Feb

25 14:22:53 GMT 2016

[ 0.000000] CPU: ARMv7 Processor [410fd034] revision 4 (ARMv7) ...

[ 0.000000] Machine model: Raspberry Pi 3 Model B Rev 1.2

[ 0.000000] cma: Reserved 8 MiB at 0x36400000 ...

[ 0.000000] Kernel command line: 8250.nr_uarts=1 dma.dmachans=0x7f35

bcm2708_fb.fbwidth=656 bcm2708_fb.fbheight=416 bcm2709.boardrev=0xa02082

bcm2709.serial=0xbbffd b2c smsc95xx.macaddr=B8:27:EB:FF:DB:2C

bcm2708_fb.fbswap=1 bcm2709.uart_clock=48000000 vc_mem.mem_base=0x3dc00000

vc_mem.mem_size=0x3f000000 dwc_otg.lpm_enable=0 console=ttyS0,115200

root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

[ 0.000000] Memory: 874456K/901120K available (6024K kernel code, 534K

rwdata, 1660K rodata, 448K init, 757K bss, 18472K reserved, 8192K cma-

reserved)

[ 0.000000] Virtual kernel memory layout:

vector : 0xffff0000 - 0xffff1000 ( 4 kB)

fixmap : 0xffc00000 - 0xfff00000 (3072 kB)

vmalloc : 0xb7800000 - 0xff000000 (1144 MB)

lowmem : 0x80000000 - 0xb7000000 ( 880 MB)

modules : 0x7f000000 - 0x80000000 ( 16 MB)

.text : 0x80008000 - 0x807895a0 (7686 kB)

.init : 0x8078a000 - 0x807fa000 ( 448 kB)

.data : 0x807fa000 - 0x8087fac0 ( 535 kB)

.bss : 0x80882000 - 0x8093f79c ( 758 kB)

...

[ 0.052103] Brought up 4 CPUs

[ 0.052201] SMP: Total of 4 processors activated (153.60 BogoMIPS).

[ 0.052231] CPU: All CPU(s) started in HYP mode. ...

[ 1.467927] console [ttyS0] enabled

...

[ 3.307558] systemd[1]: Detected architecture 'arm'.

[ 3.321650] smsc95xx 1-1.1:1.0 eth0: register 'smsc95xx' at

usb-3f980000.usb-1.1, smsc95xx USB 2.0 Ethernet, b8:27:eb:ff:db:2c

[ 3.488061] NET: Registered protocol family 10

[ 3.498204] systemd[1]: Inserted module 'ipv6'

[ 3.510056] systemd[1]: Set hostname to <erpi> ...

[ 5.450070] spi spi0.0: setting up native-CS0 as GPIO 8

[ 5.450453] spi spi0.1: setting up native-CS1 as GPIO 7 ...

...

Raspbian GNU/Linux 8 erpi ttyS0

erpi login:

Obtenemos la misma información si escribimos dmesg|more en una ventana de terminal. No es difícil ver cómo se configura el estado inicial del hardware, pero la mayoría de las entradas se antojan enigmáticas por el momento. Hay algunos puntos importantes que observar, como se pueden ver destacados en la salida anterior:

❏El núcleo de Linux se descomprime en memoria y, luego, se inicia. El ARMv7 del RPi 2/3 (kernel7.img) y el ARMv6 del RPi/RPi B+ (kernel.img) utilizan una versión ligeramente diferente del núcleo.

❏Se identifica la versión del núcleo de Linux, por ejemplo 4.1.18-v7+.

❏El modelo de la máquina se identifica de manera que se pueda cargar el árbol de código binario correcto.

❏La dirección de red MAC (Medium Access Control, control de acceso al medio (físico)), una dirección hardware única que identifica el dispositivo en la red a nivel físico) se pasa como un argumento del núcleo en la línea de comandos. La dirección MAC se establece automáticamente en el RPi mediante los tres últimos bytes del número de serie de la CPU, que se fija durante la fabricación. Ejecute cat /proc/cpuinfo para mostrar el número de serie de la placa. En este caso, el número es 00000000bbffdb2c, donde ffdb2c sirve para facilitar un número de dirección MAC único.

❏El usuario puede configurar algunos de los argumentos del núcleo restantes editando el archivo cmdline.txt, por ejemplo ejecutando sudo nano cmdline.txt del siguiente modo:

pi@erpi /boot $ more cmdline.txt

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p2

rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

❏Se muestra el formato de la memoria virtual del núcleo. La entrada de los módulos es particularmente importante y se utilizará en el capítulo 8.

El principal archivo de configuración del RPi es /boot/config.txt. Los cambios que introducimos mediante la herramienta raspi-config se reflejan en este archivo. Es posible editarlo ejecutando sudo nano /boot/config.txt para habilitar y deshabilitar el bus hardware, elevar la frecuencia del procesador, etc.

pi@erpi /boot $ more config.txt

# For more options and information see

# http://www.raspberrypi.org/documentation/configuration/config-txt.md ...

# Uncomment some or all of these to enable the optional hardware interfaces

dtparam=i2c_arm=on

#dtparam=i2s=on

dtparam=spi=on

...

# Additional overlays and parameters are documented /boot/overlays/README

El gestor de arranque del RPi utiliza un archivo de configuración para la tarjeta llamado device tree o árbol de dispositivos (también llamado device tree binary, árbol de dispositivos binario) que contiene la información específica requerida por el núcleo para arrancar el RPi. Este archivo contiene toda la información necesaria para describir el tamaño de la memoria, la velocidad del reloj, los dispositivos de la placa, etc. Este árbol de dispositivos binario o DTB, donde "binario" hace aquí referencia al archivo compilado, se crea a partir del árbol de dispositivos fuente o DTS (Device Tree Source), que es, obviamente, el archivo de código fuente a partir del que se obtiene dicho binario compilando con el DTC (Device Tree Compiler). Este tema se trata en profundidad en el capítulo 8. El directorio /boot contiene los binarios del árbol de dispositivos para los distintos modelos de RPi:

pi@erpi /boot $ ls -l *.dtb

-rwxr-xr-x 1 root root 10841 Feb 25 23:22 bcm2708-rpi-b.dtb

-rwxr-xr-x 1 root root 11120 Feb 25 23:22 bcm2708-rpi-b-plus.dtb

-rwxr-xr-x 1 root root 10871 Feb 25 23:22 bcm2708-rpi-cm.dtb

-rwxr-xr-x 1 root root 12108 Feb 25 23:22 bcm2709-rpi-2-b.dtb

-rwxr-xr-x 1 root root 12575 Feb 25 23:22 bcm2710-rpi-3-b.dtb

El código fuente de estos DTB se encuentra disponible en formato DTS. Los archivos DTS de cada modelo de RPi presentan una sintaxis similar al extracto siguiente, que detalla el hardware de los pines de los LED incorporados a la placa y de uno de los dos buses I2C del RPi 2:

&i2c1 {

pinctrl-names = "default";

pinctrl-0 = <&i2c1_pins>;

clock-frequency = <100000>;

};

&leds {

act_led: act {

label = "led0";

linux,default-trigger = "mmc0";

gpios = <&gpio 47 0>;

};

pwr_led: pwr {

label = "led1";

linux,default-trigger = "input";

gpios = <&gpio 35 0>;

};

};

El código fuente completo del archivo DTS para el RPi 2 (bcm2709-rpi-2-b.dts) está disponible en: tiny.cc/erpi302. Se pueden añadir al RPi archivos binarios del árbol de dispositivos adicionales, como sensores, placas HAT y pantallas LCD:

pi@erpi /boot/overlays $ ls

ads7846-overlay.dtb i2s-mmap-overlay.dtb pps-gpio-overlay.dtb ...

hifiberry-amp-overlay.dtb mcp2515-can0-overlay.dtb rpi-proto-overlay.dtb

hy28b-overlay.dtb piscreen-overlay.dtb w1-gpio-pullup-overlay.dtb

i2c-rtc-overlay.dtb pitft28-resistive-overlay.dtb

La descripción completa del código fuente del árbol de dispositivos para la distribución del RPi está en el código fuente del resto del libro en el directorio /chp03/dts.


Espacio del núcleo y espacio de usuario

El núcleo de Linux se ejecuta en una área de la memoria del sistema llamada espacio del núcleo (kernel space), mientras que, por su parte, las aplicaciones normales se ejecutan en el espacio de usuario (user space). Una separación estricta entre ambos espacios en memoria evita que las aplicaciones de usuario accedan al espacio y los recursos requeridos para el funcionamiento del núcleo de Linux. Esto ayuda a evitar que el núcleo se cuelgue a causa del código de usuario mal desarrollado, así como que las aplicaciones de un usuario interfieran en la ejecución de las aplicaciones de otro e invadan su espacio. También proporcionan un grado más elevado de seguridad.

El núcleo de Linux es "propietario" y tiene acceso pleno a toda la memoria física y al resto de los recursos del RPi. Así pues, debemos ser muy cuidadosos y solo permitir que el código más estable y comprobado se ejecute en el espacio del núcleo. Puede observar las arquitecturas e interfaces ilustradas en la figura 3-2, donde las aplicaciones de usuario emplean la librería GNU C (glibc) para comunicarse con la interfaz de llamadas del núcleo del sistema. Luego, los servicios del núcleo se ponen a disposición del espacio de usuario de manera controlada mediante el uso de llamadas del sistema.


Figura 3-2: Las arquitecturas del espacio de usuario y del espacio del núcleo de Linux.

Un módulo del núcleo (kernel module) es un archivo objeto que contiene código binario y que se puede cargar y descargar del núcleo bajo demanda. En muchos casos, el núcleo puede incluso cargar y descargar módulos mientras se está ejecutando, es decir, "en caliente", sin necesidad de reiniciar el RPi. Por ejemplo, si enchufamos un adaptador WiFi USB en el RPi, es posible que el núcleo utilice un LKM (Loadable Kernel Module o módulo cargable del núcleo) para hacerlo funcionar. Sin esta capacidad modular, el núcleo de Linux sería extremadamente grande, puesto que tendría que dar soporte a todos los controladores que el RPi pudiera llegar a necesitar. Asimismo, tendríamos que recompilar el núcleo cada vez que quisiéramos añadir un nuevo hardware. Una desventaja de los LKM es que los archivos de controlador se deben mantener para cada dispositivo. La interacción con los LKM se describe a lo largo de todo el libro, y en el capítulo 16 veremos cómo escribir nuestros propios LKM.

Como se indica en la figura 3-1, las etapas del gestor de arranque (bootloader stages) ceden el control al núcleo después de que este haya finalizado su descompresión en la memoria. Después, el núcleo monta el sistema de archivos raíz. El último paso del núcleo durante el proceso de arranque es la llamada a systemd init (/sbin/init en un RPi con Raspbian Jessie), que es el primer proceso de usuario que se inicia, y también el siguiente tema que vamos a tratar.

El gestor de sistema y servicios systemd

Un gestor de sistema y servicios (system and service manager) inicia y detiene servicios (por ejemplo, servidores web, servidor SSH) dependiendo del estado actual del RPi, es decir, si se está iniciando, apagando, etc. El gestor de sistema

y servicios systemd se ha añadido recientemente, y no sin controversia, a Linux y tiene como objetivo sustituir al gestor System V (SysV) init, al tiempo que mantiene la compatibilidad hacia atrás. Una desventaja grave de SysV init es que inicia los servicios en serie, es decir, que espera a que una tarea finalice antes de comenzar la siguiente, lo que puede alargar el tiempo de arranque del dispositivo. El gestor systemd está activado de forma predeterminada en Debian 8/Raspbian 8 (Jessie) y permite iniciar los servicios del sistema en paralelo, lo que reduce, obviamente, los tiempos de arranque, sobre todo en procesadores multinúcleo como los de los RPi 2/3. De hecho, podemos mostrar la duración de dicho proceso del siguiente modo:

pi@erpi ~ $ systemctl --version

systemd 215 +PAM +AUDIT +SELINUX +IMA +SYSVINIT +LIBCRYPTSETUP +GCRYPT

+ACL +XZ -SECCOMP -APPARMOR

pi@erpi ~ $ systemd-analyze time

Startup finished in 2.230s (kernel) + 6.779s (userspace) = 9.009s

ADVERTENCIA Si observa el mensaje “command not found” (comando no encontrado) en este punto, lo más probable es que esté usando una distribución Raspbian 7, que emplea SysV init. Para más información, visite la página web de este capítulo: www.exploringrpi.com/chapter3/.

Además de ser un gestor de sistema y servicios, systemd incluye software para gestión de inicios de sesión, archivos de log, gestión de dispositivos, sincronización de tiempos, etc. Los críticos de systemd insisten en que su proyecto de desarrollo ha traspasado sus propios límites y ha ido invadiendo áreas alejadas de su propósito fundamental. Hasta cierto punto, esta invasión de otras áreas ha supuesto que systemd resulte ahora básico para el futuro del propio Linux, hasta el punto de eliminar las posibilidades de elegir de los propios usuarios. Sin embargo, parece claro que systemd goza de una amplia aceptación por parte de las distribuciones Linux y que está aquí para quedarse.

Podemos utilizar el comando systemctl para inspeccionar y controlar el estado de systemd. Si lo invocamos sin argumentos, nos ofrecerá una lista completa de servicios en ejecución en el RPi (para pasar a otra pantalla, pulse la barra espaciadora, y para salir, Q):

pi@erpi ~ $ systemctl

networking.service loaded active exited LSB: Raise network interfaces

ntp.service loaded active running LSB: Start NTP daemon

serial-getty@ttyAMA0 loaded active running Serial Getty on ttyAMA0

ssh.service loaded active running OpenBSD Secure Shell server

getty.target loaded active active Login Prompts ...

El comando systemd uses archivos de servicio (service files), que presentan una extensión service, para definir el comportamiento de los diferentes servicios durante su inicio, apagado, recarga, etc. Véase el directorio /lib/systemd/system.

El servicio del protocolo NTP (Network Time Protocol, protocolo de tiempo de red) se ejecuta por defecto con la propia instalación. El gestor systemd sirve para manejar tales servicios en el RPi. Por ejemplo, podemos identificar el número exacto del servicio y obtener su estado actual del siguiente modo:

pi@erpi:~$ systemctl list-units -t service | grep ntp

ntp.service loaded active running LSB: Start NTP daemon

pi@erpi:~$ systemctl status ntp.service

• ntp.service - LSB: Start NTP daemon

Loaded: loaded (/etc/init.d/ntp)

Active: active (running) since Mon 2016-01-02 13:00:48 GMT; 2h 21min ago

Process: 502 ExecStart=/etc/init.d/ntp start (code=exited, status=0/ SUCCESS)

CGroup: /system.slice/ntp.service

├─552 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 107:112

└─559 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 107:112

Podemos detener el servicio ntp con el comando systemctl, momento a partir del que dejará de actualizar el reloj con el tiempo de la red.

pi@erpi:~$ sudo systemctl stop ntp

pi@erpi:~$ systemctl status ntp

• ntp.service - LSB: Start NTP daemon

Loaded: loaded (/etc/init.d/ntp)

Active: inactive (dead) since Mon 2017-01-02 17:42:26 GMT; 6s ago

Process: 1031 ExecStop=/etc/init.d/ntp stop (code=exited, status=0/SUCCESS)

Process: 502 ExecStart=/etc/init.d/ntp start (code=exited, status=0/SUCCESS)

Para reiniciar el servicio, ejecutamos:

pi@erpi ~ $ sudo systemctl start ntp

La tabla 3-1 ofrece un resumen de los comandos de systemd con la sintaxis del servicio ntp como ejemplo. Muchos de estos comandos exigen elevación a permisos de superusuario con el uso de sudo, como veremos en la sección siguiente.

Tabla 3-1: Comandos habituales de systemd.


ComandoDescripción
systemctlLista todos los servicios en ejecución.
systemctl start ntpInicia un servicio. No persiste después de reiniciar.
systemctl stop ntpDetiene un servicio. No persiste después de reiniciar.
systemctl status ntpMuestra el estado del servicio.
systemctl enable ntpHabilita un servicio durante el arranque.
systemctl disable ntpImpide que un servicio se inicie durante el arranque.
systemctl is-enabled sshMuestra si un servicio se inicia durante el arranque.
systemctl restart ntpReinicia un servicio (lo detiene y lo vuelve a iniciar).
systemctl condrestart ntpReinicia un servicio solo si está en ejecución.
systemctl reload ntpCarga los archivos de configuración de un servicio sin detenerlo.
journalctl –fSiga el archivo de registro systemd. Pulsamos Control+C para salir.
hostnamectl --static set-hostname ERPiCambia el nombre del host.
timedatectl Muestra fecha y hora, así como la información de la zona horaria.
systemd-analyze timeMuestra la duración del arranque.

El nivel de ejecución (runlevel) describe el estado actual del RPi y se puede utilizar para controlar los procesos o servicios iniciados por el sistema init. Bajo SysV hay diferentes niveles de ejecución, identificados como 0 (halt), 1 (single-user mode), 2 a 5 (multi-user modes), 6 (reboot) y S (start-up). Cuando el proceso init se inicia, el nivel de ejecución se inicia en N (none). Luego, entra en el nivel de ejecución S para inicializar el sistema en modo monousuario y, finalmente, pasa a uno de los modos multiusuario. Para averiguar el nivel de ejecución actual, escriba lo siguiente:

pi@erpi ~ $ who -r

run-level 5 2016-01-02 03:23

En este caso, el RPi presenta un nivel de ejecución 5. Podemos cambiar el nivel de ejecución escribiendo init seguido del número del nivel. Por ejemplo, podemos reiniciar nuestro RPi escribiendo:

pi@erpi ~ $ sudo init 6

Como vemos, systemd conserva cierta compatibilidad hacia atrás con los niveles de ejecución de SysV y sus números, puesto que los antiguos comandos de SysV funcionan correctamente en systemd. No obstante, utilizar niveles de ejecución en systemd es una práctica considerada obsoleta. En su lugar, systemd utiliza objetivos con identificador (named target units), algunos de los cuales se listan en la tabla 3-2, que muestra las equivalencias con los niveles de ejecución SysV. Para identificar el objetivo con identificador predeterminado en cada momento en el RPi, escribimos:

pi@erpi ~ $ systemctl get-default

graphical.target

Indica que la configuración actual exige que el RPi tenga un monitor para interfaz con ventanas. El comando siguiente le permite observar también la lista de unidades que el objetivo carga:

pi@erpi ~ $ systemctl list-units --type=target

UNIT LOAD ACTIVE SUB DESCRIPTION

basic.target loaded active active Basic System

cryptsetup.target loaded active active Encrypted Volumes

getty.target loaded active active Login Prompts

graphical.target loaded active active Graphical Interface

multi-user.target loaded active active Multi-User System

...

Tabla 3-2: Objetivos systemd junto con los niveles de ejecución de SysV.


Nombres de objetivoSysVDescripción y ejemplo de uso
poweroff.target0Detiene el sistema: estado de apagado para todos los servicios.
rescue.target1,SModo monousuario administrador: para funciones administrativas, por ejemplo comprobar el sistema de archivos.
multi-user.target2-4Modos estándar multiusuario sin monitor para interfaz con ventanas.
graphical.target5Modo estándar multiusuario con monitor para interfaz con ventanas.
reboot.target6Reinicia el sistema: estado de reinicio para todos los servicios.
emergency.target—Shell de emergencia solo para la consola principal.

Si utilizamos el RPi como dispositivo de red, sin monitor, mantener activos los servicios de interfaz de ventanas parece un derroche de recursos de CPU y memoria. Podemos pasar a un modo objetivo sin monitor usando la llamada siguiente, donde la interfaz gráfica LXDE dejará de estar presente y la entrada graphical.target desaparecerá de la lista de unidades:

pi@erpi ~ $ sudo systemctl isolate multi-user.target

pi@erpi ~ $ systemctl list-units --type=target | grep graphical

Análogamente, podemos reactivar el modo objetivo con monitor e interfaz gráfica de este modo:

pi@erpi ~ $ sudo systemctl isolate graphical.target

Por último, para configurar el RPi de manera que utilice un nivel de ejecución distinto de forma predeterminada durante el arranque, por ejemplo sin monitor, usaremos:

pi@erpi ~ $ sudo systemctl set-default multi-user.target

Created symlink from /etc/systemd/system/default.target to /lib/systemd/sys

tem/multi-user.target.

pi@erpi ~ $ systemctl get-default

multi-user.target

Tras reiniciar, los servicios de interfaz gráfica con ventanas no arrancarán, y el nivel de ejecución SysV equivalente se mostrará con el número 3.

Gestión de sistemas Linux

En esta sección examinaremos más de cerca el sistema de archivos de Linux, a partir de los comandos y herramientas descritas en el capítulo 2. De este modo adquiriremos un control administrativo completo del RPi.

El superusuario

En los sistemas Linux, la cuenta de administrador del sistema tiene el nivel de acceso con la seguridad más alta para todos los comandos y archivos. Esta cuenta se suele conocer como root o superuser, superusuario. En Raspbian/Debian, esta cuenta tiene el nombre de usuario root, pero suele estar deshabilitada de forma predeterminada. Sin embargo, la podemos habilitar escribiendo sudo passwd root desde un intérprete de comandos en el que haya iniciado sesión la cuenta pi (username: pi, password: raspberry):

pi@erpi ~ $ sudo passwd root

Enter new UNIX password: mySuperSecretPassword

Retype new UNIX password: mySuperSecretPassword

passwd: password updated successfully

NOTA Llamar a la cuenta “root” está relacionado con el hecho de que es la única cuenta de usuario con permiso para alterar el directorio raíz (root) de más alto nivel (/). Para más información diríjase a www.linfo.org/root.htm.

Se recomienda no realizar el manejo cotidiano del sistema Linux desde la cuenta de superusuario. Sin embargo, tampoco debemos olvidar que manejar el RPi no es lo mismo que gestionar un servidor con miles de cuentas de usuario. En muchas aplicaciones, una sola cuenta de superusuario con una contraseña no estándar es más que suficiente. Sin embargo, utilizar una cuenta estándar para los trabajos de desarrollo puede protegernos de errores catastróficos, como eliminar accidentalmente el sistema de archivos. La cuenta de usuario pi en Raspbian ha sido configurada cuidadosamente para simplificar la interacción con el hardware. De este modo, está lista para ser usada para la mayoría de las tareas descritas en este libro. Debemos, no obstante, comprender bien cómo está configurada la cuenta y por qué funciona tan bien.

Bajo muchas distribuciones de Linux, incluida Raspbian, se emplea sudo siempre que se hace necesario realizar una labor con privilegios de administrador. Normalmente, la herramienta nos pide la contraseña del administrador y seguidamente nos permite operar con esos privilegios durante un cierto periodo de tiempo. La cuenta de usuario pi de Raspbian se ha configurado de manera que no necesita que escribamos la contraseña para los privilegios de administrador.

La sección siguiente describe la gestión de cuentas de usuario, pero si creamos una nueva cuenta de usuario y deseamos que pueda usar la herramienta sudo, su nombre se debe añadir al archivo sudoers file, /etc/sudoers, utilizando la herramienta visudo. Para ello, inicie sesión como root y escriba visudo, o bien escriba directamente sudo visudo como pi. Las últimas líneas del archivo /etc/sudoers proporcionan la configuración de la cuenta de usuario pi, lo que explica por qué no hace falta contraseña para que este usuario ejecute la herramienta sudo:

#User privilege specification

Root ALL=(ALL:ALL) ALL

#username hostnames=(users permitted to run commands as) permitted commands

pi ALL=(ALL) NOPASSWD: ALL

En esta configuración, el usuario pi recibe privilegios sobre todos (el primer ALL) los nombres de host para ejecutar comandos como cualquier usuario (el segundo ALL), así como para ejecutar todos los comandos del sistema (el tercer ALL) sin tener que escribir contraseña alguna. La herramienta (sudo) funciona bien, pero puede complicar la redirección de la salida de un comando, lo que veremos claramente más adelante en este capítulo.

Existe otro comando en Linux que nos permite ejecutar un intérprete de comandos con un usuario sustituto: su. Escribir su - (lo mismo que su - root) abre un nuevo intérprete de comandos con permisos de acceso de superusuario completos. Asimismo, se puede utilizar como sigue (una vez hayamos habilitado el inicio de sesión de root):

pi@erpi ~ $ su -

Password: mySuperSecretPassword

root@erpi:~# whoami

root

root@erpi:~# exit

logout

pi@erpi ~ $ whoami

pi

El símbolo del sistema, #, indica que hemos iniciado sesión con la cuenta de superusuario. Para volver a deshabilitar el acceso como root en el RPi, podemos escribir sudo passwd -l root.

Administración del sistema

El sistema de archivos de Linux consiste en una jerarquía de directorios que sirven para organizar los archivos en un sistema Linux. Esta sección examina la propiedad de los archivos, el uso de los enlaces simbólicos y el concepto de permisos de acceso del sistema.

El sistema de archivos de Linux

Linux utiliza estructuras de datos, llamadas "inodos" (inodes, nodos-i o nodos índice) para representar los objetos del sistema de archivos, como archivos y directorios. Cuando se crea un sistema de archivos ampliado (ext) de Linux, como ext3 o ext4, en un disco físico, se configura simultáneamente una tabla de inodos (inode table). Esta tabla comprende los vínculos a la estructura de datos inodo para cada archivo y directorio en un disco físico. La estructura de datos inodo para cada archivo y directorio almacena información como permisos, punteros a sectores físicos de almacenamiento, marcas de tiempo (time stamps) o número de enlaces (link counts). Podemos ver un ejemplo de ello realizando un listado ls -ail del directorio raíz, donde -i haga que ls muestre los índices inodo. Veremos lo siguiente para el directorio /tmp :

pi@erpi ~ $ cd /

pi@erpi / $ ls -ail | grep tmp

269 drwxrwxrwt 7 root root 4096 Jun 18 01:17 tmp

Por lo tanto, 269 es el índice inodo de /tmp. Si pasamos al directorio /tmp usando cd, creamos un archivo temporal (a.txt ) y ejecutamos ls -ail, veremos que el directorio actual (.) tiene exactamente el mismo índice inodo:

pi@erpi / $ cd tmp

pi@erpi /tmp $ touch a.txt

pi@erpi /tmp $ ls -ail

269 drwxrwxrwt 7 root root 4096 Jun 18 01:41 .

2 drwxr-xr-x 22 root root 4096 Jun 16 01:57 ..

4338 -rw-r--r-- 1 pi pi 0 Jun 18 01:41 a.txt

También podemos ver que el directorio raíz (..) tiene un índice inodo de 2, y que un archivo de texto (a.txt) tiene un índice inodo de 4338. Por lo tanto, no podemos cambiar de directorio (con cd) directamente a un índice inodo, porque el índice inodo podría no referirse a un directorio.

La figura 3-3 muestra el listado de un directorio de Linux, con los permisos que nos permiten trabajar con los archivos en Linux. La primera letra indica el tipo de archivo, por ejemplo: un directorio (d), un enlace (l) o un archivo estándar (-). También podemos encontrar tipos de archivos más raros: (c) carácter especial, (b) bloque especial, (p) fifo y (s) socket. Los directorios y los archivos estándar no necesitan más explicación, pero los enlaces sí, como vemos aquí:


Figura 3-3: Listado de un directorio de Linux con los permisos de cada archivo.

Enlaces a archivos y directorios

Hay dos tipos de enlaces en Linux: los enlaces simbólicos (soft links o symbolic links) y los enlaces duros (hard links). Un enlace simbólico es un archivo que hace referencia a la ubicación de otro archivo o directorio. Por contra, los enlaces duros se vinculan directamente con el índice inodo, pero no se pueden vincular con un directorio. Podemos crear un enlace usando ln /path/to/file.txt linkname. Se crea un enlace simbólico añadiendo -s a la llamada. Para ilustrar esto, el ejemplo siguiente creará un enlace simbólico y un enlace duro al archivo /tmp/test.txt:

pi@erpi ~ $ cd /tmp

pi@erpi /tmp $ touch test.txt

pi@erpi /tmp $ ln -s /tmp/test.txt softlink

pi@erpi /tmp $ ln /tmp/test.txt hardlink

pi@erpi /tmp $ ls -al

total 8

drwxrwxrwt 2 root root 4096 Jun 18 01:55 .

drwxr-xr-x 22 root root 4096 Jun 16 01:57 ..

-rw-r--r-- 2 pi pi 0 Jun 18 01:55 hardlink

lrwxrwxrwx 1 pi pi 13 Jun 18 01:55 softlink -> /tmp/test.txt

-rw-r--r-- 2 pi pi 0 Jun 18 01:55 test.txt

Puede observar un número 2 delante del archivo test.txt (después de los permisos del archivo). Este es el número de enlaces duros asociados al archivo. Es una cuenta que se incrementó en 1 cuando se creó el enlace duro, llamado hardlink. Si tuviéramos que eliminar el enlace duro, por ejemplo mediante rm hardlink, esta cuenta volvería al valor 1. Para ilustrar la diferencia entre enlaces simbólicos y enlaces duros, añadimos un fragmento de texto al archivo test.txt:

pi@erpi /tmp $ echo "testing links on the RPi" >> test.txt

pi@erpi /tmp $ more hardlink

testing links on the RPi

pi@erpi /tmp $ more softlink

testing links on the RPi

pi@erpi /tmp $ mkdir subdirectory

pi@erpi /tmp $ mv test.txt subdirectory/

pi@erpi /tmp $ more hardlink

testing links on the RPi

pi@erpi /tmp $ more softlink

softlink: No such file or directory

Podemos observar que cuando el archivo test.txt se mueve al subdirectorio, se rompe el enlace simbólico, pero el enlace duro sigue funcionando perfectamente. Así pues, comprobamos que los enlaces simbólicos no se actualizan cuando se mueve el archivo enlazado, mientras que los enlaces duros siempre hacen referencia al origen, aunque se haya movido o eliminado. Para ilustrar el último punto, podemos eliminar el archivo test.txt escribiendo lo siguiente:

pi@erpi /tmp $ rm subdirectory/test.txt

pi@erpi /tmp $ more hardlink

testing links on the RPi

Mas el archivo todavía existe, y no se borrará hasta que eliminemos el enlace duro llamado hardlink, con lo que la cuenta bajará hasta cero. Así pues, si un archivo tiene una cuenta de enlaces duros igual a cero, y no lo utiliza ningún proceso, será borrado. En efecto, el propio nombre, test.txt, no es más que un enlace duro. Observe que no se pueden establecer enlaces duros a través de distintos sistemas de archivos, puesto que cada sistema posee su propia tabla de índices inodo que empieza en 1. Por lo tanto, el inodo 269, que es el índice inodo del directorio /tmp, seguramente describa una cosa completamente diferente en otro sistema de archivos. Escriba el comando man ln para acceder a una guía especialmente útil sobre los enlaces a archivos.

NOTA Puede escribir history para obtener una lista de todos los comandos escritos anteriormente. Asimismo, puede pulsar Control+R para acceder a una búsqueda interactiva del historial de comandos y localizar uno que haya usado recientemente. Pulsar Intro activa el comando, mientras que pulsar Tab lo sitúa en nuestra línea de comandos para que podamos modificarlo.

Usuarios y grupos

Linux es un sistema operativo multiusuario que utiliza las siguientes tres clases diferenciadas para gestionar los permisos de acceso:

❏Usuario (user): podemos crear diferentes cuentas de usuario en nuestro RPi. Esto resulta útil si deseamos limitar el acceso a determinados procesos y áreas del sistema de archivos. La cuenta de usuario root es el superusuario del RPi y tiene acceso a todos y cada uno de los archivos. Por tanto, no sería seguro ejecutar un servidor web público desde esta cuenta, ni tampoco desde pi, si el servidor soporta scripts locales.

❏Grupo (group): las cuentas de usuario se pueden marcar (flag) para indicar que pertenecen a uno o varios grupos. Grupos que pueden contar con diferentes niveles de acceso a los distintos recursos del sistema, por ejemplo dispositivos UART o buses I2C.

❏Otros (others): todos los usuarios del RPi aparte del propietario del archivo, o de un miembro de un grupo listado en los permisos.

Podemos crear usuarios desde una ventana de terminal de Linux. Podemos ver la lista completa de grupos escribiendo more /etc/group. El ejemplo siguiente demuestra cómo crear una nueva cuenta de usuario en el RPi y modificar sus propiedades según nos convenga.

Ejemplo: crear una nueva cuenta de usuario en el RPI

Este ejemplo muestra cómo crear una cuenta de usuario y, luego, cambiar sus propiedades:

1. Creamos una nueva cuenta de usuario llamada molloyd en el RPi

2. Añadimos la cuenta a un nuevo grupo diseñado por nosotros mismos.

3. Añadimos la cuenta de usuario a los grupos de interfaz estándar del RPi.

4. Cambiamos la contraseña de la nueva cuenta de usuario.

5. Comprobamos que la cuenta funcione correctamente.

Paso 1: Crear el usuario molloyd del siguiente modo:

pi@erpi ~ $ sudo adduser molloyd

Adding user 'molloyd' ...

Adding new group 'molloyd' (1002) ...

Adding new user 'molloyd' (1001) with group 'molloyd' ...

Creating home directory '/home/molloyd' ...

Copying files from '/etc/skel' ...

Enter new UNIX password: ThePassword

Retype new UNIX password: ThePassword

passwd: password updated successfully

Changing the user information for molloyd

Enter the new value, or press ENTER for the default

Full Name []: Derek Molloy

Room Number []: Home

Work Phone []: XXXX

Home Phone []: XXXX

Other []: XXXX

Is the information correct? [Y/n] Y

Paso 2: Añadir el usuario a un nuevo grupo diseñado por nosotros mismos.

pi@erpi ~ $ sudo groupadd newgroup

pi@erpi ~ $ sudo adduser molloyd newgroup

Adding user 'molloyd' to group 'newgroup' ...

Adding user molloyd to group newgroup

Done.

pi@erpi ~ $ groups molloyd

molloyd : molloyd newgroup

Paso 3: Añadir el usuario a los grupos de usuarios estándar y de interfaz del RPi:

pi@erpi ~ $ sudo usermod -a -G pi,adm,dialout,cdrom,sudo,audio,video,

plugdev,users,games,netdev,gpio,i2c,spi,input molloyd

pi@erpi ~ $ groups molloyd

molloyd : molloyd adm dialout cdrom sudo audio video plugdev games users pi

netdev input spi i2c gpio newgroup

Paso 4: Cambiar la contraseña si es preciso:

pi@erpi ~ $ sudo passwd molloyd

Enter new UNIX password: ABetterPassword

Retype new UNIX password: ABetterPassword

passwd: password updated successfully

pi@erpi ~ $ sudo chage -d 0 molloyd


Para practicar los temas presentados hasta ahora en este capítulo, los siguientes ejemplos utilizan la cuenta de usuario molloyd. El primer ejemplo muestra el comando chown (change ownership) para cambiar la propiedad de un archivo, y para cambiar la propiedad de grupo del archivo usamos chgrp (change group).

Para poder invocar correctamente la herramienta sudo en el ejemplo, el usuario molloyd debe figurar en el archivo sudoers, lo que se hace desde el usuario pi ejecutando el comando visudo. Se puede modificar el archivo para que incluya una entrada molloyd del siguiente modo:

pi@erpi ~ $ sudo visudo

pi@erpi ~ $ sudo tail -n 2 /etc/sudoers

pi ALL=(ALL) NOPASSWD: ALL

molloyd ALL=(ALL) ALL

La cuenta de usuario molloyd puede ejecutar a partir de ahora el comando sudo, pero deberá escribir su contraseña para ello.


Permisos del sistema de archivos

Los permisos del sistema de archivos (file system permissions) indican qué niveles de acceso a un archivo o directorio tiene cada una de las clases de permisos. El comando chmod (change mode, cambiar modo) permite a un usuario cambiar los permisos de acceso a los objetos del sistema de archivos. Es posible especificar los permisos de una forma relativa. Por ejemplo, chmod a+w test.txt proporciona a todos los usuarios acceso de escritura al archivo test.txt, pero no cambia ningún otro permiso.

Por otra parte, también es posible especificar los permisos de una forma absoluta. Por ejemplo, chmod a=r test.txt establece que todos los usuarios tendrán únicamente acceso de lectura al archivo test.txt. El ejemplo siguiente muestra cómo modificar los permisos del sistema de archivos para un archivo utilizando el comando chmod.


La tabla 3-3 muestra la estructura de comandos para chown y chgrp. Asimismo, lista algunos comandos de ejemplo para trabajar con usuarios, grupos y permisos.

Tabla 3-3: Comandos para trabajar con usuarios, grupos y permisos.


ComandoDescripción
chown molloyd a.txtchown molloyd:users a.txtchown -Rh molloyd /tmp/testCambia el propietario del archivo.Cambia propietario y grupo al mismo tiempo.Cambia la propiedad del directorio /tmp/test de forma recursiva. -h afecta a los enlaces simbólicos en lugar de a los archivos referenciados.
chgrp users a.txtchgrp -Rh users /tmp/testCambia la propiedad de grupo del archivo.Cambia recursivamente con la misma -h que chown.
chmod 600 a.txtchmod ugo+rw a.txtchmod a-w a.txtCambia permisos, como en la figura 3-3, para que el usuario tenga permisos de lectura/escritura al archivo. Tanto el grupo como otros no tienen acceso.Otorga a los usuarios, grupo y otros permiso de lectura/escritura a a.txt.Elimina el acceso de escritura para todos los usuarios de a, lo que quiere decir todos (usuarios, grupos y otros).
chmod ugo=rw a.txtEstablece los permisos de lectura/escritura para todos.
umaskumask -SLista la configuración de permisos por defecto. Con -S se muestra umask de una forma más legible.
umask 022umask u=rwx,g=rx,o=rxModifica los permisos predeterminados en todos los archivos y directorios de nueva creación. Los dos comandos umask mostrados aquí son equivalentes. Si establecemos este valor de máscara y creamos un archivo o directorio, será drwxr-xr-x para el directorio, y -rw-r--r-- para el archivo. Es posible establecer una umask específica de usuario en el archivo .login de la cuenta.
chmod u+s myexechmod g+s myexeEstablece un bit especial, llamado setuid bit (set user ID on execute, establecer ID de usuario al ejecutar) y setgid bit (set group ID on execute, establecer ID de grupo al ejecutar), que permite que un programa se ejecute como si lo hiciera otro usuario, pero con los permisos del propietario o grupo del archivo. Por ejemplo, esto permitiría que un programa concreto se ejecutase como si fuera el superusuario quien lo iniciase. Si el archivo no es ejecutable, se muestra una S mayúscula, en lugar de una s minúscula.
chmod 6750 myexechmod u=rwxs,g=rxs,o= myexeEstablece el valor del bit setuid de forma absoluta. Ambos otorgarán a myexe los permisos rwsr-s---, con ambos bits, setuid y setgid, configurados (observe el espacio antes de myexe).Por razones de seguridad no se puede aplicar el bit setuid a un script del intérprete de comandos.
stat /tmp/test.txtOfrece información útil sobre el estado del sistema de archivos para un archivo o directorio, por ejemplo el dispositivo físico en que se encuentra, información de su inodo, el último acceso o las últimas modificaciones o cambios.

Veamos un ejemplo de la última entrada de la tabla 3-3, el comando stat:

molloyd@erpi:/tmp$ stat test.txt

File: 'test.txt'

Size: 0 Blocks: 0 IO Block: 4096 regular empty file

Device: b302h/45826d Inode: 6723 Links: 1

Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)

Access: 2015-06-19 00:06:28.551326384 +0000

Modify: 2015-06-19 00:06:28.551326384 +0000

Change: 2015-06-19 0:07:13.151016841 +0000

Birth: -

Observe que cada archivo de Linux conserva las marcas de tiempo de acceso, modificación y cambio. Podemos cambiar las marcas temporales de acceso y modificación artificialmente usando touch -a text.txt y touch -m test.txt, respectivamente (el tiempo de cambio se ve afectado en ambos casos). El tiempo de cambio se ve afectado también por las operaciones del sistema como chmod; el tiempo de modificación se ve afectado por una operación de escritura en el archivo, y el tiempo de acceso, en teoría, se ve afectado por una operación de lectura. Sin embargo, este comportamiento operacional significa que la lectura de un archivo ocasiona una escritura. Esta característica de Linux ocasiona un desgaste significativo en la tarjeta SD del RPi y un rendimiento deficiente en las operaciones de E/S. Por tanto, la funcionalidad de marca de tiempo de acceso a los archivos suele estar deshabilitada por defecto en la SD de arranque del RPi, mediante la opción de montaje (mount option) noatime en el archivo de configuración /etc/fstab que veremos en la sección siguiente. Observe que hay una opción similar, nodiratime, específica para directorios. No obstante, la opción noatime impide la actualización de la marca de tiempo para los accesos tanto a archivos como a directorios.

Para finalizar el análisis de la figura 3-3, decir que el ejemplo de la figura tiene 22 enlaces duros al archivo. Para un directorio, esto representa el número de subdirectorios, su directorio padre (..) y a sí mismo (.). El propietario de la entrada es el root y está en el grupo del root. La entrada siguiente, 4096, es el tamaño exigido para guardar los metadatos sobre los archivos contenidos en ese directorio (el tamaño mínimo es un sector, generalmente 4.096 bytes).

Para finalizar: si pedimos un listado de directorios ls -ld en el directorio root, veremos un bit t en los permisos del directorio /tmp. Dicho bit se conoce como sticky bit (literalmente, bit pegajoso), e indica que solo el permiso de escritura no basta para borrar archivos. Así pues, en el directorio /tmp cualquier usuario puede crear archivos, pero nadie puede borrar los archivos de otro usuario.

molloyd@erpi:/tmp$ cd /

molloyd@erpi:/$ ls -dhl tmp

drwxrwxrwt 7 root root 4.0K Jun 19 00:18 tmp

El comando ls -dhl lista los nombres de directorio, el parámetro d, y no su contenido, en formato legible para las personas (al menos para algunas), el parámetro h (de human readable) y en su versión larga, parámetro d.

El directorio raíz (root) de Linux

Explorar el sistema de archivos de Linux resulta aterrador para los principiantes. Si vamos al nivel superior con el comando cd / en el RPi y escribimos ls, veremos un listado del nivel más alto de la estructura de directorios del siguiente modo:

molloyd@erpi:/$ ls

bin boot.bak etc lib media opt root sbin sys usr

boot dev home lost+found mnt proc run srv tmp var

¿Qué significa todo esto? Cada uno de estos directorios tiene su papel y, si los entendemos bien, nos permitirán saber por dónde empezar a buscar archivos de configuración o los archivos binarios que necesitemos. En la tabla 3-4 tenemos una descripción breve de cada subdirectorio de nivel más alto de Linux.

Tabla 3-4: Estructura de directorios de nivel superior en Linux.


DirectorioDescripción
binContiene los binarios ejecutables utilizados por todos los usuarios y está en la variable de entorno PATH de forma predeterminada. Otro directorio, /usr/bin, contiene ejecutables que no resultan básicos para el arranque o reparación del sistema.
bootContiene los archivos para arrancar el RPi.
boot.bakContiene una copia de /boot generada tras una actualización del sistema.
devContiene los nodos de dispositivo, enlazados a sus controladores.
etcArchivos de configuración para el sistema local.
home Contiene los directorios raíz (home) de las cuentas de usuario (/home/pi es el directorio raíz de la cuenta de usuario pi).
lib Contiene las librerías estándar del sistema.
lost+foundAquí figuran los archivos sin vínculos que aparezcan tras ejecutar fsck (file system check and repair, comprobación y reparación del sistema de archivos). El comando mklost+found vuelve a crear el directorio lost+found si se ha eliminado.
mediaUtilizado para montar dispositivos removibles, como tarjetas micro-SD.
mntSu uso típico es para montar sistemas de archivos temporales.
optUn buen lugar para instalar software opcional de terceros.
procUn archivo virtual que representa los procesos en ejecución en el RPi. Por ejemplo, si pasamos al directorio cd /proc y escribimos cat iomem, veremos algunos mapeos de asignaciones de memoria.
rootEl directorio raíz de la cuenta root (superusuario) en las distribuciones Raspbian y Debian Linux. En muchas otras distribuciones, es el directorio /home/root.
runProporciona información acerca de la ejecución del sistema desde la última vez que arrancó.
sbinContiene ejecutables para la gestión del root.
srvAlmacena datos relacionados con ftp, servidores web, rsync, etc.
sysContiene un sistema de archivos virtual que describe el sistema.
tmpContiene archivos temporales.
usrContiene programas para todos los usuarios, junto con muchos subdirectorios como: /usr/include (archivos de cabecera C/C++), /usr/lib (librerías C/C++), /usr/src (código fuente del núcleo de Linux), /usr/bin (ejecutables del usuario), /usr/local (similar a /usr, pero para usuarios locales) y /usr/share (archivos compartidos entre los usuarios).
varContiene archivos variables como los log del sistema.

Comandos para sistemas de archivos

Además de los comandos para trabajar con archivos y directorios en los sistemas de archivos, existen comandos para trabajar con el propio sistema de archivos. Los primeros comandos que deberíamos examinar son: df (disk free) y mount. El comando df ofrece un resumen de los sistemas de archivos en el RPi. El parámetro -T lista los tipos de sistemas de archivos:

pi@erpi / $ df -T

Filesystem Type 1K-blocks Used Available Use% Mounted on

/dev/root ext4 15186900 3353712 11165852 24% /

devtmpfs devtmpfs 470400 0 470400 0% /dev

tmpfs tmpfs 474688 0 474688 0% /dev/shm

tmpfs tmpfs 474688 0 474688 0% /sys/fs/cgroup

/dev/mmcblk0p1 vfat 57288 19824 37464 35% /boot

...

El comando df resulta útil para determinar si nos estamos quedando sin espacio en disco. Observamos que el sistema de archivos del root, /dev/root, está ocupado al 24% en este caso, con 11,2 GB de un tarjeta SD de 16 disponibles para instalar nuevo software. Asimismo, se listan las entradas de varios sistemas de archivos temporales (tmpfs) que en realidad se refieren a sistemas de archivos virtuales y que están mapeados en la DDR RAM del RPi. Las entradas /sys/fs/* se discuten con detalle en el capítulo 8. Además, la entrada /dev/mmcblk0p1 cuenta con un sistema de archivos vfat (virtual file allocation table, tabla de asignación de archivos virtuales), que se presentó con Windows 95, en una partición de 57 MB en la tarjeta SD. Esta partición vfat es un requisito de los gestores de arranque y para las actualizaciones de firmware.

NOTA Si nos estamos quedando sin espacio en el sistema de archivos root de la tarjeta SD del RPi, comprobaremos los log del sistema: /var/log. Unos archivos de log (o simplemente "logs") excesivamente grandes suelen ser sinónimo de problemas en el sistema, así que debemos revisarlos. Cuando hayamos resuelto cualquier problema, nos libraremos de ellos escribiendo: cat /dev/null > /var/log/messages con privilegios de root (véase también kern.log, dpkg.log y syslog). Por ejemplo, para vaciar el log dpkg.log desde la cuenta pi, sin eliminar el archivo ni reiniciar sus permisos, escribimos:

pi@erpi /var/log $ sudo sh -c "cat /dev/null > dpkg.log"

La llamada sh -c ejecuta todo el comando incluido en las comillas con permisos de superusuario. Esto es obligatorio porque, en el comando sudo cat /dev/null > dpkg.log, sudo por sí solo no efectúa la redirección de la salida >, sino que esta se intenta llevar a cabo como el usuario pi y, por tanto, falla porque sus permisos son insuficientes. Este es el problema con la redirección que presenta sudo, al que nos referimos anteriormente en el capítulo.

El comando lsblk (list block devices, listar dispositivos de bloques) presenta una lista concisa, estructurada en forma de árbol, con dispositivos tales como tarjetas SD, lápices de memoria USB y lectores de tarjetas (si los hubiera) conectados al RPi. Como se muestra en la salida siguiente, podemos ver que mmcblk0 (la tarjeta SD de arranque) se divide en dos particiones: p1, fijada a /boot, y p2, fijada a la raíz del sistema de archivos /. En este ejemplo, hay un lector USB para tarjetas micro-SD con una tarjeta de 32 GB (véase la figura 1-8(b)) conectado a uno de los puertos USB. Se muestra como el dispositivo de bloques sda con una sola partición, sda1:

pi@erpi ~ $ lsblk

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT

sda 8:0 1 29.8G 0 disk

└─sda1 8:1 1 29.8G 0 part

mmcblk0 179:0 0 14.9G 0 disk

├─mmcblk0p1 179:1 0 56M 0 part /boot

└─mmcblk0p2 179:2 0 14.8G 0 part /

Claramente, los puertos USB sirven para conectar almacenamiento adicional, lo que resulta útil si capturamos datos de vídeo y la capacidad de la tarjeta

SD del sistema no es suficiente. Podemos probar el rendimiento de las tarjetas SD para asegurarnos de que se ajustan a las necesidades de nuestras aplicaciones mediante el ejemplo de la página siguiente.

Utilizar el comando mount sin argumentos nos facilita más información del sistema de archivos en el RPi.

pi@erpi ~ $ mount

/dev/mmcblk0p2 on / type ext4 (rw,noatime,data=ordered)

sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)

proc on /proc type proc (rw,relatime) ...

Como ya vimos, el sistema de archivos se organiza como un árbol único fijado al directorio raíz: /. Escribir cd / nos lleva directamente a la raíz del sistema. El comando mount se puede emplear para montar el sistema de archivos propio de un dispositivo de almacenamiento en este árbol. Los sistemas de archivos en dispositivos físicos separados se pueden montar en puntos definidos (named points) en ubicaciones del árbol. La tabla 3-5 describe algunos de los comandos del sistema de archivos que podemos utilizar para gestionarlo. Después se exponen dos ejemplos que demuestran cómo utilizar el comando mount para realizar importantes tareas de administración del sistema en el RPi.


Tabla 3-5: Comandos útiles para los sistemas de archivos.


ComandoDescripción
du -h /optdu -hs /opt/*du -hc *.jpgUtilización de disco: muestra el espacio ocupado por un árbol de directorios. Opciones: (-h) formato legible para las personas, (-s) resumen, (-c) total. El último comando encuentra el tamaño total del los archivos JPG en el directorio actual.
df -hMuestra el espacio del disco del sistema en formato legible (-h).
lsblkLista los dispositivos de bloques.
dd if=test.img of=/dev/sdXdd if=/dev/sdX of=test.imgdd convierte y copia un archivo, donde if es el archivo de entrada (input file) y of es el de salida (output file). Use este comando en Linux para escribir una imagen en una tarjeta SD. En Linux de escritorio, se suele utilizar así:sudo dd if=./RPi*.img of=/dev/sdXdonde /dev/sdX es el dispositivo de lectura/escritura de la tarjeta SD.
cat /proc/partitionsLista todas las particiones registradas.
mkfs /dev/sdXCrea un sistema de archivos Linux. También mkfs.ext4, mkfs.vfat. Se debe usar con precaución porque destruye todos los datos del dispositivo. ¡Téngalo presente!
fdisk -lObserve que fdisk se puede usar para gestionar discos, crear y eliminar particiones, etc. El comando fdisk -l muestra todas las particiones existentes.
badblocks /dev/mmcblkXLocaliza sectores erróneos en la tarjeta SD. Las tarjetas SD incorporan circuitos para nivelación de desgaste. Si se presentan errores, es hora de adquirir una tarjeta nueva. Es mejor no grabarlos con fsck. Ejecutamos este comando con privilegios de root, siempre teniendo en cuenta que tarda un tiempo en completarse.
mount /media/storeMonta una partición si aparece en /etc/fstab.
umount /media/storeDesmonta una partición. Se nos informa antes si hay algún archivo abierto en esta partición.
sudo apt install treetree ~/exploringrpiInstalamos el comando tree y lo utilizamos para mostrar el repositorio de código de este libro con estructura de árbol de directorios.



Los comandos find y whereis

El comando find resulta útil para buscar un archivo concreto en una estructura de directorios. Tiene un alcance enormemente amplio. Escriba man find para obtener un listado completo de las opciones. Por ejemplo, utilice la llamada siguiente para encontrar el archivo de cabecera C++ iostream en el sistema de archivos RPi; usar sudo evita problemas con los permisos de acceso:

pi@erpi / $ sudo find . -name iostream*

./usr/include/c++/4.9/iostream

./usr/include/c++/4.6/iostream

Usar -iname en lugar de name no discrimina mayúsculas y minúsculas en la búsqueda.

En el ejemplo siguiente se buscan los archivos en el directorio /home que hayan sido modificados en las últimas 24 y antes de las últimas 24 horas, respectivamente:

pi@erpi ~ $ echo "RPiTest File" >> new.txt

pi@erpi ~ $ sudo find /home -mtime -1

/home/pi

/home/pi/.bash_history

/home/pi/new.txt

pi@erpi ~ $ sudo find /home -mtime +1

/home/pi/.profile

/home/pi/.bashrc ...

Otra posibilidad es utilizar las opciones momento de acceso (-atime), tamaño (-size), propietario (-user), grupo (-group) y permiso (-perm).

NOTA Use el comando grep para buscar en un directorio de forma recursiva archivos que contengan una cadena de texto concreta, donde -r especifica que la búsqueda será recursiva, -n muestra el número de línea de la ubicación y -e viene seguido de un patrón de búsqueda:

pi@erpi ~ $ sudo grep -rn /home -e "RPiTest"

/home/pi/new.txt:1:RPiTest File

Para consultar más opciones, utilice man grep.

El comando whereis es distinto en el sentido de que puede buscar binarios ejecutables, código fuente y páginas de manual (man pages) de un programa concreto:

pi@erpi ~ $ whereis find

find: /usr/bin/find /usr/share/man/man1/find.1.gz

En este caso, los comandos binarios están en /usr/bin y la página de manual está en /usr/share/man/man1 (almacenada en formato gzip para ahorrar espacio).

Los comandos more y less

El comando more (más, en inglés) ya se ha utilizado varias veces, y seguramente el lector habrá ya deducido para qué sirve. Nos permite ver un archivo grande, o una corriente de salida (output stream) muy larga, página a página. Así pues, para ver un archivo largo podemos escribir more filename. Por ejemplo, el archivo de log /var/log/dmesg contiene todos los mensajes de salida del núcleo. Podemos revisar el archivo página a página con el comando more /var/log/dmesg. Sin embargo, si queremos que la información en la pantalla sea concisa, podemos utilizar el valor -5 para que solo se muestren cinco líneas en cada página.

pi@erpi ~ $ more -5 /var/log/dmesg

[ 0.000000] Booting Linux on physical CPU 0xf00

[ 0.000000] Initializing cgroup subsys cpu

[ 0.000000] Initializing cgroup subsys cpuacct

[ 0.000000] Linux version 3.18.11-v7+ (dc4@dc4-XPS13-9333)(gcc version 4.8.3

20140303 (prerelease)(crosstool-NG linaro-1.13.1+bzr2650-Linaro GCC 2014.03)

--More--(2%)

Con la barra espaciadora pasamos las páginas y pulsando Q (Quit) salimos del archivo. Existe un comando, less (menos, en inglés), que resulta aún más potente:

pi@erpi ~ $ less /var/log/dmesg

El comando less nos proporciona una vista completamente interactiva que podemos manejar desde el teclado. Tiene, no obstante, demasiadas opciones como para listarlas aquí. Por ejemplo, podemos utilizar las teclas de cursor para movernos arriba y abajo, pasar de página con la barra espaciadora, buscar una cadena de texto escribiendo / (por ejemplo: /usb, para encontrar mensajes relacionados con dispositivos USB) y, luego, pulsar la tecla N para ir a la siguiente ocurrencia de la cadena buscada, o bien Mayús+N para ir a la ocurrencia anterior.

La fiabilidad de los sistemas de archivos en las tarjetas SD

Uno de los puntos críticos del RPi es su tarjeta SD, o como se la conoce más genéricamente, su MMC (MultiMedia Card, tarjeta multimedia). La memoria flash NAND, como la de las MMC, ofrece gran espacio de almacenamiento con bajo coste, pero presenta una cierta tendencia al desgaste que puede resultar en errores del sistema de archivos.

La amplia capacidad de las MMC se debe en gran medida al desarrollo de las memorias MLC (Multi-Level Cell) o de celda multinivel. A diferencia de la memoria SLC (Single-Level Cell) o de celda mononivel, las MLC son capaces de guardar más de 1 bit en una sola celda de memoria. Los altos niveles de voltaje necesarios para borrar una celda perjudican a las celdas adyacentes, así que la memoria flash NAND se borra en bloques de 1 a 4 KB. Con el paso del tiempo, el proceso de escritura en la memoria flash NAND hace que los electrones queden atrapados y que se reduzca la diferencia de conductividad entre los estados "guardado" y "borrado" (disponible) del sustrato semiconductor de la memoria. (El lector interesado podrá encontrar un análisis (en inglés) más profundo de las diferencias entre SLC y MLC para aplicaciones de elevada fiabilidad en la dirección web tiny.cc/erpi305.) Las MLC utilizan niveles de carga diferentes y voltajes superiores para almacenar más estados en cada celda individual. Los productos comerciales MLC suelen ofrecer entre 4 y 16 estados por celda. Como las SLC solo guardan un estado, gozan de ventaja en cuanto a fiabilidad, con unos 60.000 a 100.000 ciclos de borrado/escritura frente a los 10.000 que suelen ofrecer las memorias flash MLC. Las tarjetas MMC son perfectas para un uso cotidiano en aplicaciones como fotografía digital, donde 10.000 ciclos de escritura/borrado deberían garantizar más de 25 años de vida útil (con un ciclo de escritura/borrado de la tarjeta completa cada día, lo que tampoco suele ocurrir).

Sin embargo, los dispositivos Linux empotrados realizan constantemente tareas de escritura en sus MMC, como el registro de eventos del sistema en /var/log. Conque el RPi escriba en un archivo de log unas 20 veces diarias, la vida útil de una tarjeta SD sería de unos ocho meses. Tales cifras son conservadoras, no obstante, y gracias a la tecnología ya mencionada con algoritmos de nivelación de desgaste (wear leveling algorithms) la vida útil puede ser mucho más larga. Las MMC usan los algoritmos de nivelación de desgaste durante la escritura de datos para asegurar que las reescrituras se distribuyen uniformemente en todo el espacio de almacenamiento. De este modo se logran evitar los fallos de sistema de Linux ocasionados por una excesiva concentración de modificaciones, tales como cambios en los mismos archivos de log.

En el caso de nuestro RPi, debemos asegurarnos de adquirir una tarjeta SD de la mejor calidad posible, y mejor si es de una marca reconocida. Además, debe ser de gran capacidad. La razón es sencilla: cuanto más espacio quede sin usar en la SD, mejor funcionarán los algoritmos de nivelación de desgaste, siquiera por motivos físicos. Como nota al margen, decir que otras placas con Linux empotrado, como la BeagleBone Black, utilizan almacenamiento eMMC (embedded MMC, MMC empotrado); básicamente, una MMC en un chip soldado en la placa. Estas memorias eMMC suelen ser también MLC y ofrecen una fiabilidad análoga a la de las tarjetas SD. Sin embargo, una de sus ventajas es que el fabricante posee el control sobre la calidad y las especificaciones de la eMMC que desea incluir en su placa. Por último, la mayoría de los discos duros de estado sólido SSD (Solid State Disk) también incorporan tecnología MLC, mientras que los más caros y profesionales emplean la (más fiable) SLC.

Para aplicaciones en el RPi que requieran mayor fiabilidad, se puede utilizar un sistema de archivos basado en RAM (tmpfs) en los directorios /tmp y /var/cache, y para los archivos de log, especialmente /var/log/apt. Lograremos esto editando el archivo /etc/fstab para que los directorios necesarios se monten en memoria. Por ejemplo, si tenemos procesos que requieran compartir datos de archivos entre ellos para intercambiar datos, podríamos usar el directorio /tmp como sistema de archivos RAM (tmpfs) editando el archivo /etc/fstab del siguiente modo:

pi@erpi /etc $ sudo nano fstab

pi@erpi /etc $ more fstab

proc /proc proc defaults 0 0

/dev/mmcblk0p1 /boot vfat defaults 0 2

/dev/mmcblk0p2 / ext4 defaults,noatime 0 1

tempfs /tmp tmpfs size=100M 0 0

Seguidamente, aplicaríamos estos ajustes utilizando el comando mount.

pi@erpi /etc $ sudo mount -a

Y, luego, comprobamos que dichos ajustes se han añadido a la configuración:

pi@erpi /etc $ mount

...

tempfs on /tmp type tmpfs (rw,relatime,size=102400k)

El directorio raíz se monta de forma predeterminada con el atributo noatime activo, lo cual reduce drásticamente el número de accesos de escritura e incrementa el rendimiento de E/S, como ya vimos anteriormente en el capítulo. Siempre que sea posible debemos aplicar este atributo a todos los dispositivos de almacenamiento de estado sólido, como lápices USB, pero no es necesario para el almacenamiento basado en RAM.

Recuerde que cualquier dato que escribamos en un sistema de archivos temporal, tempfs, se perderá al reiniciar. Así pues, si utilizamos un tmpfs para /var/log, cualquier error del sistema que haga colgarse a la tarjeta no será visible en el reinicio. Podemos comprobarlo creando un archivo en el directorio /tmp con la configuración anterior y reiniciando acto seguido.

La asignación real de la RAM crece y mengua dependiendo del uso que el archivo haga del disco tmpfs. Así pues, podemos ser razonablemente generosos con la asignación de memoria. Por ejemplo, con los 100 MB del directorio /tmp montados en tmpfs:

pi@erpi /tmp $ cat /proc/meminfo | grep MemFree:

MemFree: 824368 kB

pi@erpi /tmp $ fallocate -l 75000000 test.txt

pi@erpi /tmp $ ls -l test.txt

-rw-r--r-- 1 pi pi 75000000 Jul 17 00:04 test.txt

pi@erpi /tmp $ cat /proc/meminfo | grep MemFree:

MemFree: 750788 kB

Ciertas distribuciones para el RPi emplean un sistema de archivos de solo lectura para mejorar la vida útil de la tarjeta SD, así como la estabilidad del propio sistema. Como ejemplo citaremos OpenELEC y el sistema de archivos comprimido SquashFS. No obstante, esto requiere mucho esfuerzo y no resulta práctico para el tipo de trabajo de prototipado que exponemos en este libro. Sin embargo, parece conveniente no perder esto de vista porque nos puede venir muy bien para el despliegue final del proyecto, donde la estabilidad del sistema resulta de extrema importancia.

Comandos de Linux

Cuando trabajamos en el terminal de Linux y escribimos comandos como date, el resultado de los mismos se envía a la "salida estándar" (standard output). Y vemos dicho resultado en nuestra ventana de terminal.

Redirección de entrada y salida (>, >> y <)

Es posible redirigir la salida a un archivo usando los operadores de redirección > y >>. El símbolo >> se usó anteriormente en este capítulo para añadir texto a archivos temporales. El operador > se puede emplear para enviar la salida a un nuevo archivo. Por ejemplo:

pi@erpi ~ $ cd /tmp

pi@erpi /tmp $ date > a.txt

pi@erpi /tmp $ more a.txt

Sat 20 Jun 12:59:43 UTC 2015

pi@erpi /tmp $ date > a.txt

pi@erpi /tmp $ more a.txt

Sat 20 Jun 12:59:57 UTC 2015

El operador >> manifiesta nuestro deseo de añadir contenido al archivo. El ejemplo siguiente ilustra el uso del operador >> con el nuevo archivo a.txt:

pi@erpi /tmp $ date >> a.txt

pi@erpi /tmp $ more a.txt

Sat 20 Jun 12:59:57 UTC 2015

Sat 20 Jun 13:00:17 UTC 2015

La salida estándar usando el símbolo < funciona de forma muy parecida. La inclusión de -e facilita el análisis de los caracteres de escape, como el de retorno (\n), que sitúa cada especie animal en una nueva línea:

pi@erpi /tmp $ echo -e "dog\ncat\nyak\ncow" > animals.txt

pi@erpi /tmp $ sort < animals.txt

cat

cow

dog

yak

Podemos combinar los operadores de redirección de entrada y de salida. Usando el archivo animals.txt podemos realizar operaciones como la siguiente:

pi@erpi /tmp $ sort < animals.txt > sorted.txt

pi@erpi /tmp $ more sorted.txt

cat

cow

dog

yak

Tuberías (| y tee)

Dicho simplemente: las tuberías (pipes) ,|, nos permiten conectar comandos de Linux. Al igual que redirigimos la salida a un archivo, podemos redirigir la salida de un comando para que sirva de entrada a otro comando. Por ejemplo, para listar el directorio raíz desde cualquier lugar del sistema y enviar (o "canalizar" como por una "tubería", pipe) la salida al comando sort, donde se colocará en orden inverso (reverse) merced al parámetro -r, escribiremos lo siguiente:

pi@erpi ~ $ ls / | sort -r

var

usr

...

bin

Podemos identificar qué instalaciones del usuario en el directorio /opt ocupan más espacio en disco: du nos facilita el tamaño de disco usado. Pasar el argumento -d1 significa que solo listaremos los tamaños 1 nivel por debajo del nivel del directorio actual, mientras que -h hace que los valores se muestren en formato legible. Podemos canalizar esta salida hacia el comando de filtro sort para realizar un ordenamiento numérico en orden inverso, es decir, colocando el más grande en el lugar más alto. De este modo, el comando es:

pi@erpi ~ $ du -d1 -h /opt | sort -nr

113M /opt

69M /opt/sonic-pi

41M /opt/vc

4.4M /opt/minecraft-pi

Otra herramienta útil, tee, nos permite al mismo tiempo redirigir una salida a un archivo y pasarlo al siguiente comando en la tubería; por ejemplo, guardar y ver. Usando el ejemplo anterior, si deseamos enviar la salida sin ordenar del comando du a un archivo, y mostrar una salida ordenada por la consola, escribiremos:

pi@erpi ~ $ du -d1 -h /opt | tee /tmp/unsorted.txt | sort -nr

113M /opt

69M /opt/sonic-pi

41M /opt/vc

4.4M /opt/minecraft-pi

pi@erpi ~ $ more /tmp/unsorted.txt

4.4M /opt/minecraft-pi

69M /opt/sonic-pi

41M /opt/vc

113M /opt

Asimismo, podemos utilizar tee para escribir la salida de varios archivos:

pi@erpi ~ $ du -d1 -h /opt | tee /tmp/1.txt /tmp/2.txt /tmp/3.txt

Comandos de filtro (de sort a xargs)

Cada uno de los comandos de filtro ofrece una función útil:

❏sort: este comando presenta varias opciones, por ejemplo: -r aplica un orden inverso, -f ignora mayúsculas y minúsculas, -d ordena siguiendo un diccionario e ignora la puntuación, -n ordenación numérica, -b ignora espacios en blanco, -i ignora los caracteres de control, -u muestra las líneas duplicadas una sola vez y -m une varias entradas en una sola salida.

❏wc (contar palabras): calcula el número de palabras, líneas o caracteres en una corriente (stream). Por ejemplo:

pi@erpi /tmp $ wc < animals.txt

4 4 16

Indica que hay 4 líneas, 4 palabras y 16 caracteres. Podemos seleccionar los valores independientemente usando -l para contar líneas, -w palabras, o -m caracteres, mientras que con -c imprimimos la cuenta de bytes (que en este caso también son 16).

❏head: muestra las primeras líneas de la salida, lo que resulta útil si tenemos un archivo o corriente de información y deseamos examinar solo las primeras líneas. De manera predeterminada, muestra las primeras diez líneas. Podemos especificar el número de líneas con la opción -n. Por ejemplo, para obtener las dos primeras líneas de salida del comando dmesg (display message, mostrar mensaje, o driver message, mensaje del controlador), que muestra el buffer de mensajes del núcleo, escribimos:

pi@erpi ~ $ dmesg | head -n2

[ 0.000000] Booting Linux on physical CPU 0xf00

[ 0.000000] Initializing cgroup subsys cpu

❏tail: funciona igual que head salvo porque muestra las últimas líneas de un archivo o corriente de datos. Usándolo en combinación con dmesg aporta unas salidas muy útiles, por ejemplo:

pi@erpi ~ $ dmesg | tail -n2

[ 8.896654] smsc95xx 1-1.1:1.0 eth0:link up,100Mbps,full-duplex...

[ 9.340019] Adding 102396k swap on /var/swap.

❏grep: analiza líneas utilizando texto y expresiones regulares. Podemos utilizar este comando para filtrar la salida con distintas opciones: -i ignora mayúsculas y minúsculas, -m 5 se detiene tras dar con cinco ocurrencias, -q realiza la búsqueda "en silencio" y la detiene y devuelve el estado 0 si encuentra alguna ocurrencia, -e para especificar algún patrón, -c muestra una cuenta de ocurrencias, -o solo muestra el texto que se corresponde con la búsqueda y -l muestra el nombre del archivo que contenga el texto buscado. Por ejemplo, el siguiente caso examina la salida dmesg hasta dar con las primeras tres ocurrencias de la cadena usb, usando el parámetro -i para ignorar mayúsculas y minúsculas:

pi@erpi ~ $ dmesg | grep -i -m3 usb

[ 1.280089] usbcore: registered new interface driver usbfs

[ 1.285762] usbcore: registered new interface driver hub

[ 1.291220] usbcore: registered new device driver usb

Las tuberías se pueden combinar. Por ejemplo, obtenemos exactamente la misma salida utilizando head y mostrando únicamente las tres primeras líneas de la salida de grep:

pi@erpi ~ $ dmesg | grep -i usb | head -n3

[ 1.280089] usbcore: registered new interface driver usbfs

[ 1.285762] usbcore: registered new interface driver hub

[ 1.291220] usbcore: registered new device driver usb

❏xargs: nos permite construir una lista de argumentos que utilizaremos para llamar a otro comando o herramienta. En el ejemplo siguiente, el archivo de texto args.txt, que contiene tres cadenas, se utiliza para crear tres nuevos archivos. La salida de cat se canaliza a xargs, donde pasa las tres cadenas como argumentos del comando touch, que crea tres nuevos archivos: a.txt, b.txt y c.txt:

pi@erpi /tmp $ echo "a.txt b.txt c.txt" > args.txt

pi@erpi /tmp $ cat args.txt | xargs touch

pi@erpi /tmp $ ls

args.txt a.txt b.txt c.txt

Existen más comandos de filtro muy útiles, entre ellos: awk, que programa cualquier tipo de filtro; fmt, que da formato al texto; uniq, que encuentra líneas únicas, y sed, para manipular una corriente de datos. Estos comandos van mucho más allá del ámbito de este libro. Por ejemplo, awk es un lenguaje de programación completo en sí mismo. La tabla 3-6 describe comandos útiles para emplear con tuberías y ofrece buenas ideas para usarlos.

Tabla 3-6: Comandos útiles para usar con tuberías


ComandoDescripción
apt list --installed | grep cameraLista los paquetes instalados y busca uno que contenga la cadena de caracteres "camera". Cada comando en esta tabla se escribe en una sola línea.
ls -lt | headMuestra los archivos del directorio actual por orden de antigüedad.
cat urls.txt | xargs wgetDescarga los archivos listados en URL dentro de un archivo de texto urls.txt.
dmesg | grep -c usbCuenta el número de veces que aparece la cadena usb en la salida de dmesg.
find . -name "*.mp3" | grep -vi "effects" > /tmp/playlist.txtBusca en el RPi (es decir, se ejecuta desde /con sudo) archivos mp3, ignorando cualquier archivo de efectos de sonido, para crear una lista de reproducción en /tmp.

Los comandos echo y cat

El comando echo se limita a reproducir (como el eco) una cadena de texto, la salida de un comando o un valor determinado por la salida estándar. Veamos unos ejemplos:

pi@erpi /tmp $ echo 'hello'

hello

pi@erpi /tmp $ echo "Today's date is $(date)"

Today's date is Sat 20 Jun 14:31:21 UTC 2015

pi@erpi /tmp $ echo $PATH

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

En el primer caso se reproduce una cadena de texto sencilla. En el segundo caso, las comillas," ", representan un comando emitido dentro de la llamada echo, y en el último caso se repite (echo) la variable de entorno PATH.

El comando echo nos permite también contemplar el estado de la salida de un comando usando $?. Por ejemplo:

pi@erpi ~ $ ls /tmp

args.txt a.txt b.txt c.txt playlist playlist.txt

pi@erpi ~ $ echo $?

0

pi@erpi ~ $ ls /nosuchdirectory

ls: cannot access /nosuchdirectory: No such file or directory

pi@erpi ~ $ echo $?

2

Claramente, el estado de salida para ls es 0 para una llamada con éxito, y 2 para un argumento no válido. Esto puede resultar útil cuando escribimos scripts y programas propios que devuelven un valor desde la función main().

El comando cat (concatenation, concatenar) nos facilita la unión de dos archivos desde la línea de comandos. El ejemplo siguiente usa echo para crear dos archivos, a.txt y b.txt. Luego, cat los concatena para crear uno nuevo, c.txt. Debemos utilizar el parámetro -e si queremos habilitar la interpretación de los caracteres de escape en la cadena que se pase a echo

pi@erpi ~ $ cd /tmp

pi@erpi /tmp $ echo "hello" > a.txt

pi@erpi /tmp $ echo -e "from\nthe\nRPi" > b.txt

pi@erpi /tmp $ cat a.txt b.txt > c.txt

pi@erpi /tmp $ more c.txt

hello

from

the

RPi

diff

El comando diff nos facilita la búsqueda de diferencias entre dos archivos. Ofrece una salida básica:

pi@erpi /tmp $ echo -e "dog\ncat\nbird" > list1.txt

pi@erpi /tmp $ echo -e "dog\ncow\nbird" > list2.txt

pi@erpi /tmp $ diff list1.txt list2.txt

2c2

< cat

---

> cow

El valor 2c2 en la salida indica que la línea 2 del primer archivo ha cambiado (changed) a la línea 2 del segundo, y que el cambio es cat a cow. El carácter a significa añadido o anexado (appended), y el d, borrado (deleted). Para una comparación lado a lado podemos usar lo siguiente:

pi@erpi /tmp $ diff -y -W70 list1.txt list2.txt

dog dog

cat | cow

bird bird

donde -y habilita la vista lado a lado y -W70 establece la anchura del texto que se muestra en la pantalla en 70 caracteres (columnas).

Si queremos utilizar una vista para las diferencias entre dos archivos más intuitiva, pero exigente, podemos usar el comando vimdiff (instalado mediante sudo apt install vim), que muestra una comparación lado a lado de los archivos usando el editor de texto vim (Vi IMproved). Escribimos vimdiff list1.txt list2.txt y usamos la secuencia de teclas vim: Escape : q ! dos veces para salir, o bien Escape : w q para guardar los cambios y salir. Vim requiere mucha práctica para dominar las secuencias de teclas.

tar

El comando tar es una utilidad para combinar archivos y directorios en un solo archivo (como un archivo zip descomprimido). Este archivo puede ser comprimido para ahorrar espacio. Para archivar y comprimir directorios o archivos, como /tmp, escribimos:

pi@erpi ~ $ tar cvfz tmp_backup.tar.gz /tmp

donde c significa nuevo archivo, v mostrar (verbose) el listado de archivos, z comprimir con gzip y f indica que lo que sigue es el nombre de archivo. También podemos encontrarnos la extensión .tar.gz representada como .tgz. Véase la tabla 3-7 para más ejemplos.

Tabla 3-7: Comandos útiles de tar.


ComandoDescripción
tar cvfz name.tar.gz /tmpComprimir en formato gzip.
tar cvfj name.tar.bz2 /tmpComprimir en formato bzip2, que generalmente tarda más pero genera archivos más pequeños. Introduzca cada comando de esta tabla en una sola línea.
tar cvfJ name.tar.xz /tmpComprimir en formato xz (usado en los archivos de paquete .deb).
tar xvf name.tar.*Descomprimir archivo comprimido (x indica extraer). Detectará automáticamente el tipo de compresión, como gzip o bz2.
tar xvf name.tar.* /dir/fileExtrae un archivo de otro. También funciona para un solo directorio.
tar rvf name.tar filenameAñade otro archivo.
tar cfz name-$(date +%m%d%y).tar.gz /dir/filenameCrea un archivo con la fecha actual, opción útil para los scripts y para jobs de copia de respaldo. Observe que debe hacer un espacio entre date y +%m%d%y.

md5sum

El comando md5sum nos permite verificar el código hash que garantiza la integridad de los archivos y que no se han corrompido ni maliciosa ni accidentalmente. En el ejemplo siguiente descargamos la herramienta wavemon como paquete .deb, pero no la instalamos. El comando md5sum sirve para generar la suma de verificación (checksum) md5:

pi@erpi ~ $ sudo apt-get download wavemon

Get:1 http://mirrordirector.raspbian.org/raspbian/ jessie/main

wavemon armhf 0.7.6-2 [48.2 kB] Fetched 48.2 kB in 0s (71.4 kB/s)

pi@erpi ~ $ ls -l *.deb

-rw-r--r-- 1 root root 48248 Mar 28 2014 wavemon_0.7.6-2_armhf.deb

pi@erpi ~ $ md5sum wavemon_0.7.6-2_armhf.deb

1dffa011736e25b63a054f1515d18b3e wavemon_0.7.6-2_armhf.deb

Ahora podemos comprobar la suma de verificación obtenida frente a la oficial para asegurarnos de que tenemos un archivo válido. Desgraciadamente, puede resultar difícil encontrar las sumas de verificación de cada paquete en línea. Si tenemos instalado wavemon, las sumas de verificación estarán en /var/ lib/dpkg/info/wavemon.md5sums. Podemos instalar una utilidad en Debian llamada debsums para comprobar la integridad del archivo, así como de todas sus partes.

pi@erpi ~ $ sudo apt install debsums wavemon

pi@erpi ~ $ debsums wavemon_0.7.6-2_armhf.deb

/usr/bin/wavemon OK

/usr/share/doc/wavemon/AUTHORS OK

/usr/share/doc/wavemon/NEWS.gz OK

...

Si compilamos nuestros propios paquetes para distribuirlos, resultaría útil distribuir los archivos con la suma de verificación correspondiente para que los usuarios puedan comprobar su integridad. Existe una alternativa a md5sum ,sha256sum, que se puede utilizar del mismo modo.

Procesos de Linux

Un proceso es una instancia de un programa que se está ejecutando en el SO. Debemos ser capaces de gestionar los procesos en ejecución en nuestro RPi, comprender los procesos de primer y de segundo plano y cerrar inmediatamente (kill, matar en inglés, pero también es el nombre literal de un comando Unix y Linux) cualquier proceso que se cuelgue.

Cómo controlar los procesos en Linux

El comando ps lista los procesos en ejecución en cada momento en el RPi. Tras escribir ps, vemos que el siguiente RPi está ejecutando dos procesos de usuario, el intérprete de comandos bash, con PID (Process ID, identificador de proceso) 912, y el propio comando ps, con PID 25481. El PID de ps será diferente siempre que lo ejecutemos porque se cierra cada vez que da los resultados:

pi@erpi ~ $ ps

PID TTY TIME CMD

912 pts/0 00:00:05 bash

25481 pts/0 00:00:00 ps

Para ver todos los procesos en ejecución, escribimos ps ax. En el ejemplo siguiente se aplica un filtro con los caracteres "ntp" para descubrir información acerca de los procesos ntp en ejecución en el RPi.

pi@erpi ~ $ ps ax | grep ntp

1069 ? Ss 0:00 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 107:112

1077 ? S 0:00 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 107:112

1132 ttyAMA0 S+ 0:00 grep --color=auto ntp

Está claro que se ejecutan tres procesos diferentes para el servicio, lo que le permite manejar múltiples conexiones simultáneas. En este ejemplo, todos los hilos están a la espera de que se complete un evento (S), PID 1069 es el líder de la sesión (Ss), 1077 es su clon (S) y el proceso grep, PID 1132, está en el grupo de primer plano (S+). Como vimos anteriormente, una llamada a systemctl status ntp proporciona información sobre los servicios en ejecución en el RPi, es decir, si ejecutamos la llamada veremos que los PID de los procesos se corresponden con los que muestra el comando ps.

Procesos en primer y en segundo plano

Linux es un sistema operativo multitarea que nos permite ejecutar múltiples procesos en segundo plano (background) mientras usamos un programa que se ejecuta en primer plano (foreground). Este concepto es muy similar al comportamiento que presenta una interfaz gráfica basada en ventanas, como las de Windows, Mac OS X, etc. Por ejemplo, el reloj del escritorio continúa actualizando la hora al mismo tiempo que navegamos por Internet.

Lo mismo es válido para aplicaciones que se ejecuten en una ventana de terminal. Para demostrar esto, veamos un pequeño fragmento de código fuente en C que muestra la frase "Hello World!" cada cinco segundos en una ventana de terminal de Linux. El funcionamiento preciso del código se verá en el capítulo 5, pero por el momento basta con que el lector lo escriba literalmente en un archivo, que llamará HelloRPiSleep.c, mediante el editor nano trabajando en la cuenta de usuario pi; para ello:

pi@erpi ~ $ cd ~/

pi@erpi ~ $ nano HelloRPiSleep.c

pi@erpi ~ $ more HelloRPiSleep.c

#include<unistd.h>

#include<stdio.h>

int main(){

int x=0;

do{

printf("Hello Raspberry Pi!\n");

sleep(5);

}while(x++<50);

return 0;

}

El programa consiste en un bucle que realiza 50 iteraciones, en cada una de las cuales muestra un mensaje y espera 5 segundos. Después de guardar el archivo como HelloRPiSleep.c, lo compilaremos como un ejecutable mediante el comando siguiente (-o especifica el nombre del archivo ejecutable):

pi@erpi ~ $ gcc HelloRPiSleep.c -o helloRPiSleep

pi@erpi ~ $ ls -l helloRPiSleep

-rwxr-xr-x 1 pi pi 5864 Jun 20 16:40 helloRPiSleep

Si todo ha funcionado, tendremos tanto el archivo de código fuente como el ejecutable llamado helloRPiSleep. Observe cómo este muestra la marca, x, de archivo ejecutable. Podemos, ahora, ejecutarlo sin más:

pi@erpi ~ $ ./helloRPiSleep

Hello Raspberry Pi!

Hello Raspberry Pi! ...

Continuará mostrando este mensaje cada 5 segundos. Podemos terminar su ejecución con Control+C. Sin embargo, para ejecutarlo en segundo plano tenemos dos opciones.

Primero podemos, en lugar de pulsar Control+C para terminar el proceso, pulsar Control+Z y, luego, en el símbolo del sistema, escribir el comando bg (por background, como ya hemos visto).

pi@erpi ~ $ ./helloRPiSleep

Hello Raspberry Pi!

^Z

[1]+ Stopped ./helloRPiSleep

pi@erpi ~ $ bg

[1]+ ./helloRPiSleep &

pi@erpi ~ $ Hello Raspberry Pi!

Hello Raspberry Pi!

Hello Raspberry Pi!

Cuando pulsamos Control+Z, ^Z aparece en la salida. Cuando escribimos bg, el proceso se sitúa en segundo plano, donde continúa su ejecución. De hecho, podemos continuar usando el terminal, pero resultará frustrante porque cada cinco segundos aparecerá el mensaje "Hello Raspberry Pi!" El comando fg nos permite devolver este proceso al primer plano.

pi@erpi ~ $ fg

./helloRPiSleep

Hello Raspberry Pi!

^C

pi@erpi:~$

Cuando pulsamos Control+C, que aparece como ^C, la aplicación se detiene.

La otra manera de poner la aplicación en segundo plano consiste en añadir el símbolo ampersand, &, al final de su nombre:

pi@erpi ~ $ ./helloRPiSleep &

[1] 30965

pi@erpi ~ $ Hello Raspberry Pi!

Hello Raspberry Pi!

El proceso se ha situado en segundo plano y su PID es 30965, en este caso. Para detener el proceso, usamos ps para encontrar el PID:

pi@erpi ~ $ ps aux|grep hello

pi 30965 0.0 0.0 1612 304 pts/0 S 20:14 0:00 ./helloRPiSleep

pi 30978 0.0 0.1 4208 1828 pts/0 S+ 20:15 0:00 grep hello

Para terminar el proceso, use el comando kill:

pi@erpi ~ $ kill 30965

[1]+ Terminated ./helloRPiSleep

Podemos confirmar la terminación del proceso usando ps de nuevo. Si el proceso no termina de inmediato, usaremos el argumento -9 para asegurarnos de que lo haga. Por ejemplo: kill -9 30965. Un comando diferente, pkill, termina un proceso a partir de su nombre. Así, en este caso:

pi@erpi ~ $ pkill helloRPiSleep

Otro comando que merece la pena mencionar es watch. Este ejecuta un comando a intervalos regulares y muestra el resultado en terminal a pantalla completa. Por ejemplo, para ver el log de mensajes del núcleo, escribimos:

pi@erpi ~ $ watch dmesg

Podemos concretar la duración del intervalo entre ejecuciones mediante -n seguido del número de segundos. Una buena manera de comprender el funcionamiento de watch consiste en ejecutarlo del siguiente modo:

pi@erpi ~ $ watch -n 1 ps a

Every 1.0s: ps a Sat Jun 20 20:22:39 2015

PID TTY STAT TIME COMMAND

912 pts/0 Ss 0:06 -bash

31184 pts/0 S+ 0:01 watch -n 1 ps a

31257 pts/0 S+ 0:00 watch -n 1 ps a

31258 pts/0 S+ 0:00 sh -c ps a

31259 pts/0 R+ 0:00 ps a

Veremos que el PID de ps, sh y watch cambia cada (1) segundo, lo que deja claro que watch está realmente ejecutando el comando (ps) al pasarlo a un nuevo intérprete de comandos mediante sh -c. La razón por la que watch aparece dos veces en la lista es que se reproduce a sí mismo temporalmente en el momento exacto en el que ejecuta ps a.

Otros temas de Linux

En este punto del libro, el lector ha podido revisar los principales comandos para trabajar con Linux en el RPi. Sin embargo, el tema de la gestión de sistemas Linux da mucho más de sí. Por ejemplo: ¿cómo configurar un adaptador WiFi? ¿Cómo usar cron para planificar (schedule) trabajos con el RPi? Estos temas se analizarán en los capítulos restantes del libro. Sin ir más lejos: la programación de trabajos con cron se trata en el capítulo 12, en el contexto de los dispositivos IoT.

Cómo utilizar Git para el control de versiones

De manera sencilla podemos decir que Git es un sistema que nos permite registrar cualquier cambio que se introduzca en el contenido de un proyecto de software a medida que avanza su desarrollo. Git, diseñado también por Linus Torvalds, se emplea hoy en la línea principal de desarrollo del núcleo de Linux. Git es un sistema increíblemente útil, que debemos entender bien por dos motivos principales: podemos utilizar Git en el desarrollo de nuestro propio software y además nos permite aprender a trabajar con distribuciones de código fuente del núcleo de Linux.

Git es un sistema distribuido de control de versiones, o DVCS (Distributed Version Contol System) que facilita el control del código fuente de un proyecto. Un sistema de control de versiones, VCS, registra y gestiona cualquier cambio introducido en documentos de cualquier tipo. Normalmente, los documentos que cambiemos se destacarán con números de revisión y marcas de tiempo. Se pueden comparar revisiones y hasta regresar a versiones antiguas de los documentos. Hay dos tipos de sistemas VCS:

❏Centralizados (CVCS): estos sistemas, como Apache Subversion (SVN), funcionan con la premisa de que existe una copia "maestra" única del proyecto. El flujo de trabajo es simple y directo: bajamos los cambios desde un servidor central, introducimos los nuestros propios y los volvemos a subir como definitivos a la copia maestra (esta subida definitiva de los cambios se denomina "commit", término típico también de las bases de datos; en español su uso como sustantivo ("hacer commit") es abrumadoramente mayoritario en el entorno informático, y es el que usaremos aquí).

❏Distribuidos (DVCS): usando estos sistemas, por ejemplo Git y Selenic Mercurial, no bajamos cambios, sino que clonamos el repositorio completo, incluido todo el histórico de cambios. El clonado del repositorio produce una copia tan exacta como una copia maestra, que hasta puede llegar a actuar como tal si fuera preciso. Por fortuna, los estándares actuales hacen que los documentos de texto plano y los archivos de código fuente no ocupen mucho espacio en disco. Una precisión importante: el modelo DVCS no excluye el uso de un repositorio maestro central para todos los usuarios. Véase, por ejemplo, git.kernel.org.

La ventaja principal de un DVCS frente a un CVCS es la posibilidad de hacer

commit rápidamente y probar las modificaciones localmente, en nuestro propio sistema, sin tener que subirlas antes a ninguna copia maestra. Esto permite la flexibilidad de poder subir los cambios solo cuando alcancen un nivel apropiado de calidad. La única desventaja significativa es el espacio en disco que exige el almacenamiento de todo el proyecto con su histórico de cambios, que va creciendo con el paso del tiempo.

Git es un DVCS centrado en el control y gestión de código fuente. Nos permite crear desarrollos paralelos que no afecten al original. Podemos regresar a una versión anterior de alguno de los archivos de código fuente, o bien a una de todo el proyecto. El proyecto, con sus archivos asociados e histórico de cambios, se denomina "repositorio" (repository). Esta capacidad resulta particularmente útil en proyectos de programación a gran escala, en los que es posible optar por una dirección para el desarrollo que, finalmente, acabe por resultar infructuosa. También es importante la facilidad para el desarrollo en paralelo cuando se tiene a varias personas trabajando en el mismo proyecto.

Git está escrito en C y, aunque se creó para cubrir la necesidad de control de versiones en el desarrollo del núcleo de Linux, se utiliza ampliamente en otros proyectos de código abierto como Eclipse o Android.

La manera más fácil de entender el manejo de Git es usarlo. Por tanto, hemos estructurado la sección siguiente en forma de guía paso a paso. Si todavía no lo tiene, Git se instala con facilidad mediante el comando sudo apt install git, así que no debería tener problemas para seguir los pasos directamente en el terminal. Este libro emplea GitHub como repositorio remoto de los ejemplos de código fuente. Salvo realizar commit de código fuente en el servidor, el lector podrá hacer todo lo expuesto en esta guía sin crear una cuenta en GitHub. No obstante, GitHub permite crear cuentas de repositorio públicas de forma gratuita, pero si queremos un repositorio privado, por ejemplo para desarrollos que deban salvaguardar derechos de propiedad intelectual, tendremos que pagar una cuota.

NOTA Si el lector planea embarcarse en el desarrollo de un proyecto grande y prefiere que no esté públicamente disponible en www.github.com ni pagar cuota de suscripción alguna, es posible hospedar repositorios privados de pequeña escala en sitios como bitbucket.org y gitlab.com. Con un poco más de trabajo, hasta es posible configurar GitLab en nuestro propio servidor, ya que existe una versión de código abierto de la plataforma.

Una introducción práctica

Para esta guía, hemos creado un repositorio llamado "test" en GitHub. En principio solo contiene un archivo, README.md, con una descripción breve del proyecto "test".

Como podemos ver en la figura 3-4, casi todas las operaciones son locales. Git realiza una suma de verificación en cada archivo antes de almacenarlo. Suma que garantiza que Git detecte cualquier modificación realizada fuera del propio repositorio Git, incluidas las que pudieran derivarse de la corrupción del sistema. Git emplea códigos hash de 40 caracteres para las sumas de verificación. De este modo, es capaz de registrar los cambios entre repositorios locales y remotos, lo que, a su vez, hace posible toda la funcionalidad de operaciones locales.


Figura 3-4: El flujo de trabajo básico de Git.

Cómo clonar un repositorio (git clone)

Clonar un repositorio supone realizar una copia de todos los archivos que contenga el proyecto, junto con el histórico de cambios completo, y guardarla en nuestro disco duro. Haremos esta operación una sola vez. Para clonar el repositorio envíe el comando git clone seguido del nombre completo del repositorio:

pi@erpi / $ cd ~/

pi@erpi ~ $ git clone https://github.com/derekmolloy/test.git

Cloning into 'test'...

remote: Counting objects: 14, done.

remote: Compressing objects: 100% (5/5), done.

remote: Total 14 (delta 1), reused 0 (delta 0), pack-reused 9

Unpacking objects: 100% (14/14), done.

Checking connectivity... done.

Ahora tenemos una copia completa del repositorio "test" en el directorio /test. Nuestro repositorio es igual de completo que la versión en el servidor de GitHub. Si fuera necesario, este repositorio podría quedar disponible a través de una red, en un sistema de archivos o en otra cuenta de GitHub y serviría perfectamente como versión principal del repositorio. Aunque no sea necesario contar con un servidor central, generalmente lo hay, ya que de este modo múltiples usuarios pueden insertar (check in) código fuente en un repositorio maestro conocido. El repositorio se crea en el directorio /test y en este momento contiene lo siguiente:

pi@erpi ~/test $ ls -al

total 20

drwxr-xr-x 3 pi pi 4096 Jun 20 22:00 .

drwxr-xr-x 6 pi pi 4096 Jun 20 22:00 ..

drwxr-xr-x 8 pi pi 4096 Jun 20 22:00 .git

-rw-r--r-- 1 pi pi 59 Jun 20 22:00 README.md

Podemos ver el archivo README.md que se creó cuando el proyecto se inicializó en GitHub. Podemos usar more para ver el contenido del mismo. El directorio contiene un subdirectorio .git oculto, con los siguientes archivos y directorios:

pi@erpi ~/test/.git $ ls

branches description hooks info objects refs

config HEAD index logs packed-refs

El directorio oculto .git contiene toda la información acerca del repositorio, como mensajes de commit, archivos de log y los objetos de datos. Por ejemplo, la ubicación del repositorio remoto se encuentra en el archivo config.

pi@erpi ~/test/.git $ more config | grep url

url = https://github.com/derekmolloy/test.git

La sección "Otras lecturas", al final del capítulo, incluye una referencia a un magnífico libro sobre Git que está disponible en la red de forma gratuita. En él se describe con detalle la estructura del directorio .git. Por fortuna, ahora no debemos introducir ningún cambio en el directorio .git, puesto que tenemos comandos Git que lo harán por nosotros.

NOTA Esta guía paso a paso utiliza el propio repositorio "test" del autor. No obstante, no le resultará difícil al lector crear su propio repositorio en GitHub. Después de configurar una cuenta gratuita en GitHub, diríjase a "Create New" (crear nuevo) y, luego, "New repository" (nuevo repositorio). Dé un nombre y una descripción al repositorio y hágalo disponible públicamente, seleccione la opción para inicializarlo con un README y, luego, seleccione "Create Repository" (crear repositorio). A partir de aquí podrá seguir estas instrucciones con el repositorio de su propia cuenta, y, en consecuencia, podrá comunicarse desde su RPi con su propio repositorio en GitHub.

Cómo obtener información de estado (git status)

Ahora que contamos con nuestro repositorio, el paso siguiente es añadir un nuevo archivo de texto al directorio de trabajo, donde estará en estado untracked (sin seguimiento). Cuando ejecutamos el comando git status, observamos un mensaje que indica que hay untracked files, es decir, archivos sin seguimiento:

pi@erpi ~/test $ echo "Just some text" > newfile.txt

pi@erpi ~/test $ git status

On branch master

Your branch is up-to-date with 'origin/master'.

Untracked files:

(use "git add <file>..." to include in what will be committed)

newfile.txt

nothing to commit, untracked files present (use "git add" to track)

El paso siguiente consiste en añadir cualquier archivo sin seguimiento (untracked) al área de preparación (staging area). No obstante, si no desea añadir un conjunto de archivos, también puede crear uno llamado gitignore para obviarlos. Por ejemplo, esto resultaría útil si en un proyecto C/C++ decidimos que no queremos archivos objeto, .o, intermedios. He aquí un ejemplo de cómo crear un archivo .gitignore destinado a ignorar archivos objeto, .o, de C/C++:

pi@erpi ~/test $ echo "*.o" > .gitignore

pi@erpi ~/test $ more .gitignore

*.o

pi@erpi ~/test $ touch testobject.o

pi@erpi ~/test $ git status

On branch master

Your branch is up-to-date with 'origin/master'.

Untracked files:

(use "git add <file>..." to include in what will be committed)

.gitignore

newfile.txt

nothing to commit, untracked files present (use "git add" to track)

En este caso, hay dos archivos sin seguimiento, pero no existe mención al archivo testobject.o, lo que indica que se está ignorando tal como queríamos. Observe que el archivo .gitignore forma parte también del repositorio y que se conservará en cualquier clonación del mismo, junto con su histórico de cambios, etc.

Cómo añadir archivos al área de preparación (git add)

Los archivos del directorio de trabajo se pueden añadir ahora al área de preparación con el comando git add . (comando que incluye todos los archivos en el directorio de trabajo, con la excepción de los archivos ignorados). En este ejemplo, dos archivos se agregan desde el directorio de trabajo al área de preparación. Luego, podemos mostrar el estado del repositorio del siguiente modo:

pi@erpi ~/test $ git add .

pi@erpi ~/test $ git status

On branch master

Your branch is up-to-date with 'origin/master'.

Changes to be committed:

(use "git reset HEAD <file>..." to unstage)

new file: .gitignore

new file: newfile.txt

Para eliminar (remove) un archivo del área de preparación, usamos git rm somefile.ext.

Cómo hacer commit en el repositorio local (git commit)

Después de añadir archivos al área de preparación, podemos hacer commit y convertir en definitivos los cambios desde aquella en el repositorio Git. Primero, podríamos querer añadir nuestro nombre y dirección de correo electrónico para indicar quién realiza el commit con los cambios.

pi@erpi ~/test $ git config --global user.name "Derek Molloy"

pi@erpi ~/test $ git config --global user.email derek@my.email.com

Estos valores se configuran a partir de los de nuestra cuenta de usuario Linux, de manera que persisten en el siguiente inicio de sesión. Para verlos, podemos escribir more ~/.gitconfig.

El commit permanente de los cambios de los archivos en el repositorio Git local se hace con el comando git commit:

pi@erpi ~/test $ git commit -m "Testing the repository"

[master 3eea9a2] Testing the repository

2 files changed, 2 insertions(+)

create mode 100644 .gitignore

create mode 100644 newfile.txt

Los cambios se marcan con el nombre de usuario, pero también requieren la inclusión de un mensaje. Si queremos detallar el mensaje en la línea, usamos -m para establecerlo.

NOTA El atajo git commit -a realiza un commit de los archivos modificados directamente en el repositorio local, sin necesidad de invocar add. No añade archivos nuevos. Observe la figura 3-4 en este mismo capítulo.

Envío al repositorio remoto (git push)

Para realizar este paso, debemos poseer una cuenta propia en GitHub. El comando git push envía cualquier cambio en el código al repositorio remoto. Para que tales cambios se apliquen, debemos estar registrados como usuarios que pueden, en efecto, realizar modificaciones. En Git 2.0 se ha implementado un nuevo método llamado simple, más conservador, para enviar a repositorios remotos. Está seleccionado de forma predeterminada, pero puede suprimir algún mensaje de advertencia, y el envío se puede realizar del siguiente modo (sustituya los detalles de usuario y repositorio por los suyos propios):

pi@erpi ~/test $ git config --global push.default simple

pi@erpi ~/test $ git push

Username for 'https://github.com': derekmolloy

Password for 'https://derekmolloy@github.com': mySuperSecretPassword

Counting objects: 4, done.

Delta compression using up to 4 threads.

Compressing objects: 100% (2/2), done.

Writing objects: 100% (4/4), 350 bytes | 0 bytes/s, done.

Total 4 (delta 0), reused 0 (delta 0)

To https://github.com/derekmolloy/test.git

f5c45f4..3eea9a2 master -> master

Después de que el código haya sido enviado (push) al repositorio remoto, podemos traer (pull) los cambios al repositorio local de cualquier máquina gracias al comando git pull desde el interior del directorio del repositorio local:

pi@erpi ~/test $ git pull

Already up-to-date.

En este caso, todo está actualizado.

Ramas de desarrollo de Git

Git contempla el concepto de ramas de desarrollo (branching), lo que nos permite trabajar en múltiples versiones diferentes del conjunto de archivos de nuestro proyecto. Por ejemplo, para desarrollar una nueva característica en nuestro proyecto (versión 2) pero conservar el código de la versión actual (versión 1), crearíamos una nueva rama (versión 2). Ninguna de las nuevas características o cambios introducidos en la versión 2 afectará al código de la versión 1. Después podremos pasar de una rama a otra con facilidad.

Cómo crear una rama de desarrollo (git branch)

Suponga, por ejemplo, que desea crear una nueva rama llamada mybranch (acción denominada "ramificar"). Puede hacerlo con el comando git branch mybranch y, luego, pasar a trabajar con ella usando git checkout mybranch del siguiente modo:

pi@erpi ~/test $ git branch mybranch

pi@erpi ~/test $ git checkout mybranch

Switched to branch 'mybranch'

Ahora, para demostrar el funcionamiento de todo esto, suponga que un archivo temporal llamado testmybranch.txt se añade al repositorio. Este podría ser un nuevo archivo de código para nuestro proyecto. Puede observar que el estado de la rama de desarrollo deja claro que el directorio de trabajo contiene un archivo sin seguimiento:

pi@erpi ~/test $ touch testmybranch.txt

pi@erpi ~/test $ ls

newfile.txt README.md testmybranch.txt testobject.o

pi@erpi ~/test $ git status

On branch mybranch

Untracked files:

(use "git add <file>..." to include in what will be committed)

testmybranch.txt

nothing to commit, untracked files present (use "git add" to track)

Puede añadir entonces este nuevo archivo al área de preparación de la rama usando los mismos comandos:

pi@erpi ~/test $ git add .

pi@erpi ~/test $ git status

On branch mybranch

Changes to be committed:

(use "git reset HEAD <file>..." to unstage)

new file: testmybranch.txt

Podemos hacer commit de este cambio en la rama mybranch del repositorio local. Este cambio afectará a la rama mybranch, pero no tendrá efecto sobre la rama maestra:

pi@erpi ~/test $ git commit -m "Test commit to mybranch"

[mybranch d4cabf3] Test commit to mybranch

1 file changed, 0 insertions(+), 0 deletions(-)

create mode 100644 testmybranch.txt

pi@erpi ~/test $ git status

On branch mybranch

nothing to commit, working directory clean

pi@erpi ~/test $ ls

newfile.txt README.md testmybranch.txt testobject.o

De la salida anterior puede apreciar que el archivo testmybranch.txt se encuentra en el repositorio local y podemos verlo en el directorio.

Si ahora pasa de la rama mybranch a la rama maestra mediante git checkout master, observará algo interesante al solicitar un listado del directorio:

pi@erpi ~/test $ git checkout master

Switched to branch 'master'

Your branch is up-to-date with 'origin/master'.

pi@erpi ~/test $ ls

newfile.txt README.md testobject.o

Así es, el archivo testmybranch.txt ha desaparecido del directorio. Aún existe, obviamente, pero se encuentra en forma de objeto blob (de BLOB, Binary Large OBject, objeto binario grande), dentro del directorio git/objects. Si regresa a la rama y lista el directorio, verá esto:

pi@erpi ~/test $ git checkout mybranch

Switched to branch 'mybranch'

pi@erpi ~/test $ ls

newfile.txt README.md testmybranch.txt testobject.o

Es decir, el archivo vuelve a aparecer. Por lo tanto, puede observar lo bien integrado que está el sistema de ramas de desarrollo. En este punto puede regresar a la rama maestra e introducir cambios en el código original y ver que los cambios introducidos en la rama mybranch no afectan al código maestro. Aun si cambiamos el código en el mismo archivo, carecerá de efectos sobre el código original de la rama maestra.

Cómo fusionar ramas de desarrollo (git merge)

¿Qué ocurre si deseamos aplicar los cambios introducidos en la rama de desarrollo mybranch a la versión maestra del proyecto? Es decir, ¿cómo fusionamos las dos ramas? Pues utilizaremos el comando git merge.

pi@erpi ~/test $ git checkout master

Switched to branch 'master'

Your branch is up-to-date with 'origin/master'.

pi@erpi ~/test $ git merge mybranch

Updating 3eea9a2..d4cabf3

Fast-forward

testmybranch.txt | 0

1 file changed, 0 insertions(+), 0 deletions(-)

create mode 100644 testmybranch.txt

pi@erpi ~/test $ git status

On branch master

Your branch is ahead of 'origin/master' by 1 commit.

(use "git push" to publish your local commits)

nothing to commit, working directory clean

pi@erpi ~/test $ ls

newfile.txt README.md testmybranch.txt testobject.o

Ahora el archivo testmybranch.txt está en la rama maestra y también se han aplicado el resto de cambios introducidos en cualquier otro documento de la misma. El repositorio local va ahora un commit por delante del remoto, y podemos utilizar git push para actualizar este último.

Cómo borrar una rama de desarrollo (git branch -d)

Para borrar una rama de desarrollo, use el comando git branch -d mybranch:

pi@erpi ~/test $ git branch -d mybranch

Deleted branch mybranch (was d4cabf3).

pi@erpi ~/test $ ls

newfile.txt README.md testmybranch.txt testobject.o

En este caso, la rama testmybranch.txt sigue presente en el proyecto maestro, como por otro lado deber ser, puesto que se ha fusionado con él. Si la rama se hubiera borrado antes de realizar la fusión, se habría perdido el archivo.

Comandos habituales de Git

La table 3-8 ofrece un resumen de los principales comandos de Git. Llegados a este punto, ya hemos visto el uso básico de Git. Cuando se desarrolla código directamente en el RPi, Git puede resultar muy útil, puesto que nos permite subir fácilmente nuestros desarrollos a un repositorio remoto. Esta funcionalidad sirve muy bien para realizar copias de respaldo de nuestro código, así como para volver a desplegar el proyecto en múltiples RPi.

Table 3-8: Resumen de los principales comandos Git.


OperaciónDescripciónOperaciónDescripción
git cloneRealiza la clonación desde el repositorio remoto.git rmElimina un archivo o directorio del área de preparación.
git initCrea un repositorio completamente nuevo.git mvMueve o renombra un archivo o directorio en el área de preparación.
git pullFusiona cambios desde un repositorio maestro.git logMuestra un log (registro) con los commits. El histórico del proyecto.
git fetchEncuentra los cambios en el repositorio maestro sin realizar la fusión.git tagDa nombre a un commit (por ejemplo: versión 2).
git statusMuestra el estado del proyecto.git merge [name]Fusiona la rama.
git addAñade un nuevo archivo o edita un archivo existente.git showObtiene detalles sobre el commit actual o sobre cualquier otro.
git diff Muestra las diferencias que pasarán al repositorio cuando se haga el commit.git branch [name]Crea una nueva rama de desarrollo. (Use el parámetro -d para borrar (delete)).
git commitRealiza commit en el reposi-torio.git checkout [name]Cambia a otra rama de desarrollo.
git pushEnvía los cambios desde un repositorio local a uno remoto.

Cómo utilizar escritorios virtuales

El RPi es perfectamente capaz de actuar como plataforma de computación general, pero si planeamos compilar un núcleo de Linux o realizar desarrollo multiplataforma cruzado (véase el capítulo 7) lo más recomendable es utilizar un ordenador personal con Linux. Es posible utilizar un ordenador con un gestor de arranque que nos permita un sistema dual. Sin embargo, si mayoritariamente utilizamos un PC o un Mac, podríamos decantarnos por utilizar escritorios o máquinas virtuales.

La virtualización de escritorio, o creación de máquinas virtuales, como también se conoce esta tecnología, permite que un solo ordenador ejecute varios sistemas operativos al mismo tiempo. Emplea tecnología de hipervisores (monitores de máquinas o escritorios virtuales) que incluyen elementos hardware, firmware y software para crear y ejecutar entornos de emulación software conocidos como virtual machines, máquinas virtuales o VM, por sus siglas en inglés. Si queremos ejecutar múltiples sistemas operativos en un solo PC, las máquinas virtuales ofrecen una alternativa a la configuración de un gestor de arranque con múltiples sistemas operativos.

En un entorno de virtualización suele haber dos o más SO en ejecución. El sistema operativo host es el que se ejecuta en la máquina de forma nativa y se instala el primero. El software hipervisor se utiliza después para crear una instancia de otro SO, guest o invitado, dentro de una VM. La figura 3-5 muestra una máquina Windows 8.1 (host) ejecutando una máquina virtual (guest) Linux Debian Jessie de 64 bits en una ventana. La VM Debian muestra la interfaz gráfica de usuario Cairo-Dock.


Figura 3-5: VirtualBox ejecutando Debian (Jessie) como máquina virtual en un host Windows.

Existen muchos productos de virtualización, pero la mayoría son muy costosos, tienen licencias propietarias y limitan el tipo de máquinas físicas y virtuales con las que pueden trabajar. Dos de los productos de virtualización de escritorio más populares en Linux son VMware Player y VirtualBox. VMware Player (www.vmware.com/products/player/) es gratuito para uso personal. VirtualBox (www.virtualbox.org) está disponible bajo licencia GNU GPLv2, pero algunas de sus características están disponibles gratis bajo licencia propietaria.

Ambos productos emplean hipervisores tipo 2 (hosted hypervisors) para la virtualización. Esto quiere decir que se ejecutan dentro de un SO estándar y permiten usar ambas máquinas, la física y la virtual, de forma simultánea. VirtualBox está disponible para Windows, Mac OS X y Linux, y puede virtualizar máquinas Windows, Linux y Mac OS X. En la actualidad, VMware Player no está disponible para instalaciones host en Mac OS X. En su lugar debemos adquirir un producto llamado VMware Fusion.

Ambos productos son muy potentes y sería difícil distinguir entre ellos. Sin embargo, VirtualBox funciona bajo licencia GPL e incluye una funcionalidad muy interesante llamada snapshot o instantánea (tenga en cuenta que en la documentación del programa aparece el término inglés). La interfaz de usuario hace posible capturar una instantánea de la VM y guardarla para su uso posterior. Por ejemplo, podríamos capturar una instantánea antes de introducir cambios significativos en la configuración del SO de la VM, lo que nos permitiría retornar a dicha configuración en caso de problemas. La instantánea almacena todos los ajustes de configuración de la VM, los cambios en el contenido de los discos virtuales y el estado de la memoria de la máquina en el momento de realizar la captura. Por lo tanto, cuando restauramos una instantánea, la VM continúa ejecutándose exactamente en el mismo punto en el que se capturó la instantánea.

Si instalamos el software VirtualBox Guest Additions, podremos copiar y pegar texto entre el SO de la VM y el de nuestro propio ordenador, compartir directorios e incluso redimensionar dinámicamente la ventana del hipervisor. La página web de este capítulo (www.exploringrpi.com/chapter3/) ofrece consejos sobre cómo instalar Linux en una VM de un ordenador con Windows.

NOTA Todos los paquetes y software Linux de este libro se han compilado y probado en una distribución estándar Debian de 64 bits instalada en una máquina virtual de VirtualBox.

El código fuente de este libro

Ahora que el lector tiene configurada y funcionando la instalación Linux en VirtualBox, o ha optado por una instalación completa de Linux en un ordenador, podrá descargar todo el código fuente, los scripts y la documentación empleada en el libro abriendo una ventana de terminal y escribiendo lo siguiente (en el ordenador y en el RPi):

pi@erpi ~ $ sudo apt install git

pi@erpi ~ $ git clone https://github.com/derekmolloy/exploringRPi.git

Cloning into 'exploringRPi'...

Si desea descargar el código desde Windows o Mac OS X, existe una interfaz gráfica para trabajar con repositorios GitHub, que está disponible en las direcciones windows.github.com y mac.github.com.

NOTA Si el lector tiene su propia cuenta en GitHub, puede utilizar su interfaz web para copiar (fork) este repositorio en ella. También puede consultar el repositorio de forma regular para observar si hay actualizaciones y cambios. Las cuentas GitHub sin repositorios privados son gratuitas en la actualidad. Asimismo, estudiantes y profesores pueden solicitar una cuenta Micro gratuita, que les da derecho a mantener privados hasta cinco repositorios durante dos años.

Resumen

Después de leer este capítulo debería ser capaz de hacer lo siguiente:

❏Describir los conceptos básicos de un sistema Linux empotrado.

❏Describir cómo un dispositivo Linux empotrado, por ejemplo el RPi, se inicia y arranca su SO Linux.

❏Describir conceptos Linux importantes, como espacio del núcleo (kernel space), espacio de usuario (user space) y la inicialización del sistema utilizando systemd.

❏Realizar tareas de administración de sistema de Linux en el RPi.

❏Utilizar con eficiencia el sistema de archivos del RPi.

❏Emplear comandos de Linux para gestionar archivos y procesos.

❏Gestionar sus propios proyectos de desarrollo de software mediante Git.

❏Instalar una distribución Linux en su ordenador creando una máquina virtual con una herramienta como VirtualBox.

❏Descargar el código fuente de este libro usando Git.

Otras lecturas

Los textos siguientes pueden ayudarnos a aprender más acerca de Linux empotrado, la administración de sistemas Linux, Git y las tecnologías de virtualización:

❏Embedded Linux Primer: A Practical Real-World Approach, Second Edition (Upper Saddle River, NJ: Prentice Hall, 2011), de Christopher Hallinan.

❏The Debian Policy Manual ("Manual de normas de Debian"): tiny.cc/erpi303.

❏Para aprender más acerca de Git, comience consultando el manual del propio sistema; para ello, escriba man gittutorial en la línea de comandos. Si después necesita más información, puede leer la magnífica guía de referencia Pro Git, de Scott Chacon, en el sitio tiny.cc/erpi304 (también está disponible en tapa blanda en Nueva York: Apress Media, 2009).

Bibliografía

❏ARM Holdings (11 de febrero de 2015): "ARM Holdings PLC Reports Results for the Fourth Quarter and Full Year 2014". Descargado el 14 de junio de 2015 desde www.arm.com/about/newsroom/arm-holdings-plc-reports-results-for-the-fourth-quarter-and-full-year-2014.php

❏McCracken, J.; Sherman, A., y King, I. (27 de mayo de 2015): "Avago to Buy Broadcom for $37 Billion in Biggest Tech Deal Ever". Bloomberg Business. Descargado el 14 de junio de 2015 desde www.bloomberg.com/news/articles/2015-05-27/avago-said-near-deal-to-buy-wireless-chipmaker-broadcom

❏Git FAQ (9 de marzo de 2013). Descargado el 22 de febrero de 2014 desde Git Wiki: git.wiki.kernel.org/index.php/GitFaq#Why_the_.27git.27_name.3F

❏Smith, B. (29 de julio de 2013). A Quick Guide to GPLv3. Descargado el 14 de junio de 2015 desde www.gnu.org/licenses/quick-guide-gplv3.html

Continúa

Capítulo

4

Interfaz con los componentes electrónicos

Este capítulo ofrece al lector los conocimientos prácticos de electrónica básica necesarios para lograr que sus circuitos electrónicos y la plataforma RPi trabajen armoniosamente. El capítulo comienza describiendo determinados componentes y equipos que pueden resultar muy útiles para desarrollar y depurar circuitos electrónicos. Continúa con una guía introductoria práctica sobre diseño y análisis de circuitos, donde se anima al lector a ponerse manos a la obra y construir los circuitos y emplear el equipamiento descrito al principio del capítulo. El capítulo prosigue con una relación de los componentes más típicos que se emplean con la interfaz GPIO (General Purpose Input/Output, entrada/salida de propósito general) del RPi, incluidos diodos, condensadores, transistores, optoacopladores, conmutadores o interruptores y puertas lógicas. Por último, también se analizan los principios básicos de la conversión ADC (Analog-to-Digital Conversion, analógico-digital), ya que dichos conocimientos serán necesarios en el capítulo 9 para construir circuitos que se comuniquen con los sensores analógicos del RPi.

Materiales necesarios para este capítulo:

❏Componentes usados en este capítulo (siempre que se vaya a trabajar sobre él): la lista completa se facilita al final del mismo.

❏Digilent Analog Discovery (versión 1 o 2), o bien tener a mano un multímetro digital, generador de señal y osciloscopio.

Puede encontrar más detalles sobre este capítulo en la dirección:

www.exploringrpi.com/chapter4/.

NOTA Ningún capítulo puede sustituir a varios libros de texto completos sobre electrónica digital y analógica. No obstante, hay conceptos que el lector debería manejar con solvencia antes de conectar componentes electrónicos a la cabecera GPIO del Raspberry Pi, puesto que las configuraciones incorrectas podrían arruinar la placa con suma facilidad. En próximos capítulos nos apoyaremos mucho en los conceptos electrónicos descritos en este; sin embargo, no es estrictamente necesario asimilar completamente su contenido antes de seguir adelante. Más importante aún es saber que este capítulo está presente como referencia de los conceptos electrónicos básicos que se mencionarán en capítulos venideros.

Cómo analizar nuestros circuitos

A la hora de desarrollar circuitos electrónicos para la plataforma RPi, resulta útil tener las siguientes herramientas para analizarlos antes de conectarlos a la E/S del RPi. De este modo reducimos las probabilidades de dañar la placa. En particular, es realmente útil contar con un multímetro digital y un osciloscopio de señal mixta.

NOTA El lector debe analizar cuidadosamente los componentes incluidos en esta lista. Asegúrese de hacer sus deberes y busque asesoramiento independiente antes de adquirir cualquiera de los productos. Ninguno de ellos está en la lista como resultado de acuerdo o petición comercial alguna. Todos los precios son aproximados y se dan en dólares debido a la fluctuación de la moneda. En todo caso, muchos sitios web ofrecen envíos internacionales y facilitan los precios también en euros.

Multímetro digital

Un multímetro digital o DMM (Digital Multi-Meter) es una herramienta prácticamente imprescindible para medir voltajes, intensidad de corriente y resistencia/continuidad en los circuitos del RPi. Si aún no tiene uno, intente comprar un modelo que presente las características siguientes:

❏Apagado automático. Útil para ahorrar batería.

❏Selección automática de rango. Es vital que podamos seleccionar diferentes rangos de medidas. Los medidores de gama media a menudo ofrecen la funcionalidad de selección automática del rango de medidas, lo cual permite reducir el tiempo exigido para realizar las mediciones.

❏Comprobación de continuidad. Esta funcionalidad debería producir un pitido audible a menos que haya una ruptura en el conductor, o bien una resistencia excesiva.

❏Lecturas con media cuadrática verdadera (true RMS). La mayoría de multímetros de bajo coste promedian las mediciones de corriente/voltaje AC(~). Los multímetros con RMS verdadera, por su parte, procesan las lecturas realizando el cálculo de la media cuadrática verdadera de la señal, lo que les permite tener en cuenta las distorsiones en las formas de onda al tomar las lecturas. Esta característica resulta útil para analizar equipos controlados por fase, dispositivos de estado sólido, dispositivos motorizados, etc.

❏Otras opciones útiles. Las opciones siguientes no son estrictamente necesarias, pero sí resultan útiles: pantalla retroiluminada, soporte para mediciones, pantallas con dígitos grandes, mayor número de dígitos significativos, conectividad con PC (idealmente optoaislada), sonda de temperatura y comprobador de diodos.

❏Carcasa. Busque una carcasa plástica de buena calidad y resistente a los golpes, preferiblemente con protección de caucho o goma.

Generalmente, la mayoría de las características anteriores se encuentran disponibles en DMM de gama media, con buenos niveles de precisión (1% o mejor), elevadas impedancias de entrada (> 10 MΩ) y aceptables rangos de medición. Por su parte, los multímetros de gama alta ofrecen sobre todo mediciones más rápidas y con mayor precisión. Algunos pueden incorporar funciones como medición de capacitancia, frecuencia, temperatura mediante sensor de infrarrojos, humedad y ganancia de los transistores. Algunas de las marcas más conocidas son Fluke, Tenma, Agilent, Extech y Klein Tools.

Osciloscopios

Los DMM estándar son una herramienta versátil que nos facilita la medición de voltajes, corriente y resistencias promedio. Los osciloscopios, por su parte, no miden más que el voltaje, pero nos permiten observar sus cambios a lo largo del tiempo. Generalmente podemos ver dos o más formas de onda de voltaje de manera simultánea, que son capturadas dentro de un determinado ancho de banda y un número concreto de muestras analógicas (memoria). El ancho de banda define el rango de frecuencias de señal que un osciloscopio es capaz de medir con precisión; por lo general al punto de 3 dB, es decir, la frecuencia en la que la amplitud de una onda senoidal es ~30% más baja que su verdadera amplitud. Para lograr resultados precisos, el número de muestras analógicas debe ser múltiplo del ancho de banda (lo veremos más tarde cuando discutamos el teorema de Nyquist). Los osciloscopios modernos emplean un valor cuatro o cinco veces el ancho de banda. Así, un osciloscopio de 25 MHz debe tomar un mínimo de 100 millones de muestras por segundo. Tanto el ancho de banda como el número de muestras analógicas tienen una gran influencia en el precio del osciloscopio.

En el mercado encontramos varios osciloscopios económicos de dos canales, por ejemplo: Owon PDS5022S 25 MHz (200 $), Siglent SDS1022DL 25 MHz (325 $,

con más funcionalidad), Rigol DS1052 50 MHz (325 $) y Owon SDS6062 60 MHz

(349 $). A medida que sube el ancho de banda también lo hacen los precios, siendo normales cantidades de más de 1.500 $ por un osciloscopio de 300 MHz. Las series de osciloscopios Agilent de almacenamiento digital (DSOX) y de señal mixta (MSOX) entrarían en el rango de precios medio-alto, con un coste entre 3.000 $ (100 MHz) y 16.000 $ (1 GHz). Los osciloscopios de señal mixta ofrecen también herramientas para análisis de bus digital.

El Digilent Analog Discovery con Waveforms (véase la figura 4-1) se ha usado para comprobar todos los circuitos de este libro. El Analog Discovery (así como el muy parecido Analog Discovery 2) es un osciloscopio digital USB, generador de formas de onda, generador de patrones digitales y analizador lógico para el entorno Windows. El nuevo software Waveforms 2015 es compatible con Linux (incluidas las plataformas ARM) y Mac OS X. El Analog Discovery suele costar entre 259 y 279 $. Si usted es un principiante, o bien está tratando de refrescar sus conocimientos, es un aparato realmente bueno para el precio que tiene.


Figura 4-1: La aplicación Waveforms generando una señal y

mostrando la respuesta desde el circuito físico.

NOTA El lector tiene disponible un vídeo del propio autor sobre el Analog Discovery en la página web de este capítulo: www.exploringrpi.com/chapter4. Muestra tres aplicaciones diferentes para mediciones con Analog Discovery: análisis analógico de un diodo rectificador, cómo usar el generador de patrones analógicos y el analizador lógico para investigar el comportamiento de un biestable de tipo JK (JK flip-flop), así como el uso del analizador lógico y su intérprete I2C para conectarse con el bus I2C del BeagleBone Black I y analizar su comportamiento. El análisis realizado sería igual en la plataforma RPi.

Analog Discovery se ha utilizado para generar todas las gráficas del osciloscopio que se pueden ver en este libro, ya que todos los ejemplos se han implementado mediante circuitos reales. El rango está limitado a dos canales, con 5 MHz por canal y 50 millones de muestras por segundo, tanto para el generador de formas de onda como para el osciloscopio diferencial. Como tal, el Analog Discovery está destinado principalmente a estudiantes y aficionados, pero también puede resultar útil para hacerse a la idea de las funcionalidades "imprescindibles" que exigiremos a nuestros futuros equipos, más costosos.

Existen otros osciloscopios USB de señal mixta, como los de PicoScope, que van de 160 a 10.000 $ (www.picotech.com), o los DSO de BitScope, que van de 150 a 1.000 $ (www.bitscope.com) y que son compatibles con Linux. Sin embargo, si nos basamos en las características disponibles en la actualidad en los osciloscopios USB, podría resultar adecuado económicamente un osciloscopio de banco, que disponga de un analizador lógico USB (como el Saleae Logic de www.saleae.com) para proporcionar funcionalidad de modo mixto.

NOTA The BitScope Micro (145 $) es una versión especial del BitScope realizada específicamente para el RPi. Similar al Analog Discovery, se trata de un osciloscopio bicanal (20 MHz), analizador lógico (6 canales) y analizador de espectro. El BitScope Micro está diseñado para conectarse directamente con el RPi y se puede utilizar para crear una plataforma independiente, o bien conectada a una red local, para medición y adquisición de datos. Además, incluye librerías de software que podemos utilizar para desarrollar nuestras propias aplicaciones de adquisición de datos. Para más información diríjase a bitscope.com/pi/.

Principios básicos de los circuitos

Los circuitos electrónicos están formados por componentes que se pueden clasificar genéricamente en pasivos y activos. Los componentes activos, como transistores, son aquellos capaces de controlar el flujo de la corriente de manera adaptativa, mientras que los pasivos, por ejemplo resistencias, condensadores o diodos, no pueden. El desafío a la hora de construir circuitos consiste en dar con un diseño apropiado a partir de los componentes adecuados. Por fortuna podemos apoyarnos en varias ecuaciones para análisis de circuitos.

Voltaje, intensidad de la corriente, resistencia y la ley de Ohm

La ecuación más importante que debemos aprender es la que expresa matemáticamente la ley de Ohm. Es muy sencilla en apariencia:

V = I × R

donde:

❏El voltaje (V), que se mide en voltios (V), es la diferencia de potencial eléctrico (energía) que provoca el flujo de la corriente eléctrica en el circuito. En este caso, el símil del agua resulta útil para visualizar el voltaje. Muchas casas tienen un depósito en su azotea o piso superior, conectado por las cañerías a los grifos. El agua fluirá de manera instantánea cuando abramos un grifo debido a la altura del depósito y la fuerza de gravedad de la tierra. Si el grifo estuviese a la misma altura que la parte superior del depósito, el agua no fluiría puesto que carecería de energía potencial respecto a aquél. El voltaje se comporta de una forma muy similar. Cuando el voltaje a un lado de un componente, por ejemplo una resistencia, es mayor que al otro lado, la corriente eléctrica es capaz de fluir a través de dicho componente.

❏La intensidad de la corriente, o simplemente corriente (I), medida en amperios (A), es la magnitud del flujo de carga eléctrica. Para seguir con la analogía del agua, la corriente sería el propio movimiento (flujo) del agua (carga eléctrica) del depósito (mayor energía potencial) causado instantáneamente al abrir un grifo (con un potencial menor). Recuerde que el grifo también tiene potencial y que el agua fluirá hasta el desagüe de la pila a menos que esté al nivel del suelo (técnicamente, "tierra", ground o GND por sus siglas en inglés, empleadas en electricidad y electrónica). Para poner en contexto la intensidad de la corriente, cuando construimos circuitos para conectarlos a la cabecera GPIO del RPi, estos suelen manejar una intensidad drenaje-fuente de solo 3 mA (miliamperios, o la milésima parte de un Amperio).

❏La resistencia (R) se mide en ohmios (Ω, letra omega mayúscula) y mide la oposición que se enfrenta al paso de la corriente. Una resistencia es un componente discreto que reduce el flujo de corriente disipándola en forma de energía (en inglés esta energía no es energy sino power, de ahí la letra P de la ecuación siguiente). Esta disipación ocurre de forma lineal y se mide en watios (W). Su valor viene dado por la ecuación: P = V × I , o bien integrando la ley de Ohm: P = I2 R = V2 ⁄ R. La energía se disipa en forma de calor, y todas las resistencias tienen un rango máximo en su capacidad de disipar calor. Las resistencias más comunes de hojas metálicas o de carbón disipan entre 0,125 y 1 W, y su precio crece significativamente a medida que estos valores se aproximan a o superan los 3 W. Para finalizar con la analogía del agua, la resistencia sería la fricción entre el agua y la cañería, que ocasionaría un calentamiento y una reducción del flujo de líquido. La resistencia se puede incrementar aumentando la superficie por la que el agua debe circular mientras que la luz de la cañería se mantiene constante, por ejemplo situando pequeñas cañerías dentro de la principal.

Como ejemplo, si el lector debe comprar una resistencia que limite el flujo de corriente a 100 mA mientras usa una fuente de alimentación de 5 V, como se puede ver en la figura 4-2, ¿qué resistencia debería adquirir? La corriente atravesará la resistencia con un voltaje, VR, de 5 V puesto que es el único componente del circuito. Por la ley de Ohm sabemos que VR = IR × R, así que la resistencia valdrá R = VR ⁄ (IR = 5 V) ⁄ (100 mA) = 50 Ω. La energía disipada por la resistencia se puede calcular a partir de las ecuaciones generales P = VI = I 2 R = V 2 ⁄ R , y resulta ser de 0,5 W.


Figura 4-2: (a) Circuito de ejemplo para la ley de Ohm. (b) Ejemplo de divisor de voltaje.

Una resistencia de hojas metálicas, de valor fijo y de agujeros pasantes, con una tolerancia (precisión) del 1 %, cuesta 0,1 $ para una tasa de disipación (power rating) de 0,33 W, y 0,45 $ para 1 W. Debemos tener mucho cuidado con la tasa de disipación de las resistencias que utilizaremos en nuestros circuitos, puesto que las que no cumplan las especificaciones pueden explotar. Una resistencia de 30 W costará unos 2,5 $ y puede llegar a estar extremadamente caliente. Así pues, hay que tener presente que no todas las resistencias se fabrican igual.

ADVERTENCIA ¿Por qué no se debe conectar el electrodo positivo de una fuente de alimentación (voltaje) a su electrodo negativo sin interponer una resistencia? Porque se produciría un cortocircuito, que es la manera más rápida de dañar un dispositivo delicado como el RPi. Los cables de conexión son, por su propia naturaleza, buenos conductores de la electricidad y ofrecen muy poca resistencia. Un rollo de cable de 100 m y 0,6 mm de sección tiene una resistencia total de 5 Ω. Por lo tanto, conectar 15 cm de cable entre la alimentación de 3,3 V del RPi y su terminal GND (tierra) dejaría pasar teóricamente 433 A (I = V / R = 3,3 V / 0,0076 Ω). En la práctica, esto no ocurrirá, pero la corriente máxima disponible bastaría para dañar el RPi. Asimismo, recuerde que los LED carecen de una resistencia interna fija, de manera que se comportan en cierto modo como cortocircuitos cuando están conectados en polarización directa (forward-biased). Por este motivo, prácticamente siempre es necesario usar resistencias limitadoras de corriente con los LED.

División de voltaje

Si modificamos el circuito de la figura 4-2(a) añadiéndole otra resistencia en serie (véase la figura 4-2(b)), ¿qué le ocurriría?

❏Como las resistencias está colocadas en serie, una detrás de otra, la resistencia total a la corriente que fluye por el circuito es la suma de dos valores: RT = R1 + R2.

❏El voltaje debe caer a través de las dos resistencias, así que podemos decir que Valimentación = VR1 + VR2. El voltaje que cae a través de cada resistencia es inversamente proporcional al valor de la misma. Este circuito se llama divisor de tensión.

Supongamos que hay que calcular sobre el papel el voltaje en el punto X de la figura 4-2(b) si R1 = 25 Ω y R2 = 75 Ω. La resistencia total en el circuito es RT = 25 + 75 = 100 Ω, y la caída total de voltaje a través de las resistencias debe ser de 5 V. Por lo tanto, según la ley de Ohm, la corriente que fluye por el circuito es I = V / R = 5 V / 100 Ω = 50 mA. Si la resistencia de R1 es de 25 Ω, entonces la caída de voltaje a través de VR1 = I × R = 0,05 A × 25 Ω = 1,25 V, y a través de VR2 = I × R = 0,05 A × 75 Ω = 3,75 V. Es fácil ver que la suma de ambos voltajes da 5 V. Este resultado obedece a la ley de Kirchhoff, que indica que la suma de las caídas de voltaje en un circuito en serie es igual al total del voltaje aplicado al mismo.

Para responder completamente a la pregunta: en este circuito, el voltaje cae en 1,25 V a través de R1, y 3,75 V a través de R2. Así pues, ¿cuál es el voltaje en X? Para saberlo debemos medir X respecto a otro punto. Si medimos X respecto al electrodo negativo de la fuente de alimentación, la caída de voltaje es VX en la figura 4-2(b), y es la misma que la caída de voltaje a través de R2, es decir, 3,75 V. Sin embargo, sería igual de válido preguntarse cuál es el voltaje en X respecto del electrodo positivo. En ese caso sería el negativo de la caída de voltaje a través de R1 (como X está a 3,75 V respecto al polo negativo y el positivo está a +5 V respecto al negativo). Por lo tanto, el voltaje en X con respecto al polo positivo de la fuente de alimentación es de −1,25 V.

Para calcular el valor de VX en la figura 4-2(b), la regla del divisor de voltaje se puede generalizar del siguiente modo:


Podemos utilizarla para determinar un voltaje VX, pero desgraciadamente esta configuración es muy limitada en la práctica, puesto que muy probablemente el circuito al que conectemos esta fuente de alimentación, VX, tenga en sí mismo una resistencia (o carga). Esto alteraría la característica de nuestro circuito divisor de voltaje, modificando el voltaje en VX. Sin embargo, la mayoría de los circuitos divisores de voltaje suelen ser circuitos de entrada con impedancias de entrada muy grandes y, por tanto, con un mínimo impacto sobre VX.


Figura 4-3: (a) Varios potenciómetros y el esquema de un circuito que usa una fuente

de voltaje variable. (b) Un ejemplo de circuito divisor de corriente.

La figura 4-3(a) muestra una resistencia variable, o potenciómetro y un circuito asociado donde se utiliza como único divisor de voltaje. La resistencia entre los terminales, patas o pines, 1 y 3 es un valor fijo, 10 kΩ en el caso del potenciómetro multivuelta. Sin embargo, la resistencia entre el 3 y el 2 (terminal variable o wiper pin) va de 0 a 10 kΩ. Por tanto, si la resistencia entre los terminales 2 y 3 es de 2 kΩ, la resistencia entre el 1 y el 2 será de 10 kΩ-2 kΩ = 8 kΩ. En tal caso, el voltaje de salida, Vout, será de 1 V y se podrá variar entre 0 y 5 V girando el pequeño tornillo del potenciómetro con una herramienta adecuada.

División de corriente

Si el circuito se modifica como en la figura 4-3(b) y se introducen dos resistencias en paralelo, obtenemos un divisor de corriente. La corriente eléctrica seguirá el camino que le ofrezca menos resistencia; así, si R1 = 100 Ω y R2 = 200 Ω, una mayor proporción de corriente atravesará R1. ¿Cuánta, exactamente? En este caso, la caída de voltaje a través de R1 y R2 es de 5 V en ambos casos. Por tanto, la corriente I1 será I = V / R = 5 V / 100 Ω = 50 mA, y la corriente I2, I = 5 V / 200 Ω = 25 mA. Así pues, por la resistencia de 100 Ω pasa el doble de corriente que por la de 200 Ω. Claramente, la corriente prefiere el camino de menor resistencia.

La ley de Kirchhoff de la corriente establece que la suma de las corrientes a la entrada de un nodo es igual a la suma de las corrientes a la salida del mismo. Esto significa que IS = I1 + I2 = 25 mA + 50 mA = 75 mA. La regla del divisor de corriente se puede expresar de modo general como sigue:

y

Sin embargo, esto requiere que conozcamos el valor de la corriente I (IS en este caso) que llega al nodo. Para calcular IS directamente, debemos calcular la resistencia equivalente (RT) de dos resistencias en paralelo, del siguiente modo:

o

Esto da 66,66 Ω en la figura 4-3(b). Por lo tanto, IS = V / R = 5 V / 66,66 Ω = 75 mA, que resulta consistente con los cálculos iniciales.

La potencia suministrada por la fuente: P = VI = 5 V × 0,075 A = 0.375 W. El resultado sería igual a la suma de la potencia disipada por R1 = V2 / R = 52 / 100 = 0,25 W y R2 = V2 / R = 52 / 200 = 0,125 W, lo que da un total de 0,375 W. Esto confirma la ley de la conservación de la energía.

Cómo implementar circuitos del RPi en una placa de pruebas

La placa de pruebas es una plataforma magnífica para el prototipado de circuitos y funciona perfectamente con el RPi. La figura 4-4 muestra una placa de pruebas

y describe cómo podemos utilizar los dos buses de potencia horizontales con 3,3 y 5 V. La cabecera GPIO del RPi está formada por pines macho, lo que significa que, normalmente, necesitaremos conectores hembra relativamente caros para cablear los circuitos. Hay disponibles numerosas placas de extensión del RPi GPIO, como la Adafruit Pi T-Cobbler Plus, que podemos ver en la figura 4-4, para la conexión de placas de pruebas. Resuelven el problema de tener que unir los conectores machos del RPi usando cables hembra con jumper, proporcionan una conexión muy estable y nos permiten usar cable de conexión de bajo coste en nuestros circuitos. Debemos extremar la precaución a la hora de conectar al RPi el extremo correspondiente del cable de una placa de extensión GPIO porque, como no están polarizados, es fácil conectarlos al revés.

Una placa de pruebas de buena calidad como la de la figura 4-4, con 830 conectores, cuesta entre 6 y 10 $. Las placas de pruebas gigantes, de hasta 3.220 conectores, cuestan unos 20 $. Veamos algunos consejos para el uso de la placa de pruebas:

❏Siempre que sea posible, sitúe la patilla 1 de sus circuitos integrados (Integrated Circuits, o IC) en la parte inferior izquierda para que le sea más fácil depurar los circuitos. Tenga cuidado de alinear siempre con sumo cuidado las patillas con los agujeros de la placa de pruebas antes de presionar para colocar las patillas (normalmente se escucha un clic característico). Asimismo, no olvide que los circuitos integrados necesitan electricidad.

❏Como veremos más adelante en este capítulo, dejar un cable desconectado no es lo mismo que conectarlo a tierra (GND).

❏Utilice un destornillador plano para sacar lentamente los circuitos integrados de la placa de pruebas haciendo palanca, poco a poco, por ambos extremos. De este modo evitaremos doblar las patillas.

❏Tenga cuidado de no puentear resistencias y otros componentes electrónicos situando dos de sus patillas en el mismo conector. Asimismo, conviene recortar los terminales de las resistencias antes de conectarlas a la placa, ya que unos terminales largos podrían tocarse accidentalmente y darnos problemas durante la depuración del circuito.

❏Los pulsadores, o interruptores momentáneos, suelen tener cuatro patillas, conectadas en dos pares. Debe asegurarse de orientarlas correctamente (utilice un test de continuidad en el multímetro digital).

❏Las grapas funcionan perfectamente como puentes de conexión.

❏Ciertas placas tienen una discontinuidad en los buses de potencia, puentéelos si fuera necesario.

❏Las placas de pruebas presentan un espaciado entre contactos (lead pitch) típico de 2,54 mm (0,1 pulgadas en medida inglesa). Intente comprar todos los componentes y conectores con dicho espaciado. En el caso de los circuitos integrados, elija del tipo DIP/PDIP (su código IC acaba con una N) y, para otros componentes, elija la forma de agujero pasante.

❏Utilice el color del cable de conexión de manera significativa, por ejemplo: el color rojo para 5 V y el negro para tierra (GND). Mantener esta coherencia puede resultar de gran ayuda durante la depuración. El cable de un hilo con una sección de 0,33 mm cuadrados (22 AWG, American Wire Gauge) resulta un cable de conexión perfecto y está disponible con aislante de distintos colores. Se puede adquirir cable puente preformado, pero unos cables muy largos producen circuitos embrollados. Una variedad de cable de conexión de diferentes colores junto con una herramienta pelacables de buena calidad hacen posible crear los diseños más claros y estables en la placa de pruebas.


Figura 4-4: La placa de pruebas con una placa de extensión para la cabecera GPIO del RPi

y un circuito integrado 7408 (cuatro puertas AND de dos entradas).


Multímetros digitales (DMM) y placas de pruebas

Las mediciones de voltaje, corriente y resistencia son bastante fáciles y directas cuando tenemos en cuenta ciertas reglas (véase la figura 4-6):

❏El voltaje de corriente continua (DCV por sus siglas en inglés), se mide en paralelo, es decir, a través del componente que experimenta la caída de voltaje. El medidor debe tener la sonda de color negro en la entrada COM (common, común) del multímetro digital.

❏La intensidad de la corriente continua (DCA por sus siglas en inglés) se mide en serie. Así, tendremos que "romper" la conexión en nuestro circuito y cablear el multímetro digital como si fuera un componente en serie con el conductor del circuito en el que la estemos midiendo. Utilice la sonda negra en la entrada COM, y la roja, en la entrada μAmA o equivalente. No utilice la entrada sin fusible de 10 A.

❏La resistencia (resistance) no se puede medir normalmente sobre el circuito, puesto que otras resistencias y componentes actuarían como cargas en paralelo o en serie influyendo en la medida. Aísle el componente, ponga la sonda roja del multímetro digital en la entrada VΩ y configure el medidor para la medición de Ω (ohmios). La prueba de continuidad se puede utilizar de forma razonablemente efectiva sobre el circuito, siempre que se haya drenado la energía.


Figura 4-6: Medición de voltaje, corriente y resistencia.

Si el multímetro digital no funciona, puede que hayamos fundido el fusible interno. Desconecte las sondas del multímetro digital y abra el medidor para ver el pequeño fusible de cristal. Si tenemos un segundo medidor, podremos realizar una prueba de continuidad para determinar si lo hemos fundido o no. Sustitúyalo por otro del mismo valor.

ADVERTENCIA La medición directa de la corriente a través de una fuente de voltaje sin carga, aunque solo sea una pila de 9 V, es la forma más rápida de fundir el fusible del multímetro digital, puesto que la mayoría están limitados a 200 mA. Compruebe que la sonda esté en la entrada VΩ antes de medir el voltaje.

Circuito de ejemplo: regulación de voltaje

Ahora que conocemos los principios básicos, vamos a analizar un circuito más complejo. Luego, examinaremos sus componentes con todo detalle. No debe el lector construir el circuito expuesto en esta sección, puesto que solo se muestra con el objeto de presentar el concepto de componentes interconectados.

Un regulador de voltaje es un dispositivo complejo pero fácil de usar que admite varios voltajes de entrada y facilita un voltaje constante por la salida, prácticamente con independencia de la carga conectada, inferior al de entrada. Este dispositivo mantiene constante el voltaje de salida dentro de un rango de tolerancia definido y evita las variaciones que pudieran dañar a los dispositivos electrónicos conectados.

Los modelos RPi B+ y RPi 2/3 poseen un convertidor DC-DC reductor PWM (Pulse-Width Modulation, modulación por ancho de pulsos) (PAM2306 en U3, vea tiny.cc/erpi402) que puede suministrar diferentes niveles fijos de voltaje a los componentes de la placa, junto con protección frente a cortocircuitos. Por ejemplo, hay salidas de 5, 3,3 y 1,8 V. Podemos usar las salidas de 5 y 3,3 V como fuentes de alimentación para los circuitos conectados a la cabecera GPIO del RPi, pero solo dentro de ciertos límites de intensidad de corriente. El RPi puede suministrar hasta 200-300 mA en las patillas de 5 V (números 2 y 4) y aproximadamente 50 mA en las de 3,3 V (números 1 y 17).

Si se precisasen mayores corrientes para aplicaciones como control de motores, podríamos tener que usar reguladores de voltaje como el de la figura 4-7. Es posible construirlo directamente en una placa de pruebas, o bien comprar una placa de pruebas "breadboard power supply stick 5 V/3,3 V" directamente de SparkFun (www.sparkfun.com) por unos 15 $.


Figura 4-7: El regulador de voltaje KA7805A/LM7805 y un ejemplo de circuito regulador de voltaje.

Como se puede ver en la figura 4-7, la patilla izquierda del regulador es la entrada de voltaje. Cuando suministra una corriente de 500 mA, el regulador de voltaje KA7805/LM7805 aceptará un voltaje de entrada de entre 8 y 20 V, y producirá un voltaje de salida (por la derecha) de entre 4,8 y 5,3 V. La patilla central debería conectarse al bus de tierra. La placa de aluminio de la parte posterior del regulador de voltaje actúa como disipador de calor. El agujero nos permite atornillar un disipador de mayores dimensiones y, así, trabajar con corrientes mayores de hasta 1 A.

El voltaje mínimo requerido para el KA7805/LM7805 es de 8 V. Si la fuente de voltaje no lo alcanza, podemos usar un regulador de voltaje de tipo LDO (Low Drop-Out) que puede funcionar con una fuente de voltaje tan baja como 6 V para operar un regulador de 5 V. El circuito de implementación de la figura 4-7 incluye los siguientes componentes adicionales, que le permiten proporcionar una fuente de voltaje limpia y estable de 5 V y una corriente de 1 A:

❏El diodo garantiza la protección del circuito si conectamos la fuente con la polaridad cambiada (si, por ejemplo, intercambiamos la conexión de 9 V y la de tierra, GND). Diodos como el 1N4001 (de 1 A) son muy baratos, pero tienen el inconveniente de ocasionar una pequeña caída de voltaje (aproximadamente 1 V con 1 A) antes del regulador.

❏El interruptor sirve para conectar y desconectar el circuito de la corriente. Un interruptor deslizante permite la alimentación continua del circuito.

❏El fusible rearmable PTC (Positive Temperature Coefficient, coeficiente de temperatura positivo) resulta muy útil para evitar daños por elevación de la corriente, como cortocircuitos accidentales o fallos en componentes. El PTC permite el paso de una corriente de mantenimiento con solo una mínima resistencia (sobre 0,25 Ω), pero, una vez se excede una corriente de desconexión o de disparo, la resistencia se incrementa rápidamente, y el dispositivo se comporta como un interruptor automático. Cuando se quite la corriente, el PTC se enfriará durante unos segundos y recobrará sus características anteriores al disparo. En este circuito sería recomendable usar un Polyfuse 60R110 o equivalente, ya que tiene una corriente de mantenimiento de 1,1 A y una corriente de disparo de 2,2 A, con un voltaje máximo de 60 V en corriente continua.

❏El condensador de 0,33 µF se encuentra en el lado de la alimentación del regulador, y el de 0,1 µF, en la salida. Estos son los valores que la hoja de datos recomienda para eliminar el ruido (ripple rejection, rechazo de rizado) de la fuente de alimentación. Los condensadores se analizan en breve.

❏El diodo LED y una resistencia limitadora de corriente adecuada proporcionan una luz indicadora que deja claro cuándo está alimentado el circuito.

NOTA Existen dos notaciones principales para indicar el sentido del flujo de la corriente eléctrica: La primera y real es la corriente de flujo de electrones, que tienen carga negativa, del electrodo negativo al electrodo positivo. La segunda es la corriente convencional y va precisamente en sentido contrario, del electrodo positivo al negativo: representa el flujo de carga positiva y es consistente con todos los símbolos empleados en los semiconductores. En este libro se emplea la notación de corriente convencional para indicar el sentido del flujo de la corriente.

Componentes discretos

En el ejemplo anterior se han usado varios componentes discretos para construir un único circuito alimentador de electricidad. En esta sección, los tipos de componentes que configuran el circuito serán analizados con más detalle. Cada uno de ellos se puede aplicar a diseños de circuitos muy diferentes, y es importante que los analicemos en este momento porque usaremos muchos de ellos en nuestros circuitos para el conector de entrada/salida del RPi.

Diodos

En pocas palabras, un diodo es un componente semiconductor discreto que permite que la corriente pase en una dirección, pero no en la otra. Como su nombre sugiere, un semiconductor ni es un conductor ni es un aislante. El silicio es un material semiconductor, pero resulta mucho más interesante cuando se lo dopa con impurezas como el fósforo. Ese dopaje de tipo negativo (n-type) o de tipo N resulta en un electrón débilmente ligado en la banda de valencia. El dopaje también puede ser positivo (p-type) o de tipo P, lo que dejaría un agujero en la banda de valencia, cuando se usan impurezas como el boro. Cuando unimos silicio con dopaje de tipo P y de tipo N en un pequeño bloque, obtenemos un diodo de unión PN. Los electrones libres de la banda de valencia del silicio de tipo N fluyen hacia el silicio de tipo P creando una zona desierta, capa de deplexión o capa de vaciado, y una barrera de potencial (voltaje) que se debe sobrepasar para que la corriente pueda fluir.

Cuando un diodo está conectado con polarización directa permite que la corriente fluya a través de él, mas cuando la polarización está invertida, la corriente no fluye. Un diodo tiene polarización directa cuando el voltaje en el ánodo o electrodo positivo (+ve) es mayor que en el cátodo o electrodo negativo (−ve). No obstante, la polarización debe también superar la barrera de potencial de la capa de deplexión (tensión de umbral) antes de que la corriente pueda fluir, lo que suele pasar entre 0,5 y 0,7 V en un diodo de silicio. Si se invierte la polarización del diodo aplicando un voltaje superior en el cátodo que en el ánodo, no podrá circular prácticamente corriente alguna (tal vez 1 nA). Sin embargo, si el voltaje de la polarización inversa se va incrementando, el diodo acabará por dejar pasar el flujo de corriente en sentido contrario (diodo de ruptura o de avalancha, que es un diodo de corriente inversa para un cierto valor de la polarización). Si la corriente es pequeña, no dañará el diodo; de hecho, existe un tipo de diodo especial, llamado diodo Zener, diseñado para operar en esta región de ruptura y que se puede configurar para comportarse igual que un regulador de voltaje.

El 1N4001 es un diodo de silicio de bajo coste que se puede utilizar en un circuito sencillo (véase la figura 4-8) para demostrar el uso y comportamiento de los diodos. El 1N4001 tiene un voltaje máximo de ruptura de polarización inversa de 50 V. En este circuito se aplica una onda senoidal que oscila entre +5 V y -5 V, mediante el generador de formas de onda del Analog Discovery. Cuando el voltaje Vin sea positivo y exceda la tensión de umbral, la corriente fluirá y se producirá una caída de tensión a través de la resistencia de carga, Vload, que es ligeramente inferior que Vin. Hay una pequeña caída de voltaje a través del diodo Vd, unos 0,67 V según la medición del osciloscopio, que está dentro del rango esperado para un diodo de silicio.


Figura 4-8: Circuito y comportamiento de un diodo 1N4001 con una resistencia de carga

de 1 kΩ y una fuente de alimentación de corriente alterna de 5 V.

El diodo se usa en el circuito de la figura 4-7 como una protección de polaridad inversa. Su eficacia debería quedar clara a partir de gráfica de la figura 4-8, porque, cuando Vin es negativo, el voltaje Vload es cero. Esto ocurre porque la corriente no puede fluir a través del diodo cuando tiene invertida la polaridad. Si el voltaje excede la tensión de ruptura del diodo, la corriente fluirá, pero como para el 1N4001 es de 50 V, eso no ocurrirá en este caso. En la esquina inferior derecha de la figura 4-8 se muestra una gráfica XY con los voltajes: el de salida en el eje y y el de entrada en el eje x. Se puede ver que, para un voltaje de entrada negativo, el de salida es igual a 0, pero una vez que se llega a la tensión de umbral (0,67 V), el voltaje de salida crece de forma lineal con el de entrada. Este circuito se llama rectificador de media onda. Se pueden conectar cuatro diodos en configuración de puente para crear un rectificador de onda completa.

Diodos emisores de luz (LED)

Un diodo emisor de luz (Light-Emitting Diode, LED por sus siglas en inglés) es una fuente de luz realizada con material semiconductor que se emplea a menudo como indicador de estado en todo tipo de dispositivos. En la actualidad, los LED de alta potencia se usan como faros en los coches, en las pantallas retroiluminadas de las televisiones y, últimamente, también como sustitutos de las bombillas tradicionales y de bajo consumo, sobre todo por su longevidad y extrema eficiencia a la hora de convertir la electricidad en luz. Los LED nos proporcionan información de estado muy útil sobre nuestros circuitos, incluida la necesaria para depurarlos. A menudo los usamos para saber si un estado es verdadero o falso.

Como diodos que son, los LED tienen polaridad. El símbolo de un LED se muestra en la figura 4-9. Para que un LED emita luz, el diodo debe estar conectado en polarización directa, es decir, con el ánodo (+) en una fuente más positiva que el cátodo (-). Por ejemplo, el ánodo podría conectarse a +3,3 V y el cátodo a tierra (GND). Sin embargo, hay que recordar también que el mismo efecto se conseguiría conectando el ánodo a 0 V y el cátodo a una fuente negativa de -3,3 V.

La figura 4-9 muestra un LED que tiene una patilla más larga que la otra. La más larga es el ánodo (+), y la más corta, el cátodo (-). La camisa de plástico que rodea el LED tiene, asimismo, un lado plano que indica igualmente cuál es la patilla del ánodo (-). Esta indicación resulta particularmente útil para identificar el ánodo si se le han recortado las patillas.


Figura 4-9: Ejemplo de diodo LED y de un circuito para controlar un LED con

unos niveles apropiados de voltaje y corriente con polaridad directa.

Los LED tienen ciertos requisitos operativos que vienen determinados por una tensión o voltaje directo y una corriente con polaridad directa. Cada LED es diferente, así que necesitaremos sus hojas de especificaciones como referencia para determinar dichos valores. Un LED no ofrece resistencia significativa, así que, si conectáramos el LED directamente a la fuente de 3,3 V del RPi, se produciría un cortocircuito y derivaríamos una gran cantidad de corriente a través del LED, de manera que lo dañaríamos a él y al RPi. Por lo tanto, para operar un LED necesitamos una resistencia en serie, llamada resistencia limitadora de corriente. Elegiremos este valor cuidadosamente para maximizar la producción de luz del LED y para proteger el circuito.

ADVERTENCIA No conecte ningún LED directamente a la cabecera GPIO del RPi sin usar resistencias limitadoras de corriente y/o transistores interruptores, ya que probablemente dañaría la placa. La corriente máxima que el RPi puede manejar en una patilla de la cabecera GPIO debería mantenerse por debajo de 2-3 mA.

Refiriéndonos a la figura 4-9, si el LED recibe 3,3 V desde el RPi y deseamos una caída de voltaje directo de 1,3 V a través de dicho LED, necesitamos que los 2 V de diferencia caigan a través de la resistencia limitadora de corriente. Las especificaciones del LED nos exigen limitar la corriente a 9 mA, así que debemos calcular un valor para la resistencia limitadora de corriente de la siguiente forma:

como V = IR, entonces R = V / I = 2 V / 0,009 A = 222 Ω.

Por tanto, un circuito para encender un LED quedaría como el de la figura 4-9. Allí hemos situado una resistencia de 220 Ω en serie con el LED. La combinación de una fuente de 3,3 V y la resistencia dirige una corriente de 9 mA a través del LED colocado en polarización directa. Como con esta corriente la resistencia tiene una caída de 2 V, el LED produce a su vez una caída de voltaje directo de 1,3 V. Observamos que esta corriente está bien si la tomamos de la salida de 3,3 V del RPi, pero no se puede usar con la cabecera GPIO del RPi porque la máxima corriente que podemos esperar desde una patilla del RPi está entre 2 y 3 mA. En breve veremos cómo solucionar esto, y también otra vez en el capítulo 6.

También merece la pena comentar que no deberíamos oscurecer un LED reduciendo el voltaje que lo atraviesa. Deberíamos considerar un LED como un dispositivo controlado por la corriente, la cual hace que el voltaje directo caiga cuando lo atraviesa. Por tanto, intentar controlar un LED mediante un voltaje variable podría no funcionar como esperamos. Para oscurecer un LED podríamos utilizar una señal con modulación por ancho de pulsos, o PWM, que básicamente apaga y enciende el LED con gran rapidez. Por ejemplo, si aplicamos una señal PWM rápida al LED, que haga que se encienda y se apague alternativamente la mitad del tiempo, entonces parecerá que solo está emitiendo la mitad de la luz de la que sería capaz en sus condiciones operativas habituales. Nuestros ojos no perciben los cambios cuando la frecuencia es lo bastante alta y el cerebro promedia los destellos de manera que percibimos una luz constante pero menos brillante.

La figura 4-10 muestra una señal PWM con forma de onda cuadrada en diferentes ciclos de trabajo. El ciclo de trabajo es el porcentaje del tiempo que la señal está en el punto más alto frente al tiempo que está en el punto más bajo. En este ejemplo, el nivel alto está representado por un voltaje de 3,3 V y el punto más bajo se sitúa en 0 V. Un ciclo de trabajo del 0% significa que la señal está constantemente en el punto más bajo, y un ciclo de trabajo del 100%, que está constantemente en el punto más alto.


Figura 4-10: Ciclos de trabajo de señales con modulación por ancho de pulsos (PWM).

Las señales PWM se pueden usar para controlar el nivel de luz que emite un LED, pero también para controlar la velocidad de los motores de corriente continua, la posición de los servomotores y otras muchas aplicaciones. Veremos un ejemplo de esto en el capítulo 6 cuando usemos la funcionalidad PWM integrada en el RPi.

El periodo, T, de una señal que se repite, es decir, de una señal periódica, es el tiempo que emplea en completar un ciclo. En el ejemplo de la figura 4-10, el periodo de la señal en los tres casos es de 4 ms. La frecuencia de una señal periódica, f, es la magnitud inversa del periodo y expresa la cantidad de ciclos que se completan en un tiempo dado. Es decir, una señal cuyo periodo sea de 4 ms completará 250 ciclos en un segundo (1/0,004), o lo que es lo mismo: su frecuencia será de 250 Hz (hercios). Podemos afirmar que f (Hz) = 1/T (s), y viceversa, que T (s) = 1/f (Hz). Algunos multímetros digitales de gama alta pueden medir la frecuencia, pero en general se utilizan osciloscopios para ello. Las señales PWM deben oscilar a la frecuencia adecuada para el dispositivo que se vaya a controlar. En el caso de los motores, la frecuencia suele estar en el rango de los KHz.

Condensadores de filtro o aplanamiento y de desconexión

Un condensador es un componente eléctrico pasivo que permite almacenar energía eléctrica entre dos placas aisladas cuando existe una diferencia de potencial entre ellas. La energía se guarda en un campo eléctrico entre ambas placas, donde la carga positiva se va incrementando en una, y la negativa, en la otra. Cuando se elimina o reduce la diferencia de voltaje, el condensador descarga su energía en el circuito al que esté conectado.

Por ejemplo, si modificamos el circuito del diodo que tenemos en la figura 4-8 para añadir un condensador de aplanamiento o condensador de filtro de 10 μF en paralelo con la resistencia de carga, el voltaje de salida aparecería como en la figura 4-11. Cuando el conectamos el diodo con polarización directa hay un potencial a través de los terminales del condensador, que se carga rápidamente, mientras que la corriente también fluye en paralelo a través de la resistencia de carga. Cuando conectamos el diodo con polarización inversa, no hay fuente externa generando potencial a través de la combinación condensador-resistencia, así que el potencial a través de los terminales del condensador, a causa de su carga, provoca un flujo de corriente a través de la resistencia de carga y el condensador comienza a descargarse. El efecto de este cambio es que la tensión es ahora más estable a través de la resistencia de carga, que varía entre 2,758 y 4,222 V (el voltaje de ondulación es de 1,464 V) en lugar de entre 0 y 4,34 V.


Figura 4-11: Circuito y comportamiento de un diodo 1N4001 con una resistencia de carga de 1 kΩ, una fuente de alimentación de corriente alterna de 5 V y un condensador de 10 μF en paralelo.

Los condensadores utilizan un material dieléctrico (aislante) cerámico, de cristal, papel o plástico para aislar las dos placas cargadas. Los dos tipos comunes de condensador son el cerámico y el electrolítico. Los condensadores cerámicos son pequeños y de bajo coste, y se degradan con el paso del tiempo. Por su parte, los condensadores electrolíticos pueden almacenar cargas mucho mayores, pero también se degradan con el paso del tiempo. Los condensadores de cristal, mica y tantalio suelen ofrecer mayor fiabilidad, pero son considerablemente más caros.

La figura 4-12 ilustra un condensador cerámico de 100 nF (0,1 μF) y un condensador electrolítico de 47 μF. Observe que el condensador electrolítico tiene polaridad, con el conector negativo marcado en la superficie del condensador con una banda que señala la patilla más corta, que, al igual que en el caso del LED, es la del cátodo.


Figura 4-12: Condensadores cerámico (sin polaridad) y electrolítico (con polaridad)

y un ejemplo de circuito desacoplador.

La numeración de los condensadores es razonablemente sencilla; por desgracia, en los condensadores cerámicos puede ser muy pequeña y difícil de leer:

❏El primer número es el primer dígito del valor del condensador.

❏El segundo número es el segundo dígito del valor del condensador.

❏El tercer número expresa la cantidad de ceros que siguen a los dos anteriores cuando el valor del condensador está expresado en pF (picofaradios).

❏Letras adicionales representan la tolerancia y el rango de la tensión nominal del condensador, pero las podemos ignorar por el momento.

Por tanto, tenemos:

❏104 = 100000 pF = 100 nF = 0,1 µF

❏102 = 1,000 pF = 1 nF

❏472 = 4,700 pF = 4,7 nF

El circuito regulador de voltaje presentado anteriormente (véase la figura 4-7) utilizaba dos condensadores para filtrar o aplanar los rizos (fluctuaciones) en la fuente de alimentación cargándose y descargándose en oposición a dichas fluctuaciones. Los condensadores se pueden usar también para una función relacionada conocida como decoupling o desacoplamiento.

El acoplamiento o acople es una relación, a menudo indeseable, que ocurre entre dos partes de un circuito debido a que comparten conexiones con la fuente de alimentación. Esta relación ocasiona que, si se presenta una gran demanda de potencia por una parte del circuito, el voltaje de la fuente de alimentación caerá levemente, lo que afectará a la tensión de otras partes del circuito. Los circuitos integrados transmiten una carga variable en las líneas de alimentación (potencia). De hecho, una carga que pueda variar muy rápidamente ocasiona una variación de voltaje de alta frecuencia en las líneas de alimentación de otros circuitos integrados. A medida que el número de circuitos integrados aumenta, el problema se agrava.

Unos pequeños condensadores, llamados condensadores de desacoplamiento, pueden actuar como almacenes de energía que eliminen las señales de ruido que pudieran estar presentes en las líneas de alimentación como resultado de las variaciones de carga transmitidas por los circuitos integrados. El circuito de ejemplo de la figura 4-12 muestra dos condensadores. El más grande, 47 μF, filtra las variaciones de baja frecuencia, y el de 0,1 μF, el ruido de más alta frecuencia. Idealmente, las patillas del condensador de 0,1 μF deberían ser lo más cortas posible para evitar efectos no deseados, relacionados con la inductancia, que impedirían que llegase a filtrar las frecuencias más altas. Hasta los pequeños condensadores de superficie usados en el RPi para desacoplar las patillas del montaje BGA (Ball Grid Array, matriz de rejilla de bolas) en el BCM2835/6/7 SoC producen pequeñas inductancias (1-2 nH).

Transistores

Los transistores están en el núcleo mismo del microprocesador del RPi, como también en casi cualquier otro sistema electrónico. En pocas palabras, su función puede consistir en amplificar una señal, encenderla o apagarla según sea necesario. La cabecera GPIO del RPi solo puede manejar corrientes muy modestas, así que necesitamos transistores que nos ayuden en la comunicación con circuitos electrónicos que requieran grandes corrientes para operar.

Los transistores BJT (Bipolar Junction Transistor, transistor de unión bipolar) o transistores bipolares se construyen añadiendo una nueva capa dopada a un diodo de unión PN. De este modo formamos, o bien una unión PNP (Positive-Negative-Positive, positiva-negativa-positiva) Hay otros tipos de transistores, como los FET (Field-Efect Transistor, transitor de efecto campo), que veremos en breve. El nombre "bipolar" surge del hecho físico de que tanto los electrones como los agujeros en la banda de valencia transportan corriente. Tienen tres terminales, el tercero de los cuales se conecta a la banda central del dispositivo, que es muy fina como podemos ver en la figura 4-13.

La figura 4-13 está repleta de información sobre los transistores; por ejemplo, la nomenclatura de los terminales: base (B), colector (C) y emisor (E). Aunque haya dos tipos de transistores BJT, NPN y PNP, el más utilizado en la práctica es el NPN. De hecho, cualquier ejemplo del uso de transistores en este capítulo usa un transistor NPN BC547.


Figura 4-13: Transistores de unión bipolar (BJT).

El BC547 es un transistor barato de 45 V y 100 mA de propósito general que suele estar disponible en un encapsulado TO-92 con patillas. La figura 4-13 muestra la identificación de cada patilla del BC547, pero debemos tener muy en cuenta que este orden no es consistente con todos los transistores; sin ir más lejos, la patilla del colector está a la izquierda, así que siempre debemos consultar la hoja de especificaciones. El voltaje máximo VCE (también expresado como VCEO) es de 45 V, y la corriente máxima en el colector (IC) es de 100 mA, para el BC547. Tiene una ganancia típica de corriente continua (hFE) de entre 180 y 520, dependiendo del grupo del modelo usado (A, B o C). Estas características se explican con más profundidad en las secciones siguientes.

Utilización de transistores como conmutadores

NOTA En lo que queda de libro, se utilizarán transistores FET en lugar de BJT en los circuitos conmutadores de carga para el RPi. Si el lector se siente abrumado por la cantidad de detalles de esta sección, puede pasar sin miedo a la que trata de los transistores FET, que son un poco más fáciles de aplicar.

The free sample has ended.

Genres and tags

Age restriction:
0+
Release date on Litres:
03 March 2025
Volume:
1066 p. 295 illustrations
ISBN:
9788426727800
Publishers:
Copyright Holder::
Bookwire
Download format:

Similar books