Skip to content

Commit a7e306f

Browse files
Hoernchenlaf0rge
authored andcommitted
firmware: add bootloader update "app"
This bl updater can be flashed as app and will update the bootloader and then delete itself before resetting the sam3, so the device will end up in the newly updated dfu bootloader afterwards, without having to press the bootloader button or requring any other manual interaction, ready to receive a new application image. Building the blupdater requires a previously built dfu-flash bootloader bin file that will then be embedded into the app during building. Related: OS#1704 Related: SYS5061 Change-Id: I53dea57bba790a2ab3245d9483e0ff1c8d19d5e3
1 parent 020edca commit a7e306f

File tree

5 files changed

+192
-9
lines changed

5 files changed

+192
-9
lines changed

Makefile

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,23 @@ fw-$(1)-$(2)-clean:
88
endef
99

1010
$(eval $(call RULES,simtrace,dfu))
11+
$(eval $(call RULES,simtrace,blupdate))
1112
$(eval $(call RULES,simtrace,trace))
1213
$(eval $(call RULES,simtrace,cardem))
1314
$(eval $(call RULES,qmod,dfu))
15+
$(eval $(call RULES,qmod,blupdate))
1416
$(eval $(call RULES,qmod,cardem))
1517
$(eval $(call RULES,ngff_cardem,dfu))
18+
$(eval $(call RULES,ngff_cardem,blupdate))
1619
$(eval $(call RULES,ngff_cardem,trace))
1720
$(eval $(call RULES,ngff_cardem,cardem))
1821

19-
fw-clean: fw-simtrace-dfu-clean fw-simtrace-trace-clean fw-simtrace-cardem-clean fw-qmod-dfu-clean fw-qmod-cardem-clean
20-
fw: fw-simtrace-dfu fw-simtrace-trace fw-simtrace-cardem fw-qmod-dfu fw-qmod-cardem fw-ngff_cardem-dfu fw-ngff_cardem-trace fw-ngff_cardem-cardem
22+
fw-clean: fw-simtrace-dfu-clean fw-simtrace-blupdate-clean fw-simtrace-trace-clean fw-simtrace-cardem-clean \
23+
fw-qmod-dfu-clean fw-qmod-blupdate-clean fw-qmod-cardem-clean \
24+
fw-ngff_cardem-dfu-clean fw-ngff_cardem-blupdate-clean fw-ngff_cardem-trace-clean fw-ngff_cardem-cardem-clean
25+
fw: fw-simtrace-dfu fw-simtrace-blupdate fw-simtrace-trace fw-simtrace-cardem \
26+
fw-qmod-dfu fw-qmod-blupdate fw-qmod-cardem \
27+
fw-ngff_cardem-dfu fw-ngff_cardem-blupdate fw-ngff_cardem-trace fw-ngff_cardem-cardem
2128

2229
utils:
2330
(cd host && \

firmware/Makefile

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -245,26 +245,48 @@ apps/$(APP)/usb_strings_generated.h: apps/$(APP)/usb_strings.txt.patched usbstri
245245
define RULES
246246
C_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(C_OBJECTS))
247247
ASM_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(ASM_OBJECTS))
248+
EXTRA_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(EXTRA_OBJECTS))
248249

249-
$(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1))
250-
$(SILENT)$(CC) $(CFLAGS) $(LDFLAGS) $(LD_OPTIONAL) -T"libboard/common/resources/$(CHIP)/$$@.ld" -Wl,-Map,$(OUTPUT)-$$@.map -o $(OUTPUT)-$$@.elf $$^ $(LIBS)
251-
$(SILENT)$(NM) $(OUTPUT)-$$@.elf >$(OUTPUT)-$$@.elf.txt
252-
$(SILENT)$(OBJCOPY) -O binary $(OUTPUT)-$$@.elf $(OUTPUT)-$$@.bin
253-
$(SILENT)$(SIZE) $$^ $(OUTPUT)-$$@.elf
250+
build_$(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1)) $$(EXTRA_OBJECTS_$(1))
251+
$(SILENT)$(CC) $(CFLAGS) $(LDFLAGS) $(LD_OPTIONAL) -T"libboard/common/resources/$(CHIP)/$(1).ld" -Wl,-Map,$(OUTPUT)-$(1).map -o $(OUTPUT)-$(1).elf $$^ $(LIBS)
252+
$(SILENT)$(NM) $(OUTPUT)-$(1).elf >$(OUTPUT)-$(1).elf.txt
253+
$(SILENT)$(OBJCOPY) -O binary $(OUTPUT)-$(1).elf $(OUTPUT)-$(1).bin
254+
$(SILENT)$(SIZE) $$^ $(OUTPUT)-$(1).elf
254255

