-
Notifications
You must be signed in to change notification settings - Fork 5
/
dfu.bash
executable file
·134 lines (111 loc) · 3.87 KB
/
dfu.bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/bin/bash
# dfu-util setup script
# Used for flashing firmware on dfu-enabled devices
# Expected exported variables
# FIRMWARE - Path to firmware image to flash (flash)
# DEVICE - Device attempting to flash
# DFU_NAME - Name of the DFU Bootloader
# USB_BOOT_ID - <vendor id>:<product id> of DFU Bootloader
# USB_ID - <vendor id>:<product id> of flashed device
# GITREV - Git Commit revision of firmware to flash
DEVICE_GLOB="/dev/ttyACM*"
# Convenience debug/error checker
debug() {
# Error occurred, show debug
if [ "$RETVAL" -ne "0" ]; then
echo ""
# Debug info
echo "FIRMWARE: '$FIRMWARE'"
echo "DEVICE: '$DEVICE'"
echo "DFU_NAME: '$DFU_NAME'"
echo "USB_BOOT_ID: '$USB_BOOT_ID'"
echo "USB_ID: '$USB_ID'"
echo "GITREV: '$GITREV'"
echo "CWD: '$(pwd)'"
exit $RETVAL
fi
}
# Find actual directory of this script and enter it
ORIG_PATH=$(pwd)
FIRMWARE=${ORIG_PATH}/${FIRMWARE}
cd "$(dirname $(realpath "$0"))"
# Check to make sure there are valid USB IDs to use dfu-util
lsusb -d $USB_BOOT_ID
RETVAL=$?
if [ "$RETVAL" -ne "0" ]; then
echo "ERROR: Could not find '$USB_BOOT_ID'. Check device USB cable. Might be a soldering issue."
fi
debug
# Query dfu-util for flash-ready devices
# TODO Enhance dfu-util to handle matching devices by devnum
# TODO Enhance dfu-util to ignore status (don't wait if specified)
dfu-util -l | grep "Found DFU:" | while read -r LINE; do
echo "$LINE"
# Extract USB ID, Bootloader Name and Serial
USBID=$(echo $LINE | sed -e 's/^.*\[\(.*\)\].*$/\1/')
NAME=$(echo $LINE | sed -e 's/^.*name="\([^"]\+\)".*$/\1/')
SERIAL=$(echo $LINE | sed -e 's/^.*serial="[^"]\+ - \([^"]\+\)".*$/\1/')
DEVNUM=$(echo $LINE | sed -e 's/^.*devnum=\([^,]\+\).*$/\1/')
# Compare Expected Name, Serial, and USB Boot IDs
if [ "$NAME" != "$DFU_NAME" ]; then echo "INVALID NAME: '$DFU_NAME' != '$NAME'"; continue; fi
if [ "$DEVICE" != "$SERIAL" ]; then echo "INVALID DEVICE: '$SERIAL' != '$DEVICE'"; continue; fi
if [ "$USBID" != "$USB_BOOT_ID" ]; then echo "INVALID USBID: '$USB_BOOT_ID' != '$USBID'"; continue; fi
echo "Flashing devnum $DEVNUM"
dfu-util --device $USB_BOOT_ID --download $FIRMWARE
break
done
# Wait for USB to initialize
sleep 2.5
# Check to see if USB device successfully initialized
lsusb -d $USB_ID
RETVAL=$?
if [ "$RETVAL" -ne "0" ]; then
echo "ERROR: Could not find '$USB_ID'"
fi
debug
# First scan for any fully flashed devices
DEVICES=$(ls $DEVICE_GLOB)
TMPFILE=/tmp/acmtemp
RETVAL=1 # Assume failed, unless proven otherwise
for DEV in $DEVICES; do
# TODO screen has elevated permissions, not handled here
# Check if any other programs owns the file/device and kill them
for PID in $(lsof -t $DEV); do
echo "Killing -> $PID"
kill $PID
done
# Before doing anything to the tty, make sure it has nice settings
stty -F $DEV -icrnl -imaxbel -opost -onlcr -isig -icanon -echo
# Prepare polling
# Device has a very small buffer, must start polling before sending anything
cat $DEV > $TMPFILE &
READPID=$!
sleep 0.01
# Send dummy commands to clean out buffer
printf "\r" > $DEV
# Query version information
sleep 0.01
printf "version\r" > $DEV
sleep 0.01
# Finished polling serial port
kill $READPID
# Read chip ID and git revision
CHIP=$(cat /tmp/acmtemp | sed -r "s:\x1B\[[0-9;]*[mK]::g" | grep Chip: | grep -o "[a-zA-Z0-9]*" | grep -v Chip)
REVISION=$(cat /tmp/acmtemp | sed -r "s:\x1B\[[0-9;]*[mK]::g" | grep Revision: | grep -o "[a-zA-Z0-9]*" | grep -v Revision)
# Ignore Invalid Chips
if [ "$DEVICE" != "$CHIP" ]; then continue; fi
# Check git revision
if [ "$REVISION" != "$GITREV" ]; then
echo "ERROR: Git Revision ($REVISION) does not match expected ($GITREV)"
fi
# Successful flash
RETVAL=0
break
done
if [ "$RETVAL" -ne "0" ]; then
echo "ERROR: Could not find any DFU devices to flash'"
fi
debug
# Complete
echo "$FIRMWARE - $GITREV - $DEVICE was successfully flashed to $USB_ID"
exit $RETVAL