Skip to content

Commit 47ec58d

Browse files
committed
dist/tools/openocd: fix parsing of flash bank base
Since 80fc9fabc66a0bc767467fa14c703e5a9f340cd3 the format of the `flash list` command changed to a more human readable multi-line variant. Technically, the change is white-space only. Still, the current approach of parsing them with awk, sed and cut doesn't like the new multi-line format. The parsing is now delegated into a python script that is compatible across OpenOCD versions.
1 parent 2327d74 commit 47ec58d

2 files changed

Lines changed: 75 additions & 63 deletions

File tree

dist/tools/openocd/openocd.sh

Lines changed: 6 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -195,42 +195,7 @@ _is_binfile() {
195195
[[ -z "${firmware_type}" ]] && _has_bin_extension "${firmware}"; }
196196
}
197197

198-
# Split bank info on different lines without the '{}'
199-
_split_banks() {
200-
# Input:
201-
# ...
202-
# {name nrf51 base 0 size 0 bus_width 1 chip_width 1} {name nrf51 base 268439552 size 0 bus_width 1 chip_width 1}
203-
# ...
204-
# or for newer openocd versions (v0.12.0 or higher)
205-
# ...
206-
# {name nrf51.flash driver nrf51 base 0 size 0 bus_width 1 chip_width 1 target nrf51.cpu} {name nrf51.uicr ...}
207-
# ...
208-
#
209-
# Output:
210-
# ...
211-
# name nrf51 base 0 size 0 bus_width 1 chip_width 1
212-
# name nrf51 base 268439552 size 0 bus_width 1 chip_width 1
213-
# ...
214-
# or for newer openocd versions (v0.12.0 or higher)
215-
# ...
216-
# name nrf51.flash driver nrf51 base 0 size 0 bus_width 1 chip_width 1 target nrf51.cpu
217-
# name nrf51.uicr driver nrf51 base 268439552 size 0 bus_width 1 chip_width 1 target nrf51.cpu
218-
# ...
219-
#
220-
# The following command needs specific osx handling (non gnu):
221-
# * Same commands for a pattern should be on different lines
222-
# * Cannot use '\n' in the replacement string
223-
local sed_escaped_newline=\\$'\n'
224-
225-
sed -n '
226-
/^{.*}$/ {
227-
s/\} /\}'"${sed_escaped_newline}"'/g
228-
s/[{}]//g
229-
p
230-
}'
231-
}
232-
233-
_flash_list_raw() {
198+
_flash_list() {
234199
# Openocd output for 'flash list' is either
235200
# ....
236201
# {name nrf51 base 0 size 0 bus_width 1 chip_width 1} {name nrf51 base 268439552 size 0 bus_width 1 chip_width 1}
@@ -272,32 +237,10 @@ _flash_list_raw() {
272237
-c 'shutdown'" 2>&1
273238
}
274239

275-
# Outputs bank info on different lines without the '{}'
276-
_flash_list() {
277-
# ....
278-
# name nrf51 base 0 size 0 bus_width 1 chip_width 1
279-
# name nrf51 base 268439552 size 0 bus_width 1 chip_width 1
280-
# ....
281-
# or for newer openocd versions (v0.12.0 or higher)
282-
# ....
283-
# name nrf51.flash driver nrf51 base 0 size 0 bus_width 1 chip_width 1 target nrf51.cpu
284-
# name nrf51.uicr driver nrf51 base 268439552 size 0 bus_width 1 chip_width 1 target nrf51.cpu
285-
# ....
286-
_flash_list_raw | _split_banks
287-
}
288-
289-
# Print flash address for 'bank_num' num defaults to 1
290-
# _flash_address [bank_num:1]
240+
# Print flash address for 'bank_num' num defaults to 0
241+
# _flash_address [bank_num:0]
291242
_flash_address() {
292-
# extract the line from '_flash_list' output for bank with number 'bank_num'
293-
bank=$(_flash_list | awk "NR==${1:-1}")
294-
# determine the column of base address, a line can have following formats
295-
# name nrf51 base 268439552 size 0 bus_width 1 chip_width 1
296-
# or for newer openocd versions (v0.12.0 or higher)
297-
# name nrf51.flash driver nrf51 base 0 size 0 bus_width 1 chip_width 1 target nrf51.cpu
298-
base_addr_idx=$(echo ${bank} | awk '{ for (i=1; i <= NF; i++) if ($i == "base") print i + 1 }')
299-
# extract the base address in hexadecimal format
300-
printf 0x"%08x" $(echo ${bank} | cut -d " " -f${base_addr_idx})
243+
_flash_list | "${RIOTTOOLS}/openocd/openocd_flashinfo.py" --idx "${1:-0}"
301244
}
302245

303246
do_flashr() {
@@ -317,7 +260,7 @@ do_flashr() {
317260
# This allows flashing normal binary files without env configuration
318261
if _is_binfile "${IMAGE_FILE}" "${IMAGE_TYPE}"; then
319262
# hardwritten to use the first bank
320-
FLASH_ADDR=$(_flash_address 1)
263+
FLASH_ADDR=$(_flash_address 0)
321264
echo "Binfile detected, adding ROM base address: ${FLASH_ADDR}"
322265
IMAGE_TYPE=bin
323266
IMAGE_OFFSET=$(printf "0x%08x\n" "$((${IMAGE_OFFSET} + ${FLASH_ADDR}))")
@@ -366,7 +309,7 @@ do_flash() {
366309
# This allows flashing normal binary files without env configuration
367310
if _is_binfile "${IMAGE_FILE}" "${IMAGE_TYPE}"; then
368311
# hardwritten to use the first bank
369-
FLASH_ADDR=$(_flash_address 1)
312+
FLASH_ADDR=$(_flash_address 0)
370313
echo "Binfile detected, adding ROM base address: ${FLASH_ADDR}"
371314
IMAGE_TYPE=bin
372315
IMAGE_OFFSET=$(printf "0x%08x\n" "$((${IMAGE_OFFSET} + ${FLASH_ADDR}))")
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Utility to parse the output of OpenOCD's "flash list" command
4+
"""
5+
import argparse
6+
import sys
7+
8+
NUMERIC_FIELDS = {"base", "size", "bus_width", "chip_width"}
9+
10+
11+
def parse_flash_info(lines):
12+
"""
13+
Read output of OpenOCD's "flash list" command given in lines into a list
14+
of dictionaries
15+
16+
:param lines: Output of "flash list" lines
17+
18+
:return: [{"name": "nrf52.flash", "base": 0, ...},
19+
{"name": "nrf52.uicr", ...}, ...]
20+
"""
21+
tokens = []
22+
for line in lines:
23+
for word in line.split():
24+
if word.startswith('{') and len(word) > 1:
25+
tokens += ["{", word[1:]]
26+
elif word.endswith('}') and len(word) > 1:
27+
tokens += [word[:-1], "}"]
28+
else:
29+
tokens.append(word)
30+
31+
idx = 0
32+
result = []
33+
while idx < len(tokens):
34+
entry = {}
35+
while idx < len(tokens) and tokens[idx] != "{":
36+
idx += 1
37+
idx += 1
38+
while idx < len(tokens) and tokens[idx] != "}":
39+
if idx + 1 >= len(tokens) or tokens[idx + 1] == "}":
40+
break
41+
key = tokens[idx]
42+
value = tokens[idx + 1]
43+
if key in NUMERIC_FIELDS:
44+
value = int(value, 0)
45+
entry[key] = value
46+
idx += 2
47+
if idx < len(tokens) and tokens[idx] == "}":
48+
result.append(entry)
49+
50+
return result
51+
52+
53+
if __name__ == "__main__":
54+
parser = argparse.ArgumentParser(
55+
description="Parse OpenOCD's \"flash list\" output")
56+
parser.add_argument("--field", default="base", type=str,
57+
help="Field to extract (default \"base\")")
58+
parser.add_argument("--idx", default=0, type=int,
59+
help="Index of the bank to extract info from " +
60+
"(default 0)")
61+
args = parser.parse_args()
62+
info = parse_flash_info(sys.stdin)
63+
if args.idx < 0 or args.idx >= len(info):
64+
sys.exit("flash bank index out of range")
65+
value = info[args.idx][args.field]
66+
if args.field in NUMERIC_FIELDS:
67+
print(f"0x{value:08x}")
68+
else:
69+
print(value)

0 commit comments

Comments
 (0)