Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion release.Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ BUILD_DIR ?= ./build

all: dapboot-bluepill.bin \
dapboot-maplemini.bin \
dapboot-stlink.bin
dapboot-stlink.bin \
dapboot-bluepill-128.bin \
dapboot-maplemini-128.bin \
dapboot-stlink-128.bin

clean:
$(Q)$(RM) $(BUILD_DIR)/*.bin
Expand Down Expand Up @@ -59,3 +62,21 @@ dapboot-maplemini.bin: | $(BUILD_DIR)
$(Q)$(MAKE) TARGET=MAPLEMINI -C src/ clean
$(Q)$(MAKE) TARGET=MAPLEMINI -C src/
$(Q)cp src/dapboot.bin $(BUILD_DIR)/$(@)

dapboot-bluepill-128.bin: | $(BUILD_DIR)
@printf " BUILD $(@)\n"
$(Q)$(MAKE) TARGET=BLUEPILL_128 -C src/ clean
$(Q)$(MAKE) TARGET=BLUEPILL_128 -C src/
$(Q)cp src/dapboot.bin $(BUILD_DIR)/$(@)

dapboot-stlink-128.bin: | $(BUILD_DIR)
@printf " BUILD $(@)\n"
$(Q)$(MAKE) TARGET=STLINK_128 -C src/ clean
$(Q)$(MAKE) TARGET=STLINK_128 -C src/
$(Q)cp src/dapboot.bin $(BUILD_DIR)/$(@)

dapboot-maplemini-128.bin: | $(BUILD_DIR)
@printf " BUILD $(@)\n"
$(Q)$(MAKE) TARGET=MAPLEMINI_128 -C src/ clean
$(Q)$(MAKE) TARGET=MAPLEMINI_128 -C src/
$(Q)cp src/dapboot.bin $(BUILD_DIR)/$(@)
1 change: 1 addition & 0 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ include targets.mk
SRCS := $(wildcard *.c)
SRCS += $(wildcard $(TARGET_COMMON_DIR)/*.c)
SRCS += $(wildcard $(TARGET_SPEC_DIR)/*.c)
SRCS += $(wildcard ./libc/*.c)

OBJS += $(SRCS:.c=.o)
DEPS = $(SRCS:.c=.d)
Expand Down
14 changes: 6 additions & 8 deletions src/dapboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ static inline void __set_MSP(uint32_t topOfMainStack) {
asm("msr msp, %0" : : "r" (topOfMainStack));
}

extern volatile const vector_table_t vector_table;

bool validate_application(void) {
if ((*(volatile uint32_t *)APP_BASE_ADDRESS & 0x2FFE0000) == 0x20000000) {
if (((uint32_t)(vector_table.reserved_x001c[0]) & 0x2FFE0000) == 0x20000000) {
return true;
}
return false;
Expand All @@ -41,20 +43,16 @@ bool validate_application(void) {
static void jump_to_application(void) __attribute__ ((noreturn));

static void jump_to_application(void) {
vector_table_t* app_vector_table = (vector_table_t*)APP_BASE_ADDRESS;

/* Use the application's vector table */
target_relocate_vector_table();

/* Do any necessary early setup for the application */
target_pre_main();

/* Initialize the application's stack pointer */
__set_MSP((uint32_t)(app_vector_table->initial_sp_value));
__set_MSP((uint32_t)(vector_table.reserved_x001c[0]));

/* Jump to the application entry point */
app_vector_table->reset();
vector_table.reserved_x001c[1]();

while (1);
}

Expand Down
36 changes: 35 additions & 1 deletion src/dfu.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/dfu.h>
#include <libopencm3/cm3/vector.h>

