1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #2982 from gebart/pr/openocd-verify-watchdog

kinetis_common: Disable watchdog between flashing and verifying image
This commit is contained in:
Johann Fischer 2015-05-27 14:45:09 +02:00
commit d1566254d9
16 changed files with 291 additions and 152 deletions

View File

@ -124,11 +124,26 @@ export DEBUGGER = $(RIOTBASE)/dist/tools/openocd/openocd.sh
export DEBUGSERVER = $(RIOTBASE)/dist/tools/openocd/openocd.sh
export RESET = $(RIOTBASE)/dist/tools/openocd/openocd.sh
export TERMFLAGS += -p "$(PORT)"
export FFLAGS = flash $(OPENOCD_EXTRA_INIT)
export DEBUGGER_FLAGS = debug $(OPENOCD_EXTRA_INIT)
export DEBUGSERVER_FLAGS = debug-server $(OPENOCD_EXTRA_INIT)
export RESET_FLAGS = reset $(OPENOCD_EXTRA_INIT)
export FFLAGS = flash
export DEBUGGER_FLAGS = debug
export DEBUGSERVER_FLAGS = debug-server
export RESET_FLAGS = reset
# We need special handling of the watchdog if we want to speed up the flash
# verification by using the MCU to compute the image checksum after flashing.
# wdog-disable.bin is a precompiled binary which will disable the watchdog and
# return control to the debugger (OpenOCD)
export OPENOCD_PRE_VERIFY_CMDS += \
-c 'load_image $(RIOTCPU)/kinetis_common/dist/wdog-disable.bin 0x20000000 bin' \
-c 'resume 0x20000000'
export OPENOCD_EXTRA_INIT
export PRE_FLASH_CHECK_SCRIPT = $(RIOTCPU)/kinetis_common/dist/check-fcfield-hex.sh
.PHONY: flash
flash: $(RIOTCPU)/kinetis_common/dist/wdog-disable.bin
# Reset the default goal.
.DEFAULT_GOAL :=
# define build specific options
CPU_USAGE = -mcpu=cortex-m4

View File

@ -43,6 +43,16 @@ source [find target/k60.cfg]
flash bank $_CHIPNAME.pflash.0 kinetis 0x00000000 0x20000 0 4 $_TARGETNAME
flash bank $_CHIPNAME.pflash.1 kinetis 0x00020000 0x20000 0 4 $_TARGETNAME
# Work-area is a space in RAM used for flash programming
# By default use 16kB
if { [info exists WORKAREASIZE] } {
set _WORKAREASIZE $WORKAREASIZE
} else {
set _WORKAREASIZE 0x4000
}
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
# The following section makes new gdb connections cause the MCU to do a system
# reset, in order to be in a known state.
# Comment this out in order to be able to debug an already started program.

View File

@ -42,6 +42,16 @@ source [find target/k60.cfg]
flash bank $_CHIPNAME.pflash.0 kinetis 0x00000000 0x40000 0 4 $_TARGETNAME
flash bank $_CHIPNAME.pflash.1 kinetis 0x00040000 0x40000 0 4 $_TARGETNAME
# Work-area is a space in RAM used for flash programming
# By default use 16kB
if { [info exists WORKAREASIZE] } {
set _WORKAREASIZE $WORKAREASIZE
} else {
set _WORKAREASIZE 0x4000
}
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
# The following section makes new gdb connections cause the MCU to do a system
# reset, in order to be in a known state.
# Comment this out in order to be able to debug an already started program.

View File