255256
$$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)
256257
@echo [COMPILING $$<]
257258
$(SILENT)$(CC) $(CFLAGS) -DENVIRONMENT_$(1) -DENVIRONMENT=\"$(1)\" -c -o $$@ $$<
258259

259260
$$(ASM_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.S Makefile $(OBJ) $(BIN)
260261
@echo [ASSEMBLING $$@]
261-
$(SILENT)@$(CC) $(ASFLAGS) -DENVIRONMENT_$(1) -DENVIRONMENT=\"$(1)\" -c -o $$@ $$<
262+
$(SILENT)$(CC) $(ASFLAGS) -DENVIRONMENT_$(1) -DENVIRONMENT=\"$(1)\" -c -o $$@ $$<
262263

263264
debug_$(1): $(1)
264265
$(GDB) -x "$(BOARD_LIB)/resources/gcc/$(BOARD)_$(1).gdb" -ex "reset" -readnow -se $(OUTPUT)-$(1).elf
265266
endef
266267

267-
$(foreach MEMORY, $(MEMORIES), $(eval $(call RULES,$(MEMORY))))
268+
ALL_MEMORIES = dfu flash ram
269+
$(foreach MEMORY, $(ALL_MEMORIES), $(eval $(call RULES,$(MEMORY))))
270+
271+
# files with those names do exist..
272+
.PHONY: ram
273+
.PHONY: dfu
274+
.PHONY: flash
275+
ram: build_ram
276+
dfu: build_dfu
277+
ifeq ($(APP), blupdate)
278+
$(info updating updater section with padded bootloader file..)
279+
$(SILENT)dd if=/dev/zero bs=16384 count=1 of=$(BIN)/$(BOARD)-dfu-flash-padded.bin
280+
$(SILENT)dd if=$(BIN)/$(BOARD)-dfu-flash.bin conv=notrunc of=$(BIN)/$(BOARD)-dfu-flash-padded.bin
281+
$(SILENT)$(OBJCOPY) --update-section .blupdate=bin/$(BOARD)-dfu-flash-padded.bin bin/$(BOARD)-blupdate-dfu.elf
282+
$(SILENT)$(OBJCOPY) -O binary bin/$(BOARD)-blupdate-dfu.elf bin/$(BOARD)-blupdate-dfu.bin
283+
endif
284+
flash: build_flash
285+
#alternate way of embedding: obj file
286+
#ifeq ($(APP), dfu)
287+
# $(info bootloader bin file to obj..)
288+
# $(SILENT)$(OBJCOPY) --rename-section .data=.fwupdate -I binary -O elf32-littlearm bin/$(BOARD)-dfu-flash.bin $(OBJ)/flash_fwupdate.o
289+
#endif
268290

269291
program:
270292
openocd -f openocd/openocd.cfg -c "init" -c "halt" -c "flash write_bank 0 ./bin/project-flash.bin 0" -c "reset" -c "shutdown"

firmware/apps/blupdate/Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
C_FILES += $(C_LIBUSB_DFU)
3+
4+
# Trace level used for compilation
5+
# (can be overridden by adding TRACE_LEVEL=#number to the command-line)
6+
# TRACE_LEVEL_DEBUG 5
7+
# TRACE_LEVEL_INFO 4
8+
# TRACE_LEVEL_WARNING 3
9+
# TRACE_LEVEL_ERROR 2
10+
# TRACE_LEVEL_FATAL 1
11+
# TRACE_LEVEL_NO_TRACE 0
12+
TRACE_LEVEL ?= 3

firmware/apps/blupdate/main.c

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/* SIMtrace 2 firmware USB DFU bootloader
2+
*
3+
* (C) 2015-2017 by Harald Welte <[email protected]>
4+
* (C) 2018-2019 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <[email protected]>
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU General Public License
8+
* as published by the Free Software Foundation; either version 2
9+
* of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program; if not, write to the Free Software
18+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
#include "board.h"
21+
#include "core_cm3.h"
22+
#include "flashd.h"
23+
#include "utils.h"
24+
#include "usb/device/dfu/dfu.h"
25+
#include "usb/common/dfu/usb_dfu.h"
26+
#include "manifest.h"
27+
#include "USBD_HAL.h"
28+
29+
#include <osmocom/core/timer.h>
30+
31+
/* actual section content must be replaced with the padded bootloader by running objcopy! */
32+
const uint32_t bl_update_data[BOARD_DFU_BOOT_SIZE / sizeof(uint32_t)] __attribute__((section(".fwupdate"))) = { 0xFF };
33+
34+
unsigned int g_unique_id[4];
35+
/* remember if the watchdog has been configured in the main loop so we can kick it in the ISR */
36+
static bool watchdog_configured = false;
37+
38+
extern uint32_t _end;
39+
extern uint32_t _srelocate;
40+
extern uint32_t _etext;
41+
42+
void DFURT_SwitchToDFU(void)
43+
{
44+
}
45+
void USBDFU_Runtime_RequestHandler(const USBGenericRequest *request)
46+
{
47+
}
48+
int USBDFU_handle_dnload(uint8_t altif, unsigned int offset, uint8_t *data, unsigned int len)
49+
{
50+
return 0;
51+
}
52+
int USBDFU_handle_upload(uint8_t altif, unsigned int offset, uint8_t *data, unsigned int req_len)
53+
{
54+
return 0;
55+
}
56+
int USBDFU_OverrideEnterDFU(void)
57+
{
58+
return 0;
59+
}
60+
61+
__attribute__((section(".ramfunc"), noinline)) static uint32_t flash_wait_ready()
62+
{
63+
Efc *efc = EFC;
64+
uint32_t dwStatus;
65+
66+
do {
67+
dwStatus = efc->EEFC_FSR;
68+
} while ((dwStatus & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
69+
return (dwStatus & (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE));
70+
}
71+
72+
__attribute__((section(".ramfunc"), noinline)) static void flash_cmd(uint32_t dwCommand, uint32_t dwArgument)
73+
{
74+
Efc *efc = EFC;
75+
uint32_t dwStatus;
76+
efc->EEFC_FCR = EEFC_FCR_FKEY(0x5A) | EEFC_FCR_FARG(dwArgument) | EEFC_FCR_FCMD(dwCommand);
77+
}
78+
79+
__attribute__((section(".ramfunc"), noinline, noreturn)) static void erase_first_app_sector()
80+
{
81+
/* page 64 */
82+
uint32_t first_app_page = (BOARD_DFU_BOOT_SIZE / IFLASH_PAGE_SIZE);
83+
uint32_t *first_app_address = (uint32_t *)(IFLASH_ADDR + first_app_page * IFLASH_PAGE_SIZE + 0);
84+
85+
#if 1
86+
/* overwrite first app sector so we don't keep booting this */
87+
for (int i = 0; i < IFLASH_PAGE_SIZE / 4; i++)
88+
first_app_address[i] = 0xffffffff;
89+
90+
flash_cmd(EFC_FCMD_EWP, first_app_page);
91+
#else
92+
/* why does erasing the whole flash with a protected bootloader not work at all? */
93+
flash_cmd(EFC_FCMD_EA, 0);
94+
#endif
95+
flash_wait_ready();
96+
for (;;)
97+
NVIC_SystemReset();
98+
}
99+
100+
#define MAX_USB_ITER BOARD_MCK / 72 // This should be around a second
101+
extern int main(void)
102+
{
103+
uint8_t isUsbConnected = 0;
104+
unsigned int i = 0;
105+
uint32_t reset_cause = (RSTC->RSTC_SR & RSTC_SR_RSTTYP_Msk) >> RSTC_SR_RSTTYP_Pos;
106+
107+
/* Enable watchdog for 2000ms, with no window */
108+
WDT_Enable(WDT, WDT_MR_WDRSTEN | WDT_MR_WDDBGHLT | WDT_MR_WDIDLEHLT | (WDT_GetPeriod(2000) << 16) |
109+
WDT_GetPeriod(2000));
110+
watchdog_configured = true;
111+
112+
EEFC_ReadUniqueID(g_unique_id);
113+
114+
printf("\n\r\n\r");
115+
printf("bootloader updater %s for board %s\n\r"
116+
"(C) 2010-2017 by Harald Welte, 2018-2019 by Kevin Redon\n\r",
117+
manifest_revision, manifest_board);
118+
119+
/* clear g_dfu on power-up reset */
120+
memset(g_dfu, 0, sizeof(*g_dfu));
121+
122+
TRACE_INFO("USB init...\n\r");
123+
/* Signal USB reset by disabling the pull-up on USB D+ for at least 10 ms */
124+
USBD_Disconnect();
125+
126+
/* Initialize the flash to be able to write it, using the IAP ROM code */
127+
FLASHD_Initialize(BOARD_MCK, 1);
128+
129+
__disable_irq();
130+
FLASHD_Unlock(IFLASH_ADDR, IFLASH_ADDR + IFLASH_SIZE - 1, 0, 0);
131+
FLASHD_Write(IFLASH_ADDR, bl_update_data, BOARD_DFU_BOOT_SIZE);
132+
133+
erase_first_app_sector();
134+
}

firmware/libboard/common/resources/sam3s4/dfu.ld

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,14 @@ SECTIONS
101101
*(.ARM.exidx)
102102
}
103103

104+
.blupdate :
105+
{
106+
. = ALIGN(4);
107+
_blupdate_start = .;
108+
KEEP(*(.fwupdate .fwupdate.*));
109+
_blupdate_end = .;
110+
} > rom
111+
104112
. = ALIGN(4);
105113
_etext = .;
106114

0 commit comments

Comments
 (0)