#include "dfu.h"
#include "usb_conf.h"
Expand Down Expand Up @@ -94,6 +95,23 @@ static void dfu_on_download_request(usbd_device* usbd_dev, struct usb_setup_data
(void)usbd_dev;
(void)req;

if (current_dfu_offset == 0) {
if (dfu_download_size < offsetof(vector_table_t, reserved_x001c[1])) {
/* Can't handle splitting the vector table right now */
dfu_set_status(DFU_STATUS_ERR_VENDOR);
} else {
vector_table_t* app_vector_table = (vector_table_t*)dfu_download_buffer;
/* Stash the application's initial stack value and reset
pointer in unused vector table entries */
app_vector_table->reserved_x001c[0] = (vector_table_entry_t)(app_vector_table->initial_sp_value);
app_vector_table->reserved_x001c[1] = app_vector_table->reset;
/* Overwrite the stack and reset pointer to run the
bootloader instead */
app_vector_table->initial_sp_value = &_stack;
app_vector_table->reset = reset_handler;
}
}

const uint16_t* data = (uint16_t*)dfu_download_buffer;
uint16_t* dest = (uint16_t*)(APP_BASE_ADDRESS + current_dfu_offset);

Expand Down Expand Up @@ -234,7 +252,6 @@ static int dfu_control_class_request(usbd_device *usbd_dev,
__attribute__ ((fallthrough));
}
case STATE_DFU_UPLOAD_IDLE: {
*buf = (uint8_t*)(APP_BASE_ADDRESS + current_dfu_offset);
uint16_t len_to_copy = req->wLength;
size_t max_firmware_size = target_get_max_firmware_size();
if (current_dfu_offset + req->wLength > max_firmware_size) {
Expand All @@ -244,6 +261,23 @@ static int dfu_control_class_request(usbd_device *usbd_dev,
dfu_set_state(STATE_DFU_UPLOAD_IDLE);
}
*len = len_to_copy;
if (current_dfu_offset < sizeof(vector_table_t)) {
/* Copy the flash memory to the download buffer, to
undo the vector modifications. */
memcpy(dfu_download_buffer, (const void*)(APP_BASE_ADDRESS),
sizeof(dfu_download_buffer));
vector_table_t* app_vector_table = (vector_table_t*)dfu_download_buffer;
/* Put the original stack pointer and reset vectors
back */
app_vector_table->initial_sp_value = (unsigned int*)(app_vector_table->reserved_x001c[0]);
app_vector_table->reset = app_vector_table->reserved_x001c[1];
app_vector_table->reserved_x001c[0] = 0;
app_vector_table->reserved_x001c[1] = 0;
/* Return the correct pointer */
*buf = dfu_download_buffer + current_dfu_offset;
} else {
*buf = (uint8_t*)(APP_BASE_ADDRESS + current_dfu_offset);
}
current_dfu_offset += len_to_copy;
break;
}
Expand Down
19 changes: 19 additions & 0 deletions src/libc/memcpy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* memcpy.c: Smaller memcpy implementation.
*/

#include <string.h>

// This makes GCC avoid replacing this with a call to builtin_memcpy
#pragma GCC optimize "Os"

void *memcpy(void *dst, const void *src, size_t len)
{
char *d = (char *)dst;
const char *s = (const char *)src;

while(len--)
*d++ = *s++;

return dst;
}
15 changes: 15 additions & 0 deletions src/libc/strlen.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* strlen.c: Smaller strlen implementation.
*/

#include <string.h>

// This makes GCC avoid replacing this with a call to builtin_strlen
#pragma GCC optimize "Os"

size_t strlen(const char *str)
{
const char *start = str + 1;
while(*str++);
return str - start;
}
15 changes: 15 additions & 0 deletions src/libc/strncpy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* strncpy.c: Smaller strncpy implementation.
*/

#include <string.h>

// This makes GCC avoid replacing this with a call to builtin_strncpy
#pragma GCC optimize "Os"

char *strncpy(char *dst, const char *src, size_t len)
{
char *d = dst;
while( len-- && '\0' != (*d++ = *src++) );
return dst;
}
2 changes: 1 addition & 1 deletion src/stm32f103/bluepill/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#define CONFIG_H_INCLUDED

#ifndef APP_BASE_ADDRESS
#define APP_BASE_ADDRESS 0x08002000
#define APP_BASE_ADDRESS 0x08000000
#endif
#ifndef FLASH_SIZE_OVERRIDE
#define FLASH_SIZE_OVERRIDE 0x20000
Expand Down
109 changes: 109 additions & 0 deletions src/stm32f103/common.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* This file is part of the dapboot project.
*
* Copyright (C) 2016 Devan Lai <devan.lai@gmail.com>
* Copyright (C) 2015 Karl Palsson <karlp@tweak.net.au>
* Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/

/* Common linker script */

/* Enforce emission of the vector table. */
EXTERN (vector_table)

/* Define the entry point of the output file. */
ENTRY(reset_handler)

/* Define sections. */
SECTIONS
{
/* Vector table for the initial upload */
.vectors : {
*(.vectors)
} >bootstrap

.text : {
*(.text*) /* Program code */
. = ALIGN(4);
*(.rodata*) /* Read-only data */
. = ALIGN(4);
} >rom

/* C++ Static constructors/destructors, also used for __attribute__
* ((constructor)) and the likes */
.preinit_array : {
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
} >rom
.init_array : {
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
} >rom
.fini_array : {
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
} >rom

/*
* Another section used by C++ stuff, appears when using newlib with
* 64bit (long long) printf support
*/
.ARM.extab : {
*(.ARM.extab*)
} >rom
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >rom

. = ALIGN(4);
_etext = .;

.data : {
_data = .;
*(.data*) /* Read-write initialized data */
. = ALIGN(4);
_edata = .;
} >ram AT >rom
_data_loadaddr = LOADADDR(.data);

.bss : {
*(.bss*) /* Read-write zero initialized data */
*(COMMON)
. = ALIGN(4);
_ebss = .;
} >ram

/*
* The .eh_frame section appears to be used for C++ exception handling.
* You may need to fix this if you're using C++.
*/
/DISCARD/ : { *(.eh_frame) }

. = ALIGN(4);
end = .;
}

PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram));
2 changes: 1 addition & 1 deletion src/stm32f103/generic/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#define CONFIG_H_INCLUDED

