Skip to content

Instantly share code, notes, and snippets.

@sirwolfgang
Last active January 2, 2026 20:35
Show Gist options
  • Select an option

  • Save sirwolfgang/b3f4ca1c20f6f2dfffbe5abe798feba9 to your computer and use it in GitHub Desktop.

Select an option

Save sirwolfgang/b3f4ca1c20f6f2dfffbe5abe798feba9 to your computer and use it in GitHub Desktop.
Radxa Cubie A7A hardware control scripts and systemd services (fan control, CPU LED, power button)
[Unit]
Description=CPU Activity LED
After=multi-user.target
[Service]
Type=simple
ExecStart=/usr/local/bin/cpu-led.sh
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
#!/bin/bash
# Blink LED based on CPU activity - faster blinks = higher load
set -euo pipefail
LED="/sys/class/leds/radxa:blue:user/brightness"
# Verify LED device exists
if [[ ! -w "$LED" ]]; then
echo "ERROR: LED device not found or not writable: $LED" >&2
exit 1
fi
PREV_IDLE=0
PREV_TOTAL=0
while true; do
# Read CPU stats
read -r cpu user nice system idle iowait irq softirq _ < /proc/stat
TOTAL=$((user + nice + system + idle + iowait + irq + softirq))
IDLE=$idle
# Calculate usage since last sample
DIFF_IDLE=$((IDLE - PREV_IDLE))
DIFF_TOTAL=$((TOTAL - PREV_TOTAL))
if [ $DIFF_TOTAL -gt 0 ]; then
USAGE=$((100 * (DIFF_TOTAL - DIFF_IDLE) / DIFF_TOTAL))
else
USAGE=0
fi
PREV_IDLE=$IDLE
PREV_TOTAL=$TOTAL
# Blink pattern based on load (higher load = more on time)
if [ $USAGE -gt 5 ]; then
echo 1 > $LED
# On time proportional to load (10-100ms)
sleep $(awk "BEGIN {printf \"%.2f\", $USAGE / 1000 + 0.01}")
echo 0 > $LED
# Off time inversely proportional (faster blinks at high load)
sleep $(awk "BEGIN {printf \"%.2f\", (100 - $USAGE) / 1000 + 0.02}")
else
# Idle: LED off, slow poll
echo 0 > $LED
sleep 0.2
fi
done
[Unit]
Description=Fan Control Service
After=multi-user.target
[Service]
Type=simple
ExecStart=/usr/local/bin/fan-control.sh
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
#!/bin/bash
# Fan control based on maximum junction temperature across all zones
# A733 specs: Tj max recommended 115°C, absolute 125°C
set -euo pipefail
COOLING_DEVICE="/sys/class/thermal/cooling_device2/cur_state"
# Verify cooling device exists
if [[ ! -w "$COOLING_DEVICE" ]]; then
echo "ERROR: Cooling device not found or not writable: $COOLING_DEVICE" >&2
exit 1
fi
# Thermal zones to monitor (CPU, GPU, NPU, DDR)
ZONES=(
"/sys/class/thermal/thermal_zone0/temp" # cpul
"/sys/class/thermal/thermal_zone1/temp" # cpub
"/sys/class/thermal/thermal_zone4/temp" # gpu
"/sys/class/thermal/thermal_zone5/temp" # npu
"/sys/class/thermal/thermal_zone6/temp" # ddr
)
# Temperature thresholds (millidegrees Celsius)
# Kernel throttle points: 70°C (throttle), 90°C (heavy), 110°C (crit/shutdown)
# Fan curve is aggressive to prevent throttling
TEMP_OFF=45000 # Below 45°C: fan off
TEMP_LOW=55000 # 45-55°C: state 1 (low) - stay ahead of throttle
TEMP_MED=65000 # 55-65°C: state 2 (medium) - before 70°C throttle
TEMP_HIGH=75000 # 65-75°C: state 3 (high) - throttle mitigation
# Above 75°C: state 4 (max) - well before 90°C heavy throttle
get_max_temp() {
local max=0
for zone in "${ZONES[@]}"; do
temp=$(cat "$zone" 2>/dev/null || echo 0)
if [ "$temp" -gt "$max" ]; then
max=$temp
fi
done
echo $max
}
while true; do
TEMP=$(get_max_temp)
if [ "$TEMP" -lt "$TEMP_OFF" ]; then
STATE=0
elif [ "$TEMP" -lt "$TEMP_LOW" ]; then
STATE=1
elif [ "$TEMP" -lt "$TEMP_MED" ]; then
STATE=2
elif [ "$TEMP" -lt "$TEMP_HIGH" ]; then
STATE=3
else
STATE=4
fi
echo $STATE > $COOLING_DEVICE
sleep 5
done
event=button/power.*
action=/etc/acpi/power-button.sh %e
#!/bin/bash
# Power button = graceful reboot
# For shutdown, use SSH: sudo shutdown -h now
logger "Power button pressed - rebooting"
/sbin/shutdown -r now

Radxa Cubie A7A Hardware Control Scripts

Scripts and systemd services for fan control, CPU activity LED, and power button handling on the Radxa Cubie A7A.

Fan Control

Temperature-based fan speed control monitoring CPU, GPU, NPU, and DDR thermal zones.

  1. Copy files to the system:
sudo cp fan-control.sh /usr/local/bin/fan-control.sh
sudo chmod 755 /usr/local/bin/fan-control.sh
sudo cp fan-control.service /etc/systemd/system/fan-control.service
  1. Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable fan-control.service
sudo systemctl start fan-control.service
  1. Verify:
systemctl status fan-control.service
cat /sys/class/thermal/cooling_device2/cur_state

CPU Activity LED

Blinks the blue user LED based on real CPU utilization (faster blinks = higher load).

  1. Set LED to manual control:
sudo sh -c 'echo none > /sys/class/leds/radxa:blue:user/trigger'
  1. Copy files to the system:
sudo cp cpu-led.sh /usr/local/bin/cpu-led.sh
sudo chmod 755 /usr/local/bin/cpu-led.sh
sudo cp cpu-led.service /etc/systemd/system/cpu-led.service
  1. Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable cpu-led.service
sudo systemctl start cpu-led.service
  1. Verify:
systemctl status cpu-led.service

Power Button (Reboot on Press)

By default, systemd-logind handles the power button and will shut down the system. These instructions configure acpid to handle the power button instead, triggering a graceful reboot.

  1. Install acpid:
sudo apt install -y acpid
  1. Tell systemd-logind to ignore the power button:
sudo sed -i 's/#HandlePowerKey=.*/HandlePowerKey=ignore/' /etc/systemd/logind.conf
grep -q "^HandlePowerKey" /etc/systemd/logind.conf || echo "HandlePowerKey=ignore" | sudo tee -a /etc/systemd/logind.conf
sudo systemctl restart systemd-logind
  1. Copy files to the system:
sudo cp power-button.sh /etc/acpi/power-button.sh
sudo chmod 755 /etc/acpi/power-button.sh
sudo cp power-button-event /etc/acpi/events/power-button
  1. Enable and restart acpid:
sudo systemctl enable acpid
sudo systemctl restart acpid
  1. Test by pressing the power button - system should reboot (not shutdown).

Note: To shutdown instead of reboot, use SSH: sudo shutdown -h now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment