sábado, 12 de enero de 2019

Datos, datos y mas datos....

La Raspberry Pi depende de como se use puede calentar bastante, por eso los modelos mas recientes vienen con unos pequeños disipadores para colocar sobre la CPU/GPU y el dispositivo periférico  BCM2835En algunos usos se necesita incluso agregar algún dispositivo soplador para proveer refrigeración adicional. No es raro, además, que mientras se está trabajando normalmente con cualquier GUI X-Windows (lxterminal por ejemplo), aparezca un ícono de un termómetro (sobre-temperatura), o uno como un pequeño rayo (voltaje bajo). La estrategia de gestión de la placa hace que ante eventos de esa naturaleza se intente generar mejores condiciones de funcionamiento mediante bajar la velocidad de los dispositivos (si, disminuir la frecuencia del clock). Cuando tenemos una placa funcionando permanentemente queda la duda sobre si ocurren estos eventos, que tan severos son y con que frecuencia o patrón aparecen. La mejor solución es registrar en el log (del sistema o del programa, yo prefiero del programa) datos de "telemetría" periódicos, tales como temperatura, clock del procesador o tensión. Lo interesante es como medirlo.
Viene en nuestro auxilio un comando disponible en la Raspberry Pi llamado vcgencmd el cual tiene por propósito gestionar distintos aspectos del firmware. Antes que nada es necesario transmitir algo de cautela. Se trata de un comando en el que la mayoría de las opciones no está documentado que hacen, y no son siempre funciones de "lectura", las hay también funciones que operan sobre el hardware modificando la configuración. Algunos incluso el nombre meten "dudita" sobre que tan beneficioso puede ser ejecutarlos.
Por fortuna hay unas pocas opciones del comando que si se sabe que hacen, y son muy útiles.
Para empezar, el comando se ejecuta con vcgencmd operador [argumento] el operador es siempre requerido, el argumento en ocasiones no es necesario, en otras tiene un default y en oportunidades es mandatorio dependiendo del operador. El operador "commands" (vcgencmd commands) produce un listado de todos los operadores soportados, luce como

commands="vcos, ap_output_control, ap_output_post_processing, vchi_test_init, vchi_test_exit, vctest_memmap, vctest_start, vctest_stop, vctest_set, vctest_get, pm_set_policy, pm_get_status, pm_show_stats, pm_start_logging, pm_stop_logging, version, commands, set_vll_dir, set_backlight, set_logging, get_lcd_info, arbiter, cache_flush, otp_dump, test_result, codec_enabled, get_camera, get_mem, measure_clock, measure_volts, scaling_kernel, scaling_sharpness, get_hvs_asserts, get_throttled, measure_temp, get_config, hdmi_ntsc_freqs, hdmi_adjust_clock, hdmi_status_show, hvs_update_fields, pwm_speedup, force_audio, hdmi_stream_channels, hdmi_channel_map, display_power, read_ring_osc, memtest, dispmanx_list, get_rsts, schmoo, render_bar, disk_notify, inuse_notify, sus_suspend, sus_status, sus_is_enabled, sus_stop_test_thread, egl_platform_switch, mem_validate, mem_oom, mem_reloc_stats, hdmi_cvt, hdmi_timings, file"

Lo que es, como corresponde, un poco intimidante. Por ejemplo vcgencmd display_power 0 apaga el video de la placa, vcgencmd display_power 1 lo vuelve a prender. Los operadores que son interesantes con propósito de registro y telemetría son:

vcgencmd measure_clock arm
vcgencmd measure_temp
vcgencmd measure_volts
vcgencmd get_throttled

Que sirven respectivamente para medir el clock, la temperatura del chip, el voltaje (del chip, no de la fuente) y si hay alguna condición que empuje la restricción del clock y cual es.
De esa manera, periódicamente podemos grabar en el log esta información, y luego revisarla para ver en que condiciones ha estado operando el dispositivo, y si hay que hacer algo. Por ejemplo, en el beacon en funcionamiento continuo emitiendo cada 10 minutos el clock es el nominal, la tensión se mantiene estable en 1.2-1.3V, no se observan casi nunca eventos de restricción de performance (get_throttled dá 0x00) y la temperatura oscila entre 45-52 °C dependiendo de la temperatura ambiente y el ciclo de trabajo (suele subir entre 1 °C y 2 °C durante los 2 minutos que está transmitiendo el beacon. He observado alguna ocasión que la temperatura subió a casi 70 °C pero sin mostrar restricción de performance por ello.
Para interpretar los valores de get_throttled debe revisarse la documentación disponible (aqui entre otros), pero un resumen de los posibles valores distintos de 0x00 y su significado es:

bit 0: under-voltage (0xX0001)
bit 1: arm frequency capped (0xX0002 or 0xX0003 with under-voltage)
bit 2: currently throttled (0xX0004 or 0xX0005 with under-voltage)

bit 16: under-voltage has occurred (0x1000X)
bit 17: arm frequency capped has occurred (0x2000X or 0x3000X also under-voltage occurred)
bit 18: throttling has occurred (0x4000X or 0x5000X also under-voltage occurred)

La condición de tensión baja se dá cuando la fuente externa entrega menos de 4.63V y se empieza a gestionar el clock cuando la temperatura excede los 80 ºC, cuando la temperatura excede 85 ºC empieza a marcarse que es excesiva.
La lectura se puede hacer con un simple script en Python (por ejempo picheck.py es el que uso) e integrar fácilmente con otro script que esté manejando el beacon pues la salida es entregada en stdout mediante una función en (por ejemplo) bash.

getTelemetry () {
   TEMP=`sudo python picheck.py -t`
   VOLT=`sudo python picheck.py -v`
   OPST=`sudo python picheck.py -s`
   FREQ=`sudo python picheck.py -f`
   echo "Whisper: "`date`" Telemetry: "$TEMP" °C "$VOLT" V "$FREQ" MHz ("$OPST")" | tee -a $DPATH$TLM
   CMD="python wsprtlm.py -g "$GRID$GRIX" -e "$HEIGHT" -c "$CHANNEL" -b "$VOLT" -t "$TEMP" -l -q -p"  
   TLMG=`$CMD`
   echo "Whisper: "`date`" WSPR TLMF: "$TLMG  
   return 0
}

El log termina teniendo registros que lucen como:

Whisper: vie ene 11 21:31:05 -03 2019 Telemetry: 48.2 °C 1.3125 V 900000000 MHz (Normal operation)
Whisper: vie ene 11 21:32:04 -03 2019 Telemetry: 48.7 °C 1.3125 V 900000000 MHz (Normal operation)
Whisper: vie ene 11 21:33:04 -03 2019 Telemetry: 48.7 °C 1.3125 V 900000000 MHz (Normal operation)

Usando ésta información podemos ir haciendo cambios para refrigerar mejor la placa, por ejemplo, o ponerle una fuente de mayor capacidad. Es improbable que una operación razonable dañe la placa, que por cierto es bastante robusta. Pero lo que en realidad se quiere preservar es que el firmware no recurra a hacer mas lento el clock para gestionar un problema de temperatura o de tensión.
Si tenemos la placa visible en la red con puertos abiertos en el router y la podemos acceder desde Internet, cosa que no siempre se puede hacer pero es muy útil cuando se puede, seguramente nos encontraremos a nosotros mismos tirando de tanto en tanto un

cat whisper.log | grep "Telemetry: " 

Para pegarle una mirada rápida a como van las cosas y si hay algún evento raro, se deja para el lector el ejercicio de hacer que el beacon nos mande un correo si pasa algo raro. Beacon saludable, ¡operador contento!