@ -23,24 +23,46 @@ export AS = $(PREFIX)as
export LINK = $(PREFIX)gcc
export SIZE = $(PREFIX)size
export OBJCOPY = $(PREFIX)objcopy
export OPENOCD ?= openocd
export DBG ?= $(PREFIX)gdb
export TERMPROG = $(RIOTBASE)/dist/tools/pyterm/pyterm
export FLASHER = $(RIOTBOARD)/$(BOARD)/dist/flash.sh
export DEBUGGER = $(RIOTBOARD)/$(BOARD)/dist/debug.sh
export RESET = $(RIOTBOARD)/$(BOARD)/dist/reset.sh
export DEBUGSERVER = openocd
export FLASHER = $(RIOTBASE)/dist/tools/openocd/openocd.sh
export DEBUGGER = $(RIOTBASE)/dist/tools/openocd/openocd.sh
export DEBUGSERVER = $(RIOTBASE)/dist/tools/openocd/openocd.sh
export RESET = $(RIOTBASE)/dist/tools/openocd/openocd.sh
.PHONY: flash
flash: $(RIOTCPU)/kinetis_common/dist/wdog-disable.bin
# Reset the default goal.
.DEFAULT_GOAL :=
# define build specific options
CPU_USAGE = -mcpu=cortex-m4
FPU_USAGE =
export CPU_USAGE = -mcpu=cortex-m4
export FPU_USAGE =
export CFLAGS += -ggdb -g3 -std=gnu99 -Os -Wall -Wstrict-prototypes $(CPU_USAGE) $(FPU_USAGE) -mlittle-endian -mthumb -mthumb-interwork -nostartfiles
export CFLAGS += -ffunction-sections -fdata-sections -fno-builtin
export ASFLAGS += -ggdb -g3 $(CPU_USAGE) $(FPU_USAGE) -mlittle-endian
export LINKFLAGS += -g3 -ggdb -std=gnu99 $(CPU_USAGE) $(FPU_USAGE) -mlittle-endian -static -lgcc -mthumb -mthumb-interwork -nostartfiles
export LINKFLAGS += -T$(LINKERSCRIPT)
export OFLAGS = -O binary
export FFLAGS = $(HEXFILE)
export DEBUGGER_FLAGS = $(RIOTBOARD)/$(BOARD)/dist/gdb.conf $(ELFFILE)
export FFLAGS = flash-elf
export DEBUGGER_FLAGS = debug
export DEBUGSERVER_FLAGS = debug-server
export RESET_FLAGS = reset
export TERMFLAGS = -p $(PORT)
export TUI = 1
# We need special handling of the watchdog if we want to speed up the flash
# verification by using the MCU to compute the image checksum after flashing.
# wdog-disable.bin is a precompiled binary which will disable the watchdog and
# return control to the debugger (OpenOCD)
export OPENOCD_PRE_VERIFY_CMDS += \
-c 'load_image $(RIOTCPU)/kinetis_common/dist/wdog-disable.bin 0x20000000 bin' \
-c 'resume 0x20000000'
export OPENOCD_EXTRA_INIT
export PRE_FLASH_CHECK_SCRIPT = $(RIOTCPU)/kinetis_common/dist/check-fcfield-elf.sh
# use newLib nano-specs if available
ifeq ($(shell $(LINK) -specs=nano.specs -E - 2>/dev/null >/dev/null </dev/null ; echo $$?),0)

View File

@ -1,38 +0,0 @@
#!/bin/bash
# Based on iot-lab_M3 debug.sh script.
# Author: Jonas Remmert j.remmert@phytec.de
red='\033[0;31m'
green='\033[0;32m'
NC='\033[0m'
openocd -f "$RIOTBASE/boards/pba-d-01-kw2x/dist/mkw22d512.cfg" \ #"${RIOTBOARD}/${BOARD}/dist/mkw22d512.cfg" \
-c "tcl_port 6333" \
-c "telnet_port 4444" \
-c "init" \
-c "targets" \
-c "reset halt" \
-l /dev/null &
# save pid to terminate afterwards
OCD_PID=$?
# needed for openocd to set up
sleep 1
retval=$(arm-none-eabi-readelf -x .fcfield $2 | awk '/0x00000400/ {print $2 $3 $4 $5}')
unlocked_fcfield="fffffffffffffffffffffffffeffffff"
if [ "$retval" == "$unlocked_fcfield" ]; then
echo -e "Flash configuration tested...${green} [OK]${NC}"
arm-none-eabi-gdb -tui --command=${1} ${2}
#cgdb -d arm-none-eabi-gdb --command=${1} ${2}
else
echo "Hexdump, .fcfield of $2"
retval=$(arm-none-eabi-readelf -x .fcfield $2)
echo $retval
echo -e "Fcfield not fitting to MKW22Dxxx, danger of bricking the device during flash...${red} [ABORT]${NC}"
fi
kill ${OCD_PID}

View File

