diff --git a/stm-firmware/Makefile b/stm-firmware/Makefile index f2a4e1d..793e7e3 100644 --- a/stm-firmware/Makefile +++ b/stm-firmware/Makefile @@ -123,13 +123,17 @@ debug: %.hex: %.elf $(QUIET)$(OBJCOPY) -O ihex $^ $@ + #Linking -$(target).elf: $(OBJ) $(ASOBJ) $(LINKER_SCRIPT) +$(target).elf: $(OBJ) $(ASOBJ) $(LINKER_SCRIPT) updater/ram-code/updater-ram-code.bin.c @echo [LD] $@ $(QUIET)$(CC) $(LFLAGS) $(LIBRARYPATH) -o $@ $(OBJ) $(ASOBJ) $(LIBRARIES) $(QUIET)$(SIZE) $@ @echo "Built Version $(GIT_VER)" +updater/ram-code/updater-ram-code.bin.c: + $(QUIET)$(MAKE) -C updater/ram-code updater-ram-code.bin.c + #Compiling $(OBJ): @echo [CC] $@ @@ -177,6 +181,7 @@ else endif $(QUIET)rm -f $(target).elf $(target).bin $(target).hex $(OBJ) $(ASOBJ) $(mapfile).map $(CFILES:%.c=$(OBJDIR)/%.c.d) $(ASFILES:%.S=$(OBJDIR)/%.S.d) $(QUIET)rm -rf $(OBJDIR)/* + $(MAKE) -C updater/ram-code clean ifneq ($(DEBUGBUILD),true) $(QUIET)$(MAKE) DEBUGBUILD=true clean endif diff --git a/stm-firmware/stm32f407vet6_flash.ld b/stm-firmware/stm32f407vet6_flash.ld index 7a7d8b5..11edd5d 100644 --- a/stm-firmware/stm32f407vet6_flash.ld +++ b/stm-firmware/stm32f407vet6_flash.ld @@ -20,7 +20,7 @@ * RAM: 128K * CCM RAM: 64L * FPU: fpv4-sp-d16 -* +*/ /* USER PARAMETERS */ __ld_stack_size = 0x3000; diff --git a/stm-firmware/updater/ram-code/.gitignore b/stm-firmware/updater/ram-code/.gitignore new file mode 100644 index 0000000..35c0498 --- /dev/null +++ b/stm-firmware/updater/ram-code/.gitignore @@ -0,0 +1,5 @@ +obj/* +*.bin +*.bin.c +*.elf +*.map diff --git a/stm-firmware/updater/ram-code/Makefile b/stm-firmware/updater/ram-code/Makefile new file mode 100644 index 0000000..c366b17 --- /dev/null +++ b/stm-firmware/updater/ram-code/Makefile @@ -0,0 +1,62 @@ +RAM_CODE_TARGET = updater-ram-code +OBJDIR = obj +CFILES = main.c startup.c +LINKER_SCRIPT = ram-link.ld +MAPFILE = $(RAM_CODE_TARGET) +PREFIX = arm-none-eabi- + +CC = $(PREFIX)gcc +OBJCOPY = $(PREFIX)objcopy +SIZE = $(PREFIX)size + +ifneq ($(VERBOSE),true) +QUIET=@ +else +QUIET= +endif + + +DEFINES = +INCLUDEPATH = + +LFLAGS = -mlittle-endian -mthumb -mcpu=cortex-m4 -mthumb-interwork +LFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16 --disable-newlib-supplied-syscalls -nostartfiles +LFLAGS += -T$(LINKER_SCRIPT) -Wl,-Map=$(MAPFILE).map -Wl,--print-memory-usage + +CFLAGS = -c -mlittle-endian -mthumb -mcpu=cortex-m4 -mthumb-interwork -O0 +CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16 -nostartfiles +CFLAGS += -Wall -Wextra -Wold-style-declaration -Wuninitialized -Wmaybe-uninitialized -Wunused-parameter -Wimplicit-fallthrough=3 -Wsign-compare + +OBJ = $(CFILES:%.c=$(OBJDIR)/%.c.o) + +default: $(RAM_CODE_TARGET).bin.c + +all: $(RAM_CODE_TARGET).bin.c + +%.bin.c: %.bin + @echo "[BIN2C] $@" + $(QUIET)python bin2carray.py $@ $^ + +$(RAM_CODE_TARGET).bin: $(RAM_CODE_TARGET).elf + @echo "[ELF2BIN] $@" + $(QUIET)$(OBJCOPY) -O binary $^ $@ + +$(RAM_CODE_TARGET).elf: $(OBJ) $(LINKER_SCRIPT) + @echo [LD] $@ + $(QUIET)$(CC) $(LFLAGS) $(LIBRARYPATH) -o $@ $(OBJ) $(ASOBJ) $(LIBRARIES) + $(QUIET)$(SIZE) $@ + +$(OBJ): + @echo [CC] $@ + $(eval OUTPATH=$(dir $@)) + @mkdir -p $(OUTPATH) + $(QUIET)$(CC) $(CFLAGS) -MMD -MT $@ $(INCLUDEPATH) $(DEFINES) -o $@ $(@:$(OBJDIR)/%.c.o=%.c) + +.PHONY: clean + +clean: + @echo [CLEAN] + $(QUIET)rm -f $(OBJ) $(MAPFILE).map $(CFILES:%.c=$(OBJDIR)/%.c.d) $(RAM_CODE_TARGET).bin $(RAM_CODE_TARGET).elf $(RAM_CODE_TARGET).bin.c + +-include $(CFILES:%.c=$(OBJDIR)/%.c.d) + diff --git a/stm-firmware/updater/ram-code/bin2carray.py b/stm-firmware/updater/ram-code/bin2carray.py new file mode 100755 index 0000000..313735e --- /dev/null +++ b/stm-firmware/updater/ram-code/bin2carray.py @@ -0,0 +1,30 @@ +#!env python + +# Convert a file to a c array +# bin2carray + +import os +import sys + +if len(sys.argv) < 3: + sys.exit(-1) + +source_file = sys.argv[2] +dest_file = sys.argv[1] + +print("%s --> %s" % (source_file, dest_file)) + +with open(source_file, "rb") as src: + data = src.read() + +with open(dest_file, "w") as dest: + dest.write("static const char binary_blob[%d] = {\n" % (len(data))) + for current,idx in zip(data, range(len(data))): + if ((idx+1) % 4 == 0): + dest.write(hex(current)+",\n") + else: + dest.write(hex(current)+",") + + dest.write("};\n") + +sys.exit(0) diff --git a/stm-firmware/updater/ram-code/main.c b/stm-firmware/updater/ram-code/main.c new file mode 100644 index 0000000..45c0a58 --- /dev/null +++ b/stm-firmware/updater/ram-code/main.c @@ -0,0 +1,6 @@ +#include + +int ram_code_main(void) +{ + return 0; +} diff --git a/stm-firmware/updater/ram-code/ram-link.ld b/stm-firmware/updater/ram-code/ram-link.ld new file mode 100644 index 0000000..2bc5fc5 --- /dev/null +++ b/stm-firmware/updater/ram-code/ram-link.ld @@ -0,0 +1,79 @@ +/* +* STM32F407VE Linkerscript for updater RAM code execution +* Copyright (C) 2020 Mario Hüttel +* +* This file is part of 'Shimatta Reflow Controller'. +* +* It is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, version 2 of the License. +* +* This code 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 General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this template. If not, see . +* -------------------------------------------------------------------- +* FLASH: 512K +* RAM: 128K +* CCM RAM: 64L +* FPU: fpv4-sp-d16 +*/ + +ENTRY(Reset_Handler) +__ld_top_of_stack = 0x20020000; /* One byte above the end of the SRAM. Stack is pre-decrewmenting, so this is okay */ + +/* Available memory areas */ +MEMORY +{ + FLASH (xr) : ORIGIN = 0x08000000, LENGTH = 512K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K + CCM (rw) : ORIGIN = 0x10000000, LENGTH = 64K +} + +SECTIONS +{ + .vectors : + { + . = ALIGN(4); + __ld_vector_start = .; + KEEP(*(.vectors)); + . = ALIGN(4); + } > RAM + + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + KEEP(*(.init)) /* Constructors */ + KEEP(*(.fini)) /* Destructors */ + } > RAM + + .data : + { + . = ALIGN(4); + *(.data) + *(.data*) + . = ALIGN(4); + } > RAM + + .bss (NOLOAD) : + { + . = ALIGN(4); + __ld_sbss = .; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + __ld_ebss = .; + } > RAM + +} diff --git a/stm-firmware/updater/ram-code/startup.c b/stm-firmware/updater/ram-code/startup.c new file mode 100644 index 0000000..fc681c0 --- /dev/null +++ b/stm-firmware/updater/ram-code/startup.c @@ -0,0 +1,294 @@ +/* +* STM32F4 Startup Code for STM32F407 devices +* Copyright (C) 2017 Mario Hüttel +* +* This file is part of 'STM32F4 code template'. +* +* It is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, version 2 of the License. +* +* This code 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 General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this template. If not, see . +* ------------------------------------------------------------------------ +*/ + +#include + +/* C++ library init */ +# if defined(__cplusplus) +extern "C" { + extern void __libc_init_array(void); +} +#endif + +/* Defines for weak default handlers */ +#define WEAK __attribute__((weak)) +#define ALIAS(func) __attribute__ ((weak, alias (#func))) + +/* Define for section mapping */ +#define SECTION(sec) __attribute__((section(sec))) + +/* Handler prototypes */ +#if defined(_cplusplus) +extern "C" { +#endif + + +/* Interrupt Defualt handler */ +WEAK void __int_default_handler(void); + +/* Core Interrupts */ +void Reset_Handler(void); +void NMI_Handler(void) ALIAS(__int_default_handler); +void HardFault_Handler(void) ALIAS(__int_default_handler); +void MemManage_Handler(void) ALIAS(__int_default_handler); +void BusFault_Handler(void) ALIAS(__int_default_handler); +void UsageFault_Handler(void) ALIAS(__int_default_handler); +void SVC_Handler(void) ALIAS(__int_default_handler); +void DebugMon_Handler(void) ALIAS(__int_default_handler); +void PendSV_Handler(void) ALIAS(__int_default_handler); +void SysTick_Handler(void) ALIAS(__int_default_handler); + +/* Peripheral Interrupts (by default mapped onto Default Handler) */ +void WWDG_IRQHandler(void) ALIAS(__int_default_handler); +void PVD_IRQHandler(void) ALIAS(__int_default_handler); +void TAMP_STAMP_IRQHandler(void) ALIAS(__int_default_handler); +void RTC_WKUP_IRQHandler(void) ALIAS(__int_default_handler); +void FLASH_IRQHandler(void) ALIAS(__int_default_handler); +void RCC_IRQHandler(void) ALIAS(__int_default_handler); +void EXTI0_IRQHandler(void) ALIAS(__int_default_handler); +void EXTI1_IRQHandler(void) ALIAS(__int_default_handler); +void EXTI2_IRQHandler(void) ALIAS(__int_default_handler); +void EXTI3_IRQHandler(void) ALIAS(__int_default_handler); +void EXTI4_IRQHandler(void) ALIAS(__int_default_handler); +void DMA1_Stream0_IRQHandler(void) ALIAS(__int_default_handler); +void DMA1_Stream1_IRQHandler(void) ALIAS(__int_default_handler); +void DMA1_Stream2_IRQHandler(void) ALIAS(__int_default_handler); +void DMA1_Stream3_IRQHandler(void) ALIAS(__int_default_handler); +void DMA1_Stream4_IRQHandler(void) ALIAS(__int_default_handler); +void DMA1_Stream5_IRQHandler(void) ALIAS(__int_default_handler); +void DMA1_Stream6_IRQHandler(void) ALIAS(__int_default_handler); +void ADC_IRQHandler(void) ALIAS(__int_default_handler); +void CAN1_TX_IRQHandler(void) ALIAS(__int_default_handler); +void CAN1_RX0_IRQHandler(void) ALIAS(__int_default_handler); +void CAN1_RX1_IRQHandler(void) ALIAS(__int_default_handler); +void CAN1_SCE_IRQHandler(void) ALIAS(__int_default_handler); +void EXTI9_5_IRQHandler(void) ALIAS(__int_default_handler); +void TIM1_BRK_TIM9_IRQHandler(void) ALIAS(__int_default_handler); +void TIM1_UP_TIM10_IRQHandler(void) ALIAS(__int_default_handler); +void TIM1_TRG_COM_TIM11_IRQHandler(void) ALIAS(__int_default_handler); +void TIM1_CC_IRQHandler(void) ALIAS(__int_default_handler); +void TIM2_IRQHandler(void) ALIAS(__int_default_handler); +void TIM3_IRQHandler(void) ALIAS(__int_default_handler); +void TIM4_IRQHandler(void) ALIAS(__int_default_handler); +void I2C1_EV_IRQHandler(void) ALIAS(__int_default_handler); +void I2C1_ER_IRQHandler(void) ALIAS(__int_default_handler); +void I2C2_EV_IRQHandler(void) ALIAS(__int_default_handler); +void I2C2_ER_IRQHandler(void) ALIAS(__int_default_handler); +void SPI1_IRQHandler(void) ALIAS(__int_default_handler); +void SPI2_IRQHandler(void) ALIAS(__int_default_handler); +void USART1_IRQHandler(void) ALIAS(__int_default_handler); +void USART2_IRQHandler(void) ALIAS(__int_default_handler); +void USART3_IRQHandler(void) ALIAS(__int_default_handler); +void EXTI15_10_IRQHandler(void) ALIAS(__int_default_handler); +void RTC_Alarm_IRQHandler(void) ALIAS(__int_default_handler); +void OTG_FS_WKUP_IRQHandler(void) ALIAS(__int_default_handler); +void TIM8_BRK_TIM12_IRQHandler(void) ALIAS(__int_default_handler); +void TIM8_UP_TIM13_IRQHandler(void) ALIAS(__int_default_handler); +void TIM8_TRG_COM_TIM14_IRQHandler(void) ALIAS(__int_default_handler); +void TIM8_CC_IRQHandler(void) ALIAS(__int_default_handler); +void DMA1_Stream7_IRQHandler(void) ALIAS(__int_default_handler); +void FSMC_IRQHandler(void) ALIAS(__int_default_handler); +void SDIO_IRQHandler(void) ALIAS(__int_default_handler); +void TIM5_IRQHandler(void) ALIAS(__int_default_handler); +void SPI3_IRQHandler(void) ALIAS(__int_default_handler); +void UART4_IRQHandler(void) ALIAS(__int_default_handler); +void UART5_IRQHandler(void) ALIAS(__int_default_handler); +void TIM6_DAC_IRQHandler(void) ALIAS(__int_default_handler); +void TIM7_IRQHandler(void) ALIAS(__int_default_handler); +void DMA2_Stream0_IRQHandler(void) ALIAS(__int_default_handler); +void DMA2_Stream1_IRQHandler(void) ALIAS(__int_default_handler); +void DMA2_Stream2_IRQHandler(void) ALIAS(__int_default_handler); +void DMA2_Stream3_IRQHandler(void) ALIAS(__int_default_handler); +void DMA2_Stream4_IRQHandler(void) ALIAS(__int_default_handler); +void ETH_IRQHandler(void) ALIAS(__int_default_handler); +void ETH_WKUP_IRQHandler(void) ALIAS(__int_default_handler); +void CAN2_TX_IRQHandler(void) ALIAS(__int_default_handler); +void CAN2_RX0_IRQHandler(void) ALIAS(__int_default_handler); +void CAN2_RX1_IRQHandler(void) ALIAS(__int_default_handler); +void CAN2_SCE_IRQHandler(void) ALIAS(__int_default_handler); +void OTG_FS_IRQHandler(void) ALIAS(__int_default_handler); +void DMA2_Stream5_IRQHandler(void) ALIAS(__int_default_handler); +void DMA2_Stream6_IRQHandler(void) ALIAS(__int_default_handler); +void DMA2_Stream7_IRQHandler(void) ALIAS(__int_default_handler); +void USART6_IRQHandler(void) ALIAS(__int_default_handler); +void I2C3_EV_IRQHandler(void) ALIAS(__int_default_handler); +void I2C3_ER_IRQHandler(void) ALIAS(__int_default_handler); +void OTG_HS_EP1_OUT_IRQHandler(void) ALIAS(__int_default_handler); +void OTG_HS_EP1_IN_IRQHandler(void) ALIAS(__int_default_handler); +void OTG_HS_WKUP_IRQHandler(void) ALIAS(__int_default_handler); +void OTG_HS_IRQHandler(void) ALIAS(__int_default_handler); +void DCMI_IRQHandler(void) ALIAS(__int_default_handler); +void CRYP_IRQHandler(void) ALIAS(__int_default_handler); +void HASH_RNG_IRQHandler(void) ALIAS(__int_default_handler); +void FPU_IRQHandler(void) ALIAS(__int_default_handler); + +extern int ram_code_main(void); +extern void SystemInit(void); + +extern void __ld_top_of_stack(void); +#if defined(_cplusplus) +extern "C" } +#endif + +void (* const vector_table[])(void) SECTION(".vectors") = { + &__ld_top_of_stack, + /* Core Interrupts */ + Reset_Handler, + NMI_Handler, + HardFault_Handler, + MemManage_Handler, + BusFault_Handler, + UsageFault_Handler, + 0, + 0, + 0, + 0, + SVC_Handler, + DebugMon_Handler, + 0, + PendSV_Handler, + SysTick_Handler, + /* Peripheral Interrupts */ + WWDG_IRQHandler, + PVD_IRQHandler, + TAMP_STAMP_IRQHandler, + RTC_WKUP_IRQHandler, + FLASH_IRQHandler, + RCC_IRQHandler, + EXTI0_IRQHandler, + EXTI1_IRQHandler, + EXTI2_IRQHandler, + EXTI3_IRQHandler, + EXTI4_IRQHandler, + DMA1_Stream0_IRQHandler, + DMA1_Stream1_IRQHandler, + DMA1_Stream2_IRQHandler, + DMA1_Stream3_IRQHandler, + DMA1_Stream4_IRQHandler, + DMA1_Stream5_IRQHandler, + DMA1_Stream6_IRQHandler, + ADC_IRQHandler, + CAN1_TX_IRQHandler, + CAN1_RX0_IRQHandler, + CAN1_RX1_IRQHandler, + CAN1_SCE_IRQHandler, + EXTI9_5_IRQHandler, + TIM1_BRK_TIM9_IRQHandler, + TIM1_UP_TIM10_IRQHandler, + TIM1_TRG_COM_TIM11_IRQHandler, + TIM1_CC_IRQHandler, + TIM2_IRQHandler, + TIM3_IRQHandler, + TIM4_IRQHandler, + I2C1_EV_IRQHandler, + I2C1_ER_IRQHandler, + I2C2_EV_IRQHandler, + I2C2_ER_IRQHandler, + SPI1_IRQHandler, + SPI2_IRQHandler, + USART1_IRQHandler, + USART2_IRQHandler, + USART3_IRQHandler, + EXTI15_10_IRQHandler, + RTC_Alarm_IRQHandler, + OTG_FS_WKUP_IRQHandler, + TIM8_BRK_TIM12_IRQHandler, + TIM8_UP_TIM13_IRQHandler, + TIM8_TRG_COM_TIM14_IRQHandler, + TIM8_CC_IRQHandler, + DMA1_Stream7_IRQHandler, + FSMC_IRQHandler, + SDIO_IRQHandler, + TIM5_IRQHandler, + SPI3_IRQHandler, + UART4_IRQHandler, + UART5_IRQHandler, + TIM6_DAC_IRQHandler, + TIM7_IRQHandler, + DMA2_Stream0_IRQHandler, + DMA2_Stream1_IRQHandler, + DMA2_Stream2_IRQHandler, + DMA2_Stream3_IRQHandler, + DMA2_Stream4_IRQHandler, + ETH_IRQHandler, + ETH_WKUP_IRQHandler, + CAN2_TX_IRQHandler, + CAN2_RX0_IRQHandler, + CAN2_RX1_IRQHandler, + CAN2_SCE_IRQHandler, + OTG_FS_IRQHandler, + DMA2_Stream5_IRQHandler, + DMA2_Stream6_IRQHandler, + DMA2_Stream7_IRQHandler, + USART6_IRQHandler, + I2C3_EV_IRQHandler, + I2C3_ER_IRQHandler, + OTG_HS_EP1_OUT_IRQHandler, + OTG_HS_EP1_IN_IRQHandler, + OTG_HS_WKUP_IRQHandler, + OTG_HS_IRQHandler, + DCMI_IRQHandler, + CRYP_IRQHandler, + HASH_RNG_IRQHandler, + FPU_IRQHandler +}; + +static void __fill_zero(unsigned int *start, unsigned int *end) { + while ((unsigned int) start < (unsigned int)end) { + *(start++) = 0x00000000; + } +} + +extern unsigned int __ld_vector_start; +extern unsigned int __ld_sbss; +extern unsigned int __ld_ebss; + + +#ifdef CPACR +#undef CPACR +#endif + +#define CPACR (*((volatile uint32_t *)0xE000ED88)) + +void Reset_Handler(void) { + /* Stack is already initialized by hardware */ + + /* The first thing we do here, is to initialize the FPU + * When this code is compiled optimized with hardfpu abi, + * GCC tends to generate FPU instructions for data copying + */ + CPACR |= (0xF << 20); + /* Reset the stack pointer to top of stack. SP is not required to be inside the clobber list! */ + __asm__ __volatile__ ("mov sp, %0\n\t" :: "r"(&__ld_top_of_stack) :); + + /* Fill bss with zero */ + __fill_zero(&__ld_sbss, &__ld_ebss); + /* Fill Heap with zero */ + + ram_code_main(); + + /* Catch return from main() */ + while(1); +} + +WEAK void __int_default_handler(void) +{ + while(1); +}