#ifndef APP_BASE_ADDRESS
#define APP_BASE_ADDRESS 0x08002000
#define APP_BASE_ADDRESS 0x08000000
#endif
#ifndef FLASH_SIZE_OVERRIDE
#define FLASH_SIZE_OVERRIDE 0x20000
Expand Down
2 changes: 1 addition & 1 deletion src/stm32f103/maplemini/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#define CONFIG_H_INCLUDED

#ifndef APP_BASE_ADDRESS
#define APP_BASE_ADDRESS 0x08002000
#define APP_BASE_ADDRESS 0x08000000
#endif
#ifndef FLASH_PAGE_SIZE
#define FLASH_PAGE_SIZE 1024
Expand Down
2 changes: 1 addition & 1 deletion src/stm32f103/stlink/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#define CONFIG_H_INCLUDED

#ifndef APP_BASE_ADDRESS
#define APP_BASE_ADDRESS 0x08002000
#define APP_BASE_ADDRESS 0x08000000
#endif
#ifndef FLASH_SIZE_OVERRIDE
#define FLASH_SIZE_OVERRIDE 0x20000
Expand Down
14 changes: 9 additions & 5 deletions src/stm32f103/stm32f103x8.ld
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/*
* This file is part of the libopencm3 project.
* This file is part of the dapboot project.
*
* Copyright (C) 2016 Devan Lai <devan.lai@gmail.com>
* Copyright (C) 2015 Karl Palsson <karlp@tweak.net.au>
* Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
Expand All @@ -20,12 +22,14 @@
/* Linker script for STM32F103x8, 64k flash, 20k RAM. */

/* Define memory regions. */
/* 8k for the bootloader */
/* 6.5k for the bootloader at the end, with a copy of the vector table at the
* beginning to bootstrap the bootloader
*/
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 8K
bootstrap (rx) : ORIGIN = 0x08000000, LENGTH = 1K
rom (rx) : ORIGIN = 0x0800e600, LENGTH = 0x1A00
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
}

/* Include the common ld script. */
INCLUDE libopencm3_stm32f1.ld
INCLUDE stm32f103/common.ld
Loading