@ -1,52 +0,0 @@
#!/bin/bash
# Based on iot-lab_M3 debug.sh script.
# Author: Jonas Remmert j.remmert@phytec.de
elffile=`echo $1 | sed 's/.hex/.elf/'`
red='\033[0;31m'
green='\033[0;32m'
NC='\033[0m'
echo The file: $elffile will be flashed to the board: $BOARD .
#echo Press y to proceed, v to proceed with verify or any other key to abort.
#read x
retval=$(arm-none-eabi-readelf -x .fcfield $elffile | awk '/0x00000400/ {print $2 $3 $4 $5}')
unlocked_fcfield="fffffffffffffffffffffffffeffffff"
if [ "$retval" != "$unlocked_fcfield" ]; then
echo "Hexdump, .fcfield of $elffile"
retval=$(arm-none-eabi-readelf -x .fcfield $elffile)
echo $retval
echo -e "Fcfield not fitting to MKW2xDxxx, danger of bricking the device during flash...${red} [ABORT]${NC}"
exit 0
fi
echo -e "Flash configuration tested...${green} [OK]${NC}"
# flash without verify
#if [ $x = "y" ] || [ $x = "v" ];# -o $x -eq v ];
#then
echo -e "${red}Flashing device, do not disconnect or reset the target until this script exits!!!${NC}"
openocd -f "$RIOTBASE/boards/pba-d-01-kw2x/dist/mkw22d512.cfg" \
-c "init" \
-c "reset halt" \
-c "flash write_image erase $elffile" \
-c "reset run" \
-c "exit"
#fi
# verify
#if [ "$x" = "v" ];
#then
#echo -e "${red}Flashing device, do not disconnect or reset the target until this script exits!!!${NC}"
#openocd -f "$RIOTBASE/boards/pba-d-01-kw2x/dist/mkw22d512.cfg" \
# -c "init" \
# -c "reset halt" \
# -c "verify_image $elffile" \
# -c "reset run" \
# -c "exit"
#fi
echo -e "${green}done...${NC}"

View File

@ -1,4 +0,0 @@
target remote localhost:3333
monitor reset halt
set print pretty
set arm force-mode thumb

View File

@ -1,6 +0,0 @@
#!/bin/bash
openocd -f "$RIOTBASE/boards/pba-d-01-kw2x/dist/mkw22d512.cfg" \
-c "init" \
-c "reset run" \
-c "shutdown"

View File

@ -9,3 +9,10 @@ export UNDEF += $(BINDIR)kinetis_common/startup.o
# add the CPU specific fault handlers for the linker
export UNDEF += $(BINDIR)kinetis_common/fault_handlers.o
# Define a recipe to build the watchdog disable binary, used when flashing
$(RIOTCPU)/kinetis_common/dist/wdog-disable.bin: $(RIOTCPU)/kinetis_common/dist/wdog-disable.s
$(AD)$(MAKE) -C $(RIOTCPU)/kinetis_common/dist/ $(notdir $@)
# Reset the default goal to not make wdog-disable.bin the default target.
.DEFAULT_GOAL :=

9
cpu/kinetis_common/dist/Makefile vendored Normal file
View File

@ -0,0 +1,9 @@
wdog-disable.bin: wdog-disable.o
arm-none-eabi-objcopy -O binary -j .text.wdog_disable -S -g $^ $@
wdog-disable.o: wdog-disable.s
arm-none-eabi-as -mthumb -o $@ $^
.PHONY: clean
clean:
@rm wdog-disable.o

15
cpu/kinetis_common/dist/README.md vendored Normal file
View File

@ -0,0 +1,15 @@
K60 tools
=========
This directory contains tools for working with K60 CPUs.
Watchdog disable
----------------
wdog-disable.bin is a location-independent watchdog disable function with a breakpoint instruction at the end. Useful for disabling the watchdog directly from OpenOCD.
Usage:
openocd -c 'reset halt' \
-c 'load_image wdog-disable.bin 0x20000000 bin' \
-c 'resume 0x20000000' # watchdog is disabled and core halted

24
cpu/kinetis_common/dist/check-fcfield-elf.sh vendored Executable file
View File

@ -0,0 +1,24 @@
#!/bin/sh
#
# Anti brick check script for Freescale Kinetis MCUs.
#
# This script is supposed to be called from RIOTs
# unified OpenOCD script (dist/tools/openocd/openocd.sh).
#
# @author Jonas Remmert <j.remmert@phytec.de>
# @author Johann Fischer <j.fischer@phytec.de>
ELFFILE=$1
RETVAL=$(arm-none-eabi-readelf -x .fcfield $ELFFILE | awk '/0x00000400/ {print $2 $3 $4 $5}')
UNLOCKED_FCFIELD="fffffffffffffffffffffffffeffffff"
if [ "$RETVAL" != "$UNLOCKED_FCFIELD" ]; then
echo "Danger of bricking the device during flash!"
echo "Flash configuration field of $ELFFILE:"
arm-none-eabi-readelf -x .fcfield $ELFFILE
echo "Abort flash procedure!"
exit 1
fi
echo "$ELFFILE is fine."
exit 0

36
cpu/kinetis_common/dist/check-fcfield-hex.sh vendored Executable file
View File

@ -0,0 +1,36 @@
#!/bin/sh
#
# Flash configuration field check script for Freescale Kinetis MCUs.
#
# This script is supposed to be called from RIOTs
# unified OpenOCD script (dist/tools/openocd/openocd.sh).
#
# Syntax: check-fcfield-hex.sh $HEXFILE
#
# @author Jonas Remmert <j.remmert@phytec.de>
# @author Johann Fischer <j.fischer@phytec.de>
# @author Joakim Gebart <joakim.gebart@eistec.se>
if [ $# -ne 1 ]; then
echo "Usage: $0 HEXFILE"
echo "Checks the flash configuration field protection bits to avoid flashing a locked image to a Kinetis MCU (protection against accidental bricking)."
exit 2
fi
HEXFILE="$1"
FCFIELD_START='0x400'
FCFIELD_END='0x410'
FCFIELD_AWK_REGEX='^ 0400 '
ACTUAL_FCFIELD=$(arm-none-eabi-objdump --start-address=${FCFIELD_START} --stop-address=${FCFIELD_END} ${HEXFILE} -s | awk -F' ' "/${FCFIELD_AWK_REGEX}/ { print \$2 \$3 \$4 \$5; }")
EXPECTED_FCFIELD="fffffffffffffffffffffffffeffffff"
if [ "${ACTUAL_FCFIELD}" != "${EXPECTED_FCFIELD}" ]; then
echo "Danger of bricking the device during flash!"
echo "Flash configuration field of ${HEXFILE}:"
arm-none-eabi-objdump --start-address=${FCFIELD_START} --stop-address=${FCFIELD_END} ${HEXFILE} -s
echo "Abort flash procedure!"
exit 1
fi
echo "${HEXFILE} is not locked."
exit 0

33
cpu/kinetis_common/dist/wdog-disable.s vendored Normal file
View File

@ -0,0 +1,33 @@
/*
* Copyright (C) 2015 Eistec AB
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/* GCC ARM assembler */
.text
.thumb
.align 2
/* Public functions declared in this file */
.global wdog_disable
.section .text.wdog_disable
.thumb_func
.func
wdog_disable:
movw r0, #0x200e
movw r1, #0xc520
movt r0, #0x4005
strh r1, [r0, #0]
movw r1, #0xd928
strh r1, [r0, #0]
movw r0, #0x2000
movs r1, #0xd2
movt r0, #0x4005
strh r1, [r0, #0]
bkpt #0
.endfunc

View File

@ -17,12 +17,23 @@
#
# The script supports the following actions:
#
# flash: flash a given hexfile to the target.
# flash: flash a given hex file to the target.
# hexfile is expected in ihex format and is pointed to
# by HEXFILE environment variable
#
# options:
# HEXFILE: path to the hexfile that is flashed
# HEXFILE: path to the hex file that is flashed
# PRE_FLASH_CHECK_SCRIPT: a command to run before flashing to
# verify the integrity of the image to be flashed. HEXFILE is
# passed as an argument to this command.
#
# flash-elf: flash a given ELF file to the target.
#
# options:
# ELFFILE: path to the ELF file that is flashed
# PRE_FLASH_CHECK_SCRIPT: a command to run before flashing to
# verify the integrity of the image to be flashed. ELFFILE is
# passed as an argument to this command.
#
# debug: starts OpenOCD as GDB server in the background and
# connects to the server with the GDB client specified by
@ -33,6 +44,7 @@
# TCL_PORT: port opened for TCL connections
# TELNET_PORT: port opened for telnet connections
# TUI: if TUI!=null, the -tui option will be used
# ELFFILE: path to the ELF file to debug
#
# debug-server: starts OpenOCD as GDB server, but does not connect to
# to it with any frontend. This might be useful when using
@ -117,19 +129,61 @@ test_tui() {
do_flash() {
test_config
test_hexfile
if [ -n "${PRE_FLASH_CHECK_SCRIPT}" ]; then
sh -c "${PRE_FLASH_CHECK_SCRIPT} '${HEXFILE}'"
RETVAL=$?
if [ $RETVAL -ne 0 ]; then
echo "pre-flash checks failed, status=$RETVAL"
exit $RETVAL
fi
fi
# flash device
${OPENOCD} -f "${OPENOCD_CONFIG}" \
"$@" \
-c "tcl_port 0" \
-c "telnet_port 0" \
-c "gdb_port 0" \
-c "init" \
-c "targets" \
-c "reset halt" \
-c "program ${HEXFILE} verify" \
-c "reset run" \
-c "shutdown"
echo "Done flashing"
sh -c "${OPENOCD} -f '${OPENOCD_CONFIG}' \
${OPENOCD_EXTRA_INIT} \
-c 'tcl_port 0' \
-c 'telnet_port 0' \
-c 'gdb_port 0' \
-c 'init' \
-c 'targets' \
-c 'reset halt' \
${OPENOCD_PRE_FLASH_CMDS} \
-c 'flash write_image erase \"${HEXFILE}\"' \
-c 'reset halt' \
${OPENOCD_PRE_VERIFY_CMDS} \
-c 'verify_image \"${HEXFILE}\"' \
-c 'reset run' \
-c 'shutdown'"
echo 'Done flashing'
}
do_flash_elf() {
test_config
test_elffile
if [ -n "${PRE_FLASH_CHECK_SCRIPT}" ]; then
sh -c "${PRE_FLASH_CHECK_SCRIPT} '${ELFFILE}'"
RETVAL=$?
if [ $RETVAL -ne 0 ]; then
echo "pre-flash checks failed, status=$RETVAL"
exit $RETVAL
fi
fi
# flash device
sh -c "${OPENOCD} -f '${OPENOCD_CONFIG}' \
${OPENOCD_EXTRA_INIT} \
-c 'tcl_port 0' \
-c 'telnet_port 0' \
-c 'gdb_port 0' \
-c 'init' \
-c 'targets' \
-c 'reset halt' \
${OPENOCD_PRE_FLASH_CMDS} \
-c 'flash write_image erase \"${ELFFILE}\"' \
-c 'reset halt' \
${OPENOCD_PRE_VERIFY_CMDS} \
-c 'verify_image \"${ELFFILE}\"' \
-c 'reset run' \
-c 'shutdown'"
echo 'Done flashing'
}
do_debug() {
@ -138,15 +192,15 @@ do_debug() {
test_ports
test_tui
# start OpenOCD as GDB server
${OPENOCD} -f "${OPENOCD_CONFIG}" \
"$@" \
-c "tcl_port ${TCL_PORT}" \
-c "telnet_port ${TELNET_PORT}" \
-c "gdb_port ${GDB_PORT}" \
-c "init" \
-c "targets" \
-c "reset halt" \
-l /dev/null &
sh -c "${OPENOCD} -f '${OPENOCD_CONFIG}' \
${OPENOCD_EXTRA_INIT} \
-c 'tcl_port ${TCL_PORT}' \
-c 'telnet_port ${TELNET_PORT}' \
-c 'gdb_port ${GDB_PORT}' \
-c 'init' \
-c 'targets' \
-c 'reset halt' \
-l /dev/null" &
# save PID for terminating the server afterwards
OCD_PID=$?
# connect to the GDB server
@ -159,27 +213,27 @@ do_debugserver() {
test_config
test_ports
# start OpenOCD as GDB server
${OPENOCD} -f "${OPENOCD_CONFIG}" \
"$@" \
-c "tcl_port ${TCL_PORT}" \
-c "telnet_port ${TELNET_PORT}" \
-c "gdb_port ${GDB_PORT}" \
-c "init" \
-c "targets" \
-c "reset halt"
sh -c "${OPENOCD} -f '${OPENOCD_CONFIG}' \
${OPENOCD_EXTRA_INIT} \
-c 'tcl_port ${TCL_PORT}' \
-c 'telnet_port ${TELNET_PORT}' \
-c 'gdb_port ${GDB_PORT}' \
-c 'init' \
-c 'targets' \
-c 'reset halt'"
}
do_reset() {
test_config
# start OpenOCD and invoke board reset
${OPENOCD} -f "${OPENOCD_CONFIG}" \
"$@" \
-c "tcl_port 0" \
-c "telnet_port 0" \
-c "gdb_port 0" \
-c "init" \
-c "reset run" \
-c "shutdown"
sh -c "${OPENOCD} -f '${OPENOCD_CONFIG}' \
${OPENOCD_EXTRA_INIT} \
-c 'tcl_port 0' \
-c 'telnet_port 0' \
-c 'gdb_port 0' \
-c 'init' \
-c 'reset run' \
-c 'shutdown'"
}
#
@ -193,6 +247,10 @@ case "${ACTION}" in
echo "### Flashing Target ###"
do_flash "$@"
;;
flash-elf)
echo "### Flashing Target ###"
do_flash_elf "$@"
;;
debug)
echo "### Starting Debugging ###"
do_debug "$@"