Created
December 19, 2020 20:11
-
-
Save jigpu/71fe9205dc2b465a6b7fc35c13cf06c5 to your computer and use it in GitHub Desktop.
Raspberry Pi Bluetooth Watchdog / Reset
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Force a reset of the Bluetooth interface if it freezes up. | |
# | |
# https://github.com/raspberrypi/linux/issues/2832#issuecomment-597001597 | |
if test $(id -u) -ne 0; then | |
echo "This script must be run as root." | |
exit 1 | |
fi | |
killall hciattach | |
sleep 2 | |
if grep -a Zero /proc/device-tree/model; then | |
raspi-gpio set 45 op dl | |
sleep 1 | |
raspi-gpio set 45 op dh | |
else | |
/opt/vc/bin/vcmailbox 0x38041 8 8 128 0 | |
sleep 1 | |
/opt/vc/bin/vcmailbox 0x38041 8 8 128 1 | |
fi | |
sleep 4 | |
btuart |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Unit] | |
Description=Montor and reset the Bluetooth interface if it dies | |
[Service] | |
Type=simple | |
ExecStart=/usr/local/bin/btwatchdog.sh | |
[Install] | |
WantedBy=multi-user.target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Monitor the Bluetooth clock for hiccups. If we see it act | |
# strangely (e.g. get stuck at 0 or jump by a large amount) | |
# for some reason, trigger a reset | |
# | |
# Relies on the presence of /usr/local/bin/btreset.sh | |
# May be run as a systemd service with btwatchdog.service | |
function gettime { | |
printf "%d\n" $(hcitool clock | awk '/Clock/{print $2}') | |
} | |
function difftime { | |
CLOCK_MAXIMUM=536870912 | |
OLD=$1 | |
NEW=$2 | |
DELTA=$((${2} - ${1})) | |
if [[ ${DELTA} -lt 0 ]]; then | |
DELTA=$((${DELTA} + ${CLOCK_MAXIMUM})) | |
fi | |
echo ${DELTA} | |
} | |
function clock2sec { | |
CLOCK_RATE=3200 | |
TIME=$1 | |
echo $((${TIME} / ${CLOCK_RATE})) | |
} | |
SLEEP_SECONDS=10 | |
FAIL_COUNT=0 | |
TIME_NOW=$(gettime) | |
while true; do | |
sleep ${SLEEP_SECONDS} | |
TIME_OLD=${TIME_NOW} | |
# Check how much time elapsed on the BT clock | |
TIME_NOW=$(gettime) | |
DELTA_T=$(difftime "${TIME_OLD}" "${TIME_NOW}") | |
DELTA_S=$(clock2sec "${DELTA_T}") | |
# If no time passed, something is wrong... | |
if [[ "${DELTA_S}" -eq 0 || "${DELTA_S}" -gt $((2*${SLEEP_SECONDS})) ]]; then | |
FAIL_COUNT=$((${FAIL_COUNT} + 1)) | |
echo "Encountered failure ${FAIL_COUNT}" | |
elif [[ "${FAIL_COUNT}" -gt 0 ]]; then | |
echo "Clock started back up. Resetting failure count." | |
FAIL_COUNT=0 | |
fi | |
# If we keep hitting failures, just reset the | |
# device and hope it fixes itself. | |
if [[ "${FAIL_COUNT}" -ge 5 ]]; then | |
echo "Resetting device." | |
/usr/local/bin/btreset.sh | |
FAIL_COUNT=0 | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment