mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
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.
This commit is contained in:
parent
2327d74d24
commit
47ec58dc9b
69
dist/tools/openocd/openocd.sh
vendored
69
dist/tools/openocd/openocd.sh
vendored
@ -195,42 +195,7 @@ _is_binfile() {
|
||||
[[ -z "${firmware_type}" ]] && _has_bin_extension "${firmware}"; }
|
||||
}
|
||||
|
||||
# Split bank info on different lines without the '{}'
|
||||
_split_banks() {
|
||||
# Input:
|
||||
# ...
|
||||
# {name nrf51 base 0 size 0 bus_width 1 chip_width 1} {name nrf51 base 268439552 size 0 bus_width 1 chip_width 1}
|
||||
# ...
|
||||
# or for newer openocd versions (v0.12.0 or higher)
|
||||
# ...
|
||||
# {name nrf51.flash driver nrf51 base 0 size 0 bus_width 1 chip_width 1 target nrf51.cpu} {name nrf51.uicr ...}
|
||||
# ...
|
||||
#
|
||||
# Output:
|
||||
# ...
|
||||
# name nrf51 base 0 size 0 bus_width 1 chip_width 1
|
||||
# name nrf51 base 268439552 size 0 bus_width 1 chip_width 1
|
||||
# ...
|
||||
# or for newer openocd versions (v0.12.0 or higher)
|
||||
# ...
|
||||
# name nrf51.flash driver nrf51 base 0 size 0 bus_width 1 chip_width 1 target nrf51.cpu
|
||||
# name nrf51.uicr driver nrf51 base 268439552 size 0 bus_width 1 chip_width 1 target nrf51.cpu
|
||||
# ...
|
||||
#
|
||||
# The following command needs specific osx handling (non gnu):
|
||||
# * Same commands for a pattern should be on different lines
|
||||
# * Cannot use '\n' in the replacement string
|
||||
local sed_escaped_newline=\\$'\n'
|
||||
|
||||
sed -n '
|
||||
/^{.*}$/ {
|
||||
s/\} /\}'"${sed_escaped_newline}"'/g
|
||||
s/[{}]//g
|
||||
p
|
||||
}'
|
||||
}
|
||||
|
||||
_flash_list_raw() {
|
||||
_flash_list() {
|
||||
# Openocd output for 'flash list' is either
|
||||
# ....
|
||||
# {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() {
|
||||
-c 'shutdown'" 2>&1
|
||||
}
|
||||
|
||||
# Outputs bank info on different lines without the '{}'
|
||||
_flash_list() {
|
||||
# ....
|
||||
# name nrf51 base 0 size 0 bus_width 1 chip_width 1
|
||||
# name nrf51 base 268439552 size 0 bus_width 1 chip_width 1
|
||||
# ....
|
||||
# or for newer openocd versions (v0.12.0 or higher)
|
||||
# ....
|
||||
# name nrf51.flash driver nrf51 base 0 size 0 bus_width 1 chip_width 1 target nrf51.cpu
|
||||
# name nrf51.uicr driver nrf51 base 268439552 size 0 bus_width 1 chip_width 1 target nrf51.cpu
|
||||
# ....
|
||||
_flash_list_raw | _split_banks
|
||||
}
|
||||
|
||||
# Print flash address for 'bank_num' num defaults to 1
|
||||
# _flash_address [bank_num:1]
|
||||
# Print flash address for 'bank_num' num defaults to 0
|
||||
# _flash_address [bank_num:0]
|
||||
_flash_address() {
|
||||
# extract the line from '_flash_list' output for bank with number 'bank_num'
|
||||
bank=$(_flash_list | awk "NR==${1:-1}")
|
||||
# determine the column of base address, a line can have following formats
|
||||
# name nrf51 base 268439552 size 0 bus_width 1 chip_width 1
|
||||
# or for newer openocd versions (v0.12.0 or higher)
|
||||
# name nrf51.flash driver nrf51 base 0 size 0 bus_width 1 chip_width 1 target nrf51.cpu
|
||||
base_addr_idx=$(echo ${bank} | awk '{ for (i=1; i <= NF; i++) if ($i == "base") print i + 1 }')
|
||||
# extract the base address in hexadecimal format
|
||||
printf 0x"%08x" $(echo ${bank} | cut -d " " -f${base_addr_idx})
|
||||
_flash_list | "${RIOTTOOLS}/openocd/openocd_flashinfo.py" --idx "${1:-0}"
|
||||
}
|
||||
|
||||
do_flashr() {
|
||||
@ -317,7 +260,7 @@ do_flashr() {
|
||||
# This allows flashing normal binary files without env configuration
|
||||
if _is_binfile "${IMAGE_FILE}" "${IMAGE_TYPE}"; then
|
||||
# hardwritten to use the first bank
|
||||
FLASH_ADDR=$(_flash_address 1)
|
||||
FLASH_ADDR=$(_flash_address 0)
|
||||
echo "Binfile detected, adding ROM base address: ${FLASH_ADDR}"
|
||||
IMAGE_TYPE=bin
|
||||
IMAGE_OFFSET=$(printf "0x%08x\n" "$((${IMAGE_OFFSET} + ${FLASH_ADDR}))")
|
||||
@ -366,7 +309,7 @@ do_flash() {
|
||||
# This allows flashing normal binary files without env configuration
|
||||
if _is_binfile "${IMAGE_FILE}" "${IMAGE_TYPE}"; then
|
||||
# hardwritten to use the first bank
|
||||
FLASH_ADDR=$(_flash_address 1)
|
||||
FLASH_ADDR=$(_flash_address 0)
|
||||
echo "Binfile detected, adding ROM base address: ${FLASH_ADDR}"
|
||||
IMAGE_TYPE=bin
|
||||
IMAGE_OFFSET=$(printf "0x%08x\n" "$((${IMAGE_OFFSET} + ${FLASH_ADDR}))")
|
||||
|
69
dist/tools/openocd/openocd_flashinfo.py
vendored
Executable file
69
dist/tools/openocd/openocd_flashinfo.py
vendored
Executable file
@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Utility to parse the output of OpenOCD's "flash list" command
|
||||
"""
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
NUMERIC_FIELDS = {"base", "size", "bus_width", "chip_width"}
|
||||
|
||||
|
||||
def parse_flash_info(lines):
|
||||
"""
|
||||
Read output of OpenOCD's "flash list" command given in lines into a list
|
||||
of dictionaries
|
||||
|
||||
:param lines: Output of "flash list" lines
|
||||
|
||||
:return: [{"name": "nrf52.flash", "base": 0, ...},
|
||||
{"name": "nrf52.uicr", ...}, ...]
|
||||
"""
|
||||
tokens = []
|
||||
for line in lines:
|
||||
for word in line.split():
|
||||
if word.startswith('{') and len(word) > 1:
|
||||
tokens += ["{", word[1:]]
|
||||
elif word.endswith('}') and len(word) > 1:
|
||||
tokens += [word[:-1], "}"]
|
||||
else:
|
||||
tokens.append(word)
|
||||
|
||||
idx = 0
|
||||
result = []
|
||||
while idx < len(tokens):
|
||||
entry = {}
|
||||
while idx < len(tokens) and tokens[idx] != "{":
|
||||
idx += 1
|
||||
idx += 1
|
||||
while idx < len(tokens) and tokens[idx] != "}":
|
||||
if idx + 1 >= len(tokens) or tokens[idx + 1] == "}":
|
||||
break
|
||||
key = tokens[idx]
|
||||
value = tokens[idx + 1]
|
||||
if key in NUMERIC_FIELDS:
|
||||
value = int(value, 0)
|
||||
entry[key] = value
|
||||
idx += 2
|
||||
if idx < len(tokens) and tokens[idx] == "}":
|
||||
result.append(entry)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Parse OpenOCD's \"flash list\" output")
|
||||
parser.add_argument("--field", default="base", type=str,
|
||||
help="Field to extract (default \"base\")")
|
||||
parser.add_argument("--idx", default=0, type=int,
|
||||
help="Index of the bank to extract info from " +
|
||||
"(default 0)")
|
||||
args = parser.parse_args()
|
||||
info = parse_flash_info(sys.stdin)
|
||||
if args.idx < 0 or args.idx >= len(info):
|
||||
sys.exit("flash bank index out of range")
|
||||
value = info[args.idx][args.field]
|
||||
if args.field in NUMERIC_FIELDS:
|
||||
print(f"0x{value:08x}")
|
||||
else:
|
||||
print(value)
|
Loading…
Reference in New Issue
Block a user