Skip to content
Snippets Groups Projects
Commit 747b0981 authored by Henrik Tjäder's avatar Henrik Tjäder
Browse files

Added python and makefiles

parent 1de287c8
No related branches found
No related tags found
No related merge requests found
...@@ -10,6 +10,6 @@ klee-* ...@@ -10,6 +10,6 @@ klee-*
tags tags
docs docs
.ropeproject .ropeproject
.gdb_history
code-samples code-samples
klee_profiling.db *.db
.gdb_history
Makefile 0 → 100644
PROJECT_NAME=klee
TARGET=$(PROJECT_NAME).hex
EXECUTABLE=$(PROJECT_NAME).elf
EXECOBJ=$(PROJECT_NAME).o
IROUT=$(PROJECT_NAME).bc
ifeq "$(MAKECMDGOALS)" "gcc"
# GCC
CC=arm-none-eabi-gcc
LD=arm-none-eabi-ld
AR=arm-none-eabi-ar
AS=arm-none-eabi-as
CP=arm-none-eabi-objcopy
OD=arm-none-eabi-objdump
else
# CLANG
CC=clang
LD=llvm-link
CC-native=arm-none-eabi-gcc
#LD-native=arm-none-eabi-ld
AR=llvm-ar
AS=arm-none-eabi-as
CP=arm-none-eabi-objcopy
OD=arm-none-eabi-objdump
endif
BIN=$(CP) -O ihex
# Debugging with OpenOCD
GDB = arm-none-eabi-gdb
OOCD = openocd
# General case, but now we need specifics
#OOCDFLAsyscalls = -f interface/stlink-v2-1.cfg -f board/stm32f7discovery.cfg
#OOCDFLAGS = -f interface/stlink-v2-1.cfg -f ocd_stm32f4.cfg
OOCDFLAGS = -f interface/stlink-v2-1.cfg -f stm32f4x.cfg
#DEFS = -DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DMANGUSTA_DISCOVERY -DUSE_USB_OTG_FS -DHSE_VALUE=8000000
#DEFS = -DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F40XX -DHSE_VALUE=8000000
# STM32F4x7 custom
#DEFS = -DUSE_STDPERIPH_DRIVER -DSTM32F40XX -DSTM32F4XX -DHSE_VALUE=16000000
# STM32F401
ifeq "$(MAKECMDGOALS)" "rel"
DEFS = -DSTM32F40XX -DHSE_VALUE=8000000 -DTRACE -DOS_USE_TRACE_ITM
else
DEFS = -DSTM32F40XX -DHSE_VALUE=8000000 -DKLEE
endif
# Definitions
#ifeq "$(MAKECMDGOALS)" "debug"
#DEFS = -DnoUSE_STDPERIPH_DRIVER -DHSE_VALUE=8000000 -DOS_USE_TRACE_ITM -DDEBUG -DxOS_USE_SEMIHOSTING -DTRACE -DxOS_USE_TRACE_SEMIHOSTING_DEBUG -DSTM32F746xx
#else
#DEFS = -DnoUSE_STDPERIPH_DRIVER -DHSE_VALUE=8000000 -DxOS_USE_SEMIHOSTING -DxOS_USE_TRACE_SEMIHOSTING_DEBUG -DSTM32F746xx
#endif
# Optimize for size
#OPTIMIZE = -Os
# No optimization at all
OPTIMIZE = -O0
#INCSEARCH = include
#SRCIGNORE =! -iname 'tiny_printf.c'
#INCLUDES := $(shell find $(INCSEARCH) -name '*.h' -exec dirname {} \; | uniq)
INCLUDES = -I"include" \
-I"system" \
-I"system/include/cmsis" \
-I"system/include/cmsis/stm32f4-hal"
#-I"Libraries/stm32f4-hal" \
#-I"Libraries/STM32F4xx_StdPeriph_Driver/inc"\
#-I"Libraries/CMSIS/Include"\
#-I"Libraries/Device/STM32F4xx/Include"
MCU = cortex-m4
ifeq "$(MAKECMDGOALS)" "gcc"
# GCC
include Makefile_gcc
# End of the GCC block
else
# Start of the CLANG block
# CLANG
CLANGMCFLAGS =-target arm-none-eabi -fno-integrated-as
# MCU Specific flags
MCFLAGS = -mcpu=$(MCU) -mlittle-endian -mthumb -ffreestanding \
-fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fshort-enums \
-g3 -std=gnu11 -Wall -Wextra
# For creating object file from LLVM IR
LLCFLAGS = -mtriple=arm-none-eabi -march=thumb -mcpu=$(MCU) -filetype=obj -float-abi=hard
# Assembler flags
ASFLAGS = -mcpu=$(MCU) -mlittle-endian -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard
# Linking options with -nostartfiles
#LDFLAGS = -T ldscripts/stm32f4_flash.ld -nostdlib -nostartfiles -nostartupfiles -gc-sections -print-gc-sections -Map objects/$(EXECUTABLE).map
LDFLAGS = --specs=nosys.specs -Wl,-T "ldscripts/flash.ld" -nostartfiles -Wl,-nostdlib,-print-gc-sections -Wl,-Map,objects/$(EXECUTABLE).map
# Not used:
#--specs=nano.specs --specs=nosys.specs -lc -lnosys
CLANGLDFLAGS = -flto -target arm-none-eabi -mfloat-abi=hard # -save-temps=obj
#or if you want .bc in objects -save-temps=obj
# Build the compile command
CFLAGS = $(CLANGMCFLAGS) $(MCFLAGS) $(OPTIMIZE) $(DEFS)
# Recursively add all .c files
#SRC := $(shell find $(SOURCEDIR) -name '*.c')
SRCSEARCH = src
SRCIGNORE =! -iname 'tiny_printf.c' ! -iname 'fsdata.c' ! -iname 'stm32f4xx_spi.c' ! -iname 'stm32f4xx_iwdg.c'
# Include the heap_4 RTOS_heap while excluding the other *_{1-5}
# Everything in src will be compiled
SRC := $(shell find $(SRCSEARCH) -name '*.c' $(SRCIGNORE) )
# Create dependency folders for object files
SRCDIRS := $(shell find $(SRCSEARCH) -name '*.c' $(SRCIGNORE) )
#SRCDIRS += $(shell find libs/dw1000/src -maxdepth 1 -name '*.c' -exec dirname {} \; | uniq)
SRCDIRS += startup
# Startup files
#STARTUP = startup/startup_stm32f40xx.s
#STARTUP = startup/startup_stm32f407xx.s
STARTUP = startup/startup_stm32f4.c
# Assembler file to facilitate printing of stack in case of hardfault
#HARDFAULT = startup/hardfault.s
# Create folder for storing all object files
OBJDIR = objects
OBJ := $(patsubst %.c,$(OBJDIR)/%.bc,$(SRC))
#OBJASM := $(patsubst %.s,$(OBJDIR)/%.o,$(HARDFAULT))
OBJSTART := $(patsubst %.c,$(OBJDIR)/%.o,$(STARTUP))
DEPS := $(patsubst %.bc,%.d,$(OBJ))
DEPS += $(patsubst %.o,%.d,$(OBJASM))
DEPENDS = -MT $@ -MD -MP -MF $(subst .o,.d,$@)
SHELL = /bin/bash
.PHONY: all clean distclean
debugbuild: buildrepo $(EXECUTABLE)
all: buildrepo $(EXECUTABLE)
rel: buildrepo $(EXECUTABLE)
# Link native code into final executable
#$(EXECUTABLE): $(EXECOBJ) $(OBJASM)
ifeq "$(MAKECMDGOALS)" "rel"
$(EXECUTABLE): $(EXECOBJ) $(OBJSTART)
$(CC-native) $(INCLUDES) $(MCFLAGS) $(LDFLAGS) $^ -o $@
else
$(EXECUTABLE): $(EXECOBJ)
echo "Not doing final ARM linking."
endif
# Specially compile the startup code with GCC since CLANG does not understand linker scripts
$(OBJSTART):
$(CC-native) $(MCFLAGS) $(OPTIMIZE) $(DEFS) $(DEPENDS) -c $(STARTUP) $^ -o $@ $(INCLUDES)
# Link LLVM-code into native code
$(EXECOBJ): $(IROUT)
llc $(LLCFLAGS) $(IROUT) -o $@
$(IROUT): $(OBJ)
llvm-link $^ -o $@
# Source files "-c" is to not link
$(OBJDIR)/%.bc: %.c
$(CC) $(CFLAGS) -c $(CLANGLDFLAGS) $(DEPENDS) $< -o $@ $(INCLUDES)
# Assembler files "-c" is to not link
# Clang assembler files
#$(OBJDIR)/%.o: %.s
# $(CC) $(CLANGMCFLAGS) -c $(CLANGLDFLAGS) $< -o $@ $(INCLUDES)
$(OBJDIR)/%.o: %.s
$(CC-native) $(MCFLAGS) $(OPTIMIZE) $(DEFS) $(DEPENDS) $(STARTUP) $< -o $@ $(INCLUDES)
# End of the CLANG block
endif
clean:
$(RM) -r $(OBJDIR) $(EXECOBJ) $(IR) $(IROUT)
cleanall:
$(RM) -r $(OBJDIR) $(EXECOBJ) $(IR) $(IROUT) klee-last klee-out* $(EXECUTABLE)
distclean: clean
$(RM) $(EXECUTABLE)
buildrepo:
@$(call make-repo)
flash: $(EXECUTABLE)
$(OOCD) $(OOCDFLAGS) \
-c "init" -c "targets" -c "reset halt" \
-c "flash write_image erase $<" -c "verify_image $<" \
-c "reset run" -c "shutdown"
debug: $(EXECUTABLE)
$(GDB) -n -iex 'target extended | $(OOCD) $(OOCDFLAGS) -c "gdb_port pipe"' \
-iex 'mon halt' $<
klee: buildrepo $(EXECUTABLE)
klee -emit-all-errors $(IROUT)
define make-repo
for dir in $(SRCDIRS); \
do \
mkdir -p $(OBJDIR)/$$dir; \
done
endef
ifneq "$(MAKECMDGOALS)" "distclean"
ifneq "$(MAKECMDGOALS)" "clean"
-include $(DEPS)
endif
endif
cleanold:
rm -f Startup.lst $(TARGET) $(TARGET).lst $(OBJ) $(AUTOGEN) $(TARGET).out $(TARGET).hex $(TARGET).map $(TARGET).dmp $(TARGET).elf
This diff is collapsed.
file target/thumbv7em-none-eabi/debug/emb1
target remote : 3333
monitor reset init
load
monitor reset init
file target/thumbv7em-none-eabi/release/emb1
target remote : 3333
monitor reset init
load
monitor reset init
import gdb
import os
import sys
import struct
import sqlite3
# Should ideally properly just import from ktest-tool
# from .ktesttool import KTest
version_no = 3
file_list = []
file_index_current = 0
object_index_current = 0
""" Max number of events guard """
object_index_max = 100
database_name = "klee_profiling"
""" Check if a database exists, otherwise create one """
if os.path.isfile("%s%s" % (database_name, ".db")):
os.rename("%s%s" % (database_name, ".db"),
"%s%s" % (database_name, "_old.db"))
# conn = sqlite3.connect(database_name)
# cur = conn.cursor()
# print("Opened already created database")
conn = sqlite3.connect("%s%s" % (database_name, ".db"))
cur = conn.cursor()
cur.execute('''CREATE TABLE IF NOT EXISTS events
(ID INTEGER PRIMARY KEY AUTOINCREMENT,
FILE TEXT NOT NULL,
TIME INT NOT NULL,
RESOURCE TEXT NOT NULL,
ACTION TEXT);''')
class KTestError(Exception):
pass
class KTest:
@staticmethod
def fromfile(path):
if not os.path.exists(path):
print("ERROR: file %s not found" % (path))
sys.exit(1)
f = open(path, 'rb')
hdr = f.read(5)
if len(hdr) != 5 or (hdr != b'KTEST' and hdr != b"BOUT\n"):
raise KTestError('unrecognized file')
version, = struct.unpack('>i', f.read(4))
if version > version_no:
raise KTestError('unrecognized version')
numArgs, = struct.unpack('>i', f.read(4))
args = []
for i in range(numArgs):
size, = struct.unpack('>i', f.read(4))
args.append(str(f.read(size).decode(encoding='ascii')))
if version >= 2:
symArgvs, = struct.unpack('>i', f.read(4))
symArgvLen, = struct.unpack('>i', f.read(4))
else:
symArgvs = 0
symArgvLen = 0
numObjects, = struct.unpack('>i', f.read(4))
objects = []
for i in range(numObjects):
size, = struct.unpack('>i', f.read(4))
name = f.read(size)
size, = struct.unpack('>i', f.read(4))
bytes = f.read(size)
objects.append((name, bytes))
# Create an instance
b = KTest(version, args, symArgvs, symArgvLen, objects)
# Augment with extra filename field
b.filename = path
return b
def __init__(self, version, args, symArgvs, symArgvLen, objects):
self.version = version
self.symArgvs = symArgvs
self.symArgvLen = symArgvLen
self.args = args
self.objects = objects
# add a field that represents the name of the program used to
# generate this .ktest file:
program_full_path = self.args[0]
program_name = os.path.basename(program_full_path)
# sometimes program names end in .bc, so strip them
if program_name.endswith('.bc'):
program_name = program_name[:-3]
self.programName = program_name
class MainBP(gdb.Breakpoint):
def stop(self):
# print("##### breakpoint")
global file_index_current
gdb.events.stop.connect(stop_event)
if self.location == "main":
# gdb.write("Breakpoint in main()\n")
gdb.prompt_hook = prompt
gdb.post_event(posted_event_main)
elif self.location == "finish_execution":
# gdb.write("Breakpoint in finish_execution\n")
# gdb.write("Stopped before the main loop\n")
""" Save the execution time and
reload back to the main function.
"""
gdb.prompt_hook = prompt
gdb.post_event(posted_event_finish_execution)
""" Needed to actually stop after the breakpoint """
return True
# Subscribing to the stop events
def stop_event(evt):
# print("#### stop event")
# print("evt %r" % evt)
gdb.events.stop.disconnect(stop_event)
# Hooking the prompt:
def prompt(current):
# print("current %r" % current)
# print("#### prompt")
gdb.prompt_hook = current
# Posting events (which seem to work well when height=0)
# def posted_event():
# print("#### posted event")
# gdb.execute("
def posted_event_main():
""" Called when the breakpoint at main() is hit """
# print("# main BP")
global file_index_current
ktest_setdata(file_index_current)
gdb.execute("continue")
def posted_event_finish_execution():
""" Called when the breakpoint at finish_execution() is hit """
global file_list
global file_index_current
global object_index_current
global object_index_max
# gdb.execute("print eventlist")
# print("object_current: %r " % object_index_current)
print("object_max: %r " % object_index_max)
while object_index_current < object_index_max:
""" Collect all data for the database """
event_time = gdb.parse_and_eval("eventlist[" +
str(object_index_current) +
"].time")
event_resource = gdb.parse_and_eval("eventlist[" +
str(object_index_current) +
"].elem")
event_action = gdb.parse_and_eval("eventlist[" +
str(object_index_current) +
"].action")
"""
print("file: %r " % str(file_list[file_index_current]))
print("time: %r " % int(event_time))
print("resource: %r" % str(event_resource))
print("action: %r" % str(event_action))
"""
event = []
event.append(str(file_list[file_index_current]))
event.append(int(event_time))
event.append(str(event_resource))
event.append(str(event_action))
print("Event: %r " % event)
try:
cur = conn.cursor()
cur.execute('INSERT INTO events(FILE, TIME, RESOURCE, ACTION)\
VALUES (?,?,?,?)', event)
except sqlite3.Error as e:
print("An error occurred:", e.args[0])
object_index_current += 1
""" If this was the END of execution go for next file """
if str(event_action) == 'E':
""" All events covered, break out from loop """
break
""" Reset object counter for next file """
file_index_current += 1
object_index_current = 0
""" All done, commit to database and tidy after ourselves """
if len(file_list) == file_index_current:
print("Committing to database")
conn.commit()
conn.close()
gdb.execute("quit")
else:
gdb.execute("run")
def trimZeros(str):
for i in range(len(str))[::-1]:
if str[i] != '\x00':
return str[:i + 1]
return ''
def ktest_setdata(file_index):
"""
Substitute every variable found in ktest-file
"""
global file_list
b = KTest.fromfile(file_list[file_index])
# print('ktest filename : %r' % filename)
gdb.write('ktest file : %r \n' % file_list[file_index])
# print('args : %r' % b.args)
# print('num objects: %r' % len(b.objects))
for i, (name, data) in enumerate(b.objects):
str = trimZeros(data)
# print('object %4d: name: %r' % (i, name))
# print('object %4d: size: %r' % (i, len(data)))
# if opts.writeInts and len(data) == 4:
obj_data = struct.unpack('i', str)[0]
"""
print('object %4d: data: %r' %
(i, obj_data))
"""
# gdb.execute('whatis %r' % name.decode('UTF-8'))
# gdb.execute('whatis %r' % obj_data)
gdb.execute('set variable %s = %r' %
(name.decode('UTF-8'), obj_data))
# gdb.write('Variable %s is:' % name.decode('UTF-8'))
# gdb.execute('print %s' % name.decode('UTF-8'))
# else:
# print('object %4d: data: %r' % (i, str))
def ktest_iterate():
""" Iterate over all files ending with ktest in klee-last folder """
directory = "klee-last"
for filename in os.listdir(directory):
if filename.endswith(".ktest"):
file_list.append(os.path.join(directory, filename))
else:
continue
file_list.sort()
return file_list
""" Break at main to set variable values """
# AddBreakpoint("main")
MainBP("main")
""" Also break at the main-loop """
# AddBreakpoint("finish_execution")
MainBP("finish_execution")
MainBP("terminate_execution")
"""Used for making it scriptable"""
gdb.execute("set confirm off")
gdb.execute("set pagination off")
gdb.execute("set verbose off")
""" Save all ktest files into an array """
file_list = ktest_iterate()
print(file_list)
""" Run until the main() breakpoint """
gdb.execute("c")
import os
import sys
import struct
import sqlite3
import argparse
version_no = 3
file_list = []
file_index_current = 0
object_index_current = 0
database_name = "klee_profiling.db"
""" Check if a database exists, otherwise create one """
if os.path.isfile(database_name):
conn = sqlite3.connect(database_name)
c = conn.cursor()
print("Opened already created database")
else:
print("No file named %s exists in current folder!")
exit()
class KTestError(Exception):
pass
class KTest:
@staticmethod
def fromfile(path):
if not os.path.exists(path):
print("ERROR: file %s not found" % (path))
sys.exit(1)
f = open(path, 'rb')
hdr = f.read(5)
if len(hdr) != 5 or (hdr != b'KTEST' and hdr != b"BOUT\n"):
raise KTestError('unrecognized file')
version, = struct.unpack('>i', f.read(4))
if version > version_no:
raise KTestError('unrecognized version')
numArgs, = struct.unpack('>i', f.read(4))
args = []
for i in range(numArgs):
size, = struct.unpack('>i', f.read(4))
args.append(str(f.read(size).decode(encoding='ascii')))
if version >= 2:
symArgvs, = struct.unpack('>i', f.read(4))
symArgvLen, = struct.unpack('>i', f.read(4))
else:
symArgvs = 0
symArgvLen = 0
numObjects, = struct.unpack('>i', f.read(4))
objects = []
for i in range(numObjects):
size, = struct.unpack('>i', f.read(4))
name = f.read(size)
size, = struct.unpack('>i', f.read(4))
bytes = f.read(size)
objects.append((name, bytes))
# Create an instance
b = KTest(version, args, symArgvs, symArgvLen, objects)
# Augment with extra filename field
b.filename = path
return b
def __init__(self, version, args, symArgvs, symArgvLen, objects):
self.version = version
self.symArgvs = symArgvs
self.symArgvLen = symArgvLen
self.args = args
self.objects = objects
# add a field that represents the name of the program used to
# generate this .ktest file:
program_full_path = self.args[0]
program_name = os.path.basename(program_full_path)
# sometimes program names end in .bc, so strip them
if program_name.endswith('.bc'):
program_name = program_name[:-3]
self.programName = program_name
def trimZeros(str):
for i in range(len(str))[::-1]:
if str[i] != '\x00':
return str[:i + 1]
return ''
def ktest_setdata(filename):
"""
Substitute every variable found in ktest-file
"""
global file_list
b = KTest.fromfile(filename)
# print('ktest filename : %r' % filename)
# print('args : %r' % b.args)
print('num objects: %r' % len(b.objects))
for i, (name, data) in enumerate(b.objects):
str = trimZeros(data)
print('object %4d: name: %r' % (i, name))
print('object %4d: size: %r' % (i, len(data)))
# if opts.writeInts and len(data) == 4:
obj_data = struct.unpack('i', str)[0]
print('object %4d: data: %r' %
(i, obj_data))
# else:
# print('object %4d: data: %r' % (i, str))
def ktest_iterate():
""" Iterate over all files ending with ktest in klee-last folder """
directory = "klee-last"
for filename in os.listdir(directory):
if filename.endswith(".ktest"):
file_list.append(os.path.join(directory, filename))
else:
continue
file_list.sort()
return file_list
def print_db_ktest():
global file_list
""" E - S For total task time
R - L For total lock time
"""
for filename in file_list:
print("Testcase: %s" % filename)
ktest_setdata(filename)
""" Return all resources/tasks """
c.execute('SELECT DISTINCT resource FROM events WHERE (file=?)',
(filename,))
resources = c.fetchall()
""" Go through the unique list of resources
If they are called multiple times this is handled later
"""
for res in resources:
c.execute('''SELECT time FROM events WHERE
(file=? AND resource=?)''',
(str(filename), str(res[0]),))
rows = c.fetchall()
# Check if resource has been claimed more than than once
claims = len(rows)
# 2 is the expected value for 1 lock and 1 release
x = 0
while x < claims:
print("Number of instructions taken for %s: %d"
% (res[0], rows[x+1][0] - rows[x][0]))
x += 2
print("\n")
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=
'Parse and print a profiling database.')
parser.add_argument('filename', metavar='filename', type=open,
help='The database to be parsed')
args = parser.parse_args()
""" Save all ktest files into an array """
file_list = ktest_iterate()
print_db_ktest()
# This is for all ST NUCLEO with any STM32F4. Known boards at the moment:
# STM32F401RET6
# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260000
# STM32F411RET6
# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260320
source [find interface/stlink-v2-1.cfg]
transport select hla_swd
# source [find target/stm32f4x.cfg]
# local file
source [find ./stm32f4x.cfg]
# reset-init will set the processor to 64MHz, jtag to 4000kHz
# itm ports on seems not necessary, port 0 is enabled by default
# itm ports on
reset_config srst_only
# Henriks f7 setting
# tpiu config internal swo.log uart off 216000000 1800000
# info: http://openocd.org/doc/html/Architecture-and-Core-Commands.html
tpiu config internal swo.log uart off 64000000
# creates a swo.log in the current directory
# use tail -f swo.log to continously monitor the output
# This is for all ST NUCLEO with any STM32F4. Known boards at the moment:
# STM32F401RET6
# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260000
# STM32F411RET6
# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260320
source [find interface/stlink-v2-1.cfg]
transport select hla_swd
# source [find target/stm32f4x.cfg]
# local file
source [find ./stm32f4x.cfg]
# reset-init will set the processor to 64MHz, jtag to 4000kHz
# itm ports on seems not necessary, port 0 is enabled by default
# itm ports on
reset_config srst_only
# Henriks f7 setting
# tpiu config internal swo.log uart off 216000000 1800000
# info: http://openocd.org/doc/html/Architecture-and-Core-Commands.html
tpiu config internal /Users/pln/shared/swo.log uart off 64000000
# creates a swo.log in the current directory
# use tail -f swo.log to continously monitor the output
/*
* =====================================================================================
*
* Filename: startup_stm32f4.c
*
* Description: Startup code for STM32F4 MCU
* Based on http://electronics.stackexchange.com/questions/224618/minimal-code-required-to-startup-a-stm32f4
*
* Version: 1.0
* Created: 12/11/2016 02:54:57 PM
* Revision: none
* Compiler: gcc
*
* Organization:
*
* =====================================================================================
*/
#include "stdint.h"
#include "stm32f401xe.h"
/*#include "stm32f4xx.h"*/
/*#include "stm32f4xx_hal_gpio.h"*/
/*#include "stm32f4xx_hal_flash.h"*/
/** Main program entry point. */
extern int main(void);
/** Exit system call. */
extern void _exit(int code);
extern unsigned int __textdata__;
extern unsigned int __data_start__;
extern unsigned int __data_end__;
extern unsigned int __bss_start__;
extern unsigned int __bss_end__;
/** Initializes the data section. */
static void __attribute__((always_inline)) __initialize_data (unsigned int* from,
unsigned int* region_begin, unsigned int* region_end);
/** Initializes the BSS section. */
static void __attribute__((always_inline)) __initialize_bss (unsigned int* region_begin,
unsigned int* region_end);
/** Start-up code. */
void __attribute__ ((section(".after_vectors"), noreturn, used)) _start(void);
void _start (void)
{
//Before switching on the main oscillator and the PLL,
//and getting to higher and dangerous frequencies,
//configuration of the flash controller is necessary.
//Enable the flash prefetch buffer. Can be achieved when CCLK
//is lower than 24MHz.
/*FLASH_PrefetchBufferCmd(1);*/
/* Enable or disable the Prefetch Buffer */
/*if(NewState != DISABLE)*/
/*{*/
FLASH->ACR |= FLASH_ACR_PRFTEN;
/*}*/
/*else*/
/*{*/
/*FLASH->ACR &= (~FLASH_ACR_PRFTEN);*/
/*}*/
//Set latency to 2 clock cycles. Necessary for setting the clock
//to the maximum 72MHz.
/*FLASH_SetLatency(2);*/
/* Perform Byte access to FLASH_ACR[8:0] to set the Latency value */
*(__IO uint8_t *)FLASH_ACR_BYTE0_ADDRESS = (uint8_t)2;
// Initialize hardware right after configuring flash, to switch
//clock to higher frequency and have the rest of the
//initializations run faster.
//
//Testing to let OpenOCD set these instead
/*SystemInit();*/
// Copy the DATA segment from Flash to RAM (inlined).
__initialize_data(&__textdata__, &__data_start__, &__data_end__);
// Zero fill the BSS section (inlined).
__initialize_bss(&__bss_start__, &__bss_end__);
//Core is running normally, RAM and FLASH are initialized
//properly, now the system must be fully functional.
//Update the SystemCoreClock variable.
/*SystemCoreClockUpdate();*/
// Call the main entry point, and save the exit code.
int code = main();
//Main should never return. If it does, let the system exit gracefully.
_exit (code);
// Should never reach this, _exit() should have already
// performed a reset.
while(1);
}
static inline void __initialize_data (unsigned int* from, unsigned int* region_begin,
unsigned int* region_end)
{
// Iterate and copy word by word.
// It is assumed that the pointers are word aligned.
unsigned int *p = region_begin;
while (p < region_end)
{
*p++ = *from++;
}
}
static inline void __initialize_bss (unsigned int* region_begin, unsigned int* region_end)
{
// Iterate and clear word by word.
// It is assumed that the pointers are word aligned.
unsigned int *p = region_begin;
while (p < region_end)
{
*p++ = 0;
}
}
# script for stm32f4x family
#
# stm32 devices support both JTAG and SWD transports.
#
source [find target/swj-dp.tcl]
source [find mem_helper.tcl]
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME stm32f4x
}
set _ENDIAN little
# Work-area is a space in RAM used for flash programming
# By default use 32kB (Available RAM in smallest device STM32F410)
if { [info exists WORKAREASIZE] } {
set _WORKAREASIZE $WORKAREASIZE
} else {
set _WORKAREASIZE 0x8000
}
#jtag scan chain
if { [info exists CPUTAPID] } {
set _CPUTAPID $CPUTAPID
} else {
if { [using_jtag] } {
# See STM Document RM0090
# Section 38.6.3 - corresponds to Cortex-M4 r0p1
set _CPUTAPID 0x4ba00477
} {
set _CPUTAPID 0x2ba01477
}
}
swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
if { [info exists BSTAPID] } {
set _BSTAPID $BSTAPID
} else {
# See STM Document RM0090
# Section 38.6.2
# STM32F405xx/07xx and STM32F415xx/17xx
set _BSTAPID1 0x06413041
# STM32F42xxx and STM32F43xxx
set _BSTAPID2 0x06419041
# See STM Document RM0368 (Rev. 3)
# STM32F401B/C
set _BSTAPID3 0x06423041
# STM32F401D/E
set _BSTAPID4 0x06433041
# See STM Document RM0383 (Rev 2)
# STM32F411
set _BSTAPID5 0x06431041
# See STM Document RM0386
# STM32F469
set _BSTAPID6 0x06434041
# See STM Document RM0401
# STM32F410
set _BSTAPID7 0x06458041
# STM32F412
set _BSTAPID8 0x06441041
}
if {[using_jtag]} {
swj_newdap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \
-expected-id $_BSTAPID2 -expected-id $_BSTAPID3 \
-expected-id $_BSTAPID4 -expected-id $_BSTAPID5 \
-expected-id $_BSTAPID6 -expected-id $_BSTAPID7 \
-expected-id $_BSTAPID8
}
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME
# JTAG speed should be <= F_CPU/6. F_CPU after reset is 16MHz, so use F_JTAG = 2MHz
#
# Since we may be running of an RC oscilator, we crank down the speed a
# bit more to be on the safe side. Perhaps superstition, but if are
# running off a crystal, we can run closer to the limit. Note
# that there can be a pretty wide band where things are more or less stable.
adapter_khz 2000
adapter_nsrst_delay 100
if {[using_jtag]} {
jtag_ntrst_delay 100
}
reset_config srst_nogate
if {![using_hla]} {
# if srst is not fitted use SYSRESETREQ to
# perform a soft reset
cortex_m reset_config sysresetreq
}
$_TARGETNAME configure -event examine-end {
# Enable debug during low power modes (uses more power)
# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP
mmw 0xE0042004 0x00000007 0
# Stop watchdog counters during halt
# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP
mmw 0xE0042008 0x00001800 0
}
$_TARGETNAME configure -event trace-config {
# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync
# change this value accordingly to configure trace pins
# assignment
mmw 0xE0042004 0x00000020 0
}
$_TARGETNAME configure -event reset-init {
# Configure PLL to boost clock to HSI x 4 (64 MHz)
mww 0x40023804 0x08012008 ;# RCC_PLLCFGR 16 Mhz /8 (M) * 128 (N) /4(P)
mww 0x40023C00 0x00000102 ;# FLASH_ACR = PRFTBE | 2(Latency)
mmw 0x40023800 0x01000000 0 ;# RCC_CR |= PLLON
sleep 10 ;# Wait for PLL to lock
mmw 0x40023808 0x00001000 0 ;# RCC_CFGR |= RCC_CFGR_PPRE1_DIV2
mmw 0x40023808 0x00000002 0 ;# RCC_CFGR |= RCC_CFGR_SW_PLL
# Boost JTAG frequency
adapter_khz 4000
}
$_TARGETNAME configure -event reset-start {
# Reduce speed since CPU speed will slow down to 16MHz with the reset
adapter_khz 2000
}
swo.sh 0 → 100755
#!/bin/bash
clear
echo "reset swo.log"
>| swo.log
tail -f swo.log
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment