🛠 Surveiller la thermique et les fréquences big.LITTLE
Objetivos
Establecer una monitorización seria del S922X big.LITTLE (4× Cortex-A73 + 2× Cortex-A53): frecuencias reales por núcleo, temperaturas de las zonas térmicas y detección del throttling. Contexto: el N2 (Rev-B, 1,8 GHz) sufría throttling bajo carga sostenida; el N2+ (Rev-C) mantiene 2,4 GHz sin ventilador con una temperatura ambiente de 35 °C, y el ventilador se activa alrededor de los 65 °C. Los mantenedores de Armbian recomiendan el governor «performance» para evitar bloqueos aleatorios tras más de 24 horas (inestabilidad cpufreq/OPP).
Material
- ODROID-N2/N2+ con Armbian, disipador instalado (¡el SoC está debajo de la placa!)
stress-ngpara la carga:sudo apt install stress-ng- Ventilador de 2 pines opcional (kit dependiente) >
Código completo
#!/usr/bin/env python3
"""thermal_watch.py — fréquences + températures S922X, alerte throttling."""
import glob, time, subprocess
CPU = "/sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq" # kHz
MAXF = "/sys/devices/system/cpu/cpu*/cpufreq/scaling_max_freq"
ZONE = "/sys/class/thermal/thermal_zone*/temp" # milli-°C
# Ordonné : cpu0-3 = A73 (max 2400 MHz N2+ / 1800 N2), cpu4-5 = A53 (2016/1900)
def read(path): return int(open(path).read.strip)
while True:
freqs = [read(p) // 1000 for p in sorted(CPU and glob.glob(CPU),
key=lambda s: int(s.split("cpu")[1].split("/")[0]))]
maxs = [read(p) // 1000 for p in sorted(glob.glob(MAXF),
key=lambda s: int(s.split("cpu")[1].split("/")[0]))]
temps = [read(p) / 1000 for p in glob.glob(ZONE)]
hot = [t for t in temps if t > 75]
throttled = any(f < m * 0.9 for f, m in zip(freqs, maxs))
print(f"{time.strftime('%H:%M:%S')} MHz={freqs} "
f"°C={[round(t,1) for t in temps]} "
f"{'THROTTLING!' if throttled else ''}{' HOT!' if hot else ''}")
time.sleep(2)
# Lancer en parallèle : stress-ng --cpu 6 --cpu-method matrixprod
Verificación esperada
lscpu -e confirma 6 CPU (los A53 cpu4/cpu5 deben estar en línea — algunas imágenes del fabricante con kernel 4.9 los dejaban fuera de línea). En reposo: 1,6–1,8 W y frecuencias bajas (governor ondemand) o máximas (performance). Bajo estrés matrixprod: N2 ≈ 5,2 W, N2+ ≈ 6 W; el script debe mostrar los A73 limitados a 1800 MHz (N2) o 2400 MHz (N2+) sin caídas sostenidas con un disipador correcto (≤ 74–80 °C medidos por CNX). cat /sys/class/thermal/thermal_zone*/type nombra las zonas (soc_thermal, etc.).
Errores frecuentes
- Leer scaling_cur_freq de un solo núcleo y sacar conclusiones: el big.LITTLE migra las tareas; monitoriza los 6 núcleos.
- Usar el governor powersave/conservador y creer que es un defecto: cambia a
performance(cpupower frequency-set -g performance), recomendado por Armbian contra los bloqueos > 24 h. - Ignorar las zonas térmicas: no todas las thermal_zone* corresponden al SoC; verifica
typeantes de lanzar alertas. - Monitorizar con el dedo: el disipador está DEBAJO de la placa, la sensación táctil es engañosa y puede quemar.
- Olvidar la diferencia entre N2/N2+: los límites OPP son diferentes (1800/1900 vs 2400/2016 MHz), no diagnostiques un falso throttling.
- >
Otros tutoriales para esta placa
Ejemplos de código para esta placa
clignotante.pyPythonbouton-gpio.pyPythoncapteur-i2c.shBashsurveillance-temperature.shBashcapteur-dht11.pyPythonservo-pwm-sysfs.shBash